diff --git a/.gitattributes b/.gitattributes index cf5cffa2..b867c9f7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ *.bat text eol=crlf -*.cmd text eol=crlf \ No newline at end of file +*.cmd text eol=crlf +webui/dist/** binary \ No newline at end of file diff --git a/.github/workflows/docker-image-dev.yml b/.github/workflows/docker-image-dev.yml new file mode 100644 index 00000000..63fdafee --- /dev/null +++ b/.github/workflows/docker-image-dev.yml @@ -0,0 +1,160 @@ +name: Docker Build and Push (Dev) + +on: + schedule: + - cron: '0 0 * * *' # every day at midnight UTC + # branches: + # - dev + workflow_dispatch: # 允许手动触发工作流 + inputs: + branch: + description: 'Branch to build' + required: false + default: 'dev' + +# Workflow's jobs +jobs: + build-amd64: + name: Build AMD64 Image + runs-on: ubuntu-24.04 + outputs: + digest: ${{ steps.build.outputs.digest }} + steps: + - name: Check out git repository + uses: actions/checkout@v4 + with: + ref: dev + fetch-depth: 0 + + # Clone required dependencies + # - name: Clone maim_message + # run: git clone https://github.com/MaiM-with-u/maim_message maim_message + + - name: Clone lpmm + run: git clone https://github.com/Mai-with-u/MaiMBot-LPMM.git MaiMBot-LPMM + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: --debug + + # Log in docker hub + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Generate metadata for Docker images + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ secrets.DOCKERHUB_USERNAME }}/maibot + + # Build and push AMD64 image by digest + - name: Build and push AMD64 + id: build + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64 + labels: ${{ steps.meta.outputs.labels }} + file: ./Dockerfile + cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/maibot:dev-amd64-buildcache + cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/maibot:dev-amd64-buildcache,mode=max + outputs: type=image,name=${{ secrets.DOCKERHUB_USERNAME }}/maibot,push-by-digest=true,name-canonical=true,push=true + build-args: | + BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') + VCS_REF=${{ github.sha }} + + build-arm64: + name: Build ARM64 Image + runs-on: ubuntu-24.04-arm + outputs: + digest: ${{ steps.build.outputs.digest }} + steps: + - name: Check out git repository + uses: actions/checkout@v4 + with: + ref: dev + fetch-depth: 0 + + # Clone required dependencies + # - name: Clone maim_message + # run: git clone https://github.com/MaiM-with-u/maim_message maim_message + + - name: Clone lpmm + run: git clone https://github.com/Mai-with-u/MaiMBot-LPMM.git MaiMBot-LPMM + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: --debug + + # Log in docker hub + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Generate metadata for Docker images + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ secrets.DOCKERHUB_USERNAME }}/maibot + + # Build and push ARM64 image by digest + - name: Build and push ARM64 + id: build + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/arm64/v8 + labels: ${{ steps.meta.outputs.labels }} + file: ./Dockerfile + cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/maibot:dev-arm64-buildcache + cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/maibot:dev-arm64-buildcache,mode=max + outputs: type=image,name=${{ secrets.DOCKERHUB_USERNAME }}/maibot,push-by-digest=true,name-canonical=true,push=true + build-args: | + BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') + VCS_REF=${{ github.sha }} + + create-manifest: + name: Create Multi-Arch Manifest + runs-on: ubuntu-24.04 + needs: + - build-amd64 + - build-arm64 + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # Log in docker hub + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Generate metadata for Docker images + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ secrets.DOCKERHUB_USERNAME }}/maibot + tags: | + type=raw,value=dev + type=schedule,pattern=dev-{{date 'YYMMDD'}} + + - name: Create and Push Manifest + run: | + # 为每个标签创建多架构镜像 + for tag in $(echo "${{ steps.meta.outputs.tags }}" | tr '\n' ' '); do + echo "Creating manifest for $tag" + docker buildx imagetools create -t $tag \ + ${{ secrets.DOCKERHUB_USERNAME }}/maibot@${{ needs.build-amd64.outputs.digest }} \ + ${{ secrets.DOCKERHUB_USERNAME }}/maibot@${{ needs.build-arm64.outputs.digest }} + done diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image-main.yml similarity index 88% rename from .github/workflows/docker-image.yml rename to .github/workflows/docker-image-main.yml index 989888b2..3d9b14ab 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image-main.yml @@ -1,8 +1,6 @@ -name: Docker Build and Push +name: Docker Build and Push (Main) on: - schedule: - - cron: '0 0 * * *' push: branches: - main @@ -13,6 +11,11 @@ on: - "*.*.*" - "*.*.*-*" workflow_dispatch: # 允许手动触发工作流 + inputs: + branch: + description: 'Branch to build' + required: false + default: 'main' # Workflow's jobs jobs: @@ -25,15 +28,14 @@ jobs: - name: Check out git repository uses: actions/checkout@v4 with: - ref: ${{ github.event_name == 'schedule' && 'dev' || github.ref }} fetch-depth: 0 # Clone required dependencies - - name: Clone maim_message - run: git clone https://github.com/MaiM-with-u/maim_message maim_message + # - name: Clone maim_message + # run: git clone https://github.com/MaiM-with-u/maim_message maim_message - name: Clone lpmm - run: git clone https://github.com/MaiM-with-u/MaiMBot-LPMM.git MaiMBot-LPMM + run: git clone https://github.com/Mai-with-u/MaiMBot-LPMM.git MaiMBot-LPMM - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -79,15 +81,14 @@ jobs: - name: Check out git repository uses: actions/checkout@v4 with: - ref: ${{ github.event_name == 'schedule' && 'dev' || github.ref }} fetch-depth: 0 # Clone required dependencies - - name: Clone maim_message - run: git clone https://github.com/MaiM-with-u/maim_message maim_message + # - name: Clone maim_message + # run: git clone https://github.com/MaiM-with-u/maim_message maim_message - name: Clone lpmm - run: git clone https://github.com/MaiM-with-u/MaiMBot-LPMM.git MaiMBot-LPMM + run: git clone https://github.com/Mai-with-u/MaiMBot-LPMM.git MaiMBot-LPMM - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -164,4 +165,4 @@ jobs: docker buildx imagetools create -t $tag \ ${{ secrets.DOCKERHUB_USERNAME }}/maibot@${{ needs.build-amd64.outputs.digest }} \ ${{ secrets.DOCKERHUB_USERNAME }}/maibot@${{ needs.build-arm64.outputs.digest }} - done \ No newline at end of file + done diff --git a/.gitignore b/.gitignore index 9db98c1d..debe4266 100644 --- a/.gitignore +++ b/.gitignore @@ -22,8 +22,10 @@ MaiMBot-LPMM *.zip run_bot.bat run_na.bat +run_all_in_wt.bat run.bat log_debug/ +NapCat.Shell.Windows.OneKey run_amds.bat run_none.bat docs-mai/ @@ -33,9 +35,6 @@ message_queue_content.bat message_queue_window.bat message_queue_window.txt queue_update.txt -memory_graph.gml -/src/tools/tool_can_use/auto_create_tool.py -/src/tools/tool_can_use/execute_python_code_tool.py .env .env.* .cursor @@ -46,13 +45,10 @@ config/lpmm_config.toml config/lpmm_config.toml.bak template/compare/bot_config_template.toml template/compare/model_config_template.toml -(测试版)麦麦生成人格.bat -(临时版)麦麦开始学习.bat -src/plugins/utils/statistic.py CLAUDE.md MaiBot-Dashboard/ cloudflare-workers/ - +result.json # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -325,6 +321,7 @@ run_pet.bat !/plugins/emoji_manage_plugin !/plugins/take_picture_plugin !/plugins/deep_think +!/plugins/MaiBot_MCPBridgePlugin !/plugins/ChatFrequency/ !/plugins/__init__.py @@ -332,4 +329,5 @@ config.toml interested_rates.txt MaiBot.code-workspace -*.lock \ No newline at end of file +*.lock +actionlint diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 98d846ac..f95b6c9b 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -71,7 +71,6 @@ 1. **GitHub Issues**: 对于公开的违规行为,可以在相关issue中直接指出 2. **私下联系**: 可以通过GitHub私信联系项目维护者 -3. **邮件联系**: [如果有项目邮箱地址,请在此提供] 所有报告都将得到及时和公正的处理。我们承诺保护报告者的隐私和安全。 diff --git a/EULA.md b/EULA.md index 249c0e48..ebc7a141 100644 --- a/EULA.md +++ b/EULA.md @@ -1,8 +1,9 @@ -# **MaiBot最终用户许可协议** -**版本:V1.1** -**更新日期:2025年7月10日** -**生效日期:2025年3月18日** -**适用的MaiBot版本号:所有版本** +# **MaiBot最终用户许可协议** + +**版本:V1.2** +**更新日期:2025年12月01日** +**生效日期:2025年12月01日** +**适用的MaiBot版本号:所有版本** **2025© MaiBot项目团队** @@ -14,130 +15,120 @@ **1.2** 在运行或使用本项目之前,您**必须阅读并同意本协议的所有条款**。未成年人或其它无/不完全民事行为能力责任人请**在监护人的陪同下**阅读并同意本协议。如果您不同意,则不得运行或使用本项目。在这种情况下,您应立即从您的设备上卸载或删除本项目及其所有副本。 - ## 二、许可授权 ### 源代码许可 + **2.1** 您**了解**本项目的源代码是基于GPLv3(GNU通用公共许可证第三版)开源协议发布的。您**可以自由使用、修改、分发**本项目的源代码,但**必须遵守**GPLv3许可证的要求。详细内容请参阅项目仓库中的LICENSE文件。 -**2.2** 您**了解**本项目的源代码中可能包含第三方开源代码,这些代码的许可证可能与GPLv3许可证不同。您**同意**在使用这些代码时**遵守**相应的许可证要求。 - +**2.2** 您**了解**本项目的源代码中可能包含第三方开源代码,这些代码的许可证可能与GPLv3许可证不同。您**同意**在使用这些代码时**遵守**相应的许可证要求. ### 输入输出内容授权 -**2.3** 您**了解**本项目是使用您的配置信息、提交的指令(以下简称“输入内容”)和生成的内容(以下简称“输出内容”)构建请求发送到第三方API生成回复的机器人项目。 - +**2.4** 您**了解**本项目是使用您的配置信息、提交的指令(以下简称“输入内容”)和生成的内容(以下简称“输出内容”)构建请求发送到第三方生成回复的机器人项目。 **2.4** 您**授权**本项目使用您的输入和输出内容按照项目的隐私政策用于以下行为: - - 调用第三方API生成回复; - - 调用第三方API用于构建本项目专用的存储于您部署或使用的数据库中的知识库和记忆库; - - 收集并记录本项目专用的存储于您部署或使用的设备中的日志; + +- 调用第三方API生成回复; +- 调用第三方API用于构建本项目专用的存储于您使用的数据库中的知识库和记忆库; +- 调用第三方开发的插件系统功能; +- 收集并记录本项目专用的存储于您使用的设备中的日志; **2.4** 您**了解**本项目的源代码中包含第三方API的调用代码,这些API的使用可能受到第三方的服务条款和隐私政策的约束。在使用这些API时,您**必须遵守**相应的服务条款。 **2.5** 项目团队**不对**第三方API的服务质量、稳定性、准确性、安全性负责,亦**不对**第三方API的服务变更、终止、限制等行为负责。 - -### 插件系统授权和责任免责 - -**2.6** 您**了解**本项目包含插件系统功能,允许加载和使用由第三方开发者(非MaiBot核心开发组成员)开发的插件。这些第三方插件可能具有独立的许可证条款和使用协议。 - -**2.7** 您**了解并同意**: - - 第三方插件的开发、维护、分发由其各自的开发者负责,**与MaiBot项目团队无关**; - - 第三方插件的功能、质量、安全性、合规性**完全由插件开发者负责**; - - MaiBot项目团队**仅提供**插件系统的技术框架,**不对**任何第三方插件的内容、行为或后果承担责任; - - 您使用任何第三方插件的风险**完全由您自行承担**; - -**2.8** 在使用第三方插件前,您**应当**: - - 仔细阅读并遵守插件开发者提供的许可证条款和使用协议; - - 自行评估插件的安全性、合规性和适用性; - - 确保插件的使用符合您所在地区的法律法规要求; - - ## 三、用户行为 -**3.1** 您**了解**本项目会将您的配置信息、输入指令和生成内容发送到第三方API,您**不应**在输入指令和生成内容中包含以下内容: - - 涉及任何国家或地区秘密、商业秘密或其他可能会对国家或地区安全或者公共利益造成不利影响的数据; - - 涉及个人隐私、个人信息或其他敏感信息的数据; - - 任何侵犯他人合法权益的内容; - - 任何违反国家或地区法律法规、政策规定的内容; +**3.1** 您**了解**本项目会将您的配置信息、输入指令和生成内容发送到第三方,您**不应**在输入指令和生成内容中包含以下内容: + +- 涉及任何国家或地区秘密、商业秘密或其他可能会对国家或地区安全或者公共利益造成不利影响的数据; +- 涉及个人隐私、个人信息或其他敏感信息的数据; +- 任何侵犯他人合法权益的内容; +- 任何违反国家或地区法律法规、政策规定的内容; **3.2** 您**不应**将本项目用于以下用途: - - 违反任何国家或地区法律法规、政策规定的行为; + +- 违反任何国家或地区法律法规、政策规定的行为; **3.3** 您**应当**自行确保您被存储在本项目的知识库、记忆库和日志中的输入和输出内容的合法性与合规性以及存储行为的合法性与合规性。您需**自行承担**由此产生的任何法律责任。 **3.4** 对于第三方插件的使用,您**不应**: - - 使用可能存在安全漏洞、恶意代码或违法内容的插件; - - 通过插件进行任何违反法律法规的行为; - - 将插件用于侵犯他人权益或危害系统安全的用途; -**3.5** 您**承诺**对使用第三方插件的行为及其后果承担**完全责任**,包括但不限于因插件缺陷、恶意行为或不当使用造成的任何损失或法律纠纷。 +- 安装、使用任何来源不明或未经验证的第三方插件; +- 使用任何违反法律法规、政策规定或第三方平台规则的第三方插件; +**3.5** 您**应当**自行确保您安装和使用的第三方插件的合法性与合规性以及安装和使用行为的合法性与合规性。您需**自行承担**由此产生的任何法律责任。 +**3.6** 由于本项目会将您的输入指令和生成内容发送到第三方,当您将本项目用于第三方交流环境(如与除您以外的人私聊、群聊、论坛、直播等)时,您**应当**事先明确告知其他交流参与者本项目的使用情况,包括但不限于: + +- 本项目的输出内容是由人工智能生成的; +- 本项目会将交流内容发送到第三方; +- 本项目的隐私政策和用户行为要求; + +您需**自行承担**由此产生的任何后果和法律责任。 + +**3.7** 项目团队**不鼓励**也**不支持**将本项目用于商业用途,但若您确实需要将本项目用于商业用途,您**应当**标明项目地址(如“本项目由MaiBot()驱动”),并**自行承担**由此产生的任何法律责任。 ## 四、免责条款 **4.1** 本项目的输出内容依赖第三方API,**不受**项目团队控制,亦**不代表**项目团队的观点。 -**4.2** 除本协议条目2.4提到的隐私政策之外,项目团队**不会**对您提供任何形式的担保,亦**不对**使用本项目的造成的任何后果负责。 +**4.2** 除本协议条目2.4提到的隐私政策之外,项目团队**不会**对您提供任何形式的担保,亦**不对**使用本项目的造成的任何直接或间接后果负责。 -**4.3** 关于第三方插件,项目团队**明确声明**: - - 项目团队**不对**任何第三方插件的功能、安全性、稳定性、合规性或适用性提供任何形式的保证或担保; - - 项目团队**不对**因使用第三方插件而产生的任何直接或间接损失、数据丢失、系统故障、安全漏洞、法律纠纷或其他后果承担责任; - - 第三方插件的质量问题、技术支持、bug修复等事宜应**直接联系插件开发者**,与项目团队无关; - - 项目团队**保留**在不另行通知的情况下,对插件系统功能进行修改、限制或移除的权利; +**4.3** 关于第三方插件,项目团队**声明**: + +- 项目团队**不对**任何第三方插件的功能、安全性、稳定性、合规性或适用性提供任何形式的保证或担保; +- 项目团队**不对**因使用第三方插件而产生的任何直接或间接后果承担责任; +- 项目团队**不对**第三方插件的质量问题、技术支持、bug修复等事宜负责。如有相关问题,应**直接联系插件开发者**; ## 五、其他条款 -**5.1** 项目团队有权**随时修改本协议的条款**,但**没有**义务通知您。修改后的协议将在本项目的新版本中生效,您应定期检查本协议的最新版本。 +**5.1** 项目团队有权**随时修改本协议的条款**,但**无义务**通知您。修改后的协议将在本项目的新版本中推送,您应定期检查本协议的最新版本。 **5.2** 项目团队**保留**本协议的最终解释权。 - ## 附录:其他重要须知 -### 一、过往版本使用条件追溯 +### 一、风险提示 -**1.1** 对于本项目此前未配备 EULA 协议的版本,自本协议发布之日起,若用户希望继续使用本项目,应在本协议生效后的合理时间内,通过升级到最新版本并同意本协议全部条款。若在本版协议生效日(2025年3月18日)之后,用户仍使用此前无 EULA 协议的项目版本且未同意本协议,则用户无权继续使用,项目方有权采取措施阻止其使用行为,并保留追究相关法律责任的权利。 +**1.1** 隐私安全风险 +- 本项目会将您的配置信息、输入指令和生成内容发送到第三方API,而这些API的服务质量、稳定性、准确性、安全性不受项目团队控制。 +- 本项目会收集您的输入和输出内容,用于构建本项目专用的知识库和记忆库,以提高回复的准确性和连贯性。 -### 二、风险提示 +**因此,为了保障您的隐私信息安全,请注意以下事项:** -**2.1 隐私安全风险** +- 避免在涉及个人隐私、个人信息或其他敏感信息的环境中使用本项目; +- 避免在不可信的环境中使用本项目; - - 本项目会将您的配置信息、输入指令和生成内容发送到第三方API,而这些API的服务质量、稳定性、准确性、安全性不受项目团队控制。 - - 本项目会收集您的输入和输出内容,用于构建本项目专用的知识库和记忆库,以提高回复的准确性和连贯性。 - - **因此,为了保障您的隐私信息安全,请注意以下事项:** - - - 避免在涉及个人隐私、个人信息或其他敏感信息的环境中使用本项目; - - 避免在不可信的环境中使用本项目; - -**2.2 精神健康风险** +**1.2** 精神健康风险 本项目仅为工具型机器人,不具备情感交互能力。建议用户: - - 避免过度依赖AI回复处理现实问题或情绪困扰; - - 如感到心理不适,请及时寻求专业心理咨询服务。 - - 如遇心理困扰,请寻求专业帮助(全国心理援助热线:12355)。 -**2.3 第三方插件风险** +- 避免过度依赖AI回复处理现实问题或情绪困扰; +- 如感到心理不适,请及时寻求专业心理咨询服务; +- 如遇心理困扰,请寻求专业帮助(全国心理援助热线:12355); + +**1.3** 第三方插件风险 本项目的插件系统允许加载第三方开发的插件,这可能带来以下风险: - - **安全风险**:第三方插件可能包含恶意代码、安全漏洞或未知的安全威胁; - - **稳定性风险**:插件可能导致系统崩溃、性能下降或功能异常; - - **隐私风险**:插件可能收集、传输或泄露您的个人信息和数据; - - **合规风险**:插件的功能或行为可能违反相关法律法规或平台规则; - - **兼容性风险**:插件可能与主程序或其他插件产生冲突; - **因此,在使用第三方插件时,请务必:** +- **安全风险**:第三方插件可能包含恶意代码、安全漏洞或未知的安全威胁; +- **稳定性风险**:插件可能导致系统崩溃、性能下降或功能异常; +- **隐私风险**:插件可能收集、传输或泄露您的个人信息和数据; +- **合规风险**:插件的功能或行为可能违反相关法律法规或平台规则; +- **兼容性风险**:插件可能与主程序或其他插件产生冲突; - - 仅从可信来源获取和安装插件; - - 在安装前仔细了解插件的功能、权限和开发者信息; - - 定期检查和更新已安装的插件; - - 如发现插件异常行为,请立即停止使用并卸载; - - 对插件的使用后果承担完全责任; +**因此,在使用第三方插件时,请务必:** -### 三、其他 -**3.1 争议解决** - - 本协议适用中国法律,争议提交相关地区法院管辖; - - 若因GPLv3许可产生纠纷,以许可证官方解释为准。 +- 仅从可信来源获取和安装插件; +- 在安装前仔细了解插件的功能、权限和开发者信息; +- 定期检查和更新已安装的插件; +- 如发现插件异常行为,请立即停止使用并卸载; + +### 二、其他 + +**2.1** 争议解决 + +- 本协议适用中国法律,争议提交相关地区法院管辖; +- 若因GPLv3许可产生纠纷,以许可证官方解释为准。 diff --git a/README.md b/README.md index de5b2e28..3ee493c2 100644 --- a/README.md +++ b/README.md @@ -46,16 +46,20 @@ ## 🔥 更新和安装 -**最新版本: v0.11.5** ([更新日志](changelogs/changelog.md)) +**最新版本: v0.11.6** ([更新日志](changelogs/changelog.md)) 可前往 [Release](https://github.com/MaiM-with-u/MaiBot/releases/) 页面下载最新版本 + 可前往 [启动器发布页面](https://github.com/MaiM-with-u/mailauncher/releases/)下载最新启动器 + +注意,启动器处于早期开发版本,仅支持MacOS + **GitHub 分支说明:** - `main`: 稳定发布版本(推荐) - - `dev`: 开发测试版本(不稳定) + - `classical`: 经典版本(停止维护) ### 最新版本部署教程 @@ -69,18 +73,23 @@ ## 💬 讨论 -**技术交流群:** +**技术交流群/答疑群:** [麦麦脑电图](https://qm.qq.com/q/RzmCiRtHEW) | - [麦麦脑磁图](https://qm.qq.com/q/wlH5eT8OmQ) | [麦麦大脑磁共振](https://qm.qq.com/q/VQ3XZrWgMs) | - [麦麦要当VTB](https://qm.qq.com/q/wGePTl1UyY) + [麦麦要当VTB](https://qm.qq.com/q/wGePTl1UyY) | + + 为了维持技术交流和互帮互助的氛围,请不要在技术交流群讨论过多无关内容~ **聊天吹水群:** - [麦麦之闲聊群](https://qm.qq.com/q/JxvHZnxyec) + 麦麦相关闲聊群,此群仅用于聊天,提问部署/技术问题可能不会快速得到答案 + **插件开发/测试版讨论群:** - [插件开发群](https://qm.qq.com/q/1036092828) + 进阶内容,包括插件开发,测试版使用等等 + ## 📚 文档 **部分内容可能更新不够及时,请注意版本对应** diff --git a/bot.py b/bot.py index 68c6e110..35e1ded1 100644 --- a/bot.py +++ b/bot.py @@ -5,16 +5,22 @@ import time import platform import traceback import shutil +import sys +import subprocess from dotenv import load_dotenv from pathlib import Path from rich.traceback import install +from src.common.logger import initialize_logging, get_logger, shutdown_logging + +# 设置工作目录为脚本所在目录 +script_dir = os.path.dirname(os.path.abspath(__file__)) +os.chdir(script_dir) env_path = Path(__file__).parent / ".env" template_env_path = Path(__file__).parent / "template" / "template.env" if env_path.exists(): load_dotenv(str(env_path), override=True) - print("成功加载环境变量配置") else: try: if template_env_path.exists(): @@ -28,23 +34,93 @@ else: print(f"自动创建 .env 失败: {e}") raise -# 最早期初始化日志系统,确保所有后续模块都使用正确的日志格式 -from src.common.logger import initialize_logging, get_logger, shutdown_logging # noqa +# 检查是否是 Worker 进程,只在 Worker 进程中输出详细的初始化信息 +# Runner 进程只需要基本的日志功能,不需要详细的初始化日志 +is_worker = os.environ.get("MAIBOT_WORKER_PROCESS") == "1" +initialize_logging(verbose=is_worker) +install(extra_lines=3) +logger = get_logger("main") -initialize_logging() +# 定义重启退出码 +RESTART_EXIT_CODE = 42 + + +def run_runner_process(): + """ + Runner 进程逻辑:作为守护进程运行,负责启动和监控 Worker 进程。 + 处理重启请求 (退出码 42) 和 Ctrl+C 信号。 + """ + script_file = sys.argv[0] + python_executable = sys.executable + + # 设置环境变量,标记子进程为 Worker 进程 + env = os.environ.copy() + env["MAIBOT_WORKER_PROCESS"] = "1" + + while True: + logger.info(f"正在启动 {script_file}...") + + # 启动子进程 (Worker) + # 使用 sys.executable 确保使用相同的 Python 解释器 + cmd = [python_executable, script_file] + sys.argv[1:] + + process = subprocess.Popen(cmd, env=env) + + try: + # 等待子进程结束 + return_code = process.wait() + + if return_code == RESTART_EXIT_CODE: + logger.info("检测到重启请求 (退出码 42),正在重启...") + time.sleep(1) # 稍作等待 + continue + else: + logger.info(f"程序已退出 (退出码 {return_code})") + sys.exit(return_code) + + except KeyboardInterrupt: + # 向子进程发送终止信号 + if process.poll() is None: + # 在 Windows 上,Ctrl+C 通常已经发送给了子进程(如果它们共享控制台) + # 但为了保险,我们可以尝试 terminate + try: + process.terminate() + process.wait(timeout=5) + except subprocess.TimeoutExpired: + logger.warning("子进程未响应,强制关闭...") + process.kill() + sys.exit(0) + + +# 检查是否是 Worker 进程 +# 如果没有设置 MAIBOT_WORKER_PROCESS 环境变量,说明是直接运行的脚本, +# 此时应该作为 Runner 运行。 +if os.environ.get("MAIBOT_WORKER_PROCESS") != "1": + if __name__ == "__main__": + run_runner_process() + # 如果作为模块导入,不执行 Runner 逻辑,但也不应该执行下面的 Worker 逻辑 + sys.exit(0) + +# 以下是 Worker 进程的逻辑 + +# 最早期初始化日志系统,确保所有后续模块都使用正确的日志格式 +# 注意:Runner 进程已经在第 37 行初始化了日志系统,但 Worker 进程是独立进程,需要重新初始化 +# 由于 Runner 和 Worker 是不同进程,它们有独立的内存空间,所以都会初始化一次 +# 这是正常的,但为了避免重复的初始化日志,我们在 initialize_logging() 中添加了防重复机制 +# 不过由于是不同进程,每个进程仍会初始化一次,这是预期的行为 from src.main import MainSystem # noqa from src.manager.async_task_manager import async_task_manager # noqa -logger = get_logger("main") +# logger = get_logger("main") -install(extra_lines=3) +# install(extra_lines=3) # 设置工作目录为脚本所在目录 -script_dir = os.path.dirname(os.path.abspath(__file__)) -os.chdir(script_dir) +# script_dir = os.path.dirname(os.path.abspath(__file__)) +# os.chdir(script_dir) logger.info(f"已设置工作目录为: {script_dir}") @@ -58,6 +134,33 @@ app = None loop = None +def print_opensource_notice(): + """打印开源项目提示,防止倒卖""" + from colorama import init, Fore, Style + + init() + + notice_lines = [ + "", + f"{Fore.CYAN}{'═' * 70}{Style.RESET_ALL}", + f"{Fore.GREEN} ★ MaiBot - 开源 AI 聊天机器人 ★{Style.RESET_ALL}", + f"{Fore.CYAN}{'─' * 70}{Style.RESET_ALL}", + f"{Fore.YELLOW} 本项目是完全免费的开源软件,基于 GPL-3.0 协议发布{Style.RESET_ALL}", + f"{Fore.WHITE} 如果有人向你「出售本软件」,你被骗了!{Style.RESET_ALL}", + "", + f"{Fore.WHITE} 官方仓库: {Fore.BLUE}https://github.com/MaiM-with-u/MaiBot {Style.RESET_ALL}", + f"{Fore.WHITE} 官方文档: {Fore.BLUE}https://docs.mai-mai.org {Style.RESET_ALL}", + f"{Fore.WHITE} 官方群聊: {Fore.BLUE}1006149251{Style.RESET_ALL}", + f"{Fore.CYAN}{'─' * 70}{Style.RESET_ALL}", + f"{Fore.RED} ⚠ 将本软件作为「商品」倒卖、隐瞒开源性质均违反协议!{Style.RESET_ALL}", + f"{Fore.CYAN}{'═' * 70}{Style.RESET_ALL}", + "", + ] + + for line in notice_lines: + print(line) + + def easter_egg(): # 彩蛋 from colorama import init, Fore @@ -78,6 +181,7 @@ async def graceful_shutdown(): # sourcery skip: use-named-expression # 关闭 WebUI 服务器 try: from src.webui.webui_server import get_webui_server + webui_server = get_webui_server() if webui_server and webui_server._server: await webui_server.shutdown() @@ -202,6 +306,9 @@ def raw_main(): if platform.system().lower() != "windows": time.tzset() # type: ignore + # 打印开源提示(防止倒卖) + print_opensource_notice() + check_eula() logger.info("检查EULA和隐私条款完成") @@ -235,15 +342,33 @@ if __name__ == "__main__": loop.run_until_complete(main_tasks) except KeyboardInterrupt: - # loop.run_until_complete(get_global_api().stop()) logger.warning("收到中断信号,正在优雅关闭...") + + # 取消主任务 + if "main_tasks" in locals() and main_tasks and not main_tasks.done(): + main_tasks.cancel() + try: + loop.run_until_complete(main_tasks) + except asyncio.CancelledError: + pass + + # 执行优雅关闭 if loop and not loop.is_closed(): try: loop.run_until_complete(graceful_shutdown()) - except Exception as ge: # 捕捉优雅关闭时可能发生的错误 + except Exception as ge: logger.error(f"优雅关闭时发生错误: {ge}") # 新增:检测外部请求关闭 + except SystemExit as e: + # 捕获 SystemExit (例如 sys.exit()) 并保留退出代码 + if isinstance(e.code, int): + exit_code = e.code + else: + exit_code = 1 if e.code else 0 + if exit_code == RESTART_EXIT_CODE: + logger.info("收到重启信号,准备退出并请求重启...") + except Exception as e: logger.error(f"主程序发生异常: {str(e)} {str(traceback.format_exc())}") exit_code = 1 # 标记发生错误 diff --git a/changelogs/changelog.md b/changelogs/changelog.md index 0a4f34b9..11545b58 100644 --- a/changelogs/changelog.md +++ b/changelogs/changelog.md @@ -1,4 +1,68 @@ # Changelog + +## [0.12.0] - 2025-12-16 +### 🌟 重大更新 +- 添加思考力度机制,动态控制回复时间和长度 +- planner和replyer现在开启联动,更好的回复逻辑 +- 新的私聊系统,吸收了pfc的优秀机制 +- 增加麦麦做梦功能 +- mcp插件作为内置插件加入,默认不启用 +- 添加全局记忆配置项,现在可以选择让记忆为全局的 + +### 细节功能更改 +- 移除频率自动调整 +- 移除情绪功能 +- 优化记忆差许多呢超时设置 +- 部分配置为0的bug +- 黑话和表达不再提取包含名称的内容 + +## [0.11.6] - 2025-12-2 +### 🌟 重大更新 +- 大幅提高记忆检索能力,略微提高token消耗 +- 重构历史消息概括器,更好的主题记忆 +- 日志查看器性能革命性优化 +- 支持可视化查看麦麦LPMM知识图谱 +- 支持根据不同的模型提供商/模板/URL自动获取模型,可以不用手动输入模型了 +- 新增Baka引导系统,使用React-JoyTour实现很棒的用户引导系统(让Baka也能看懂!) +- 本地聊天室功能!!你可以直接在WebUI网页和麦麦聊天!! +- 使用cookie模式替换原有的LocalStorage Token存储,可能需要重新手动输入一遍Token +- WebUI本地聊天室支持用户模拟和平台模拟的功能! +- WebUI新增黑话管理 & 编辑界面 + +### 细节功能更改 +- 可选记忆识别中是否启用jargon +- 解耦表情包识别和图片识别 +- 修复部分破损json的解析问题 +- 黑话更高的提取效率,增加提取准确性 +- 升级jargon,更快更精准 +- 新增Lpmm可视化 + +### webui细节更新 +- 修复侧边栏收起、UI及表格横向滚动等问题,优化Toast动画 +- 修复适配器配置、插件克隆、表情包注册等相关BUG +- 新增适配器/模型预设模式及模板,自动填写URL和类型 +- 支持模型任务列表拖拽排序 +- 更新重启弹窗和首次引导内容 +- 多处界面命名及标题优化,如模型配置相关菜单重命名和描述更新 +- 修复聊天配置“提及回复”相关开关命名错误 +- 调试配置新增“显示记忆/Planner/LPMM Prompt”选项 +- 新增卡片尺寸、排序、字号、行间距等个性化功能 +- 聊天ID及群聊选择优化,显示可读名称 +- 聊天编辑界面精简字段,新增后端聊天列表API支持 +- 默认行间距减小,显示更紧凑 +- 修复页面滚动、表情包排序、发言频率为0等问题 +- 新增React异常Traceback界面及模型列表搜索 +- 更新WebUI Icon,修复适配器docker路径等问题 +- 插件配置可视化编辑,表单控件/元数据/布局类型扩展 +- 新增插件API与开发文档 +- 新增机器人状态卡片和快速操作按钮 +- 调整饼图显示、颜色算法,修复部分统计及解析错误 +- 新增缓存、WebSocket配置 +- 表情包支持上传和缩略图 +- 修复首页极端加载、重启后CtrlC失效、主程序配置移动端适配等问题 +- 新增表达反思设置和WebUI聊天室“思考中”占位组件 +- 细节如移除部分字段或UI控件、优化按钮/弹窗/编辑逻辑等 + ## [0.11.5] - 2025-11-21 ### 🌟 重大更新 - WebUI 现支持手动重启麦麦,曲线救国版“热重载” diff --git a/docker-compose.yml b/docker-compose.yml index 29887250..06124848 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,7 @@ services: # image: infinitycat/maibot:dev environment: - TZ=Asia/Shanghai -# - EULA_AGREE=99f08e0cab0190de853cb6af7d64d4de # 同意EULA +# - EULA_AGREE=1b662741904d7155d1ce1c00b3530d0d # 同意EULA # - PRIVACY_AGREE=9943b855e72199d0f5016ea39052f1b6 # 同意EULA ports: - "18001:8001" # webui端口 @@ -35,11 +35,12 @@ services: volumes: - ./docker-config/mmc/.env:/MaiMBot/.env # 持久化env配置文件 - ./docker-config/mmc:/MaiMBot/config # 持久化bot配置文件 + - ./docker-config/adapters:/MaiMBot/adapters-config # adapter配置文件夹映射 - ./data/MaiMBot/maibot_statistics.html:/MaiMBot/maibot_statistics.html #统计数据输出 - ./data/MaiMBot:/MaiMBot/data # 共享目录 - ./data/MaiMBot/plugins:/MaiMBot/plugins # 插件目录 - ./data/MaiMBot/logs:/MaiMBot/logs # 日志目录 - - site-packages:/usr/local/lib/python3.13/site-packages # 持久化Python包 + # - site-packages:/usr/local/lib/python3.13/site-packages # 持久化Python包,需要时启用 restart: always networks: - maim_bot @@ -86,8 +87,8 @@ services: # networks: # - maim_bot -volumes: - site-packages: +# volumes: # 若需要持久化Python包时启用 +# site-packages: networks: maim_bot: driver: bridge diff --git a/docs-src/lpmm_parameters_guide.md b/docs-src/lpmm_parameters_guide.md new file mode 100644 index 00000000..5d190589 --- /dev/null +++ b/docs-src/lpmm_parameters_guide.md @@ -0,0 +1,156 @@ +# LPMM 关键参数调节指南(进阶版) + +> 本文是对 `config/bot_config.toml` 中 `[lpmm_knowledge]` 段的补充说明。 +> 如果你只想使用默认配置,可以不改这些参数,脚本仍然可以正常工作。 +> +> 重要提醒:无论是修改 `[lpmm_knowledge]` 段的参数,还是通过脚本导入 / 删除 LPMM 知识库数据,主程序都需要重启(或在内部调用一次 `lpmm_start_up()`)后,新的参数和知识才会真正生效到聊天侧。 + +所有与 LPMM 相关的参数,都集中在: + +```toml +[lpmm_knowledge] # lpmm知识库配置 +enable = true +lpmm_mode = "agent" +... +``` + +下面按功能将常用参数分为三组介绍。 + +--- + +## 一、检索相关参数(影响答案质量与风格) + +```toml +qa_relation_search_top_k = 10 # 关系检索TopK +qa_relation_threshold = 0.5 # 关系阈值,相似度高于该值才认为“命中关系” +qa_paragraph_search_top_k = 1000 # 段落检索TopK,越小可能影响召回 +qa_paragraph_node_weight = 0.05 # 段落节点权重,在图检索&PPR中的权重 +qa_ent_filter_top_k = 10 # 实体过滤TopK +qa_ppr_damping = 0.8 # PPR阻尼系数 +qa_res_top_k = 3 # 最终提供给问答模型的段落数 +``` + +- `qa_relation_search_top_k` + 控制“最多考虑多少条关系向量候选”。 + - 数值大:召回更全面,但略慢; + - 数值小:更快,可能遗漏部分隐含关系。 + +- `qa_relation_threshold` + 关系相似度的阈值: + - 数值高:只信任非常相关的关系,系统更可能退化为纯段落向量检索; + - 数值低:图结构影响更大,适合实体关系较丰富的场景。 + +- `qa_paragraph_search_top_k` + 控制“最多考虑多少段落候选”。 + - 太小:可能召回不全,导致答案缺失; + - 太大:略微增加计算量,一般 1000 为安全默认。 + +- `qa_paragraph_node_weight` + 文段节点在图检索中的权重: + - 数值大:更依赖段落向量相似度(传统向量检索); + - 数值小:更依赖图结构和实体网络。 + +- `qa_ppr_damping` + Personalized PageRank 的阻尼系数: + - 通常保持在 0.8 左右即可; + - 越接近 1:偏向长路径探索,结果更发散; + - 略低:更集中在与问题直接相关的节点附近。 + +- `qa_res_top_k` + LPMM 最终会把相关度最高的前 `qa_res_top_k` 条段落组合成“知识上下文”给问答模型。 + - 太多:增加模型负担、阅读更多文字; + - 太少:信息不够充分,一般 3–5 比较平衡。 + +> 调参建议: +> - 优先在 `qa_relation_threshold`、`qa_paragraph_node_weight` 上做小幅调整; +> - 每次调整后,用 `scripts/test_lpmm_retrieval.py` 跑一遍固定问题,感受回答变化。 + +--- + +## 二、性能与硬件相关参数 + +```toml +embedding_dimension = 1024 # 嵌入向量维度,应与模型输出维度一致 +max_embedding_workers = 12 # 嵌入/抽取并发线程数 +embedding_chunk_size = 16 # 每批嵌入的条数 +info_extraction_workers = 3 # 实体抽取同时执行线程数 +enable_ppr = true # 是否启用PPR,低配机器可关闭 +``` + +- `embedding_dimension` + 必须与所选嵌入模型的输出维度一致(比如 768、1024 等)。**不要随意修改,除非你知道你在做什么!!!** + +- `max_embedding_workers` + 决定导入/抽取阶段的并行线程数: + - 机器配置好:可以适当调大,加快导入速度; + - 机器配置弱:建议调低(如 2 或 4),避免 CPU 长时间 100%。 + +- `embedding_chunk_size` + 每批发送给嵌入 API 的段落数量: + - 数值大:请求次数少,但单次请求更“重”; + - 数值小:请求次数多,但对网络和 API 的单次压力小。 + +- `info_extraction_workers` + `scripts/info_extraction.py` 中实体抽取的并行线程数: + - 使用 Pro/贵价模型时建议不要太大,避免并行费用过高; + - 一般 2–4 就能取得较好平衡。 + +- `enable_ppr` + 是否启用个性化 PageRank(PPR)图检索: + - `true`:检索会结合向量+知识图,效果更好,但略慢; + - `false`:只用向量检索,牺牲一定效果,性能更稳定。 + + +> 调参建议: +> - 若导入/检索阶段机器明显“顶不住”(>=1MB的大文本,且分配配置<4C),优先调低: +> - `max_embedding_workers` +> - `embedding_chunk_size` +> - `info_extraction_workers` +> - 或暂时将 `enable_ppr = false` (除非真的出现问题,否则不建议禁用此项,大幅影响检索效果) +> - 调整后重新执行导入或检索,观察日志与系统资源占用。 + +> 小提示:每次大改参数或批量删除知识后,建议用 +> - `scripts/test_lpmm_retrieval.py` 看回答风格是否如预期; +> - 如需确认当前磁盘数据能否正常初始化,可执行 `scripts/refresh_lpmm_knowledge.py` 做一次快速自检。 + +--- + +## 三、开启/关闭 LPMM 与模式说明 + +```toml +enable = true # 是否开启lpmm知识库 +lpmm_mode = "agent" # 可选 classic / agent +``` + +- `enable` + - `true`:LPMM 知识库启用,检索和问答会使用知识库; + - `false`:LPMM 完全关闭,脚本仍可导入/删除数据,但对聊天问答不生效。 + +- `lpmm_mode` + - `classic`:传统模式,仅使用 LPMM 知识库本身; + - `agent`:与新的记忆系统联动,用于更复杂的记忆+知识混合场景。 + +> 修改 `enable` 或 `lpmm_mode` 后,需要重启主程序,让配置生效。 + +--- + +## 四、推荐的调参流程 + +1. **保持默认配置,先跑一轮完整流程** + - 导入 → `inspect_lpmm_global.py` → `test_lpmm_retrieval.py`; + - 记录当前“答案风格”和“响应速度”。 + +2. **每次只调整一到两个参数** + - 例如先调 `qa_relation_threshold`、`qa_paragraph_node_weight`; + - 或在性能不佳时调整 `max_embedding_workers`、`enable_ppr`。 + +3. **调整后重复同一组测试问题** + - 使用 `scripts/test_lpmm_retrieval.py`; + - 对比不同配置下的答案,选择更符合需求的组合。 + +4. **出现“怎么调都不对”时** + - 将 `[lpmm_knowledge]` 段恢复为仓库中的默认配置; + - 重启主程序,即可回到“出厂设置”。 + +通过本指南中的参数调节,你可以在“检索质量”“响应速度”“系统资源占用”之间找到适合自己麦麦和机器的平衡点! + diff --git a/docs-src/lpmm_pipelines_guide.md b/docs-src/lpmm_pipelines_guide.md new file mode 100644 index 00000000..6539a2fc --- /dev/null +++ b/docs-src/lpmm_pipelines_guide.md @@ -0,0 +1,326 @@ +## LPMM 知识库流水线使用指南(命令行版) + +本文档介绍如何使用 `scripts/lpmm_manager.py` 及相关子脚本,完成 **导入 / 删除 / 自检 / 刷新 / 回归测试** 等常见流水线操作,并说明各参数在交互式与非交互(脚本化)场景下的用法。 + +所有命令均假设在项目根目录 `MaiBot/` 下执行: + +```bash +cd MaiBot +``` + +--- + +## 1. 管理脚本总览:`scripts/lpmm_manager.py` + +### 1.1 基本用法 + +```bash +python scripts/lpmm_manager.py [--interactive] [-a ACTION] [--non-interactive] [-- ...子脚本参数...] +``` + +- `--interactive` / `-i`:进入交互式菜单模式(推荐人工运维时使用)。 +- `--action` / `-a`:直接执行指定操作(非交互入口),可选值: + - `prepare_raw`:预处理 `data/lpmm_raw_data/*.txt`。 + - `info_extract`:信息抽取,生成 OpenIE JSON 批次。 + - `import_openie`:导入 OpenIE 批次到向量库与知识图。 + - `delete`:删除/回滚知识(封装 `delete_lpmm_items.py`)。 + - `batch_inspect`:检查指定 OpenIE 批次的存在情况。 + - `global_inspect`:全库状态统计。 + - `refresh`:刷新 LPMM 磁盘数据到内存。 + - `test`:检索效果回归测试。 + - `full_import`:一键执行「预处理原始语料 → 信息抽取 → 导入 → 刷新」。 +- `--non-interactive`: + - 启用 **非交互模式**:`lpmm_manager` 自身不会再调用 `input()` 询问确认; + - 同时自动向子脚本透传 `--non-interactive`(若子脚本支持),用于在 CI / 定时任务中实现无人值守。 +- `--` 之后的内容会原样传递给对应子脚本的 `main()`,用于设置更细粒度参数。 + +> 注意:`--interactive` 与 `--non-interactive` 互斥,不能同时使用。 + +--- + +## 2. 典型流水线一:全量导入(从原始 txt 到可用 LPMM) + +### 2.1 前置条件 + +- 将待导入的原始文本放入: + +```text +data/lpmm_raw_data/*.txt +``` + +- 文本按「空行分段」,每个段落为一条候选知识。 + +### 2.2 一键全流程(交互式) + +```bash +python scripts/lpmm_manager.py --interactive +``` + +菜单中依次: + +1. 选择 `9. full_import`(预处理 → 信息抽取 → 导入 → 刷新)。 +2. 按提示确认可能的费用与时间消耗。 +3. 等待脚本执行完成。 + +### 2.3 一键全流程(非交互 / CI 友好) + +```bash +python scripts/lpmm_manager.py -a full_import --non-interactive +``` + +执行顺序: + +1. `prepare_raw`:调用 `raw_data_preprocessor.load_raw_data()`,统计段落与去重哈希数。 +2. `info_extract`:调用 `info_extraction.main(--non-interactive)`,从 `data/lpmm_raw_data` 读取段落,生成 OpenIE JSON 并写入 `data/openie/`。 +3. `import_openie`:调用 `import_openie.main(--non-interactive)`,导入 OpenIE 批次到嵌入库与 KG。 +4. `refresh`:调用 `refresh_lpmm_knowledge.main()`,刷新 LPMM 知识库到内存。 + +在 `--non-interactive` 模式下: + +- 若 `data/lpmm_raw_data` 中没有 `.txt` 文件,或 `data/openie` 中没有 `.json` 文件,将直接报错退出,并在日志中说明缺少的目录/文件。 +- 若 OpenIE 批次中存在非法文段,导入脚本会 **直接报错退出**,不会卡在交互确认上。 + +--- + +## 3. 典型流水线二:分步导入 + +若需要逐步调试或只执行部分步骤,可以分开调用: + +### 3.1 预处理原始语料:`prepare_raw` + +```bash +python scripts/lpmm_manager.py -a prepare_raw +``` + +行为: +- 使用 `raw_data_preprocessor.load_raw_data()` 读取 `data/lpmm_raw_data/*.txt`; +- 输出段落总数与去重后的哈希数,供人工检查原始数据质量。 + +### 3.2 信息抽取:`info_extract` + +#### 交互式(带费用提示) + +```bash +python scripts/lpmm_manager.py -a info_extract +``` + +脚本会: +- 打印预计费用/时间提示; +- 询问 `确认继续执行?(y/n)`; +- 然后开始从 `data/lpmm_raw_data` 中读取段落,调用 LLM 提取实体与三元组,并生成 OpenIE JSON。 + +#### 非交互式(无人工确认) + +```bash +python scripts/lpmm_manager.py -a info_extract --non-interactive +``` + +行为差异: +- 跳过`确认继续执行`的交互提示,直接开始抽取; +- 若 `data/lpmm_raw_data` 下没有 `.txt` 文件,会打印告警并以错误方式退出。 + +### 3.3 导入 OpenIE 批次:`import_openie` + +#### 交互式 + +```bash +python scripts/lpmm_manager.py -a import_openie +``` + +脚本会: +- 提示导入开销与资源占用情况; +- 询问是否继续; +- 调用 `OpenIE.load()` 加载批次,再将其导入嵌入库与 KG。 + +#### 非交互式 + +```bash +python scripts/lpmm_manager.py -a import_openie --non-interactive +``` + +- 跳过导入开销确认; +- 若数据存在非法文段: + - 在交互模式下会询问是否删除这些非法文段并继续; + - 在非交互模式下,会直接 `logger.error` 并 `sys.exit(1)`,防止导入不完整数据。 + +> 提示:当前 `OpenIE.load()` 仍可能在内部要求你选择具体批次文件,若需完全无交互的导入,可后续扩展为显式指定文件路径。 + +### 3.4 刷新 LPMM 知识库:`refresh` + +```bash +python scripts/lpmm_manager.py -a refresh +# 或 +python scripts/lpmm_manager.py -a refresh --non-interactive +``` + +两者行为相同: +- 调用 `refresh_lpmm_knowledge.main()`,内部执行 `lpmm_start_up()`; +- 日志中输出当前向量与 KG 规模,验证导入是否成功。 + +--- + +## 4. 典型流水线三:删除 / 回滚 + +删除操作通过 `lpmm_manager.py -a delete` 封装 `scripts/delete_lpmm_items.py`。 + +### 4.1 交互式删除(推荐人工操作) + +```bash +python scripts/lpmm_manager.py --interactive +``` + +菜单中选择: + +1. `4. delete - 删除/回滚知识` +2. 再选择删除方式: + - 按哈希文件(`--hash-file`) + - 按 OpenIE 批次(`--openie-file`) + - 按原始语料 + 段落索引(`--raw-file + --raw-index`) + - 按关键字搜索现有段落(`--search-text`) +3. 管理脚本会根据你的选择自动拼好常用参数(是否删除实体/关系、是否删除孤立实体、是否 dry-run、是否自动确认等),最后调用 `delete_lpmm_items.py` 执行。 + +### 4.2 非交互删除(CI / 脚本场景) + +#### 示例:按哈希文件删除(带完整保护参数) + +```bash +python scripts/lpmm_manager.py -a delete --non-interactive -- \ + --hash-file data/lpmm_delete_hashes.txt \ + --delete-entities \ + --delete-relations \ + --remove-orphan-entities \ + --max-delete-nodes 2000 \ + --yes +``` + +- `--non-interactive`(manager):禁止任何 `input()` 询问; +- 子脚本 `delete_lpmm_items.py` 中: + - `--hash-file`:指定待删段落哈希列表; + - `--delete-entities` / `--delete-relations` / `--remove-orphan-entities`:同步清理实体与关系; + - `--max-delete-nodes`:单次删除节点数上限,避免误删过大规模; + - `--yes`:跳过终极确认,适合已验证的自动流水线。 + +#### 按 OpenIE 批次删除(常用于批次回滚) + +```bash +python scripts/lpmm_manager.py -a delete --non-interactive -- \ + --openie-file data/openie/2025-01-01-12-00-openie.json \ + --delete-entities \ + --delete-relations \ + --remove-orphan-entities \ + --yes +``` + +### 4.3 非交互模式下的安全限制 + +在 `delete_lpmm_items.py` 中: + +- 若使用 `--search-text`,需要用户通过输入序号选择要删条目; + - 在 `--non-interactive` 模式下,这一步会直接报错退出,提示改用 `--hash-file / --openie-file / --raw-file` 等纯参数方式。 +- 若未指定 `--yes`: + - 非交互模式下会报错退出,提示「非交互模式且未指定 --yes,出于安全考虑删除操作已被拒绝」。 + +--- + +## 5. 典型流水线四:自检与状态检查 + +### 5.1 检查指定 OpenIE 批次状态:`batch_inspect` + +```bash +python scripts/lpmm_manager.py -a batch_inspect -- --openie-file data/openie/xx.json +``` + +输出该批次在当前库中的: +- 段落向量数量 / KG 段落节点数量; +- 实体向量数量 / KG 实体节点数量; +- 关系向量数量; +- 少量仍存在的样例内容。 + +常用于: +- 导入后确认是否完全成功; +- 删除后确认是否完全回滚。 + +### 5.2 查看整库状态:`global_inspect` + +```bash +python scripts/lpmm_manager.py -a global_inspect +``` + +输出: +- 段落 / 实体 / 关系向量条数; +- KG 节点/边总数,段落节点数、实体节点数; +- 实体计数表 `ent_appear_cnt` 的条目数; +- 少量剩余段落/实体样例,便于快速 sanity check。 + +--- + +## 6. 典型流水线五:检索效果回归测试 + +### 6.1 使用默认测试用例 + +```bash +python scripts/lpmm_manager.py -a test +``` + +- 调用 `test_lpmm_retrieval.py` 内置的 `DEFAULT_TEST_CASES`; +- 对每条用例输出: + - 原始结果; + - 状态(`PASS` / `WARN` / `NO_HIT` / `ERROR`); + - 期望关键字与命中关键字列表。 + +### 6.2 自定义测试问题与期望关键字 + +```bash +python scripts/lpmm_manager.py -a test -- --query "LPMM 是什么?" \ + --expect-keyword 哈希列表 \ + --expect-keyword 删除脚本 +``` + +也可以直接调用子脚本: + +```bash +python scripts/test_lpmm_retrieval.py \ + --query "LPMM 是什么?" \ + --expect-keyword 哈希列表 \ + --expect-keyword 删除脚本 +``` + +--- + +## 7. 推荐组合示例 + +### 7.1 导入 + 刷新 + 简单回归 + +```bash +# 1. 执行全量导入(支持非交互) +python scripts/lpmm_manager.py -a full_import --non-interactive + +# 2. 使用内置用例做一次检索回归 +python scripts/lpmm_manager.py -a test +``` + +### 7.2 批次回滚 + 自检 + +```bash +TARGET_BATCH=data/openie/2025-01-01-12-00-openie.json + +# 1. 按批次删除(非交互) +python scripts/lpmm_manager.py -a delete --non-interactive -- \ + --openie-file "$TARGET_BATCH" \ + --delete-entities \ + --delete-relations \ + --remove-orphan-entities \ + --yes + +# 2. 检查该批次是否彻底删除 +python scripts/lpmm_manager.py -a batch_inspect -- --openie-file "$TARGET_BATCH" + +# 3. 查看全库状态 +python scripts/lpmm_manager.py -a global_inspect +``` + +--- + +如需扩展更多流水线(例如「导入特定批次后自动跑自定义测试用例」),可以在 `scripts/lpmm_manager.py` 中新增对应的 `ACTION_INFO` 条目和 `run_action` 分支,或直接在 CI / shell 脚本中串联上述命令。该管理脚本已支持参数化与非交互调用,适合作为二次封装的基础入口。 + + diff --git a/docs-src/lpmm_user_guide.md b/docs-src/lpmm_user_guide.md new file mode 100644 index 00000000..147ebcab --- /dev/null +++ b/docs-src/lpmm_user_guide.md @@ -0,0 +1,411 @@ +# LPMM 知识库脚本使用指南(零基础用户版) + +本指南面向不熟悉命令行和代码的 C 端用户,帮助你完成: + +- LPMM 知识库的初始部署(从本地 txt 到可检索知识库) +- 安全删除知识(按批次、按原文、按哈希、按关键字) +- 导入 / 删除后的自检与检索效果验证 + +> 说明:本文默认你已经完成 MaiBot 的基础安装,并能在项目根目录打开命令行终端。 +> 重要提醒:每次使用导入 / 删除相关脚本(如 `import_openie.py`、`delete_lpmm_items.py`)修改 LPMM 知识库后,聊天机器人 / WebUI 端要想看到最新知识,需要重启主程序,或在主程序内部显式调用一次 `lpmm_start_up()` 重新初始化 LPMM + +--- +。 + + +## 一、需要用到的脚本一览 + +在项目根目录(`MaiBot-dev`)下,这些脚本是 LPMM 相关的“工具箱”: + +- 导入相关: + - `scripts/raw_data_preprocessor.py` + 从 `data/lpmm_raw_data` 目录读取 `.txt` 文件,按空行拆分为一个个段落,并做去重。 + - `scripts/info_extraction.py` + 调用大模型,从每个段落里抽取实体和三元组,生成中间的 OpenIE JSON 文件。 + - `scripts/import_openie.py` + 把 `data/openie` 目录中的 OpenIE JSON 文件导入到 LPMM 知识库(向量库 + 知识图)。 +- 删除相关: + - `scripts/delete_lpmm_items.py` + LPMM 知识库删除入口,支持按批次、按原始文本段落、按哈希列表、按关键字模糊搜索删除。 +- 自检相关: + - `scripts/inspect_lpmm_global.py` + 查看整个知识库的当前状态:段落/实体/关系条数、知识图节点/边数量、示例内容等。 + - `scripts/inspect_lpmm_batch.py` + 针对某个 OpenIE JSON 批次,检查它在向量库和知识图中的“残留情况”(导入与删除前后对比)。 + - `scripts/test_lpmm_retrieval.py` + 使用几条预设问题测试 LPMM 检索能力,帮助你判断知识库是否正常工作。 + - `scripts/refresh_lpmm_knowledge.py` + 手动重新加载 `data/embedding` 和 `data/rag` 到内存,用来确认当前磁盘上的 LPMM 知识库能正常初始化。 + +> 注意:所有命令示例都假设你已经在虚拟环境中,命令行前缀类似 `(.venv)`,并且当前目录是项目根目录。 + +--- + +## 二、LPMM 知识库的初始部署 + +### 2.1 准备原始 txt 文本 + +1. 把要导入的知识文档放到: + + ```text + data/lpmm_raw_data + ``` + +2. 文件要求: + + - 必须是 `.txt` 文件,建议使用 UTF-8 编码; + - 用**空行**分隔段落:一段话后空一行,即视为一条独立知识。 + +示例文件: + +- `data/lpmm_raw_data/lpmm_large_sample.txt`:仓库内已经提供了一份大样本测试文本,可以直接用来练习。 + +### 2.2 第一步:预处理原始文本(拆段 + 去重) + +在项目根目录执行: + +```bash +.\.venv\Scripts\python.exe scripts/raw_data_preprocessor.py +``` + +成功时通常会看到日志类似: + +- 正在处理文件: `lpmm_large_sample.txt` +- 共读取到 XX 条数据 + +这一步不会调用大模型,仅做拆段和去重。 + +### 2.3 第二步:进行信息抽取(生成 OpenIE JSON) + +执行: + +```bash +.\.venv\Scripts\python.exe scripts/info_extraction.py +``` + +你会看到一个“重要操作确认”提示,说明: + +- 信息抽取会调用大模型,消耗 API 费用和时间; +- 如果确认无误,输入 `y` 回车继续。 + +提取过程中可能出现: + +- 类似“模型 ... 网络错误(可重试)”这样的日志; + 这表示脚本在遇到网络问题时自动重试,一般无需手动干预。 + +运行结束后,会有类似提示: + +```text +信息提取结果已保存到: data/openie/11-27-10-06-openie.json +``` + +- 请记住这个文件名,比如:`11-27-10-06-openie.json` + 接下来我们会用 `` 来代指这类文件。 + +### 2.4 第三步:导入 OpenIE 数据到 LPMM 知识库 + +执行: + +```bash +.\.venv\Scripts\python.exe scripts/import_openie.py +``` + +这个脚本会: + +- 从 `data/openie` 目录读取所有 `*.json` 文件,并合并导入; +- 将新段落的嵌入向量写入 `data/embedding`; +- 将三元组构建为知识图写入 `data/rag`。 + +> 提示:如果你希望“只导入某几批数据”,可以暂时把不需要的 JSON 文件移出 `data/openie`,导入结束后再移回。 + +### 2.5 第四步:全局自检(确认导入成功) + +执行: + +```bash +.\.venv\Scripts\python.exe scripts/inspect_lpmm_global.py +``` + +你会看到类似输出: + +- 段落向量条数: `52` +- 实体向量条数: `260` +- 关系向量条数: `299` +- KG 节点总数 / 边总数 / 段落节点数 / 实体节点数 +- 若干条示例段落与实体内容预览 + +只要这些数字大于 0,就表示 LPMM 知识库已经有可用的数据了。 + +### 2.6 第五步:用脚本测试 LPMM 检索效果(可选但推荐) + +执行: + +```bash +.\.venv\Scripts\python.exe scripts/test_lpmm_retrieval.py +``` + +脚本会: + +- 自动初始化 LPMM(加载向量库与知识图); +- 用几条预设问题查询 LPMM; +- 打印原始检索结果和关键词命中情况。 + +你可以通过观察“RAW RESULT”里的内容,粗略判断: + +- 能否命中与问题高度相关的知识; +- 删除或导入新知识后,回答内容是否发生变化。 + +--- + +## 三、安全删除知识的几种方式 + +> 强烈建议:删除前先备份以下目录,以便“回档”: +> +> - `data/embedding`(向量库) +> - `data/rag`(知识图) + +所有删除操作使用同一个脚本: + +```bash +.\.venv\Scripts\python.exe scripts/delete_lpmm_items.py [参数...] +``` + +脚本特点: + +- 删除前会打印“待删除段落数量 / 实体数量 / 关系数量 / 预计删除节点数”等摘要; +- 需要你输入大写 `YES` 确认才会真正执行; +- 支持多种删除策略,可灵活组合。 + +### 3.1 按批次删除(推荐:整批回滚) + +适用场景:某次导入的整批知识有问题,希望整体回滚。 + +1. 删除前,先检查该批次状态: + + ```bash + .\.venv\Scripts\python.exe scripts/inspect_lpmm_batch.py ^ + --openie-file data/openie/.json + ``` + + 你会看到该批次: + + - 段落:总计多少条、向量库剩余多少、KG 中剩余多少; + - 实体、关系的类似统计; + - 少量示例段落/实体内容预览。 + +2. 确认无误后,按批次删除: + + ```bash + .\.venv\Scripts\python.exe scripts/delete_lpmm_items.py ^ + --openie-file data/openie/.json ^ + --delete-entities --delete-relations --remove-orphan-entities + ``` + + 参数含义: + + - `--delete-entities`:删除该批次涉及的实体向量; + - `--delete-relations`:删除该批次涉及的关系向量; + - `--remove-orphan-entities`:顺带清理删除后不再参与任何边的“孤立实体”节点。 + +3. 删除后再检查: + + ```bash + .\.venv\Scripts\python.exe scripts/inspect_lpmm_batch.py ^ + --openie-file data/openie/.json + + .\.venv\Scripts\python.exe scripts/inspect_lpmm_global.py + ``` + + 若批次检查显示“向量库剩余 0 / KG 中剩余 0”,则说明该批次已被彻底删除。 + +### 3.2 按原始文本段落删除(精确定位某一段) + +适用场景:某个原始 txt 的特定段落写错了,只想删这段对应的知识。 + +命令示例: + +```bash +.\.venv\Scripts\python.exe scripts/delete_lpmm_items.py ^ + --raw-file data/lpmm_raw_data/lpmm_large_sample.txt ^ + --raw-index 2 +``` + +说明: + +- `--raw-index` 从 1 开始计数,可用逗号多选,例如:`1,3,5`; +- 脚本会展示该段落的内容预览和哈希值,再请求你确认。 + +### 3.3 按哈希列表删除(进阶用法) + +适用场景:你有一份“需要删除的段落哈希列表”(比如从其他系统导出)。 + +示例哈希列表文件: + +- `data/openie/lpmm_delete_test_hashes.txt` + +命令: + +```bash +.\.venv\Scripts\python.exe scripts/delete_lpmm_items.py ^ + --hash-file data/openie/lpmm_delete_test_hashes.txt +``` + +说明: + +- 文件中每行一条,可以是 `paragraph-xxxx` 或纯哈希,脚本会自动识别; +- 适合“精确控制删除哪些段落”,但准备哈希列表需要一定技术基础。 + +### 3.4 按关键字模糊搜索删除(对非技术用户最友好) + +适用场景:只知道某段话里包含某个关键词,不知道它在哪个 txt 或批次里。 + +示例 1:删除与“近义词扩展”相关的段落 + +```bash +.\.venv\Scripts\python.exe scripts/delete_lpmm_items.py --search-text "近义词扩展" --search-limit 5 +``` + +示例 2:删除与“LPMM”强相关的一些段落 + +```bash +.\.venv\Scripts\python.exe scripts/delete_lpmm_items.py --search-text "LPMM" --search-limit 20 + +``` + +执行过程: + +1. 脚本在当前段落库中查找包含该关键字的段落; +2. 列出前 N 条候选(`--search-limit` 决定数量); +3. 提示你输入要删除的序号列表,例如:`1,2,5`; +4. 再次提示你输入 `YES` 确认,才会真正执行删除。 + +> 建议: +> +> - 第一次使用时可以先加 `--dry-run` 看看效果: +> ```bash +> .\.venv\Scripts\python.exe scripts/delete_lpmm_items.py ^ +> --search-text "LPMM" ^ +> --search-limit 20 ^ +> --dry-run +> ``` +> - 确认候选列表确实是你要删的内容后,再去掉 `--dry-run` 正式执行。 + +--- + +## 四、自检:如何确认导入 / 删除是否“生效” + +### 4.1 全局状态检查 + +每次导入或删除之后,建议跑一次: + +```bash +.\.venv\Scripts\python.exe scripts/inspect_lpmm_global.py +``` + +你可以在这里看到: + +- 段落向量条数、实体向量条数、关系向量条数; +- 知识图的节点总数、边总数、段落节点和实体节点数量; +- 若干条“剩余段落示例”和“剩余实体示例”。 + +观察方式: + +- 导入后:数字应该明显上升(说明新增数据生效); +- 删除后:数字应该明显下降(说明删除操作生效)。 + +### 4.2 某个批次的局部状态 + +如果你想确认“某一个 OpenIE 文件对应的那一批知识”是否存在,可以使用: + +```bash +.\.venv\Scripts\python.exe scripts/inspect_lpmm_batch.py --openie-file data/openie/.json +``` + +输出中会包含: + +- 该批次的段落 / 实体 / 关系的总数; +- 在向量库中还剩多少条,在 KG 中还剩多少条; +- 若干条仍存在的段落/实体示例。 + +典型用法: + +- 导入后立刻检查一次:确认这一批已经“写入”; +- 删除后再检查一次:确认这一批是否已经“清空”。 + +### 4.3 检索效果回归测试 + +每次做完导入或删除,你都可以用这条命令快速验证检索效果: + +```bash +.\.venv\Scripts\python.exe scripts/test_lpmm_retrieval.py +``` + +它会: + +- 初始化 LPMM(加载当前向量库和知识图); +- 用几条预设问题(包括与 LPMM 和配置相关的问题)进行检索; +- 打印检索结果以及命中关键词情况。 + +通过对比不同时间点的输出,你可以判断: + +- 某些知识是否已经被成功删除(不再出现在回答中); + +- 新增的知识是否已经能被检索到。 + +### 4.4 进阶:一键刷新(可选) + +- 想简单确认“现在这份 data/embedding + data/rag 是否健康”?执行: + + `.\.venv\Scripts\python.exe scripts/refresh_lpmm_knowledge.py ` + + 它会尝试初始化 LPMM,并打印当前段落/实体/关系条数和图大小。 + + + + + +--- + +## 五、常见提示与注意事项 + +1. **看到“网络错误(可重试)”需要担心吗?** + + - 不需要。 + - 这些日志说明脚本在自动处理网络抖动,多数情况下会在重试后成功返回结果。 + - 只要脚本最后没有报“重试耗尽并退出”,一般导入/提取结果是有效的。 + +2. **删除操作会不会“一删全没”?** + + - 不会直接“一删全没”: + - 每次删除会打印摘要信息; + - 必须输入 `YES` 才会真正执行; + - 大批次时还有 `--max-delete-nodes` 保护,超过阈值会警告。 + - 但仍然建议: + - 在大规模删除前备份 `data/embedding` 和 `data/rag`; + - 先通过 `--dry-run` 看看待删列表。 + +3. **可以多次导入吗?需要先清空吗?** + + - 可以多次导入,系统会根据段落内容的哈希做去重; + - 不需要每次都清空,只要你希望老数据仍然保留即可; + - 如果你确实想“重来一遍”,可以: + - 先备份,然后删除 `data/embedding` 和 `data/rag`; + - 再重新跑导入流程。 + +4. **LPMM 开关在哪里?** + + - 配置文件:`config/bot_config.toml`; + - 小节:`[lpmm_knowledge]`; + - 其中有 `enable = true/false` 开关: + - 为 `true`:LPMM 知识库启用,问答时会使用; + - 为 `false`:LPMM 关闭,即使知识库有数据,也不会参与回答。 + - 修改后需要重启主程序,让设置生效。 + +--- + +如果你是普通用户,只需要记住一句话: + +> “导入三步走:预处理 → 信息抽取 → 导入 OpenIE; +> 删除三步走:先检查 → 再删除 → 然后再检查。” + +照着本指南中的命令一步一步执行,就可以安全地管理你的 LPMM 知识库。*** diff --git a/dummy b/dummy new file mode 100644 index 00000000..5cae3661 --- /dev/null +++ b/dummy @@ -0,0 +1,10 @@ +{ + "cells": [], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/helm-chart/.gitignore b/helm-chart/.gitignore index b5ec6e00..8c2aec04 100644 --- a/helm-chart/.gitignore +++ b/helm-chart/.gitignore @@ -1 +1,2 @@ !napcat +!.env \ No newline at end of file diff --git a/helm-chart/.gitlab-ci.yml b/helm-chart/.gitlab-ci.yml index ce6f25e5..d00ae558 100644 --- a/helm-chart/.gitlab-ci.yml +++ b/helm-chart/.gitlab-ci.yml @@ -8,35 +8,18 @@ workflow: - if: '$CI_COMMIT_BRANCH == "helm-chart"' - when: never -# 构建并推送adapter-cm-generator镜像 -build-adapter-cm-generator: +# 构建并推送processor镜像 +build-preprocessor: stage: build-image image: reg.mikumikumi.xyz/base/kaniko-builder:latest variables: BUILD_NO_CACHE: true rules: - changes: - - helm-chart/adapter-cm-generator/** + - helm-chart/preprocessor/** script: - - export BUILD_CONTEXT=helm-chart/adapter-cm-generator - - export TMP_DST=reg.mikumikumi.xyz/maibot/adapter-cm-generator - - export CHART_VERSION=$(cat helm-chart/Chart.yaml | grep '^version:' | cut -d' ' -f2) - - export BUILD_DESTINATION="${TMP_DST}:${CHART_VERSION}" - - export BUILD_ARGS="--destination ${TMP_DST}:latest" - - build - -# 构建并推送core-webui-cm-sync镜像 -build-core-webui-cm-sync: - stage: build-image - image: reg.mikumikumi.xyz/base/kaniko-builder:latest - variables: - BUILD_NO_CACHE: true - rules: - - changes: - - helm-chart/core-webui-cm-sync/** - script: - - export BUILD_CONTEXT=helm-chart/core-webui-cm-sync - - export TMP_DST=reg.mikumikumi.xyz/maibot/core-webui-cm-sync + - export BUILD_CONTEXT=helm-chart/preprocessor + - export TMP_DST=reg.mikumikumi.xyz/maibot/preprocessor - export CHART_VERSION=$(cat helm-chart/Chart.yaml | grep '^version:' | cut -d' ' -f2) - export BUILD_DESTINATION="${TMP_DST}:${CHART_VERSION}" - export BUILD_ARGS="--destination ${TMP_DST}:latest" diff --git a/helm-chart/.helmignore b/helm-chart/.helmignore index d4fe42ef..84ca3f29 100644 --- a/helm-chart/.helmignore +++ b/helm-chart/.helmignore @@ -1,3 +1,2 @@ -adapter-cm-generator -core-webui-cm-sync +preprocessor .gitlab-ci.yml \ No newline at end of file diff --git a/helm-chart/Chart.yaml b/helm-chart/Chart.yaml index ea75ef79..e77ebde3 100644 --- a/helm-chart/Chart.yaml +++ b/helm-chart/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: maibot description: "Maimai Bot, a cyber friend dedicated to group chats" type: application -version: 0.11.5-beta -appVersion: 0.11.5-beta +version: 0.12.0 +appVersion: 0.12.0 diff --git a/helm-chart/README.md b/helm-chart/README.md index edbb417c..f3929696 100644 --- a/helm-chart/README.md +++ b/helm-chart/README.md @@ -10,6 +10,8 @@ | Helm Chart版本 | 对应的MaiBot版本 | Commit SHA | |----------------|--------------|------------------------------------------| +| 0.12.0 | 0.12.0 | baa6e90be7b20050fe25dfc74c0c70653601d00e | +| 0.11.6-beta | 0.11.6-beta | 0bfff0457e6db3f7102fb7f77c58d972634fc93c | | 0.11.5-beta | 0.11.5-beta | ad2df627001f18996802f23c405b263e78af0d0f | | 0.11.3-beta | 0.11.3-beta | cd6dc18f546f81e08803d3b8dba48e504dad9295 | | 0.11.2-beta | 0.11.2-beta | d3c8cea00dbb97f545350f2c3d5bcaf252443df2 | @@ -34,35 +36,39 @@ helm install maimai \ 1. `EULA` & `PRIVACY`: 用户必须同意这里的协议才能成功部署麦麦。 -2. `adapter`: 麦麦的Adapter的部署配置。 +2. `pre_processor`: 部署之前的预处理Job的配置。 -3. `core`: 麦麦本体的部署配置。 +3. `adapter`: 麦麦的Adapter的部署配置。 -4. `statistics_dashboard`: 麦麦的运行统计看板部署配置。 +4. `core`: 麦麦本体的部署配置。 + +5. `statistics_dashboard`: 麦麦的运行统计看板部署配置。 麦麦每隔一段时间会自动输出html格式的运行统计报告,此统计报告可以部署为看板。 出于隐私考虑,默认禁用。 -5. `napcat`: Napcat的部署配置。 +6. `napcat`: Napcat的部署配置。 考虑到复用外部Napcat实例的情况,Napcat部署已被解耦。用户可选是否要部署Napcat。 默认会捆绑部署Napcat。 -6. `sqlite_web`: sqlite-web的部署配置。 +7. `sqlite_web`: sqlite-web的部署配置。 通过sqlite-web可以在网页上操作麦麦的数据库,方便调试。不部署对麦麦的运行无影响。 此服务如果暴露在公网会十分危险,默认不会部署。 -7. `config`: 这里填写麦麦各部分组件的运行配置文件。 +8. `config`: 这里填写麦麦各部分组件的运行配置。 - 这里填写的配置文件需要严格遵守yaml文件的缩进格式。 + 这里填写的配置仅会在初次部署时或用户指定时覆盖实际配置文件,且需要严格遵守yaml文件的缩进格式。 + + - `override_*_config`: 指定本次部署/升级是否用以下配置覆盖实际配置文件。默认不覆盖。 - `adapter_config`: 对应adapter的`config.toml`。 - 此配置文件中对于`host`和`port`的配置会被上面`adapter.service`中的配置覆盖,因此不需要改动。 + 此配置文件中对于`napcat_server`和`maibot_server`的`host`和`port`字段的配置会被上面`adapter.service`中的配置覆盖,因此不需要改动。 - `core_model_config`: 对应core的`model_config.toml`。 @@ -72,60 +78,41 @@ helm install maimai \ 使用此Helm Chart的一些注意事项。 -### 修改麦麦配置 +### 麦麦的配置 -麦麦的配置文件会通过ConfigMap资源注入各个组件内。 +要修改麦麦的配置,最好的方法是通过WebUI来操作。此处的配置只会在初次部署时或者指定覆盖时注入到MaiBot中。 -对于通过Helm Chart部署的麦麦,如果需要修改配置,不应该直接修改这些ConfigMap,否则下次Helm更新可能会覆盖掉所有配置。 +`0.11.6-beta`之前的版本将配置存储于k8s的ConfigMap资源中。随着版本迭代,MaiBot对配置文件的操作复杂性增加,k8s的适配复杂度也同步增加,且WebUI可以直接修改配置文件,因此自`0.11.6-beta`版本开始,各组件的配置不再存储于k8s的ConfigMap中,而是直接存储于存储卷的实际文件中。 -最佳实践是重新配置Helm Chart的values,然后通过`helm upgrade`更新实例。 +从旧版本升级的用户,旧的ConfigMap的配置会自动迁移到新的存储卷的配置文件中。 -### 动态生成的ConfigMap +### 部署时自动重置的配置 -adapter的ConfigMap是每次部署/更新Helm安装实例时动态生成的。 +adapter的配置中的`napcat_server`和`maibot_server`的`host`和`port`字段,会在每次部署/更新Helm安装实例时被自动重置。 +core的配置中的`webui`和`maim_message`的部分字段也会在每次部署/更新Helm安装实例时被自动重置。 -动态生成的原因: +自动重置的原因: -- core服务的DNS名称是动态的,无法在adapter服务的配置文件中提前确定。 -- 一些与k8s现有资源冲突的配置需要被重置。 +- core的Service的DNS名称是动态的(由安装实例名拼接),无法在adapter的配置文件中提前确定。 +- 为了使adapter监听所有地址以及保持Helm Chart中配置的端口号,需要在adapter的配置文件中覆盖这些配置。 +- core的WebUI启停需要由helm chart控制,以便正常创建Service和Ingress资源。 +- core的maim_message的api server现在可以作为k8s服务暴露出来。监听的IP和端口需要由helm chart控制,以便Service正确映射。 -因此,首次部署时,ConfigMap的生成会需要一些时间,部分Pod会无法启动,等待几分钟即可。 +首次部署时,预处理任务会负责重置这些配置。这会需要一些时间,因此部署进程可能比较慢,且部分Pod可能会无法启动,等待一分钟左右即可。 -### 运行统计看板与core的挂载冲突 +### 跨节点PVC挂载问题 -如果启用了运行统计看板,那么statistics_dashboard会与core共同挂载statistics_dashboard存储卷,用于同步html文件。 +MaiBot的一些组件会挂载同一PVC,这主要是为了同步数据或修改配置。 -如果k8s集群有多个节点,且statistics_dashboard与core未调度到同一节点,那么就需要statistics_dashboard的PVC访问模式具备`ReadWriteMany`访问模式。 +如果k8s集群有多个节点,且共享相同PVC的Pod未调度到同一节点,那么就需要此PVC访问模式具备`ReadWriteMany`访问模式。 -不是所有存储卷的底层存储都支持`ReadWriteMany`访问模式。 +不是所有存储控制器都支持`ReadWriteMany`访问模式。 -如果你的存储底层无法支持`ReadWriteMany`访问模式,你可以通过`nodeSelector`配置将statistics_dashboard与core调度到同一节点来避免问题。 +如果你的存储控制器无法支持`ReadWriteMany`访问模式,你可以通过`nodeSelector`配置将彼此之间共享相同PVC的Pod调度到同一节点来避免问题。 -*如果启用了`sqlite-web`,那么上述问题也同样适用于`sqlite-web`与`core`,需要注意。* +会共享PVC的组件列表: -### 麦麦的默认插件 - -麦麦的`core`容器提供了一些默认插件,以提升使用体验。但是插件目录存储在存储卷中,容器启动时挂载的存储卷会完全覆盖掉容器的默认插件目录,导致默认插件无法加载,也难以被用户感知。 - -为了解决这一问题,此Helm Chart中为`core`容器引入了初始化容器。此初始化容器用于为用户自动安装默认插件到存储卷中。可以选择启用(默认启用)。 - -*初始化容器使用与`core`主容器相同的镜像,且用后即销毁,因此不会消耗额外的带宽和存储成本。* - -#### 触发插件安装的条件 - -- 首次部署时(此时没有任何插件处于安装状态) -- 默认插件更新(即默认插件内容发生变化) - -#### 安装状态识别能力 - -初始化容器会记录安装过的默认插件,不会重复安装。为了实现这一点,初始化容器会将安装状态写入`/MaiMBot/data/plugins/.installed-setup-plugins`文件中。 - -基于上述状态识别能力,如果用户不需要某个插件,可以将其删除。由于此插件已自动安装过(记录在状态文件中),即使插件本体不存在也不会再次安装(除非插件更新)。 - -#### 插件更新 - -一旦在镜像中检测到新版本插件(即插件内容不同),初始化容器即会用新插件覆盖旧插件。 - -考虑到旧插件中可能存在用户自定义配置,因此旧插件在被覆盖前会备份到`/MaiMBot/data/plugins-backup`目录中,并以时间归档。 - -因此在升级麦麦后,请注意观察初始容器的日志并重新配置插件。 +- `core`和`adapter`:共享`adapter-config`,用于为`core`的WebUI提供修改adapter的配置文件的能力。 +- `core`和`statistics-dashboard`:共享`statistics-dashboard`,用于同步统计数据的html文件。 +- `core`和`sqlite-web`:共享`maibot-core`,用于为`sqlite-web`提供操作MaiBot数据库的能力。 +- 部署时的预处理任务`preprocessor`和`adapter`、`core`:共享`adapter-config`和`core-config`,用于初始化`core`和`adapter`的配置文件。 diff --git a/helm-chart/adapter-cm-generator/adapter-cm-generator.py b/helm-chart/adapter-cm-generator/adapter-cm-generator.py deleted file mode 100644 index 95d7b65b..00000000 --- a/helm-chart/adapter-cm-generator/adapter-cm-generator.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/python3 -# 这个脚本的作用是在部署helm chart时动态生成adapter的配置文件,保存在configmap中 -# 需要动态生成的原因是core服务的DNS名称是动态的,无法在adapter服务的配置文件中提前确定 -# 一些与k8s现有资源冲突的配置也会在这里重置 - -import os -import toml -import base64 -from kubernetes import client, config -from datetime import datetime, timezone - -config.load_incluster_config() -core_api = client.CoreV1Api() -apps_api = client.AppsV1Api() - -# 读取部署的关键信息 -namespace = os.getenv("NAMESPACE") -release_name = os.getenv("RELEASE_NAME") -data_b64 = os.getenv("DATA_B64") - -# 解析并覆盖关键配置 -# 这里被覆盖的配置应当在helm chart中针对对应的k8s资源来灵活修改 -data = toml.loads(base64.b64decode(data_b64).decode("utf-8")) -data.setdefault('napcat_server', {}) -data['napcat_server']['host'] = '0.0.0.0' -data['napcat_server']['port'] = 8095 -data.setdefault('maibot_server', {}) -data['maibot_server']['host'] = f'{release_name}-maibot-core' # 根据release名称动态拼接core服务的DNS名称 -data['maibot_server']['port'] = 8000 - -# 创建/修改configmap -cm_name = f'{release_name}-maibot-adapter-config' -cm = client.V1ConfigMap( - metadata=client.V1ObjectMeta(name=cm_name), - data={'config.toml': toml.dumps(data)} -) -try: - core_api.create_namespaced_config_map(namespace, cm) - print(f"ConfigMap `{cm_name}` created successfully") -except client.exceptions.ApiException as e: - if e.status == 409: # 已存在,更新 - core_api.replace_namespaced_config_map(cm_name, namespace, cm) - print(f"ConfigMap `{cm_name}` replaced successfully") - else: - raise - -# 重启adapter和core的statefulset -now = datetime.now(timezone.utc).isoformat() -body = { - "spec": { - "template": { - "metadata": { - "annotations": { - "kubectl.kubernetes.io/restartedAt": now - } - } - } - } -} -apps_api.patch_namespaced_stateful_set( - name=f'{release_name}-maibot-adapter', - namespace=namespace, - body=body, -) -print(f"StatefulSet `{release_name}-maibot-adapter` restarted successfully") -apps_api.patch_namespaced_stateful_set( - name=f'{release_name}-maibot-core', - namespace=namespace, - body=body, -) -print(f"StatefulSet `{release_name}-maibot-core` restarted successfully") - -print('Job succeed.') diff --git a/helm-chart/core-webui-cm-sync/Dockerfile b/helm-chart/core-webui-cm-sync/Dockerfile deleted file mode 100644 index 55a8c25b..00000000 --- a/helm-chart/core-webui-cm-sync/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -# 此镜像用于辅助麦麦的WebUI更新配置文件,随core容器持续运行 -FROM python:3.13-slim - -WORKDIR /MaiMBot - -COPY . /MaiMBot - -RUN pip3 install --no-cache-dir -r requirements.txt - -ENTRYPOINT ["python3", "core-webui-cm-sync.py"] diff --git a/helm-chart/core-webui-cm-sync/core-webui-cm-sync.py b/helm-chart/core-webui-cm-sync/core-webui-cm-sync.py deleted file mode 100644 index e179d6f6..00000000 --- a/helm-chart/core-webui-cm-sync/core-webui-cm-sync.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/python3 -# 这个程序的作用是辅助麦麦的WebUI更新配置文件,随core容器持续运行。 -# 麦麦的配置文件存储于ConfigMap中,挂载进core容器后属于只读文件,无法直接修改。 -# 此程序将core容器内的配置文件替换为可读写的中间层临时文件。启动时将实际配置文件写入,并在后台持续检测文件变化,实时同步到k8s apiServer,反向修改ConfigMap。 -# 工作目录:/MaiMBot/webui-cm-sync - -import os -import time -from datetime import datetime -from kubernetes import client, config -from watchdog.observers import Observer -from watchdog.events import FileSystemEventHandler - -work_dir = '/MaiMBot/webui-cm-sync' -os.chdir(work_dir) - -config.load_incluster_config() -core_api = client.CoreV1Api() -with open("/var/run/secrets/kubernetes.io/serviceaccount/namespace", "r") as f: - namespace = f.read().strip() -release_name = os.getenv("RELEASE_NAME") -model_configmap_name = f'{release_name}-maibot-core-model-config' -bot_configmap_name = f'{release_name}-maibot-core-bot-config' - -# 过滤列表,只监控指定文件 -target_files = { - os.path.abspath("model_config.toml"): (model_configmap_name, "model_config.toml"), - os.path.abspath("bot_config.toml"): (bot_configmap_name, "bot_config.toml") -} - - -def get_configmap(configmap_name: str): - """获取core的ConfigMap内容""" - cm = core_api.read_namespaced_config_map(name=configmap_name, namespace=namespace) - return cm.data - - -def set_configmap(configmap_name: str, configmap_data: dict[str, str]): - """设置core的ConfigMap内容""" - core_api.patch_namespaced_config_map(configmap_name, namespace, {'data': configmap_data}) - - -class ConfigObserverHandler(FileSystemEventHandler): - """配置文件变化的事件处理器""" - def on_modified(self, event): - if os.path.abspath(event.src_path) in target_files: - print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] File `{event.src_path}` was modified. ' - f'Start to sync...') - with open(event.src_path, "r", encoding="utf-8") as _f: - current_data = _f.read() - _path = str(os.path.abspath(event.src_path)) - new_cm = { - target_files[_path][1]: current_data - } - try: - set_configmap(target_files[_path][0], new_cm) - print(f'\tSync done.') - except client.exceptions.ApiException as _e: - print(f'\tError while setting configmap:\n' - f'\t\tStatus Code: {_e.status}\n' - f'\t\tReason: {_e.reason}') - - -if __name__ == '__main__': - # 初始化配置文件 - print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] Initializing config files...') - try: - __initial_model_config = get_configmap(model_configmap_name)['model_config.toml'] - __initial_bot_config = get_configmap(bot_configmap_name)['bot_config.toml'] - except client.exceptions.ApiException as e: - print(f'\tError while getting configmap:\n' - f'\t\tStatus Code: {e.status}\n' - f'\t\tReason: {e.reason}') - exit(1) - with open('model_config.toml', 'w') as f: - f.write(__initial_model_config) - with open('bot_config.toml', 'w') as f: - f.write(__initial_bot_config) - with open('ready', 'w') as f: - f.write('true') - print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] Initializing done. Ready to sync.') - - # 持续检测变化并同步 - observer = Observer() - observer.schedule(ConfigObserverHandler(), work_dir, recursive=False) - observer.start() - try: - while True: - time.sleep(1) - except KeyboardInterrupt: - observer.stop() - observer.join() diff --git a/helm-chart/core-webui-cm-sync/requirements.txt b/helm-chart/core-webui-cm-sync/requirements.txt deleted file mode 100644 index 58c73d28..00000000 --- a/helm-chart/core-webui-cm-sync/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -toml~=0.10.2 -kubernetes~=34.1.0 -watchdog~=6.0.0 diff --git a/helm-chart/files/.env b/helm-chart/files/.env new file mode 100644 index 00000000..c34eed76 --- /dev/null +++ b/helm-chart/files/.env @@ -0,0 +1,4 @@ +HOST=0.0.0.0 +PORT=8000 +WEBUI_HOST=0.0.0.0 +WEBUI_PORT=8001 diff --git a/helm-chart/files/k8s-init.sh b/helm-chart/files/k8s-init.sh index 3729a68f..3fd805f4 100644 --- a/helm-chart/files/k8s-init.sh +++ b/helm-chart/files/k8s-init.sh @@ -1,12 +1,8 @@ #!/bin/sh # 此脚本用于覆盖core容器的默认启动命令,进行一些初始化 -# 1 # 由于k8s与docker-compose的卷挂载方式有所不同,需要利用此脚本为一些文件和目录提前创建好软链接 # /MaiMBot/data是麦麦数据的实际挂载路径 # /MaiMBot/statistics是统计数据的实际挂载路径 -# 2 -# 此脚本等待辅助容器webui-cm-sync就绪后再启动麦麦 -# 通过检测/MaiMBot/webui-cm-sync/ready文件来判断 set -e echo "[K8s Init] Preparing volume..." @@ -34,22 +30,6 @@ fi echo "[K8s Init] Volume ready." -# 如果启用了WebUI,则等待辅助容器webui-cm-sync就绪,然后创建中间层配置文件软链接 -if [ "$MAIBOT_WEBUI_ENABLED" = "true" ] -then - echo "[K8s Init] WebUI enabled. Waiting for container 'webui-cm-sync' ready..." - while [ ! -f /MaiMBot/webui-cm-sync/ready ]; do - sleep 1 - done - echo "[K8s Init] Container 'webui-cm-sync' ready." - mkdir -p /MaiMBot/config - ln -s /MaiMBot/webui-cm-sync/model_config.toml /MaiMBot/config/model_config.toml - ln -s /MaiMBot/webui-cm-sync/bot_config.toml /MaiMBot/config/bot_config.toml - echo "[K8s Init] Config files middle layer for WebUI created." -else - echo "[K8s Init] WebUI is disabled." -fi - # 启动麦麦 echo "[K8s Init] Waking up MaiBot..." echo diff --git a/helm-chart/files/setup-plugins.py b/helm-chart/files/setup-plugins.py deleted file mode 100644 index 9fde6804..00000000 --- a/helm-chart/files/setup-plugins.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/local/bin/python3 -# 用户插件目录存储在存储卷中,会在启动时覆盖掉容器的默认插件目录。此脚本用于默认插件更新后或麦麦首次启动时为用户自动安装默认插件到存储卷中 -# 如果用户主动删除插件且插件无更新,则不会再次安装。插件状态保存在/MaiMBot/data/plugins/.installed-setup-plugins文件中 -# 此脚本应当挂载进初始化容器中,从/MaiMBot工作路径开始运行。初始化容器的镜像同core容器,初始化容器中应挂载core存储卷的数据到/MaiMBot/data -import os -import shutil -import hashlib -from datetime import datetime - -SRC_DIR = '/MaiMBot/plugins' -DST_DIR = '/MaiMBot/data/plugins' -STATUS_FILE = f'{DST_DIR}/.installed-setup-plugins' -BAK_DIR = '/MaiMBot/data/plugins-backup' -CURRENT_TIME = datetime.now().strftime('%Y%m%d%H%M%S') - -def hash_dir_file(path: str): - """计算目录/文件的SHA256,用于判断是否发生变化""" - def hash_file(_file_path: str): - _h = hashlib.sha256() - with open(_file_path, 'rb') as _f: - for _chunk in iter(lambda: _f.read(8192), b''): - _h.update(_chunk) - return _h.hexdigest() - - if os.path.isfile(path): - return hash_file(path) - - h = hashlib.sha256() - for root, dirs, files in os.walk(path): - for filename in sorted(files): - filepath = os.path.join(root, filename) - relpath = os.path.relpath(filepath, path) - file_hash = hash_file(filepath) - h.update(relpath.encode('utf-8')) - h.update(file_hash.encode('utf-8')) - return h.hexdigest() - -def copy_plugin(plugin: str): - """复制插件,如果插件已存在则备份旧的插件然后用新的插件覆盖""" - src = os.path.join(SRC_DIR, plugin) - if not os.path.exists(src): - raise FileNotFoundError(f"File not found: {src}") - - dst = os.path.join(DST_DIR, plugin) - if os.path.exists(dst): - print(f"\t\tWarning: Old version of plugin '{plugin}' already exists. " - f"Old plugin will be moved to '{BAK_DIR}/{CURRENT_TIME}/{plugin}'. " - f"Remember to re-edit config of this plugin.") - if not os.path.exists(os.path.join(BAK_DIR, CURRENT_TIME)): - os.makedirs(os.path.join(BAK_DIR, CURRENT_TIME)) - if os.path.isdir(dst): - shutil.copytree(dst, os.path.join(BAK_DIR, CURRENT_TIME, plugin)) - shutil.rmtree(dst) - else: - shutil.copy2(dst, os.path.join(BAK_DIR, CURRENT_TIME)) - os.remove(dst) - - if os.path.isdir(src): - shutil.copytree(src, dst) - else: - shutil.copy2(src, DST_DIR) - -setup_plugins = {plugin: hash_dir_file(plugin) for plugin in os.listdir(SRC_DIR)} -installed_plugins = {} -to_install_plugins = {} - -print(f"[SetupPlugins] Default plugin, which has been updated or never been installed, " - f"will be installed in this init container.") -if os.path.exists(STATUS_FILE) and os.path.isfile(STATUS_FILE): - print(f"[SetupPlugins] Reading status file: '{STATUS_FILE}'...") - with open(STATUS_FILE, 'r', encoding='utf-8') as f: - lines = f.readlines() - for line in lines: - if line == '': - continue - plugin = line.strip().split(':') - installed_plugins[plugin[0]] = plugin[1] - print(f"[SetupPlugins] Found {len(installed_plugins)} default plugins which used to be installed:") - for plugin in installed_plugins.keys(): - print(f'\t{plugin}') -else: - print(f"[SetupPlugins] No status file found. Status file '{STATUS_FILE}' will be created. " - f"All default plugins will be installed now.") - -print(f"[SetupPlugins] Checking plugins...") -for plugin, sha256 in setup_plugins.items(): - if (plugin not in installed_plugins) or (sha256 != installed_plugins[plugin]): - print(f"\tFound default plugin to install: '{plugin}'. Installing...") - copy_plugin(plugin) - installed_plugins[plugin] = sha256 - -with open(STATUS_FILE, 'w', encoding='utf-8') as f: - f.write('\n'.join(sorted([f'{plugin}:{sha256}' for plugin, sha256 in installed_plugins.items()]))) - -print(f"[SetupPlugins] Default plugin checking done. Status saved to '{STATUS_FILE}'.") diff --git a/helm-chart/adapter-cm-generator/Dockerfile b/helm-chart/preprocessor/Dockerfile similarity index 72% rename from helm-chart/adapter-cm-generator/Dockerfile rename to helm-chart/preprocessor/Dockerfile index 3149f0f5..58452dd5 100644 --- a/helm-chart/adapter-cm-generator/Dockerfile +++ b/helm-chart/preprocessor/Dockerfile @@ -3,8 +3,10 @@ FROM python:3.13-slim WORKDIR /app +ENV PYTHONUNBUFFERED=1 + COPY . /app RUN pip3 install --no-cache-dir -r requirements.txt -ENTRYPOINT ["python3", "adapter-cm-generator.py"] +ENTRYPOINT ["python3", "preprocessor.py"] diff --git a/helm-chart/preprocessor/preprocessor.py b/helm-chart/preprocessor/preprocessor.py new file mode 100644 index 00000000..e8fe5b11 --- /dev/null +++ b/helm-chart/preprocessor/preprocessor.py @@ -0,0 +1,266 @@ +#!/bin/python3 +# 此脚本会被helm chart的post-install hook触发,在正式部署后通过k8s的job自动运行一次。 +# 这个脚本的作用是在部署helm chart时迁移旧版ConfigMap到配置文件,调整adapter的配置文件中的服务监听和服务连接字段,调整core的配置文件中的maim_message_api_server和WebUI配置。 +# +# - 迁移旧版ConfigMap到配置文件是因为0.11.6-beta之前版本的helm chart将各个配置文件存储在k8s的ConfigMap中, +# 由于功能复杂度提升,自0.11.6-beta版本开始配置文件采用文件形式存储到存储卷中。 +# 从旧版升级来的用户会通过这个脚本自动执行配置的迁移。 +# +# - 需要调整adapter的配置文件的原因是: +# 1. core的Service的DNS名称是动态的(由安装实例名拼接),无法在adapter的配置文件中提前确定。 +# 用于对外连接的maibot_server.host和maibot_server.port字段,会被替换为core的Service对应的DNS名称和8000端口(硬编码,用户无需配置)。 +# 2. 为了使adapter监听所有地址以及保持chart中配置的端口号,需要在adapter的配置文件中覆盖这些配置。 +# 用于监听的napcat_server.host和napcat_server.port字段,会被替换为0.0.0.0和8095端口(实际映射到的Service端口会在Service中配置)。 +# +# - 需要调整core的配置文件的原因是: +# 1. core的WebUI启停需要由helm chart控制,以便正常创建Service和Ingress资源。 +# 配置文件中的webui.enabled、webui.allowed_ips将由此脚本覆盖为正确配置。 +# 2. core的maim_message的api server现在可以作为k8s服务暴露出来。监听的IP和端口需要由helm chart控制,以便Service正确映射。 +# 配置文件中的maim_message.enable_api_server、maim_message.api_server_host、maim_message.api_server_port将由此脚本覆盖为正确配置。 + +import os +import toml +import time +import base64 +from kubernetes import client, config +from kubernetes.client.exceptions import ApiException +from datetime import datetime, timezone + +config.load_incluster_config() +core_api = client.CoreV1Api() +apps_api = client.AppsV1Api() + +# 读取部署的关键信息 +with open("/var/run/secrets/kubernetes.io/serviceaccount/namespace", 'r') as f: + namespace = f.read().strip() +release_name = os.getenv("RELEASE_NAME").strip() +is_webui_enabled = os.getenv("IS_WEBUI_ENABLED").lower() == "true" +is_maim_message_api_server_enabled = os.getenv("IS_MMSG_ENABLED").lower() == "true" +config_adapter_b64 = os.getenv("CONFIG_ADAPTER_B64") +config_core_env_b64 = os.getenv("CONFIG_CORE_ENV_B64") +config_core_bot_b64 = os.getenv("CONFIG_CORE_BOT_B64") +config_core_model_b64 = os.getenv("CONFIG_CORE_MODEL_B64") + + +def log(func: str, msg: str, level: str = 'INFO'): + print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] [{level}] [{func}] {msg}') + + +def migrate_old_config(): + """迁移旧版配置""" + func_name = 'migrate_old_config' + log(func_name, 'Checking whether there are old configmaps to migrate...') + old_configmap_version = None + status_migrating = { # 存储adapter的config.toml、core的bot_config.toml和model_config.toml三个文件的迁移状态 + 'adapter_config.toml': False, + 'core_bot_config.toml': False, + 'core_model_config.toml': False + } + + # 如果存储卷中已存在配置文件,则跳过迁移 + if os.path.isfile('/app/config/core/bot_config.toml') or os.path.isfile('/app/config/core/model_config.toml') or \ + os.path.isfile('/app/config/adapter/config.toml'): + log(func_name, 'Found existing config file(s) in PV. Migration will be ignored. Done.') + return + + def migrate_cm_to_file(cm_name: str, key_name: str, file_path: str) -> bool: + """检测是否有指定名称的configmap,如果有的话备份到指定的配置文件里并删除configmap,返回是否已备份""" + try: + cm = core_api.read_namespaced_config_map( + name=cm_name, + namespace=namespace + ) + log(func_name, f'\tMigrating `{key_name}` of `{cm_name}`...') + with open(file_path, 'w', encoding='utf-8') as _f: + _f.write(cm.data[key_name]) + core_api.delete_namespaced_config_map( + name=cm_name, + namespace=namespace + ) + log(func_name, f'\tSuccessfully migrated `{key_name}` of `{cm_name}`.') + except ApiException as e: + if e.status == 404: + return False + return True + + # 对于0.11.5-beta版本,adapter的config.toml、core的bot_config.toml和model_config.toml均存储于不同的ConfigMap,需要依次迁移 + if True not in status_migrating.values(): + status_migrating['adapter_config.toml'] = migrate_cm_to_file(f'{release_name}-maibot-adapter-config', + 'config.toml', + '/app/config/adapter/config.toml') + status_migrating['core_bot_config.toml'] = migrate_cm_to_file(f'{release_name}-maibot-core-bot-config', + 'bot_config.toml', + '/app/config/core/bot_config.toml') + status_migrating['core_model_config.toml'] = migrate_cm_to_file(f'{release_name}-maibot-core-model-config', + 'model_config.toml', + '/app/config/core/model_config.toml') + if True in status_migrating.values(): + old_configmap_version = '0.11.5-beta' + + # 对于低于0.11.5-beta的版本,adapter的1个配置和core的3个配置位于各自的configmap中 + if True not in status_migrating.values(): + status_migrating['adapter_config.toml'] = migrate_cm_to_file(f'{release_name}-maibot-adapter', + 'config.toml', + '/app/config/adapter/config.toml') + status_migrating['core_bot_config.toml'] = migrate_cm_to_file(f'{release_name}-maibot-core', + 'bot_config.toml', + '/app/config/core/bot_config.toml') + status_migrating['core_model_config.toml'] = migrate_cm_to_file(f'{release_name}-maibot-core', + 'model_config.toml', + '/app/config/core/model_config.toml') + if True in status_migrating.values(): + old_configmap_version = 'before 0.11.5-beta' + + if old_configmap_version: + log(func_name, f'Migrating status for version `{old_configmap_version}`:') + for k, v in status_migrating.items(): + log(func_name, f'\t{k}: {v}') + if False in status_migrating.values(): + log(func_name, 'There is/are config(s) that not been migrated. Please check the config manually.', + level='WARNING') + else: + log(func_name, 'Successfully migrated old configs. Done.') + else: + log(func_name, 'Old config not found. Ignoring migration. Done.') + + +def write_config_files(): + """当注入了配置文件时(一般是首次安装或者用户指定覆盖),将helm chart注入的配置写入存储卷中的实际文件""" + func_name = 'write_config_files' + log(func_name, 'Detecting config files...') + if config_adapter_b64: + log(func_name, '\tWriting `config.toml` of adapter...') + config_str = base64.b64decode(config_adapter_b64).decode("utf-8") + with open('/app/config/adapter/config.toml', 'w', encoding='utf-8') as _f: + _f.write(config_str) + log(func_name, '\t`config.toml` of adapter wrote.') + if True: # .env直接覆盖 + log(func_name, '\tWriting .env file of core...') + config_str = base64.b64decode(config_core_env_b64).decode("utf-8") + with open('/app/config/core/.env', 'w', encoding='utf-8') as _f: + _f.write(config_str) + log(func_name, '\t`.env` of core wrote.') + if config_core_bot_b64: + log(func_name, '\tWriting `bot_config.toml` of core...') + config_str = base64.b64decode(config_core_bot_b64).decode("utf-8") + with open('/app/config/core/bot_config.toml', 'w', encoding='utf-8') as _f: + _f.write(config_str) + log(func_name, '\t`bot_config.toml` of core wrote.') + if config_core_model_b64: + log(func_name, '\tWriting `model_config.toml` of core...') + config_str = base64.b64decode(config_core_model_b64).decode("utf-8") + with open('/app/config/core/model_config.toml', 'w', encoding='utf-8') as _f: + _f.write(config_str) + log(func_name, '\t`model_config.toml` of core wrote.') + log(func_name, 'Detection done.') + + +def reconfigure_adapter(): + """调整adapter的配置文件的napcat_server和maibot_server字段,使其Service能被napcat连接以及连接到core的Service""" + func_name = 'reconfigure_adapter' + log(func_name, 'Reconfiguring `config.toml` of adapter...') + with open('/app/config/adapter/config.toml', 'r', encoding='utf-8') as _f: + config_adapter = toml.load(_f) + config_adapter.setdefault('napcat_server', {}) + config_adapter['napcat_server']['host'] = '0.0.0.0' + config_adapter['napcat_server']['port'] = 8095 + config_adapter.setdefault('maibot_server', {}) + config_adapter['maibot_server']['host'] = f'{release_name}-maibot-core' # 根据release名称动态拼接core服务的DNS名称 + config_adapter['maibot_server']['port'] = 8000 + with open('/app/config/adapter/config.toml', 'w', encoding='utf-8') as _f: + _f.write(toml.dumps(config_adapter)) + log(func_name, 'Reconfiguration done.') + + +def reconfigure_core(): + """调整core的配置文件的webui和maim_message字段,使其服务能被正确映射""" + func_name = 'reconfigure_core' + log(func_name, 'Reconfiguring `bot_config.toml` of core...') + with open('/app/config/core/bot_config.toml', 'r', encoding='utf-8') as _f: + config_core = toml.load(_f) + config_core.setdefault('webui', {}) + config_core['webui']['enabled'] = is_webui_enabled + config_core['webui']['allowed_ips'] = '0.0.0.0/0' # 部署于k8s内网,使用宽松策略 + config_core.setdefault('maim_message', {}) + config_core['maim_message']['enable_api_server'] = is_maim_message_api_server_enabled + config_core['maim_message']['api_server_host'] = '0.0.0.0' + config_core['maim_message']['api_server_port'] = 8090 + with open('/app/config/core/bot_config.toml', 'w', encoding='utf-8') as _f: + _f.write(toml.dumps(config_core)) + log(func_name, 'Reconfiguration done.') + + +def _scale_statefulsets(statefulsets: list[str], replicas: int, wait: bool = False, timeout: int = 300): + """调整指定几个statefulset的副本数,wait参数控制是否等待调整完成再返回""" + statefulsets = set(statefulsets) + for name in statefulsets: + apps_api.patch_namespaced_stateful_set_scale( + name=name, + namespace=namespace, + body={"spec": {"replicas": replicas}} + ) + if not wait: + return + + start_time = time.time() + while True: + remaining_pods = [] + + pods = core_api.list_namespaced_pod(namespace).items + + for pod in pods: + owners = pod.metadata.owner_references or [] + for owner in owners: + if owner.kind == "StatefulSet" and owner.name in statefulsets: + remaining_pods.append(pod.metadata.name) + + if not remaining_pods: + return + + elapsed = time.time() - start_time + if elapsed > timeout: + raise TimeoutError( + f"Timeout waiting for Pods to be deleted. " + f"Remaining Pods: {remaining_pods}" + ) + time.sleep(5) + + +def _restart_statefulset(name: str, ignore_error: bool = False): + """重启指定的statefulset""" + now = datetime.now(timezone.utc).isoformat() + body = { + "spec": { + "template": { + "metadata": { + "annotations": { + "kubectl.kubernetes.io/restartedAt": now + } + } + } + } + } + try: + apps_api.patch_namespaced_stateful_set( + name=name, + namespace=namespace, + body=body + ) + except ApiException as e: + if ignore_error: + pass + else: + raise e + + +if __name__ == '__main__': + log('main', 'Start to process data before install/upgrade...') + log('main', 'Scaling adapter and core to 0...') + _scale_statefulsets([f'{release_name}-maibot-adapter', f'{release_name}-maibot-core'], 0, wait=True) + migrate_old_config() + write_config_files() + reconfigure_adapter() + reconfigure_core() + log('main', 'Scaling adapter and core to 1...') + _scale_statefulsets([f'{release_name}-maibot-adapter', f'{release_name}-maibot-core'], 1) + log('main', 'Process done.') diff --git a/helm-chart/adapter-cm-generator/requirements.txt b/helm-chart/preprocessor/requirements.txt similarity index 100% rename from helm-chart/adapter-cm-generator/requirements.txt rename to helm-chart/preprocessor/requirements.txt diff --git a/helm-chart/templates/adapter/pvc.yaml b/helm-chart/templates/adapter/pvc.yaml index 61778630..4bc24506 100644 --- a/helm-chart/templates/adapter/pvc.yaml +++ b/helm-chart/templates/adapter/pvc.yaml @@ -4,13 +4,30 @@ metadata: name: {{ .Release.Name }}-maibot-adapter namespace: {{ .Release.Namespace }} spec: - {{- if .Values.adapter.persistence.accessModes }} + {{- if .Values.adapter.persistence.data.accessModes }} accessModes: - {{ toYaml .Values.adapter.persistence.accessModes | nindent 4 }} + {{ toYaml .Values.adapter.persistence.data.accessModes | nindent 4 }} {{- end }} resources: requests: - storage: {{ .Values.adapter.persistence.size }} - {{- if .Values.adapter.persistence.storageClass }} - storageClassName: {{ .Values.adapter.persistence.storageClass | default nil }} + storage: {{ .Values.adapter.persistence.data.size }} + {{- if .Values.adapter.persistence.data.storageClass }} + storageClassName: {{ .Values.adapter.persistence.data.storageClass | default nil }} + {{- end }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Release.Name }}-maibot-adapter-config + namespace: {{ .Release.Namespace }} +spec: + {{- if .Values.adapter.persistence.config.accessModes }} + accessModes: + {{ toYaml .Values.adapter.persistence.config.accessModes | nindent 4 }} + {{- end }} + resources: + requests: + storage: {{ .Values.adapter.persistence.config.size }} + {{- if .Values.adapter.persistence.config.storageClass }} + storageClassName: {{ .Values.adapter.persistence.config.storageClass | default nil }} {{- end }} diff --git a/helm-chart/templates/adapter/statefulset.yaml b/helm-chart/templates/adapter/statefulset.yaml index 0d9b76da..ec914b16 100644 --- a/helm-chart/templates/adapter/statefulset.yaml +++ b/helm-chart/templates/adapter/statefulset.yaml @@ -7,7 +7,7 @@ metadata: app: {{ .Release.Name }}-maibot-adapter spec: serviceName: {{ .Release.Name }}-maibot-adapter - replicas: 1 + replicas: 0 # post-install任务初始化完毕后自动扩容至1 selector: matchLabels: app: {{ .Release.Name }}-maibot-adapter @@ -21,7 +21,7 @@ spec: env: - name: TZ value: Asia/Shanghai - image: {{ .Values.adapter.image.repository | default "unclas/maimbot-adapter" }}:{{ .Values.adapter.image.tag | default "main-20250924053857" }} + image: {{ .Values.adapter.image.repository | default "unclas/maimbot-adapter" }}:{{ .Values.adapter.image.tag | default "main-20251211074617" }} imagePullPolicy: {{ .Values.adapter.image.pullPolicy }} ports: - containerPort: 8095 @@ -36,7 +36,6 @@ spec: name: data - mountPath: /adapters/config.toml name: config - readOnly: true subPath: config.toml {{- if .Values.adapter.image.pullSecrets }} imagePullSecrets: @@ -54,9 +53,6 @@ spec: - name: data persistentVolumeClaim: claimName: {{ .Release.Name }}-maibot-adapter - - configMap: - items: - - key: config.toml - path: config.toml - name: {{ .Release.Name }}-maibot-adapter-config - name: config + - name: config + persistentVolumeClaim: + claimName: {{ .Release.Name }}-maibot-adapter-config diff --git a/helm-chart/templates/core/configmap-bot-config.yaml b/helm-chart/templates/core/configmap-bot-config.yaml deleted file mode 100644 index d1395296..00000000 --- a/helm-chart/templates/core/configmap-bot-config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if or .Release.IsInstall (and .Values.core.webui.enabled .Values.config.enable_config_override_with_webui) (and (not .Values.core.webui.enabled) .Values.config.enable_config_override_without_webui) }} -# 渲染规则: -# 初次安装,或配置了覆盖规则 -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-maibot-core-bot-config - namespace: {{ .Release.Namespace }} - annotations: - "helm.sh/resource-policy": keep -data: - bot_config.toml: | - {{ .Values.config.core_bot_config | nindent 4 }} -{{- end }} diff --git a/helm-chart/templates/core/configmap-env-config.yaml b/helm-chart/templates/core/configmap-env-config.yaml deleted file mode 100644 index 17b1d627..00000000 --- a/helm-chart/templates/core/configmap-env-config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-maibot-core-env-config - namespace: {{ .Release.Namespace }} -data: - .env: | - HOST=0.0.0.0 - PORT=8000 - WEBUI_ENABLED={{ if .Values.core.webui.enabled }}true{{ else }}false{{ end }} - WEBUI_MODE=production - WEBUI_HOST=0.0.0.0 - WEBUI_PORT=8001 diff --git a/helm-chart/templates/core/configmap-model-config.yaml b/helm-chart/templates/core/configmap-model-config.yaml deleted file mode 100644 index bf122244..00000000 --- a/helm-chart/templates/core/configmap-model-config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if or .Release.IsInstall (and .Values.core.webui.enabled .Values.config.enable_config_override_with_webui) (and (not .Values.core.webui.enabled) .Values.config.enable_config_override_without_webui) }} -# 渲染规则: -# 初次安装,或配置了覆盖规则 -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-maibot-core-model-config - namespace: {{ .Release.Namespace }} - annotations: - "helm.sh/resource-policy": keep -data: - model_config.toml: | - {{ .Values.config.core_model_config | nindent 4 }} -{{- end }} diff --git a/helm-chart/templates/core/pvc.yaml b/helm-chart/templates/core/pvc.yaml index e7fe15c7..66c6ac12 100644 --- a/helm-chart/templates/core/pvc.yaml +++ b/helm-chart/templates/core/pvc.yaml @@ -4,13 +4,30 @@ metadata: name: {{ .Release.Name }}-maibot-core namespace: {{ .Release.Namespace }} spec: - {{- if .Values.core.persistence.accessModes }} + {{- if .Values.core.persistence.data.accessModes }} accessModes: - {{ toYaml .Values.core.persistence.accessModes | nindent 4 }} + {{ toYaml .Values.core.persistence.data.accessModes | nindent 4 }} {{- end }} resources: requests: - storage: {{ .Values.core.persistence.size }} - {{- if .Values.core.persistence.storageClass }} - storageClassName: {{ .Values.core.persistence.storageClass | default nil }} + storage: {{ .Values.core.persistence.data.size }} + {{- if .Values.core.persistence.data.storageClass }} + storageClassName: {{ .Values.core.persistence.data.storageClass | default nil }} + {{- end }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Release.Name }}-maibot-core-config + namespace: {{ .Release.Namespace }} +spec: + {{- if .Values.core.persistence.config.accessModes }} + accessModes: + {{ toYaml .Values.core.persistence.config.accessModes | nindent 4 }} + {{- end }} + resources: + requests: + storage: {{ .Values.core.persistence.config.size }} + {{- if .Values.core.persistence.config.storageClass }} + storageClassName: {{ .Values.core.persistence.config.storageClass | default nil }} {{- end }} diff --git a/helm-chart/templates/core/service.yaml b/helm-chart/templates/core/service.yaml index 5b67de50..2a049eeb 100644 --- a/helm-chart/templates/core/service.yaml +++ b/helm-chart/templates/core/service.yaml @@ -20,6 +20,15 @@ spec: nodePort: {{ .Values.core.webui.service.nodePort | default nil }} {{- end }} {{- end }} + {{- if .Values.core.maim_message_api_server.enabled }} + - name: maim-message + port: {{ .Values.core.maim_message_api_server.service.port }} + protocol: TCP + targetPort: 8090 + {{- if eq .Values.core.maim_message_api_server.service.type "NodePort" }} + nodePort: {{ .Values.core.maim_message_api_server.service.nodePort | default nil }} + {{- end }} + {{- end }} selector: app: {{ .Release.Name }}-maibot-core type: ClusterIP diff --git a/helm-chart/templates/core/statefulset.yaml b/helm-chart/templates/core/statefulset.yaml index 2bc8d14c..50fed52d 100644 --- a/helm-chart/templates/core/statefulset.yaml +++ b/helm-chart/templates/core/statefulset.yaml @@ -7,7 +7,7 @@ metadata: app: {{ .Release.Name }}-maibot-core spec: serviceName: {{ .Release.Name }}-maibot-core - replicas: 1 + replicas: 0 # post-install任务初始化完毕后自动扩容至1 selector: matchLabels: app: {{ .Release.Name }}-maibot-core @@ -26,14 +26,10 @@ spec: - name: TZ value: "Asia/Shanghai" - name: EULA_AGREE - value: "99f08e0cab0190de853cb6af7d64d4de" + value: "1b662741904d7155d1ce1c00b3530d0d" - name: PRIVACY_AGREE value: "9943b855e72199d0f5016ea39052f1b6" - {{- if .Values.core.webui.enabled }} - - name: MAIBOT_WEBUI_ENABLED - value: "true" - {{- end}} - image: {{ .Values.core.image.repository | default "sengokucola/maibot" }}:{{ .Values.core.image.tag | default "0.11.5-beta" }} + image: {{ .Values.core.image.repository | default "sengokucola/maibot" }}:{{ .Values.core.image.tag | default "0.12.0" }} imagePullPolicy: {{ .Values.core.image.pullPolicy }} ports: - containerPort: 8000 @@ -56,59 +52,21 @@ spec: readOnly: true subPath: k8s-init.sh - mountPath: /MaiMBot/.env - name: env-config - readOnly: true + name: config subPath: .env - {{- if not .Values.core.webui.enabled }} - mountPath: /MaiMBot/config/model_config.toml - name: model-config - readOnly: true + name: config subPath: model_config.toml - mountPath: /MaiMBot/config/bot_config.toml - name: bot-config - readOnly: true + name: config subPath: bot_config.toml - {{- end }} + - mountPath: /MaiMBot/adapters-config/config.toml # WebUI修改adapter配置所用 + name: adapter-config + subPath: config.toml {{- if .Values.statistics_dashboard.enabled }} - mountPath: /MaiMBot/statistics name: statistics {{- end }} - {{- if .Values.core.webui.enabled }} - - mountPath: /MaiMBot/webui-cm-sync - name: webui-cm-sync - {{- end }} - {{- if .Values.core.webui.enabled }} - - name: webui-cm-sync - image: {{ .Values.core.webui.cm_sync.image.repository | default "reg.mikumikumi.xyz/maibot/core-webui-cm-sync" }}:{{ .Values.core.webui.cm_sync.image.tag | default "0.11.5-beta" }} - imagePullPolicy: {{ .Values.core.webui.cm_sync.image.pullPolicy }} - env: - - name: PYTHONUNBUFFERED - value: "1" - - name: RELEASE_NAME - value: {{ .Release.Name }} - volumeMounts: - - mountPath: /MaiMBot/webui-cm-sync - name: webui-cm-sync - {{- end }} - {{- if .Values.core.setup_default_plugins }} - initContainers: # 用户插件目录存储在存储卷中,会在启动时覆盖掉容器的默认插件目录。此初始化容器用于默认插件更新后或麦麦首次启动时为用户自动安装默认插件到存储卷中 - - args: - - setup-plugins.py - command: - - python3 - workingDir: /MaiMBot - image: {{ .Values.core.image.repository | default "sengokucola/maibot" }}:{{ .Values.core.image.tag | default "0.11.5-beta" }} - imagePullPolicy: {{ .Values.core.image.pullPolicy }} - name: setup-plugins - resources: { } - volumeMounts: - - mountPath: /MaiMBot/data - name: data - - mountPath: /MaiMBot/setup-plugins.py - name: scripts - readOnly: true - subPath: setup-plugins.py - {{- end }} serviceAccountName: {{ .Release.Name }}-maibot-sa {{- if .Values.core.image.pullSecrets }} imagePullSecrets: @@ -130,38 +88,16 @@ spec: items: - key: k8s-init.sh path: k8s-init.sh - {{- if .Values.core.setup_default_plugins }} - - key: setup-plugins.py - path: setup-plugins.py - {{- end }} name: {{ .Release.Name }}-maibot-scripts name: scripts - - configMap: - items: - - key: .env - path: .env - name: {{ .Release.Name }}-maibot-core-env-config - name: env-config - {{- if not .Values.core.webui.enabled }} - - configMap: - items: - - key: model_config.toml - path: model_config.toml - name: {{ .Release.Name }}-maibot-core-model-config - name: model-config - - configMap: - items: - - key: bot_config.toml - path: bot_config.toml - name: {{ .Release.Name }}-maibot-core-bot-config - name: bot-config - {{- end }} + - name: config + persistentVolumeClaim: + claimName: {{ .Release.Name }}-maibot-core-config + - name: adapter-config + persistentVolumeClaim: + claimName: {{ .Release.Name }}-maibot-adapter-config {{- if .Values.statistics_dashboard.enabled }} - name: statistics persistentVolumeClaim: claimName: {{ .Release.Name }}-maibot-statistics-dashboard {{- end }} - {{- if .Values.core.webui.enabled }} - - emptyDir: {} - name: webui-cm-sync - {{- end }} diff --git a/helm-chart/templates/napcat/statefulset.yaml b/helm-chart/templates/napcat/statefulset.yaml index 7cca56df..dc022b21 100644 --- a/helm-chart/templates/napcat/statefulset.yaml +++ b/helm-chart/templates/napcat/statefulset.yaml @@ -26,7 +26,7 @@ spec: value: "{{ .Values.napcat.permission.uid }}" - name: TZ value: Asia/Shanghai - image: {{ .Values.napcat.image.repository | default "mlikiowa/napcat-docker" }}:{{ .Values.napcat.image.tag | default "v4.9.73" }} + image: {{ .Values.napcat.image.repository | default "mlikiowa/napcat-docker" }}:{{ .Values.napcat.image.tag | default "v4.9.80" }} imagePullPolicy: {{ .Values.napcat.image.pullPolicy }} livenessProbe: failureThreshold: 3 diff --git a/helm-chart/templates/other/check-eula-privacy.yaml b/helm-chart/templates/other/check-eula-privacy.yaml index 18b0cca2..db997a60 100644 --- a/helm-chart/templates/other/check-eula-privacy.yaml +++ b/helm-chart/templates/other/check-eula-privacy.yaml @@ -1,8 +1,8 @@ # 检查EULA和PRIVACY {{- if not .Values.EULA_AGREE }} -{{- fail "You must accept the EULA by setting 'EULA_AGREE: true'. EULA: https://github.com/MaiM-with-u/MaiBot/blob/main/EULA.md" }} +{{ fail "You must accept the EULA by setting 'EULA_AGREE: true'. EULA: https://github.com/Mai-with-u/MaiBot/blob/main/EULA.md" }} {{- end }} {{- if not .Values.PRIVACY_AGREE }} -{{- fail "You must accept the Privacy Policy by setting 'PRIVACY_AGREE: true'. Privacy Policy: https://github.com/MaiM-with-u/MaiBot/blob/main/PRIVACY.md" }} +{{ fail "You must accept the Privacy Policy by setting 'PRIVACY_AGREE: true'. Privacy Policy: https://github.com/Mai-with-u/MaiBot/blob/main/PRIVACY.md" }} {{- end }} diff --git a/helm-chart/templates/other/configmap-scripts.yaml b/helm-chart/templates/other/configmap-scripts.yaml index dd61ca68..3fe96794 100644 --- a/helm-chart/templates/other/configmap-scripts.yaml +++ b/helm-chart/templates/other/configmap-scripts.yaml @@ -7,8 +7,3 @@ data: # core k8s-init.sh: | {{ .Files.Get "files/k8s-init.sh" | nindent 4 }} - # core的初始化容器 - {{- if .Values.core.setup_default_plugins }} - setup-plugins.py: | - {{ .Files.Get "files/setup-plugins.py" | nindent 4 }} - {{- end }} diff --git a/helm-chart/templates/other/job-gen-adapter-cm.yaml b/helm-chart/templates/other/job-gen-adapter-cm.yaml deleted file mode 100644 index ad01b568..00000000 --- a/helm-chart/templates/other/job-gen-adapter-cm.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# 动态生成adapter配置文件的configmap的job,仅会在部署时运行一次 -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Release.Name }}-maibot-adapter-cm-generator - namespace: {{ .Release.Namespace }} - annotations: - "helm.sh/hook": post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -spec: - backoffLimit: 2 - template: - spec: - serviceAccountName: {{ .Release.Name }}-maibot-sa - restartPolicy: Never - containers: - - name: adapter-cm-generator - image: {{ .Values.adapter.cm_generator.image.repository | default "reg.mikumikumi.xyz/maibot/adapter-cm-generator" }}:{{ .Values.adapter.cm_generator.image.tag | default "0.11.5-beta" }} - workingDir: /app - env: - - name: PYTHONUNBUFFERED - value: "1" - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: RELEASE_NAME - value: {{ .Release.Name }} - - name: DATA_B64 - value: {{ .Values.config.adapter_config | b64enc }} # 将配置文件编码为base64,从环境变量注入 diff --git a/helm-chart/templates/other/job-preprocessor.yaml b/helm-chart/templates/other/job-preprocessor.yaml new file mode 100644 index 00000000..8545f5af --- /dev/null +++ b/helm-chart/templates/other/job-preprocessor.yaml @@ -0,0 +1,62 @@ +# 预处理脚本,仅会在部署前运行一次 +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-maibot-preprocessor + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 2 + template: + spec: + serviceAccountName: {{ .Release.Name }}-maibot-sa + restartPolicy: Never + containers: + - name: preprocessor + image: {{ .Values.pre_processor.image.repository | default "reg.mikumikumi.xyz/maibot/preprocessor" }}:{{ .Values.pre_processor.image.tag | default "0.12.0" }} + imagePullPolicy: {{ .Values.pre_processor.image.pullPolicy }} + env: + - name: RELEASE_NAME + value: {{ .Release.Name }} + - name: IS_WEBUI_ENABLED + value: {{ .Values.core.webui.enabled | quote }} + - name: IS_MMSG_ENABLED + value: {{ .Values.core.maim_message_api_server.enabled | quote }} + {{- if or .Values.config.override_adapter_config .Release.IsInstall }} + - name: CONFIG_ADAPTER_B64 + value: {{ .Values.config.adapter_config | b64enc | quote }} + {{- end }} + - name: CONFIG_CORE_ENV_B64 + value: {{ tpl (.Files.Get "files/.env") . | b64enc | quote }} + {{- if or .Values.config.override_core_bot_config .Release.IsInstall }} + - name: CONFIG_CORE_BOT_B64 + value: {{ .Values.config.core_bot_config | b64enc | quote }} + {{- end }} + {{- if or .Values.config.override_core_model_config .Release.IsInstall }} + - name: CONFIG_CORE_MODEL_B64 + value: {{ .Values.config.core_model_config | b64enc | quote }} + {{- end }} + volumeMounts: + - mountPath: /app/config/adapter + name: adapter-config + - mountPath: /app/config/core + name: core-config + imagePullSecrets: + {{ toYaml .Values.pre_processor.image.pullSecrets | nindent 8 }} + {{- if .Values.pre_processor.nodeSelector }} + nodeSelector: + {{ toYaml .Values.pre_processor.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.pre_processor.tolerations }} + tolerations: + {{ toYaml .Values.pre_processor.tolerations | nindent 8 }} + {{- end }} + volumes: + - name: adapter-config + persistentVolumeClaim: + claimName: {{ .Release.Name }}-maibot-adapter-config + - name: core-config + persistentVolumeClaim: + claimName: {{ .Release.Name }}-maibot-core-config diff --git a/helm-chart/templates/other/rbac.yaml b/helm-chart/templates/other/rbac.yaml index 8b8075c7..2edb11b4 100644 --- a/helm-chart/templates/other/rbac.yaml +++ b/helm-chart/templates/other/rbac.yaml @@ -12,11 +12,14 @@ metadata: namespace: {{ .Release.Namespace }} rules: - apiGroups: [""] - resources: ["configmaps"] - verbs: ["get", "list", "create", "update", "patch"] + resources: ["configmaps", "pods"] + verbs: ["get", "list", "delete"] - apiGroups: ["apps"] resources: ["statefulsets"] - verbs: ["get", "list", "create", "update", "patch"] + verbs: ["get", "list", "update", "patch"] + - apiGroups: ["apps"] + resources: ["statefulsets/scale"] + verbs: ["get", "patch", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml index dacb8c3d..92e84a6e 100644 --- a/helm-chart/values.yaml +++ b/helm-chart/values.yaml @@ -5,12 +5,23 @@ EULA_AGREE: false PRIVACY_AGREE: false +# 预处理Job的配置 +pre_processor: + image: + repository: # 默认 reg.mikumikumi.xyz/maibot/preprocessor + tag: # 默认 0.12.0 + pullPolicy: IfNotPresent + pullSecrets: [ ] + + nodeSelector: { } + tolerations: [ ] + # 麦麦Adapter的部署配置 adapter: image: repository: # 默认 unclas/maimbot-adapter - tag: # 默认 main-20250924053857 + tag: # 默认 main-20251211074617 pullPolicy: IfNotPresent pullSecrets: [ ] @@ -29,26 +40,23 @@ adapter: nodePort: # 仅在设置NodePort类型时有效,不指定则会随机分配端口 persistence: - storageClass: - accessModes: - - ReadWriteOnce - size: 1Gi - - # adapter的动态生成configmap的Job的配置 - cm_generator: - image: - repository: # 默认 reg.mikumikumi.xyz/maibot/adapter-cm-generator - tag: # 默认 0.11.5-beta - pullPolicy: IfNotPresent - pullSecrets: [ ] - + config: # 配置文件的存储卷 + storageClass: + accessModes: + - ReadWriteOnce + size: 10Mi + data: # 数据的存储卷 + storageClass: + accessModes: + - ReadWriteOnce + size: 1Gi # 麦麦本体的部署配置 core: image: repository: # 默认 sengokucola/maibot - tag: # 默认 0.11.5-beta + tag: # 默认 0.12.0 pullPolicy: IfNotPresent pullSecrets: [ ] @@ -58,23 +66,19 @@ core: tolerations: [ ] persistence: - storageClass: - accessModes: - - ReadWriteOnce - size: 10Gi - - setup_default_plugins: true # 启用一个初始化容器,用于为用户自动安装默认插件到存储卷中 + config: # 配置文件的存储卷 + storageClass: + accessModes: + - ReadWriteOnce + size: 10Mi + data: # 数据的存储卷 + storageClass: + accessModes: + - ReadWriteOnce + size: 10Gi webui: # WebUI相关配置 - # 对从helm chart 0.11.5-beta 之前的旧版升级的用户的重要提示: - # 旧版本helm chart没有配置configmap的保留策略,直接升级同时开启WebUI后会导致configmap丢失从而无法启动。 - # 这种情况可以先禁用WebUI更新一次,再启用WebUI更新一次即可解决问题。 enabled: true # 默认启用 - cm_sync: # WebUI的辅助容器配置 - image: - repository: # 默认 reg.mikumikumi.xyz/maibot/core-webui-cm-sync - tag: # 默认 0.11.5-beta - pullPolicy: IfNotPresent service: type: ClusterIP # ClusterIP / NodePort 指定NodePort可以将内网的服务端口映射到物理节点的端口 port: 8001 # 服务端口 @@ -87,6 +91,14 @@ core: path: / pathType: Prefix + maim_message_api_server: + enabled: false + service: + type: ClusterIP # ClusterIP / NodePort 指定NodePort可以将内网的服务端口映射到物理节点的端口 + port: 8090 # 服务端口 + nodePort: # 仅在设置NodePort类型时有效,不指定则会随机分配端口 + + # 麦麦的运行统计看板配置 # 麦麦每隔一段时间会自动输出html格式的运行统计报告,此统计报告可以作为静态网页访问 # 此功能默认禁用。如果你认为报告可以被公开访问(报告包含联系人/群组名称、模型token花费信息等),则可以启用此功能 @@ -139,7 +151,7 @@ napcat: image: repository: # 默认 mlikiowa/napcat-docker - tag: # 默认 v4.9.73 + tag: # 默认 v4.9.91 pullPolicy: IfNotPresent pullSecrets: [ ] @@ -211,15 +223,17 @@ sqlite_web: path: / pathType: Prefix -# 手动设置麦麦各部分组件的运行配置文件 +# 设置麦麦各部分组件的初始运行配置 +# 考虑到配置文件的操作复杂性增加,k8s的适配复杂度也同步增加,且WebUI可以直接修改配置文件 +# 自0.11.6-beta版本开始,各组件的配置不再存储于k8s的configmap中,而是直接存储于存储卷的实际文件中 +# 从旧版本升级的用户,旧的configmap的配置会自动迁移到新的存储卷的配置文件中 +# 此处的配置只在初次部署时或者指定覆盖时注入到MaiBot中 config: - # 启用WebUI后,配置文件的修改即可在WebUI进行。如果通过WebUI修改了配置,则实际的配置文件将与values中的配置存在差异。 - # 如果用户在k8s的ConfigMap中手动修改了配置文件,则实际的配置文件也会与values中的配置存在差异。 - # 出现上述两种情况时,为了避免helm升级麦麦时,下面values中的配置覆盖掉已有的配置文件而导致配置丢失,可以在这里禁止本次部署时的配置覆盖。 - # 注:由于adapter的配置无法通过WebUI修改,因此下面的adapter_config配置仍然会覆盖已有配置文件。 - enable_config_override_without_webui: true # 未启用WebUI时,默认覆盖 - enable_config_override_with_webui: false # 启用WebUI时,默认不覆盖 + # 指定是否用下面的配置覆盖MaiBot现有的配置文件 + override_adapter_config: false + override_core_bot_config: false + override_core_model_config: false # adapter的config.toml adapter_config: | @@ -256,7 +270,7 @@ config: # core的model_config.toml core_model_config: | [inner] - version = "1.7.8" + version = "1.9.1" # 配置文件版本号迭代规则同bot_config.toml @@ -303,7 +317,7 @@ config: api_provider = "DeepSeek" # API服务商名称(对应在api_providers中配置的服务商名称) price_in = 2.0 # 输入价格(用于API调用统计,单位:元/ M token)(可选,若无该字段,默认值为0) price_out = 8.0 # 输出价格(用于API调用统计,单位:元/ M token)(可选,若无该字段,默认值为0) - #force_stream_mode = true # 强制流式输出模式(若模型不支持非流式输出,请取消该注释,启用强制流式输出,若无该字段,默认值为false) + # force_stream_mode = true # 强制流式输出模式(若模型不支持非流式输出,请取消该注释,启用强制流式输出,若无该字段,默认值为false) [[models]] model_identifier = "deepseek-ai/DeepSeek-V3.2-Exp" @@ -311,17 +325,48 @@ config: api_provider = "SiliconFlow" price_in = 2.0 price_out = 3.0 + # temperature = 0.5 # 可选:为该模型单独指定温度,会覆盖任务配置中的温度 + # max_tokens = 4096 # 可选:为该模型单独指定最大token数,会覆盖任务配置中的max_tokens [models.extra_params] # 可选的额外参数配置 enable_thinking = false # 不启用思考 + [[models]] model_identifier = "deepseek-ai/DeepSeek-V3.2-Exp" name = "siliconflow-deepseek-v3.2-think" api_provider = "SiliconFlow" price_in = 2.0 price_out = 3.0 + # temperature = 0.7 # 可选:为该模型单独指定温度,会覆盖任务配置中的温度 + # max_tokens = 4096 # 可选:为该模型单独指定最大token数,会覆盖任务配置中的max_tokens [models.extra_params] # 可选的额外参数配置 - enable_thinking = true # 不启用思考 + enable_thinking = true # 启用思考 + + + [[models]] + model_identifier = "Qwen/Qwen3-Next-80B-A3B-Instruct" + name = "qwen3-next-80b" + api_provider = "SiliconFlow" + price_in = 1.0 + price_out = 4.0 + + [[models]] + model_identifier = "zai-org/GLM-4.6" + name = "siliconflow-glm-4.6" + api_provider = "SiliconFlow" + price_in = 3.5 + price_out = 14.0 + [models.extra_params] # 可选的额外参数配置 + enable_thinking = false # 不启用思考 + + [[models]] + model_identifier = "zai-org/GLM-4.6" + name = "siliconflow-glm-4.6-think" + api_provider = "SiliconFlow" + price_in = 3.5 + price_out = 14.0 + [models.extra_params] # 可选的额外参数配置 + enable_thinking = true # 启用思考 [[models]] model_identifier = "deepseek-ai/DeepSeek-R1" @@ -364,64 +409,75 @@ config: [model_task_config.utils] # 在麦麦的一些组件中使用的模型,例如表情包模块,取名模块,关系模块,麦麦的情绪变化等,是麦麦必须的模型 model_list = ["siliconflow-deepseek-v3.2"] # 使用的模型列表,每个子项对应上面的模型名称(name) temperature = 0.2 # 模型温度,新V3建议0.1-0.3 - max_tokens = 2048 # 最大输出token数 + max_tokens = 4096 # 最大输出token数 + slow_threshold = 15.0 # 慢请求阈值(秒),模型等待回复时间超过此值会输出警告日志 [model_task_config.utils_small] # 在麦麦的一些组件中使用的小模型,消耗量较大,建议使用速度较快的小模型 model_list = ["qwen3-30b","qwen3-next-80b"] temperature = 0.7 max_tokens = 2048 + slow_threshold = 10.0 [model_task_config.tool_use] #工具调用模型,需要使用支持工具调用的模型 model_list = ["qwen3-30b","qwen3-next-80b"] temperature = 0.7 max_tokens = 800 + slow_threshold = 10.0 [model_task_config.replyer] # 首要回复模型,还用于表达器和表达方式学习 - model_list = ["siliconflow-deepseek-v3.2-think","siliconflow-glm-4.6-think","siliconflow-glm-4.6"] + model_list = ["siliconflow-deepseek-v3.2","siliconflow-deepseek-v3.2-think","siliconflow-glm-4.6","siliconflow-glm-4.6-think"] temperature = 0.3 # 模型温度,新V3建议0.1-0.3 max_tokens = 2048 + slow_threshold = 25.0 [model_task_config.planner] #决策:负责决定麦麦该什么时候回复的模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.3 max_tokens = 800 + slow_threshold = 12.0 [model_task_config.vlm] # 图像识别模型 model_list = ["qwen3-vl-30"] max_tokens = 256 + slow_threshold = 15.0 [model_task_config.voice] # 语音识别模型 model_list = ["sensevoice-small"] + slow_threshold = 12.0 - #嵌入模型 + # 嵌入模型 [model_task_config.embedding] model_list = ["bge-m3"] + slow_threshold = 5.0 - #------------LPMM知识库模型------------ + # ------------LPMM知识库模型------------ [model_task_config.lpmm_entity_extract] # 实体提取模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.2 max_tokens = 800 + slow_threshold = 20.0 [model_task_config.lpmm_rdf_build] # RDF构建模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.2 max_tokens = 800 + slow_threshold = 20.0 [model_task_config.lpmm_qa] # 问答模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.7 max_tokens = 800 + slow_threshold = 20.0 # core的bot_config.toml core_bot_config: | [inner] - version = "6.21.8" + version = "7.2.5" #----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读---- - #如果你想要修改配置文件,请递增version的值 - #如果新增项目,请阅读src/config/official_configs.py中的说明 + # 如果你想要修改配置文件,请递增version的值 + # 如果新增项目,请阅读src/config/official_configs.py中的说明 # # 版本格式:主版本号.次版本号.修订号,版本号递增规则如下: # 主版本号:MMC版本更新 @@ -440,21 +496,31 @@ config: [personality] # 建议120字以内,描述人格特质 和 身份特征 - personality = "是一个女大学生,现在在读大二,会刷贴吧。" - #アイデンティティがない 生まれないらららら - # 描述麦麦说话的表达风格,表达习惯,如要修改,可以酌情新增内容 - reply_style = "请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。" + personality = "是一个大二在读女大学生,现在正在上网和群友聊天,有时有点攻击性,有时比较温柔" + # アイデンティティがない 生まれないらららら + # 描述麦麦说话的表达风格,表达习惯,如要修改,可以酌情新增内容,建议1-2行 + reply_style = "请不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。" - # 麦麦的兴趣,会影响麦麦对什么话题进行回复 - interest = "对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题" + # 多种回复风格列表,可选配置:当 non-empty 且 multiple_probability>0 时,会按概率随机从中选择一个替换 reply_style + multiple_reply_style = [ + # "你的风格平淡但不失讽刺,很简短,很白话。可以参考贴吧,微博的回复风格。", + # "用1-2个字进行回复", + # "用1-2个符号进行回复", + # "言辭凝練古雅,穿插《論語》經句卻不晦澀,以文言短句為基,輔以淺白語意,持長者溫和風範,全用繁體字表達,具先秦儒者談吐韻致。", + # "带点翻译腔,但不要太长", + ] + + # 替换概率:每次构建回复时,以该概率从 multiple_reply_style 中随机选择一个替换 reply_style(0.0-1.0) + multiple_probability = 0.3 # 麦麦的说话规则,行为风格: plan_style = """ 1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 2.如果相同的内容已经被执行,请不要重复执行 - 3.请控制你的发言频率,不要太过频繁的发言 - 4.如果有人对你感到厌烦,请减少回复 - 5.如果有人对你进行攻击,或者情绪激动,请你以合适的方法应对""" + 3.你对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题 + 4.请控制你的发言频率,不要太过频繁的发言 + 5.如果有人对你感到厌烦,请减少回复 + 6.如果有人在追问你,或者话题没有说完,请你继续回复""" # 麦麦识图规则,不建议修改 visual_style = "请用中文描述这张图片的内容。如果有文字,请把文字描述概括出来,请留意其主题,直观感受,输出为一段平文本,最多30字,请注意不要分点,就输出一段文本" @@ -475,18 +541,19 @@ config: # 替换概率,每次构建人格时替换personality的概率(0.0-1.0) state_probability = 0.3 + + [expression] # 表达学习配置 learning_list = [ # 表达学习配置列表,支持按聊天流配置 - ["", "enable", "enable", "1.0"], # 全局配置:使用表达,启用学习,学习强度1.0 - ["qq:1919810:group", "enable", "enable", "1.5"], # 特定群聊配置:使用表达,启用学习,学习强度1.5 - ["qq:114514:private", "enable", "disable", "0.5"], # 特定私聊配置:使用表达,禁用学习,学习强度0.5 + ["", "enable", "enable", "enable"], # 全局配置:使用表达,启用学习,启用jargon学习 + ["qq:1919810:group", "enable", "enable", "enable"], # 特定群聊配置:使用表达,启用学习,启用jargon学习 + ["qq:114514:private", "enable", "disable", "disable"], # 特定私聊配置:使用表达,禁用学习,禁用jargon学习 # 格式说明: # 第一位: chat_stream_id,空字符串表示全局配置 # 第二位: 是否使用学到的表达 ("enable"/"disable") # 第三位: 是否学习表达 ("enable"/"disable") - # 第四位: 学习强度(浮点数),影响学习频率,最短学习时间间隔 = 300/学习强度(秒) - # 学习强度越高,学习越频繁;学习强度越低,学习越少 + # 第四位: 是否启用jargon学习 ("enable"/"disable") ] expression_groups = [ @@ -498,12 +565,21 @@ config: # 注意:如果为群聊,则需要设置为group,如果设置为私聊,则需要设置为private ] + reflect = false # 是否启用表达反思(Bot主动向管理员询问表达方式是否合适) + reflect_operator_id = "" # 表达反思操作员ID,格式:platform:id:type (例如 "qq:123456:private" 或 "qq:654321:group") + allow_reflect = [] # 允许进行表达反思的聊天流ID列表,格式:["qq:123456:private", "qq:654321:group", ...],只有在此列表中的聊天流才会提出问题并跟踪。如果列表为空,则所有聊天流都可以进行表达反思(前提是 reflect = true) - [chat] #麦麦的聊天设置 - talk_value = 1 #聊天频率,越小越沉默,范围0-1 + all_global_jargon = true # 是否开启全局黑话模式,注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除 + enable_jargon_explanation = true # 是否在回复前尝试对上下文中的黑话进行解释(关闭可减少一次LLM调用,仅影响回复前的黑话匹配与解释,不影响黑话学习) + jargon_mode = "planner" # 黑话解释来源模式,可选: "context"(使用上下文自动匹配黑话) 或 "planner"(仅使用Planner在reply动作中给出的unknown_words列表) + + + [chat] # 麦麦的聊天设置 + talk_value = 1 # 聊天频率,越小越沉默,范围0-1 mentioned_bot_reply = true # 是否启用提及必回复 max_context_size = 30 # 上下文长度 - planner_smooth = 2 #规划器平滑,增大数值会减小planner负荷,略微降低反应速度,推荐1-5,0为关闭,必须大于等于0 + planner_smooth = 3 # 规划器平滑,增大数值会减小planner负荷,略微降低反应速度,推荐1-5,0为关闭,必须大于等于0 + think_mode = "dynamic" # 思考模式,可选:classic(默认浅度思考和回复)、deep(会进行比较长的,深度回复)、dynamic(动态选择两种模式) enable_talk_value_rules = true # 是否启用动态发言频率规则 @@ -511,7 +587,7 @@ config: # 推荐格式(对象数组):{ target="platform:id:type" 或 "", time="HH:MM-HH:MM", value=0.5 } # 说明: # - target 为空字符串表示全局;type 为 group/private,例如:"qq:1919810:group" 或 "qq:114514:private"; - # - 支持跨夜区间,例如 "23:00-02:00";数值范围建议 0-1。 + # - 支持跨夜区间,例如 "23:00-02:00";数值范围建议 0-1,如果 value 设置为0会自动转换为0.0001以避免除以零错误。 talk_value_rules = [ { target = "", time = "00:00-08:59", value = 0.8 }, { target = "", time = "09:00-22:59", value = 1.0 }, @@ -519,22 +595,37 @@ config: { target = "qq:114514:private", time = "00:00-23:59", value = 0.3 }, ] - include_planner_reasoning = false # 是否将planner推理加入replyer,默认关闭(不加入) - [memory] - max_agent_iterations = 3 # 记忆思考深度(最低为1(不深入思考)) + max_agent_iterations = 3 # 记忆思考深度(最低为1) + agent_timeout_seconds = 45.0 # 最长回忆时间(秒) + enable_jargon_detection = true # 记忆检索过程中是否启用黑话识别 + global_memory = false # 是否允许记忆检索进行全局查询 - [jargon] - all_global = true # 是否开启全局黑话模式,注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除 + [dream] + interval_minutes = 60 # 做梦时间间隔(分钟),默认30分钟 + max_iterations = 20 # 做梦最大轮次,默认20轮 + first_delay_seconds = 1800 # 程序启动后首次做梦前的延迟时间(秒),默认60秒 + + # 做梦结果推送目标,格式为 "platform:user_id" + # 例如: "qq:123456" 表示在做梦结束后,将梦境文本额外发送给该QQ私聊用户。 + # 为空字符串时不推送。 + dream_send = "" + + # 做梦时间段配置,格式:["HH:MM-HH:MM", ...] + # 如果列表为空,则表示全天允许做梦。 + # 如果配置了时间段,则只有在这些时间段内才会实际执行做梦流程。 + # 时间段外,调度器仍会按间隔检查,但不会进入做梦流程。 + # 支持跨夜区间,例如 "23:00-02:00" 表示从23:00到次日02:00。 + # 示例: + dream_time_ranges = [ + # "09:00-22:00", # 白天允许做梦 + "23:00-10:00", # 跨夜时间段(23:00到次日10:00) + ] + # dream_time_ranges = [] [tool] enable_tool = true # 是否启用工具 - [mood] - enable_mood = false # 是否启用情绪系统 - mood_update_threshold = 1 # 情绪更新阈值,越高,更新越慢 - # 情感特征,影响情绪的变化情况 - emotion_style = "情绪较为稳定,但遭遇特定事件的时候起伏较大" [emoji] emoji_chance = 0.4 # 麦麦激活表情包动作的概率 @@ -556,37 +647,38 @@ config: ban_msgs_regex = [ # 需要过滤的消息(原始消息)匹配的正则表达式,匹配到的消息将被过滤,若不了解正则表达式请勿修改 - #"https?://[^\\s]+", # 匹配https链接 - #"\\d{4}-\\d{2}-\\d{2}", # 匹配日期 + # "https?://[^\\s]+", # 匹配https链接 + # "\\d{4}-\\d{2}-\\d{2}", # 匹配日期 ] [lpmm_knowledge] # lpmm知识库配置 enable = false # 是否启用lpmm知识库 lpmm_mode = "agent" - # 可选:classic经典模式,agent 模式,结合最新的记忆一同使用 - rag_synonym_search_top_k = 10 # 同义词搜索TopK - rag_synonym_threshold = 0.8 # 同义词阈值(相似度高于此阈值的词语会被认为是同义词) - info_extraction_workers = 3 # 实体提取同时执行线程数,非Pro模型不要设置超过5 - qa_relation_search_top_k = 10 # 关系搜索TopK - qa_relation_threshold = 0.5 # 关系阈值(相似度高于此阈值的关系会被认为是相关的关系) - qa_paragraph_search_top_k = 1000 # 段落搜索TopK(不能过小,可能影响搜索结果) + # 可选择classic传统模式/agent 模式,结合新的记忆一同使用 + rag_synonym_search_top_k = 10 # 同义检索TopK + rag_synonym_threshold = 0.8 # 同义阈值,相似度高于该值的关系会被当作同义词 + info_extraction_workers = 3 # 实体抽取同时执行线程数,非Pro模型不要设置超过5 + qa_relation_search_top_k = 10 # 关系检索TopK + qa_relation_threshold = 0.5 # 关系阈值,相似度高于该值的关系会被认为是相关关系 + qa_paragraph_search_top_k = 1000 # 段落检索TopK(不能过小,可能影响搜索结果) qa_paragraph_node_weight = 0.05 # 段落节点权重(在图搜索&PPR计算中的权重,当搜索仅使用DPR时,此参数不起作用) qa_ent_filter_top_k = 10 # 实体过滤TopK qa_ppr_damping = 0.8 # PPR阻尼系数 - qa_res_top_k = 3 # 最终提供的文段TopK - embedding_dimension = 1024 # 嵌入向量维度,应该与模型的输出维度一致 + qa_res_top_k = 3 # 最终提供段落TopK + embedding_dimension = 1024 # 嵌入向量维度,输出维度一致 + # 性能与降级参数(低配机器可下调) + # 低配机器参考:单/双核或内存≤4GB(如轻量云主机/云函数/开发板),建议先关闭PPR并降低并发 + max_embedding_workers = 3 # 嵌入/抽取并发线程数 + embedding_chunk_size = 4 # 每批嵌入的条数 + max_synonym_entities = 2000 # 同义边参与的实体数上限,超限则跳过 + enable_ppr = true # 是否启用PPR,低配机器可关闭 - # keyword_rules 用于设置关键词触发的额外回复知识 - # 添加新规则方法:在 keyword_rules 数组中增加一项,格式如下: - # { keywords = ["关键词1", "关键词2"], reaction = "触发这些关键词时的回复内容" } - # 例如,添加一个新规则:当检测到“你好”或“hello”时回复“你好,有什么可以帮你?” - # { keywords = ["你好", "hello"], reaction = "你好,有什么可以帮你?" } [keyword_reaction] keyword_rules = [ { keywords = ["人机", "bot", "机器", "入机", "robot", "机器人", "ai", "AI"], reaction = "有人说你是人机或者机器人,否定这一事实,攻击或反问他。注意,只有认为你是机器人才回复,否则不要否认" }, { keywords = ["测试关键词回复", "test"], reaction = "回答测试成功" }, - #{ keywords = ["你好", "hello"], reaction = "你好,有什么可以帮你?" } + # { keywords = ["你好", "hello"], reaction = "你好,有什么可以帮你?" } # 在此处添加更多规则,格式同上 ] @@ -634,19 +726,35 @@ config: show_lpmm_paragraph = false # 是否显示lpmm找到的相关文段日志 [maim_message] - auth_token = [] # 认证令牌,用于API验证,为空则不启用验证 - # 以下项目若要使用需要打开use_custom,并单独配置maim_message的服务器 - use_custom = false # 是否启用自定义的maim_message服务器,注意这需要设置新的端口,不能与.env重复 - host="127.0.0.1" - port=8090 - mode="ws" # 支持ws和tcp两种模式 - use_wss = false # 是否使用WSS安全连接,只支持ws模式 - cert_file = "" # SSL证书文件路径,仅在use_wss=true时有效 - key_file = "" # SSL密钥文件路径,仅在use_wss=true时有效 + auth_token = [] # 认证令牌,用于旧版API验证,为空则不启用验证 + + # 新版API Server配置(额外监听端口) + enable_api_server = false # 是否启用额外的新版API Server + api_server_host = "0.0.0.0" # 新版API Server主机地址 + api_server_port = 8090 # 新版API Server端口号 + api_server_use_wss = false # 新版API Server是否启用WSS + api_server_cert_file = "" # 新版API Server SSL证书文件路径 + api_server_key_file = "" # 新版API Server SSL密钥文件路径 + api_server_allowed_api_keys = [] # 新版API Server允许的API Key列表,为空则允许所有连接 [telemetry] #发送统计信息,主要是看全球有多少只麦麦 enable = true + [webui] # WebUI 独立服务器配置 + # 注意: WebUI 的监听地址(host)和端口(port)已移至 .env 文件中的 WEBUI_HOST 和 WEBUI_PORT + enabled = true # 是否启用WebUI + mode = "production" # 模式: development(开发) 或 production(生产) + + # 防爬虫配置 + anti_crawler_mode = "basic" # 防爬虫模式: false(禁用) / strict(严格) / loose(宽松) / basic(基础-只记录不阻止) + allowed_ips = "127.0.0.1" # IP白名单(逗号分隔,支持精确IP、CIDR格式和通配符) + # 示例: 127.0.0.1,192.168.1.0/24,172.17.0.0/16 + trusted_proxies = "" # 信任的代理IP列表(逗号分隔),只有来自这些IP的X-Forwarded-For才被信任 + # 示例: 127.0.0.1,192.168.1.1,172.17.0.1 + trust_xff = false # 是否启用X-Forwarded-For代理解析(默认false) + # 启用后,仍要求直连IP在trusted_proxies中才会信任XFF头 + secure_cookie = false # 是否启用安全Cookie(仅通过HTTPS传输,默认false) + [experimental] #实验性功能 # 为指定聊天添加额外的prompt配置 # 格式: ["platform:id:type:prompt内容", ...] @@ -659,6 +767,6 @@ config: chat_prompts = [] - #此系统暂时移除,无效配置 + # 此系统暂时移除,无效配置 [relationship] enable_relationship = true # 是否启用关系系统 diff --git a/plugins/ChatFrequency/_manifest.json b/plugins/ChatFrequency/_manifest.json index 9a3a9632..669de6b8 100644 --- a/plugins/ChatFrequency/_manifest.json +++ b/plugins/ChatFrequency/_manifest.json @@ -8,18 +8,25 @@ "url": "https://github.com/MaiM-with-u" }, "license": "GPL-v3.0-or-later", - "host_application": { "min_version": "0.10.3" }, "homepage_url": "https://github.com/SengokuCola/BetterFrequency", "repository_url": "https://github.com/SengokuCola/BetterFrequency", - "keywords": ["frequency", "control", "talk_frequency", "plugin", "shortcut"], - "categories": ["Chat", "Frequency", "Control"], - + "keywords": [ + "frequency", + "control", + "talk_frequency", + "plugin", + "shortcut" + ], + "categories": [ + "Chat", + "Frequency", + "Control" + ], "default_locale": "zh-CN", "locales_path": "_locales", - "plugin_info": { "is_built_in": false, "plugin_type": "frequency", @@ -46,5 +53,6 @@ "支持完整命令和简化命令", "快速操作支持" ] - } + }, + "id": "SengokuCola.BetterFrequency" } \ No newline at end of file diff --git a/plugins/MaiBot_MCPBridgePlugin/.gitignore b/plugins/MaiBot_MCPBridgePlugin/.gitignore new file mode 100644 index 00000000..ebef83b0 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/.gitignore @@ -0,0 +1,30 @@ +# 运行时配置(包含用户敏感信息) +config.toml + +# 备份文件 +*.backup.* +*.bak + +# 日志 +logs/ +*.log +*.jsonl + +# Python 缓存 +__pycache__/ +*.py[cod] +*$py.class +*.so + +# 本地测试脚本(仓库不提交) +test_*.py + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# 系统文件 +.DS_Store +Thumbs.db diff --git a/plugins/MaiBot_MCPBridgePlugin/CHANGELOG.md b/plugins/MaiBot_MCPBridgePlugin/CHANGELOG.md new file mode 100644 index 00000000..0c3feb46 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +本文件记录 `MaiBot_MCPBridgePlugin` 的用户可感知变更。 + +## 2.0.0 + +- 配置入口统一:MCP 服务器仅使用 Claude Desktop `mcpServers` JSON(`servers.claude_config_json`) +- 兼容迁移:自动识别旧版 `servers.list` 并迁移为 `mcpServers`(需在 WebUI 保存一次固化) +- 保持功能不变:保留 Workflow(硬流程/工具链)与 ReAct(软流程)双轨制能力 +- 精简实现:移除旧的 WebUI 导入导出/快速添加服务器实现与 `tomlkit` 依赖 +- 易用性:完善 Workflow 变量替换(支持数组下标与 bracket 写法),并优化 WebUI 配置区顺序 + +## 1.9.0 + +- 双轨制架构:ReAct(软流程)+ Workflow(硬流程/工具链) + +## 1.8.0 + +- Workflow(工具链):多工具顺序执行、变量替换、自定义 Workflow 并注册为组合工具 + +## 1.7.0 + +- 断路器模式、状态刷新、工具搜索等易用性增强 + diff --git a/plugins/MaiBot_MCPBridgePlugin/DEVELOPMENT.md b/plugins/MaiBot_MCPBridgePlugin/DEVELOPMENT.md new file mode 100644 index 00000000..7299fe13 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/DEVELOPMENT.md @@ -0,0 +1,356 @@ +# MCP 桥接插件开发文档 + +本文档面向开发者,介绍插件的架构设计、核心模块和扩展方式。 + +## 架构概览 + +``` +MaiBot_MCPBridgePlugin/ +├── plugin.py # 主插件文件,包含所有核心逻辑 +├── mcp_client.py # MCP 客户端封装 +├── tool_chain.py # 工具链(Workflow)模块 +├── core/ +│ └── claude_config.py # Claude Desktop mcpServers 解析/迁移 +├── config.toml # 运行时配置 +└── _manifest.json # 插件元数据 +``` + +## 核心模块 + +### 1. MCP 客户端 (`mcp_client.py`) + +封装了与 MCP 服务器的通信逻辑。 + +```python +from .mcp_client import mcp_manager, MCPServerConfig, TransportType + +# 添加服务器 +config = MCPServerConfig( + name="my-server", + transport=TransportType.STREAMABLE_HTTP, + url="https://mcp.example.com/mcp" +) +await mcp_manager.add_server(config) + +# 调用工具 +result = await mcp_manager.call_tool("server_tool_name", {"param": "value"}) +if result.success: + print(result.content) +``` + +**支持的传输类型:** +- `STDIO`: 本地进程通信 +- `SSE`: Server-Sent Events +- `HTTP`: HTTP 请求 +- `STREAMABLE_HTTP`: 流式 HTTP(推荐) + +### 2. 工具注册系统 + +MCP 工具通过动态类创建注册到 MaiBot: + +```python +# 创建工具代理类 +class MCPToolProxy(BaseTool): + name = "mcp_server_tool" + description = "工具描述" + parameters = [("param", ToolParamType.STRING, "参数描述", True, None)] + available_for_llm = True + + async def execute(self, function_args): + result = await mcp_manager.call_tool(self._mcp_tool_key, function_args) + return {"name": self.name, "content": result.content} +``` + +### 3. 工具链模块 (`tool_chain.py`) + +实现 Workflow 硬流程,支持多工具顺序执行。 + +```python +from .tool_chain import ToolChainDefinition, ToolChainStep, tool_chain_manager + +# 定义工具链 +chain = ToolChainDefinition( + name="search_and_detail", + description="搜索并获取详情", + input_params={"query": "搜索关键词"}, + steps=[ + ToolChainStep( + tool_name="mcp_server_search", + args_template={"keyword": "${input.query}"}, + output_key="search_result" + ), + ToolChainStep( + tool_name="mcp_server_detail", + args_template={"id": "${prev}"} + ) + ] +) + +# 注册并执行 +tool_chain_manager.add_chain(chain) +result = await tool_chain_manager.execute_chain("search_and_detail", {"query": "test"}) +``` + +**变量替换语法:** +- `${input.参数名}`: 用户输入 +- `${step.输出键}`: 指定步骤的输出 +- `${prev}`: 上一步输出 +- `${prev.字段}`: 上一步输出(JSON)的字段 +- `${step.geo.return.0.location}` / `${step.geo.return[0].location}`: 数组下标访问 +- `${step.geo['return'][0]['location']}`: bracket 写法(最通用) + +## 双轨制架构 + +### ReAct 软流程 + +将 MCP 工具注册到 MaiBot 的记忆检索 ReAct 系统,LLM 自主决策调用。 + +```python +def _register_tools_to_react(self) -> int: + from src.memory_system.retrieval_tools import register_memory_retrieval_tool + + def make_execute_func(tool_key: str): + async def execute_func(**kwargs) -> str: + result = await mcp_manager.call_tool(tool_key, kwargs) + return result.content if result.success else f"失败: {result.error}" + return execute_func + + register_memory_retrieval_tool( + name="mcp_tool_name", + description="工具描述", + parameters=[{"name": "param", "type": "string", "required": True}], + execute_func=make_execute_func("tool_key") + ) +``` + +### Workflow 硬流程 + +用户预定义的固定执行流程,注册为组合工具。 + +```python +def _register_tool_chains(self) -> None: + from src.plugin_system.core.component_registry import component_registry + + for chain_name, chain in tool_chain_manager.get_enabled_chains().items(): + info, tool_class = tool_chain_registry.register_chain(chain) + info.plugin_name = self.plugin_name + component_registry.register_component(info, tool_class) +``` + +## 配置系统 + +### MCP 服务器配置(Claude Desktop 规范) + +插件只接受 Claude Desktop 的 `mcpServers` JSON(见 `core/claude_config.py`)。配置入口统一为: + +- WebUI/配置文件:`[servers].claude_config_json` +- 命令:`/mcp import`(合并 `mcpServers`)与 `/mcp export`(导出当前 `mcpServers`) + +兼容迁移: +- 若检测到旧版 `servers.list`,会自动迁移为 `servers.claude_config_json`(仅迁移到内存配置,需 WebUI 保存一次固化)。 + +### WebUI 配置 Schema + +使用 `ConfigField` 定义 WebUI 配置项: + +```python +config_schema = { + "section_name": { + "field_name": ConfigField( + type=str, # 类型: str, bool, int, float + default="default_value", # 默认值 + description="字段描述", + label="显示标签", + input_type="textarea", # 输入类型: text, textarea, password + rows=5, # textarea 行数 + disabled=True, # 只读 + choices=["a", "b"], # 下拉选项 + hint="提示信息", + order=1, # 排序 + ), + }, +} +``` + +### 配置读取 + +```python +# 在组件中读取配置 +value = self.get_config("section.key", default="fallback") + +# 在插件类中读取 +value = self.config.get("section", {}).get("key", "default") +``` + +## 事件处理 + +### 启动事件 + +```python +class MCPStartupHandler(BaseEventHandler): + event_type = EventType.ON_START + handler_name = "mcp_startup" + + async def execute(self, message): + global _plugin_instance + if _plugin_instance: + await _plugin_instance._async_connect_servers() + return (True, True, None, None, None) +``` + +### 停止事件 + +```python +class MCPStopHandler(BaseEventHandler): + event_type = EventType.ON_STOP + handler_name = "mcp_stop" + + async def execute(self, message): + await mcp_manager.shutdown() + return (True, True, None, None, None) +``` + +## 命令系统 + +```python +class MCPStatusCommand(BaseCommand): + command_name = "mcp_status" + command_pattern = r"^/mcp(?:\s+(?P\S+))?(?:\s+(?P.+))?$" + + async def execute(self) -> Tuple[bool, str, bool]: + action = self.matched_groups.get("action", "") + arg = self.matched_groups.get("arg", "") + + if action == "tools": + await self.send_text("工具列表...") + elif action == "reconnect": + await self._handle_reconnect(arg) + + return (True, None, True) # (成功, 消息, 拦截) +``` + +## 高级功能 + +### 调用追踪 + +```python +from plugin import tool_call_tracer, ToolCallRecord + +# 记录调用 +record = ToolCallRecord( + call_id="xxx", + timestamp=time.time(), + tool_name="tool", + server_name="server", + arguments={"key": "value"}, + success=True, + duration_ms=100.0 +) +tool_call_tracer.record(record) + +# 查询记录 +recent = tool_call_tracer.get_recent(10) +by_tool = tool_call_tracer.get_by_tool("tool_name") +``` + +### 调用缓存 + +```python +from plugin import tool_call_cache + +# 配置缓存 +tool_call_cache.configure( + enabled=True, + ttl=300, # 秒 + max_entries=200, + exclude_tools="mcp_*_time_*" # 排除模式 +) + +# 使用缓存 +cached = tool_call_cache.get("tool_name", {"param": "value"}) +if cached is None: + result = await call_tool(...) + tool_call_cache.set("tool_name", {"param": "value"}, result) +``` + +### 权限控制 + +```python +from plugin import permission_checker + +# 配置权限 +permission_checker.configure( + enabled=True, + default_mode="allow_all", # 或 "deny_all" + rules_json='[{"tool": "mcp_*_delete_*", "denied": ["qq:123:group"]}]', + quick_deny_groups="123456789", + quick_allow_users="111111111" +) + +# 检查权限 +allowed = permission_checker.check( + tool_name="mcp_server_delete", + chat_id="123456", + user_id="789", + is_group=True +) +``` + +### 断路器模式 + +MCP 客户端内置断路器,故障服务器快速失败: + +- 连续失败 N 次后熔断 +- 熔断期间直接返回错误 +- 定期尝试恢复 + +## 扩展开发 + +### 添加新的传输类型 + +1. 在 `mcp_client.py` 中添加 `TransportType` 枚举值 +2. 实现对应的连接逻辑 +3. 更新 `_create_transport()` 方法 + +### 添加新的工具类型 + +1. 继承 `BaseTool` 创建新类 +2. 在 `get_plugin_components()` 中注册 +3. 实现 `execute()` 方法 + +### 添加新的命令 + +1. 在 `MCPStatusCommand.execute()` 中添加新的 action 分支 +2. 或创建新的 `BaseCommand` 子类 + +## 调试技巧 + +### 日志级别 + +```python +from src.common.logger import get_logger +logger = get_logger("mcp_bridge_plugin") + +logger.debug("详细调试信息") +logger.info("一般信息") +logger.warning("警告") +logger.error("错误") +``` + +### 常用调试命令 + +```bash +/mcp # 查看状态 +/mcp tools # 查看工具列表 +/mcp trace # 查看调用记录 +/mcp cache # 查看缓存状态 +/mcp chain # 查看工具链 +``` + +## 更新日志 + +见 `plugins/MaiBot_MCPBridgePlugin/CHANGELOG.md` + +## 开发约定 + +- 本仓库不提交测试脚本/临时复现文件;如需本地验证,可自行在工作区创建未跟踪文件(建议放到 `.local/` 并加入 `.gitignore`)。 diff --git a/plugins/MaiBot_MCPBridgePlugin/README.md b/plugins/MaiBot_MCPBridgePlugin/README.md new file mode 100644 index 00000000..61aca8f5 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/README.md @@ -0,0 +1,357 @@ +# MCP 桥接插件 + +将 [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) 服务器的工具桥接到 MaiBot,使麦麦能够调用外部 MCP 工具。 + +image + +## 🚀 快速开始 + +### 1. 安装 + +```bash +# 克隆到 MaiBot 插件目录 +cd /path/to/MaiBot/plugins +git clone https://github.com/CharTyr/MaiBot_MCPBridgePlugin.git MCPBridgePlugin + +# 安装依赖 +pip install mcp + +# 复制配置文件 +cd MCPBridgePlugin +cp config.example.toml config.toml +``` + +### 2. 添加服务器 + +编辑 `config.toml`,在 `[servers]` 的 `claude_config_json` 中填写 Claude Desktop 的 `mcpServers` JSON: + +```toml +[servers] +claude_config_json = ''' +{ + "mcpServers": { + "time": { "transport": "streamable_http", "url": "https://mcp.api-inference.modelscope.cn/server/mcp-server-time" }, + "my-server": { "transport": "streamable_http", "url": "https://mcp.xxx.com/mcp", "headers": { "Authorization": "Bearer 你的密钥" } }, + "fetch": { "command": "uvx", "args": ["mcp-server-fetch"] } + } +} +''' +``` + +### 3. 启动 + +重启 MaiBot,或发送 `/mcp reconnect` + +--- + +## 📚 去哪找 MCP 服务器? + +| 平台 | 说明 | +|------|------| +| [mcp.modelscope.cn](https://mcp.modelscope.cn/) | 魔搭 ModelScope,免费推荐 | +| [smithery.ai](https://smithery.ai/) | MCP 服务器注册中心 | +| [github.com/modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) | 官方服务器列表 | + +--- + +## 💡 常用命令 + +| 命令 | 说明 | +|------|------| +| `/mcp` | 查看连接状态 | +| `/mcp tools` | 查看可用工具 | +| `/mcp reconnect` | 重连服务器 | +| `/mcp trace` | 查看调用记录 | +| `/mcp cache` | 查看缓存状态 | +| `/mcp perm` | 查看权限配置 | +| `/mcp import ` | 🆕 导入 Claude Desktop 配置 | +| `/mcp export` | 🆕 导出配置 | +| `/mcp search <关键词>` | 🆕 搜索工具 | +| `/mcp chain` | 🆕 查看工具链 | +| `/mcp chain <名称>` | 🆕 查看工具链详情 | +| `/mcp chain test <名称> <参数>` | 🆕 测试执行工具链 | + +--- + +## ✨ 功能特性 + +### 核心功能 +- 🔌 多服务器同时连接 +- 📡 支持 stdio / SSE / HTTP / Streamable HTTP +- 🔄 自动重试、心跳检测、断线重连 +- 🖥️ WebUI 完整配置支持 + +### 双轨制架构 +- 🔄 **ReAct(软流程)**:LLM 自主决策,多轮动态调用 MCP 工具(适合探索式场景) +- 🔗 **Workflow(硬流程/工具链)**:用户预定义步骤顺序与参数传递(适合可控可复用场景) + +### 高级功能 +- 📦 Resources 支持(实验性) +- 📝 Prompts 支持(实验性) +- 🔄 结果后处理(LLM 摘要提炼) +- 🔍 调用追踪 / 🗄️ 调用缓存 / 🔐 权限控制 / 🚫 工具禁用 + +### 更新日志 +- 见 `plugins/MaiBot_MCPBridgePlugin/CHANGELOG.md` + +--- + +## ⚙️ 配置说明 + +### 服务器配置 + +```json +{ + "mcpServers": { + "server_name": { + "transport": "streamable_http", + "url": "https://..." + } + } +} +``` + +| 字段 | 说明 | +|------|------| +| `mcpServers.` | 服务器名称(唯一) | +| `enabled` | 是否启用(可选,默认 true) | +| `transport` | `stdio` / `sse` / `http` / `streamable_http` | +| `url` | 远程服务器地址 | +| `headers` | 🆕 鉴权头(如 `{"Authorization": "Bearer xxx"}`) | +| `command` / `args` | 本地服务器启动命令 | + +### 权限控制 + +**快捷配置(推荐):** +```toml +[permissions] +perm_enabled = true +quick_deny_groups = "123456789" # 禁用的群号 +quick_allow_users = "111111111" # 管理员白名单 +``` + +**高级规则:** +```json +[{"tool": "mcp_*_delete_*", "denied": ["qq:123456:group"]}] +``` + +### 工具禁用 + +```toml +[tools] +disabled_tools = ''' +mcp_filesystem_delete_file +mcp_filesystem_write_file +''' +``` + +### 调用缓存 + +```toml +[settings] +cache_enabled = true +cache_ttl = 300 +cache_exclude_tools = "mcp_*_time_*" +``` + +--- + +## ❓ 常见问题 + +**Q: 工具没有注册?** +- 检查 `enabled = true` +- 检查 MaiBot 日志错误信息 +- 确认 `pip install mcp` + +**Q: JSON 格式报错?** +- 多行 JSON 用 `'''` 三引号包裹 +- 使用英文双引号 `"` + +**Q: 如何手动重连?** +- `/mcp reconnect` 或 `/mcp reconnect 服务器名` + +--- + +## 📥 配置导入导出(Claude mcpServers) + +### 从 Claude Desktop 导入 + +如果你已有 Claude Desktop 的 MCP 配置,可以直接导入: + +``` +/mcp import {"mcpServers":{"time":{"command":"uvx","args":["mcp-server-time"]},"fetch":{"command":"uvx","args":["mcp-server-fetch"]}}} +``` + +支持的格式: +- Claude Desktop 格式(`mcpServers` 对象) +- 兼容旧版:MaiBot servers 列表数组(将自动迁移为 `mcpServers`) + +### 导出配置 + +``` +/mcp export # 导出为 Claude Desktop 格式(默认) +/mcp export claude # 导出为 Claude Desktop 格式 +``` + +### 注意事项 +- 导入时会自动跳过同名服务器 +- 导入后需要发送 `/mcp reconnect` 使配置生效 +- 支持 stdio、sse、http、streamable_http 全部传输类型 + +--- + +## 🔗 Workflow(硬流程/工具链) + +工具链允许你将多个 MCP 工具按顺序执行,后续工具可以使用前序工具的输出作为输入。 + +### 1 分钟上手(推荐 WebUI) +1. 先完成 MCP 服务器配置并 `/mcp reconnect` +2. 发送 `/mcp tools`,复制你要用的工具名 +3. 打开 WebUI → 「Workflow(硬流程/工具链)」→ 用“快速添加”表单填入: + - 名称/描述 + - 输入参数(每行 `参数名=描述`) + - 执行步骤(每行 `工具名|参数JSON|输出键`) +4. 在“确认添加”中输入 `ADD` 并保存 + +### 快速添加工具链(推荐) + +在 WebUI 的「工具链」配置区,使用表单快速添加: + +1. **名称**: 填写工具链名称(英文,如 `search_and_detail`) +2. **描述**: 填写工具链用途(供 LLM 理解何时使用) +3. **输入参数**: 每行一个,格式 `参数名=描述` + ``` + query=搜索关键词 + max_results=最大结果数 + ``` +4. **执行步骤**: 每行一个,格式 `工具名|参数JSON|输出键` + ``` + mcp_server_search|{"keyword":"${input.query}"}|search_result + mcp_server_detail|{"id":"${prev}"}| + ``` +5. **确认添加**: 输入 `ADD` 并保存 + +### JSON 配置方式 + +也可以直接在「工具链列表」中编写 JSON: + +```json +[ + { + "name": "search_and_detail", + "description": "先搜索模组,再获取详情", + "input_params": { + "query": "搜索关键词" + }, + "steps": [ + { + "tool_name": "mcp_mcmod_search_mod", + "args_template": {"keyword": "${input.query}", "limit": 1}, + "output_key": "search_result", + "description": "搜索模组" + }, + { + "tool_name": "mcp_mcmod_get_mod_detail", + "args_template": {"mod_id": "${prev}"}, + "description": "获取详情" + } + ] + } +] +``` + +### 变量替换 + +| 变量格式 | 说明 | +|---------|------| +| `${input.参数名}` | 用户输入的参数 | +| `${step.输出键}` | 某个步骤的输出(通过 `output_key` 指定) | +| `${prev}` | 上一步的输出 | +| `${prev.字段}` | 上一步输出(JSON)的某个字段 | +| `${step.geo.return.0.location}` | 数组下标访问(dot) | +| `${step.geo.return[0].location}` | 数组下标访问([]) | +| `${step.geo['return'][0]['location']}` | bracket 写法(最通用) | + +### 工具链字段说明 + +| 字段 | 说明 | +|------|------| +| `name` | 工具链名称,将生成 `chain_xxx` 工具 | +| `description` | 描述,供 LLM 理解何时使用 | +| `input_params` | 输入参数定义 `{参数名: 描述}` | +| `steps` | 执行步骤数组 | +| `steps[].tool_name` | 要调用的工具名 | +| `steps[].args_template` | 参数模板,支持变量替换 | +| `steps[].output_key` | 输出存储键名(可选) | +| `steps[].optional` | 是否可选,失败时继续执行(默认 false) | + +### 命令 + +```bash +/mcp chain # 查看所有工具链 +/mcp chain list # 列出工具链 +/mcp chain <名称> # 查看详情 +/mcp chain test <名称> {"query": "JEI"} # 测试执行 +/mcp chain reload # 重新加载配置 +``` + +--- + +## 🔄 双轨制架构 + +MCP 桥接插件支持两种工具调用模式,可根据场景选择: + +### ReAct 软流程 + +LLM 自主决策的多轮工具调用模式,适合复杂、不确定的场景。 + +**工作原理:** +1. 用户提问 → LLM 分析需要什么信息 +2. LLM 选择调用工具 → 获取结果 +3. LLM 观察结果 → 决定是否需要更多信息 +4. 重复 2-3 直到信息足够 → 生成最终回答 + +**启用方式:** +在 WebUI「ReAct (软流程)」配置区启用,MCP 工具将自动注册到 MaiBot 的记忆检索 ReAct 系统。 + +**适用场景:** +- 复杂问题需要多步推理 +- 不确定需要调用哪些工具 +- 需要根据中间结果动态调整 + +### Workflow 硬流程 + +用户预定义的工作流,固定执行顺序,适合可靠、可控的场景。 + +**工作原理:** +1. 用户定义步骤顺序和参数传递 +2. 按顺序执行每个步骤 +3. 后续步骤可使用前序步骤的输出 +4. 返回最终结果 + +**适用场景:** +- 流程固定、可预测 +- 需要可靠、可重复的执行 +- 希望精确控制工具调用顺序 + +### 对比 + +| 特性 | ReAct 软流程 | Workflow 硬流程 | +|------|-------------|----------------| +| 决策者 | LLM 自主决策 | 用户预定义 | +| 灵活性 | 高,动态调整 | 低,固定流程 | +| 可预测性 | 低 | 高 | +| 适用场景 | 复杂、探索性任务 | 固定、重复性任务 | +| 配置方式 | 启用即可 | 需要定义步骤 | + +--- + +## 📋 依赖 + +- MaiBot >= 0.11.6 +- Python >= 3.10 +- mcp >= 1.0.0 + +## 📄 许可证 + +AGPL-3.0 diff --git a/plugins/MaiBot_MCPBridgePlugin/__init__.py b/plugins/MaiBot_MCPBridgePlugin/__init__.py new file mode 100644 index 00000000..80e2ae47 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/__init__.py @@ -0,0 +1,44 @@ +""" +MCP 桥接插件 +将 MCP (Model Context Protocol) 服务器的工具桥接到 MaiBot + +v1.1.0 新增功能: +- 心跳检测和自动重连 +- 调用统计(次数、成功率、耗时) +- 更好的错误处理 + +v1.2.0 新增功能: +- Resources 支持(资源读取) +- Prompts 支持(提示模板) +""" + +from .plugin import MCPBridgePlugin, mcp_tool_registry, MCPStartupHandler, MCPStopHandler +from .mcp_client import ( + mcp_manager, + MCPClientManager, + MCPServerConfig, + TransportType, + MCPCallResult, + MCPToolInfo, + MCPResourceInfo, + MCPPromptInfo, + ToolCallStats, + ServerStats, +) + +__all__ = [ + "MCPBridgePlugin", + "mcp_tool_registry", + "mcp_manager", + "MCPClientManager", + "MCPServerConfig", + "TransportType", + "MCPCallResult", + "MCPToolInfo", + "MCPResourceInfo", + "MCPPromptInfo", + "ToolCallStats", + "ServerStats", + "MCPStartupHandler", + "MCPStopHandler", +] diff --git a/plugins/MaiBot_MCPBridgePlugin/_manifest.json b/plugins/MaiBot_MCPBridgePlugin/_manifest.json new file mode 100644 index 00000000..85225a43 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/_manifest.json @@ -0,0 +1,67 @@ +{ + "manifest_version": 1, + "name": "MCP桥接插件", + "version": "2.0.0", + "description": "将 MCP (Model Context Protocol) 服务器的工具桥接到 MaiBot,使麦麦能够调用外部 MCP 工具", + "author": { + "name": "CharTyr", + "url": "https://github.com/CharTyr" + }, + "license": "AGPL-3.0", + "host_application": { + "min_version": "0.11.6" + }, + "homepage_url": "https://github.com/CharTyr/MaiBot_MCPBridgePlugin", + "repository_url": "https://github.com/CharTyr/MaiBot_MCPBridgePlugin", + "keywords": [ + "mcp", + "bridge", + "tool", + "integration", + "resources", + "prompts", + "post-process", + "cache", + "trace", + "permissions", + "import", + "export", + "claude-desktop", + "workflow", + "react", + "agent" + ], + "categories": [ + "工具扩展", + "外部集成" + ], + "default_locale": "zh-CN", + "plugin_info": { + "is_built_in": false, + "components": [], + "features": [ + "支持多个 MCP 服务器", + "自动发现并注册 MCP 工具", + "支持 stdio、SSE、HTTP、Streamable HTTP 四种传输方式", + "工具参数自动转换", + "心跳检测与自动重连", + "调用统计(次数、成功率、耗时)", + "WebUI 配置支持", + "Resources 支持(实验性)", + "Prompts 支持(实验性)", + "结果后处理(LLM 摘要提炼)", + "工具禁用管理", + "调用链路追踪", + "工具调用缓存(LRU)", + "工具权限控制(群/用户级别)", + "配置导入导出(Claude Desktop mcpServers)", + "断路器模式(故障快速失败)", + "状态实时刷新", + "Workflow 硬流程(顺序执行多个工具)", + "Workflow 快速添加(表单式配置)", + "ReAct 软流程(LLM 自主多轮调用)", + "双轨制架构(软流程 + 硬流程)" + ] + }, + "id": "MaiBot Community.MCPBridgePlugin" +} diff --git a/plugins/MaiBot_MCPBridgePlugin/config.example.toml b/plugins/MaiBot_MCPBridgePlugin/config.example.toml new file mode 100644 index 00000000..4edac27a --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/config.example.toml @@ -0,0 +1,309 @@ +# MCP桥接插件 - 配置文件示例 +# 将 MCP (Model Context Protocol) 服务器的工具桥接到 MaiBot +# +# 使用方法:复制此文件为 config.toml,然后根据需要修改配置 +# +# ============================================================ +# 🎯 快速开始(三步) +# ============================================================ +# 1. 在下方 [servers] 添加 MCP 服务器配置 +# 2. 将 enabled 改为 true 启用服务器 +# 3. 重启 MaiBot 或发送 /mcp reconnect +# +# ============================================================ +# 📚 去哪找 MCP 服务器? +# ============================================================ +# +# 【远程服务(推荐新手)】 +# - ModelScope: https://mcp.modelscope.cn/ (免费,推荐) +# - Smithery: https://smithery.ai/ +# - Glama: https://glama.ai/mcp/servers +# +# 【本地服务(需要 npx 或 uvx)】 +# - 官方列表: https://github.com/modelcontextprotocol/servers +# +# ============================================================ + +# ============================================================ +# 🔌 MCP 服务器配置 +# ============================================================ +# +# ⚠️ 重要:配置格式(Claude Desktop 规范) +# ──────────────────────────────────────────────────────────── +# 统一使用 Claude Desktop 的 mcpServers JSON。 +# +# claude_config_json 的内容应为 JSON 对象: +# { +# "mcpServers": { +# "server_name": { ...server config... }, +# "another": { ... } +# } +# } +# +# 每个服务器支持字段: +# transport - 传输方式: "stdio" / "sse" / "http" / "streamable_http"(可选) +# url - 服务器地址(sse/http/streamable_http 模式) +# command - 启动命令(stdio 模式,如 "npx" / "uvx") +# args - 命令参数数组(stdio 模式) +# env - 环境变量对象(stdio 模式,可选) +# headers - 鉴权头(可选,如 {"Authorization": "Bearer xxx"}) +# enabled - 是否启用(可选,默认 true) +# post_process - 服务器级别后处理配置(可选) +# +# ============================================================ + +[servers] +claude_config_json = ''' +{ + "mcpServers": { + "time-mcp-server": { + "enabled": false, + "transport": "streamable_http", + "url": "https://mcp.api-inference.modelscope.cn/server/mcp-server-time" + }, + "my-auth-server": { + "enabled": false, + "transport": "streamable_http", + "url": "https://mcp.api-inference.modelscope.net/xxxxxx/mcp", + "headers": { + "Authorization": "Bearer ms-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } + }, + "fetch-local": { + "enabled": false, + "command": "uvx", + "args": ["mcp-server-fetch"] + } + } +} +''' + +# ============================================================ +# 插件基本信息 +# ============================================================ +[plugin] +name = "mcp_bridge_plugin" +version = "2.0.0" +config_version = "2.0.0" +enabled = false # 默认禁用,在 WebUI 中启用 + +# ============================================================ +# Workflow(硬流程/工具链) +# ============================================================ +# +# 作用:把多个工具按顺序执行;后续步骤可引用前序输出。 +# +# ✅ 推荐配置方式:WebUI「Workflow(硬流程/工具链)」里用“快速添加”表单。 +# ✅ 也可以直接写 chains_list(JSON 数组)。 +# +# 变量替换: +# ${input.xxx} - 用户输入 +# ${step.} - 指定步骤输出(需设置 output_key) +# ${prev} - 上一步输出 +# ${prev.字段} - 上一步输出(JSON)的字段 +# ${step.geo.return.0.location} - 数组/下标访问(dot) +# ${step.geo.return[0].location} - 数组/下标访问([]) +# ${step.geo['return'][0]['location']} - bracket 写法 +# +# ============================================================ + +[tool_chains] +chains_enabled = true + +chains_list = ''' +[ + { + "name": "search_and_detail", + "description": "先搜索,再根据结果获取详情", + "input_params": { "query": "搜索关键词" }, + "steps": [ + { "tool_name": "把这里替换成你的搜索工具名", "args_template": { "keyword": "${input.query}" }, "output_key": "search" }, + { "tool_name": "把这里替换成你的详情工具名", "args_template": { "id": "${prev}" } } + ] + } +] +''' + +# ============================================================ +# ReAct(软流程) +# ============================================================ +# +# 作用:把 MCP 工具注册到 MaiBot 的 ReAct 系统,LLM 可自主多轮调用。 +# +# 注意:ReAct 适合“探索式/不确定”场景;Workflow 适合“固定/可控”场景。 +# +# ============================================================ + +[react] +react_enabled = false +filter_mode = "whitelist" # whitelist / blacklist +tool_filter = "" # 每行一个工具名,支持通配符 * + +# ============================================================ +# 全局设置(高级设置建议保持默认) +# ============================================================ +[settings] +# 🏷️ 工具前缀 - 用于区分 MCP 工具和原生工具 +tool_prefix = "mcp" + +# ⏱️ 连接超时(秒) +connect_timeout = 30.0 + +# ⏱️ 调用超时(秒) +call_timeout = 60.0 + +# 🔄 自动连接 - 启动时自动连接所有已启用的服务器 +auto_connect = true + +# 🔁 重试次数 - 连接失败时的重试次数 +retry_attempts = 3 + +# ⏳ 重试间隔(秒) +retry_interval = 5.0 + +# 💓 心跳检测 - 定期检测服务器连接状态 +heartbeat_enabled = true + +# 💓 心跳间隔(秒)- 建议 30-120 秒 +heartbeat_interval = 60.0 + +# 🔄 自动重连 - 检测到断开时自动尝试重连 +auto_reconnect = true + +# 🔄 最大重连次数 - 连续重连失败后暂停重连 +max_reconnect_attempts = 3 + +# ============================================================ +# 高级功能(实验性) +# ============================================================ +# 📦 启用 Resources - 允许读取 MCP 服务器提供的资源 +enable_resources = false + +# 📝 启用 Prompts - 允许使用 MCP 服务器提供的提示模板 +enable_prompts = false + +# ============================================================ +# 结果后处理功能 +# ============================================================ +# 当 MCP 工具返回的内容过长时,使用 LLM 对结果进行摘要提炼 + +# 🔄 启用结果后处理 +post_process_enabled = false + +# 📏 后处理阈值(字符数)- 结果长度超过此值才触发后处理 +post_process_threshold = 500 + +# 🔢 后处理输出限制 - LLM 摘要输出的最大 token 数 +post_process_max_tokens = 500 + +# 🤖 后处理模型(可选)- 留空则使用 utils 模型组 +post_process_model = "" + +# 🧠 后处理提示词模板 +post_process_prompt = '''用户问题:{query} + +工具返回内容: +{result} + +请从上述内容中提取与用户问题最相关的关键信息,简洁准确地输出:''' + +# ============================================================ +# 调用链路追踪 +# ============================================================ +# 记录工具调用详情,便于调试和分析 + +# 🔍 启用调用追踪 +trace_enabled = true + +# 📊 追踪记录上限 - 内存中保留的最大记录数 +trace_max_records = 50 + +# 📝 追踪日志文件 - 是否将追踪记录写入日志文件 +# 启用后记录写入 plugins/MaiBot_MCPBridgePlugin/logs/trace.jsonl +trace_log_enabled = false + +# ============================================================ +# 工具调用缓存 +# ============================================================ +# 缓存相同参数的调用结果,减少重复请求 + +# 🗄️ 启用调用缓存 +cache_enabled = false + +# ⏱️ 缓存有效期(秒) +cache_ttl = 300 + +# 📦 最大缓存条目 - 超出后 LRU 淘汰 +cache_max_entries = 200 + +# 🚫 缓存排除列表 - 即不缓存的工具(每行一个,支持通配符 *) +# 时间类、随机类工具建议排除 +cache_exclude_tools = ''' +mcp_*_time_* +mcp_*_random_* +''' + +# ============================================================ +# 工具管理 +# ============================================================ +[tools] +# 📋 工具清单(只读)- 启动后自动生成 +tool_list = "(启动后自动生成)" + +# 🚫 禁用工具列表 - 要禁用的工具名(每行一个) +# 从上方工具清单复制工具名,禁用后该工具不会被 LLM 调用 +# 示例: +# disabled_tools = ''' +# mcp_filesystem_delete_file +# mcp_filesystem_write_file +# ''' +disabled_tools = "" + +# ============================================================ +# 权限控制 +# ============================================================ +[permissions] +# 🔐 启用权限控制 - 按群/用户限制工具使用 +perm_enabled = false + +# 📋 默认模式 +# allow_all: 未配置规则的工具默认允许 +# deny_all: 未配置规则的工具默认禁止 +perm_default_mode = "allow_all" + +# ──────────────────────────────────────────────────────────── +# 🚀 快捷配置(推荐新手使用) +# ──────────────────────────────────────────────────────────── + +# 🚫 禁用群列表 - 这些群无法使用任何 MCP 工具(每行一个群号) +# 示例: +# quick_deny_groups = ''' +# 123456789 +# 987654321 +# ''' +quick_deny_groups = "" + +# ✅ 管理员白名单 - 这些用户始终可以使用所有工具(每行一个QQ号) +# 示例: +# quick_allow_users = ''' +# 111111111 +# ''' +quick_allow_users = "" + +# ──────────────────────────────────────────────────────────── +# 📜 高级权限规则(可选,针对特定工具配置) +# ──────────────────────────────────────────────────────────── +# 格式: qq:ID:group/private/user,工具名支持通配符 * +# 示例: +# perm_rules = ''' +# [ +# {"tool": "mcp_*_delete_*", "denied": ["qq:123456:group"]} +# ] +# ''' +perm_rules = "[]" + +# ============================================================ +# 状态显示(只读) +# ============================================================ +[status] +connection_status = "未初始化" diff --git a/plugins/MaiBot_MCPBridgePlugin/core/__init__.py b/plugins/MaiBot_MCPBridgePlugin/core/__init__.py new file mode 100644 index 00000000..8e85539f --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/core/__init__.py @@ -0,0 +1,2 @@ +"""Core helpers for MCP Bridge Plugin.""" + diff --git a/plugins/MaiBot_MCPBridgePlugin/core/claude_config.py b/plugins/MaiBot_MCPBridgePlugin/core/claude_config.py new file mode 100644 index 00000000..6ae5ff97 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/core/claude_config.py @@ -0,0 +1,170 @@ +import json +from dataclasses import dataclass, field +from typing import Any, Dict, List, Literal, Optional + + +class ClaudeConfigError(ValueError): + pass + + +Transport = Literal["stdio", "sse", "http", "streamable_http"] + + +@dataclass(frozen=True) +class ClaudeMcpServer: + name: str + transport: Transport + command: str = "" + args: List[str] = field(default_factory=list) + env: Dict[str, str] = field(default_factory=dict) + url: str = "" + headers: Dict[str, str] = field(default_factory=dict) + enabled: bool = True + + +def _normalize_transport(value: Optional[str]) -> Transport: + if not value: + return "streamable_http" + v = value.strip().lower().replace("-", "_") + if v in ("streamable_http", "streamablehttp", "streamable"): + return "streamable_http" + if v in ("http",): + return "http" + if v in ("sse",): + return "sse" + if v in ("stdio",): + return "stdio" + raise ClaudeConfigError(f"unsupported transport: {value}") + + +def _coerce_str_list(value: Any, field_name: str) -> List[str]: + if value is None: + return [] + if isinstance(value, list): + return [str(v) for v in value] + raise ClaudeConfigError(f"{field_name} must be a list") + + +def _coerce_str_dict(value: Any, field_name: str) -> Dict[str, str]: + if value is None: + return {} + if isinstance(value, dict): + return {str(k): str(v) for k, v in value.items()} + raise ClaudeConfigError(f"{field_name} must be an object") + + +def parse_claude_mcp_config(config_json: str) -> List[ClaudeMcpServer]: + """Parse Claude Desktop style MCP config JSON. + + Supported: + - Full object: {"mcpServers": {...}} + - Direct mapping: {...} treated as mcpServers + """ + text = (config_json or "").strip() + if not text: + return [] + + try: + data = json.loads(text) + except json.JSONDecodeError as e: + raise ClaudeConfigError(f"invalid JSON: {e}") from e + + if not isinstance(data, dict): + raise ClaudeConfigError("config must be a JSON object") + + servers_obj = data.get("mcpServers", data) + if not isinstance(servers_obj, dict): + raise ClaudeConfigError("mcpServers must be an object") + + servers: List[ClaudeMcpServer] = [] + for name, raw in servers_obj.items(): + if not isinstance(name, str) or not name.strip(): + raise ClaudeConfigError("server name must be a non-empty string") + if not isinstance(raw, dict): + raise ClaudeConfigError(f"server '{name}' must be an object") + + enabled = bool(raw.get("enabled", True)) + command = str(raw.get("command", "") or "") + url = str(raw.get("url", "") or "") + args = _coerce_str_list(raw.get("args"), "args") + env = _coerce_str_dict(raw.get("env"), "env") + headers = _coerce_str_dict(raw.get("headers"), "headers") + + transport_hint = raw.get("transport", raw.get("type")) + + if command: + transport: Transport = "stdio" + elif url: + try: + transport = _normalize_transport(str(transport_hint) if transport_hint is not None else None) + except ClaudeConfigError: + transport = "streamable_http" + else: + raise ClaudeConfigError(f"server '{name}' must have either 'command' or 'url'") + + servers.append( + ClaudeMcpServer( + name=name, + transport=transport, + command=command, + args=args, + env=env, + url=url, + headers=headers, + enabled=enabled, + ) + ) + + return servers + + +def legacy_servers_list_to_claude_config(servers_list_json: str) -> str: + """Convert legacy v1.x servers list (JSON array) to Claude mcpServers JSON. + + Legacy item schema: + {"name","enabled","transport","url","headers","command","args","env"} + """ + text = (servers_list_json or "").strip() + if not text: + return "" + try: + data = json.loads(text) + except json.JSONDecodeError: + return "" + if isinstance(data, dict): + data = [data] + if not isinstance(data, list): + return "" + + mcp_servers: Dict[str, Any] = {} + for item in data: + if not isinstance(item, dict): + continue + name = str(item.get("name", "") or "").strip() + if not name: + continue + enabled = bool(item.get("enabled", True)) + transport = str(item.get("transport", "") or "").strip().lower().replace("-", "_") + + if transport == "stdio" or item.get("command"): + entry: Dict[str, Any] = { + "enabled": enabled, + "command": item.get("command", "") or "", + "args": item.get("args", []) or [], + } + if item.get("env"): + entry["env"] = item.get("env") + mcp_servers[name] = entry + continue + + entry = {"enabled": enabled, "url": item.get("url", "") or ""} + if item.get("headers"): + entry["headers"] = item.get("headers") + if transport: + entry["transport"] = transport + mcp_servers[name] = entry + + if not mcp_servers: + return "" + return json.dumps({"mcpServers": mcp_servers}, ensure_ascii=False, indent=2) + diff --git a/plugins/MaiBot_MCPBridgePlugin/mcp_client.py b/plugins/MaiBot_MCPBridgePlugin/mcp_client.py new file mode 100644 index 00000000..0d4eebff --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/mcp_client.py @@ -0,0 +1,1542 @@ +""" +MCP 客户端封装模块 +负责与 MCP 服务器建立连接、获取工具列表、执行工具调用 + +v1.7.0 稳定性优化: +- 断路器模式:连续失败 5 次后熔断,60 秒后试探恢复 +- 熔断期间快速失败,避免等待超时 +- 连接成功时自动重置断路器 + +v1.5.2 性能优化: +- 智能心跳间隔:根据服务器稳定性动态调整心跳频率 +- 稳定服务器逐渐增加间隔(最高 3x),减少不必要的检测 +- 断开的服务器使用较短间隔快速重连 + +v1.1.0 新增功能: +- 调用统计(次数、成功率、耗时) +- 心跳检测 +- 自动重连 +- 更好的错误处理 + +v1.2.0 新增功能: +- Resources 支持(资源读取) +- Prompts 支持(提示模板) +- 新增配置项: enable_resources, enable_prompts +""" + +import asyncio +import time +import logging +from typing import Any, Dict, List, Optional, Tuple +from dataclasses import dataclass, field +from enum import Enum + +# 尝试导入 MaiBot 的 logger,如果失败则使用标准 logging +try: + from src.common.logger import get_logger + logger = get_logger("mcp_client") +except ImportError: + # Fallback: 使用标准 logging + logger = logging.getLogger("mcp_client") + if not logger.handlers: + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter('[%(levelname)s] %(name)s: %(message)s')) + logger.addHandler(handler) + logger.setLevel(logging.INFO) + + +class TransportType(Enum): + """MCP 传输类型""" + STDIO = "stdio" # 本地进程通信 + SSE = "sse" # Server-Sent Events (旧版 HTTP) + HTTP = "http" # HTTP Streamable (新版,推荐) + STREAMABLE_HTTP = "streamable_http" # HTTP Streamable 的别名 + + +@dataclass +class MCPToolInfo: + """MCP 工具信息""" + name: str + description: str + input_schema: Dict[str, Any] + server_name: str + + +@dataclass +class MCPResourceInfo: + """MCP 资源信息""" + uri: str + name: str + description: str + mime_type: Optional[str] + server_name: str + + +@dataclass +class MCPPromptInfo: + """MCP 提示模板信息""" + name: str + description: str + arguments: List[Dict[str, Any]] # [{name, description, required}] + server_name: str + + +@dataclass +class MCPServerConfig: + """MCP 服务器配置""" + name: str + enabled: bool = True + transport: TransportType = TransportType.STDIO + # stdio 配置 + command: str = "" + args: List[str] = field(default_factory=list) + env: Dict[str, str] = field(default_factory=dict) + # http/sse 配置 + url: str = "" + headers: Dict[str, str] = field(default_factory=dict) # v1.4.2: 鉴权头支持 + + +@dataclass +class MCPCallResult: + """MCP 工具调用结果""" + success: bool + content: Any + error: Optional[str] = None + duration_ms: float = 0.0 # 调用耗时(毫秒) + circuit_broken: bool = False # v1.7.0: 是否被断路器拦截 + + +class CircuitState(Enum): + """断路器状态""" + CLOSED = "closed" # 正常状态,允许请求 + OPEN = "open" # 熔断状态,拒绝请求 + HALF_OPEN = "half_open" # 半开状态,允许少量试探请求 + + +@dataclass +class CircuitBreaker: + """v1.7.0: 断路器 - 防止对故障服务器持续请求 + + 状态转换: + - CLOSED -> OPEN: 连续失败次数达到阈值 + - OPEN -> HALF_OPEN: 熔断时间到期 + - HALF_OPEN -> CLOSED: 试探请求成功 + - HALF_OPEN -> OPEN: 试探请求失败 + """ + + # 配置 + failure_threshold: int = 5 # 连续失败多少次后熔断 + recovery_timeout: float = 60.0 # 熔断后多久尝试恢复(秒) + half_open_max_calls: int = 1 # 半开状态最多允许几次试探调用 + + # 状态 + state: CircuitState = field(default=CircuitState.CLOSED) + failure_count: int = 0 + success_count: int = 0 + last_failure_time: float = 0.0 + last_state_change: float = field(default_factory=time.time) + half_open_calls: int = 0 + + def can_execute(self) -> Tuple[bool, Optional[str]]: + """检查是否允许执行请求 + + Returns: + (是否允许, 拒绝原因) + """ + current_time = time.time() + + if self.state == CircuitState.CLOSED: + return True, None + + if self.state == CircuitState.OPEN: + # 检查是否到了恢复时间 + time_since_failure = current_time - self.last_failure_time + if time_since_failure >= self.recovery_timeout: + # 转换到半开状态 + self._transition_to(CircuitState.HALF_OPEN) + return True, None + else: + remaining = self.recovery_timeout - time_since_failure + return False, f"断路器熔断中,{remaining:.0f}秒后重试" + + if self.state == CircuitState.HALF_OPEN: + # 半开状态,检查是否还有试探配额 + if self.half_open_calls < self.half_open_max_calls: + return True, None + else: + return False, "断路器半开状态,等待试探结果" + + return True, None + + def record_success(self) -> None: + """记录成功调用""" + self.success_count += 1 + + if self.state == CircuitState.HALF_OPEN: + # 半开状态下成功,恢复到关闭状态 + self._transition_to(CircuitState.CLOSED) + logger.info("断路器恢复正常(试探成功)") + elif self.state == CircuitState.CLOSED: + # 正常状态下成功,重置失败计数 + self.failure_count = 0 + + def record_failure(self) -> None: + """记录失败调用""" + self.failure_count += 1 + self.last_failure_time = time.time() + + if self.state == CircuitState.HALF_OPEN: + # 半开状态下失败,重新熔断 + self._transition_to(CircuitState.OPEN) + logger.warning("断路器重新熔断(试探失败)") + elif self.state == CircuitState.CLOSED: + # 检查是否达到熔断阈值 + if self.failure_count >= self.failure_threshold: + self._transition_to(CircuitState.OPEN) + logger.warning(f"断路器熔断(连续失败 {self.failure_count} 次)") + + def _transition_to(self, new_state: CircuitState) -> None: + """状态转换""" + old_state = self.state + self.state = new_state + self.last_state_change = time.time() + + if new_state == CircuitState.CLOSED: + self.failure_count = 0 + self.half_open_calls = 0 + elif new_state == CircuitState.HALF_OPEN: + self.half_open_calls = 0 + + logger.debug(f"断路器状态: {old_state.value} -> {new_state.value}") + + def reset(self) -> None: + """重置断路器""" + self.state = CircuitState.CLOSED + self.failure_count = 0 + self.success_count = 0 + self.half_open_calls = 0 + self.last_state_change = time.time() + + def get_status(self) -> Dict[str, Any]: + """获取断路器状态""" + return { + "state": self.state.value, + "failure_count": self.failure_count, + "success_count": self.success_count, + "failure_threshold": self.failure_threshold, + "recovery_timeout": self.recovery_timeout, + "time_since_last_failure": time.time() - self.last_failure_time if self.last_failure_time > 0 else None, + } + + +@dataclass +class ToolCallStats: + """工具调用统计""" + tool_key: str + total_calls: int = 0 + success_calls: int = 0 + failed_calls: int = 0 + total_duration_ms: float = 0.0 + last_call_time: Optional[float] = None + last_error: Optional[str] = None + + @property + def success_rate(self) -> float: + """成功率(0-100)""" + if self.total_calls == 0: + return 0.0 + return (self.success_calls / self.total_calls) * 100 + + @property + def avg_duration_ms(self) -> float: + """平均耗时(毫秒)""" + if self.success_calls == 0: + return 0.0 + return self.total_duration_ms / self.success_calls + + def record_call(self, success: bool, duration_ms: float, error: Optional[str] = None) -> None: + """记录一次调用""" + self.total_calls += 1 + self.last_call_time = time.time() + if success: + self.success_calls += 1 + self.total_duration_ms += duration_ms + else: + self.failed_calls += 1 + self.last_error = error + + def to_dict(self) -> Dict[str, Any]: + """转换为字典""" + return { + "tool_key": self.tool_key, + "total_calls": self.total_calls, + "success_calls": self.success_calls, + "failed_calls": self.failed_calls, + "success_rate": round(self.success_rate, 2), + "avg_duration_ms": round(self.avg_duration_ms, 2), + "last_call_time": self.last_call_time, + "last_error": self.last_error, + } + + +@dataclass +class ServerStats: + """服务器统计""" + server_name: str + connect_count: int = 0 # 连接次数 + disconnect_count: int = 0 # 断开次数 + reconnect_count: int = 0 # 重连次数 + last_connect_time: Optional[float] = None + last_disconnect_time: Optional[float] = None + last_heartbeat_time: Optional[float] = None + consecutive_failures: int = 0 # 连续失败次数 + + def record_connect(self) -> None: + self.connect_count += 1 + self.last_connect_time = time.time() + self.consecutive_failures = 0 + + def record_disconnect(self) -> None: + self.disconnect_count += 1 + self.last_disconnect_time = time.time() + + def record_reconnect(self) -> None: + self.reconnect_count += 1 + self.consecutive_failures = 0 + + def record_failure(self) -> None: + self.consecutive_failures += 1 + + def record_heartbeat(self) -> None: + self.last_heartbeat_time = time.time() + + def to_dict(self) -> Dict[str, Any]: + return { + "server_name": self.server_name, + "connect_count": self.connect_count, + "disconnect_count": self.disconnect_count, + "reconnect_count": self.reconnect_count, + "last_connect_time": self.last_connect_time, + "last_disconnect_time": self.last_disconnect_time, + "last_heartbeat_time": self.last_heartbeat_time, + "consecutive_failures": self.consecutive_failures, + } + + +class MCPClientSession: + """MCP 客户端会话,管理与单个 MCP 服务器的连接""" + + def __init__(self, config: MCPServerConfig, call_timeout: float = 60.0): + self.config = config + self.call_timeout = call_timeout + self._session = None + self._read_stream = None + self._write_stream = None + self._process: Optional[asyncio.subprocess.Process] = None + self._tools: List[MCPToolInfo] = [] + self._resources: List[MCPResourceInfo] = [] # v1.2.0: Resources 支持 + self._prompts: List[MCPPromptInfo] = [] # v1.2.0: Prompts 支持 + self._connected = False + self._lock = asyncio.Lock() + + # 功能支持标记(服务器可能不支持某些功能) + self._supports_resources: bool = False + self._supports_prompts: bool = False + + # 统计信息 + self.stats = ServerStats(server_name=config.name) + self._tool_stats: Dict[str, ToolCallStats] = {} + + # v1.7.0: 断路器 + self._circuit_breaker = CircuitBreaker() + + @property + def is_connected(self) -> bool: + return self._connected + + @property + def tools(self) -> List[MCPToolInfo]: + return self._tools.copy() + + @property + def resources(self) -> List[MCPResourceInfo]: + """v1.2.0: 获取资源列表""" + return self._resources.copy() + + @property + def prompts(self) -> List[MCPPromptInfo]: + """v1.2.0: 获取提示模板列表""" + return self._prompts.copy() + + @property + def supports_resources(self) -> bool: + """v1.2.0: 服务器是否支持 Resources""" + return self._supports_resources + + @property + def supports_prompts(self) -> bool: + """v1.2.0: 服务器是否支持 Prompts""" + return self._supports_prompts + + @property + def server_name(self) -> str: + return self.config.name + + def get_tool_stats(self, tool_name: str) -> Optional[ToolCallStats]: + """获取工具统计""" + return self._tool_stats.get(tool_name) + + def get_circuit_breaker_status(self) -> Dict[str, Any]: + """v1.7.0: 获取断路器状态""" + return self._circuit_breaker.get_status() + + def reset_circuit_breaker(self) -> None: + """v1.7.0: 重置断路器""" + self._circuit_breaker.reset() + logger.info(f"[{self.server_name}] 断路器已重置") + + def get_all_tool_stats(self) -> Dict[str, ToolCallStats]: + """获取所有工具统计""" + return self._tool_stats.copy() + + async def connect(self) -> bool: + """连接到 MCP 服务器""" + async with self._lock: + if self._connected: + return True + + try: + success = False + if self.config.transport == TransportType.STDIO: + success = await self._connect_stdio() + elif self.config.transport == TransportType.SSE: + success = await self._connect_sse() + elif self.config.transport in (TransportType.HTTP, TransportType.STREAMABLE_HTTP): + success = await self._connect_http() + else: + logger.error(f"[{self.server_name}] 不支持的传输类型: {self.config.transport}") + return False + + if success: + self.stats.record_connect() + # v1.7.0: 连接成功时重置断路器 + self._circuit_breaker.reset() + else: + self.stats.record_failure() + return success + + except Exception as e: + logger.error(f"[{self.server_name}] 连接失败: {e}") + self._connected = False + self.stats.record_failure() + return False + + async def _connect_stdio(self) -> bool: + """通过 stdio 连接 MCP 服务器""" + try: + try: + from mcp import ClientSession, StdioServerParameters + from mcp.client.stdio import stdio_client + except ImportError: + logger.error(f"[{self.server_name}] 未安装 mcp 库,请运行: pip install mcp") + return False + + server_params = StdioServerParameters( + command=self.config.command, + args=self.config.args, + env=self.config.env if self.config.env else None + ) + + self._stdio_context = stdio_client(server_params) + self._read_stream, self._write_stream = await self._stdio_context.__aenter__() + + self._session_context = ClientSession(self._read_stream, self._write_stream) + self._session = await self._session_context.__aenter__() + + await self._session.initialize() + await self._fetch_tools() + + self._connected = True + logger.info(f"[{self.server_name}] stdio 连接成功,发现 {len(self._tools)} 个工具") + return True + + except Exception as e: + logger.error(f"[{self.server_name}] stdio 连接失败: {e}") + await self._cleanup() + return False + + async def _connect_sse(self) -> bool: + """通过 SSE 连接 MCP 服务器""" + try: + try: + from mcp import ClientSession + from mcp.client.sse import sse_client + except ImportError: + logger.error(f"[{self.server_name}] 未安装 mcp 库,请运行: pip install mcp") + return False + + if not self.config.url: + logger.error(f"[{self.server_name}] SSE 传输需要配置 url") + return False + + logger.debug(f"[{self.server_name}] 正在连接 SSE MCP 服务器: {self.config.url}") + + # v1.4.2: 支持 headers 鉴权 + sse_kwargs = { + "url": self.config.url, + "timeout": 60.0, + "sse_read_timeout": 300.0, + } + if self.config.headers: + sse_kwargs["headers"] = self.config.headers + + self._sse_context = sse_client(**sse_kwargs) + self._read_stream, self._write_stream = await self._sse_context.__aenter__() + + self._session_context = ClientSession(self._read_stream, self._write_stream) + self._session = await self._session_context.__aenter__() + + await self._session.initialize() + await self._fetch_tools() + + self._connected = True + logger.info(f"[{self.server_name}] SSE 连接成功,发现 {len(self._tools)} 个工具") + return True + + except Exception as e: + logger.error(f"[{self.server_name}] SSE 连接失败: {e}") + import traceback + logger.debug(f"[{self.server_name}] 详细错误: {traceback.format_exc()}") + await self._cleanup() + return False + + async def _connect_http(self) -> bool: + """通过 HTTP Streamable 连接 MCP 服务器""" + try: + try: + from mcp import ClientSession + from mcp.client.streamable_http import streamablehttp_client + except ImportError: + logger.error(f"[{self.server_name}] 未安装 mcp 库,请运行: pip install mcp") + return False + + if not self.config.url: + logger.error(f"[{self.server_name}] HTTP 传输需要配置 url") + return False + + logger.debug(f"[{self.server_name}] 正在连接 HTTP MCP 服务器: {self.config.url}") + + # v1.4.2: 支持 headers 鉴权 + http_kwargs = { + "url": self.config.url, + "timeout": 60.0, + "sse_read_timeout": 300.0, + } + if self.config.headers: + http_kwargs["headers"] = self.config.headers + + self._http_context = streamablehttp_client(**http_kwargs) + self._read_stream, self._write_stream, self._get_session_id = await self._http_context.__aenter__() + + self._session_context = ClientSession(self._read_stream, self._write_stream) + self._session = await self._session_context.__aenter__() + + await self._session.initialize() + await self._fetch_tools() + + self._connected = True + logger.info(f"[{self.server_name}] HTTP 连接成功,发现 {len(self._tools)} 个工具") + return True + + except Exception as e: + logger.error(f"[{self.server_name}] HTTP 连接失败: {e}") + import traceback + logger.debug(f"[{self.server_name}] 详细错误: {traceback.format_exc()}") + await self._cleanup() + return False + + async def _fetch_tools(self) -> None: + """获取 MCP 服务器的工具列表""" + if not self._session: + return + + try: + result = await self._session.list_tools() + self._tools = [] + + for tool in result.tools: + tool_info = MCPToolInfo( + name=tool.name, + description=tool.description or f"MCP tool: {tool.name}", + input_schema=tool.inputSchema if hasattr(tool, 'inputSchema') else {}, + server_name=self.server_name + ) + self._tools.append(tool_info) + # 初始化工具统计 + if tool.name not in self._tool_stats: + self._tool_stats[tool.name] = ToolCallStats(tool_key=tool.name) + logger.debug(f"[{self.server_name}] 发现工具: {tool.name}") + + except Exception as e: + logger.error(f"[{self.server_name}] 获取工具列表失败: {e}") + self._tools = [] + + async def fetch_resources(self) -> bool: + """v1.2.0: 获取 MCP 服务器的资源列表 + + Returns: + bool: 是否成功获取(服务器不支持时返回 False) + """ + if not self._session: + return False + + try: + result = await asyncio.wait_for( + self._session.list_resources(), + timeout=self.call_timeout + ) + self._resources = [] + + for resource in result.resources: + resource_info = MCPResourceInfo( + uri=str(resource.uri), + name=resource.name or str(resource.uri), + description=resource.description or "", + mime_type=resource.mimeType if hasattr(resource, 'mimeType') else None, + server_name=self.server_name + ) + self._resources.append(resource_info) + logger.debug(f"[{self.server_name}] 发现资源: {resource_info.uri}") + + self._supports_resources = True + logger.info(f"[{self.server_name}] 获取到 {len(self._resources)} 个资源") + return True + + except Exception as e: + # 服务器可能不支持 resources,这不是错误 + error_str = str(e).lower() + if "not supported" in error_str or "not implemented" in error_str or "method not found" in error_str: + logger.debug(f"[{self.server_name}] 服务器不支持 Resources 功能") + else: + logger.warning(f"[{self.server_name}] 获取资源列表失败: {e}") + self._supports_resources = False + self._resources = [] + return False + + async def fetch_prompts(self) -> bool: + """v1.2.0: 获取 MCP 服务器的提示模板列表 + + Returns: + bool: 是否成功获取(服务器不支持时返回 False) + """ + if not self._session: + return False + + try: + result = await asyncio.wait_for( + self._session.list_prompts(), + timeout=self.call_timeout + ) + self._prompts = [] + + for prompt in result.prompts: + # 解析参数 + arguments = [] + if hasattr(prompt, 'arguments') and prompt.arguments: + for arg in prompt.arguments: + arguments.append({ + "name": arg.name, + "description": arg.description or "", + "required": arg.required if hasattr(arg, 'required') else False, + }) + + prompt_info = MCPPromptInfo( + name=prompt.name, + description=prompt.description or f"MCP prompt: {prompt.name}", + arguments=arguments, + server_name=self.server_name + ) + self._prompts.append(prompt_info) + logger.debug(f"[{self.server_name}] 发现提示模板: {prompt.name}") + + self._supports_prompts = True + logger.info(f"[{self.server_name}] 获取到 {len(self._prompts)} 个提示模板") + return True + + except Exception as e: + # 服务器可能不支持 prompts,这不是错误 + error_str = str(e).lower() + if "not supported" in error_str or "not implemented" in error_str or "method not found" in error_str: + logger.debug(f"[{self.server_name}] 服务器不支持 Prompts 功能") + else: + logger.warning(f"[{self.server_name}] 获取提示模板列表失败: {e}") + self._supports_prompts = False + self._prompts = [] + return False + + async def read_resource(self, uri: str) -> MCPCallResult: + """v1.2.0: 读取指定资源的内容 + + Args: + uri: 资源 URI + + Returns: + MCPCallResult: 包含资源内容的结果 + """ + start_time = time.time() + + if not self._connected or not self._session: + return MCPCallResult( + success=False, + content=None, + error=f"服务器 {self.server_name} 未连接" + ) + + if not self._supports_resources: + return MCPCallResult( + success=False, + content=None, + error=f"服务器 {self.server_name} 不支持 Resources 功能" + ) + + try: + result = await asyncio.wait_for( + self._session.read_resource(uri), + timeout=self.call_timeout + ) + + duration_ms = (time.time() - start_time) * 1000 + + # 处理返回内容 + content_parts = [] + for content in result.contents: + if hasattr(content, 'text'): + content_parts.append(content.text) + elif hasattr(content, 'blob'): + # 二进制数据,返回 base64 或提示 + import base64 + blob_data = content.blob + if len(blob_data) < 10000: # 小于 10KB 返回 base64 + content_parts.append(f"[base64]{base64.b64encode(blob_data).decode()}") + else: + content_parts.append(f"[二进制数据: {len(blob_data)} bytes]") + else: + content_parts.append(str(content)) + + return MCPCallResult( + success=True, + content="\n".join(content_parts) if content_parts else "", + duration_ms=duration_ms + ) + + except asyncio.TimeoutError: + duration_ms = (time.time() - start_time) * 1000 + return MCPCallResult( + success=False, + content=None, + error=f"读取资源超时({self.call_timeout}秒)", + duration_ms=duration_ms + ) + except Exception as e: + duration_ms = (time.time() - start_time) * 1000 + logger.error(f"[{self.server_name}] 读取资源 {uri} 失败: {e}") + return MCPCallResult( + success=False, + content=None, + error=str(e), + duration_ms=duration_ms + ) + + async def get_prompt(self, name: str, arguments: Optional[Dict[str, str]] = None) -> MCPCallResult: + """v1.2.0: 获取提示模板的内容 + + Args: + name: 提示模板名称 + arguments: 模板参数 + + Returns: + MCPCallResult: 包含提示内容的结果 + """ + start_time = time.time() + + if not self._connected or not self._session: + return MCPCallResult( + success=False, + content=None, + error=f"服务器 {self.server_name} 未连接" + ) + + if not self._supports_prompts: + return MCPCallResult( + success=False, + content=None, + error=f"服务器 {self.server_name} 不支持 Prompts 功能" + ) + + try: + result = await asyncio.wait_for( + self._session.get_prompt(name, arguments=arguments or {}), + timeout=self.call_timeout + ) + + duration_ms = (time.time() - start_time) * 1000 + + # 处理返回的消息 + messages = [] + for msg in result.messages: + role = msg.role if hasattr(msg, 'role') else "unknown" + content_text = "" + if hasattr(msg, 'content'): + if hasattr(msg.content, 'text'): + content_text = msg.content.text + elif isinstance(msg.content, str): + content_text = msg.content + else: + content_text = str(msg.content) + messages.append(f"[{role}]: {content_text}") + + return MCPCallResult( + success=True, + content="\n\n".join(messages) if messages else "", + duration_ms=duration_ms + ) + + except asyncio.TimeoutError: + duration_ms = (time.time() - start_time) * 1000 + return MCPCallResult( + success=False, + content=None, + error=f"获取提示模板超时({self.call_timeout}秒)", + duration_ms=duration_ms + ) + except Exception as e: + duration_ms = (time.time() - start_time) * 1000 + logger.error(f"[{self.server_name}] 获取提示模板 {name} 失败: {e}") + return MCPCallResult( + success=False, + content=None, + error=str(e), + duration_ms=duration_ms + ) + + async def check_health(self) -> bool: + """检查连接健康状态(心跳检测) + + 通过调用 list_tools 来验证连接是否正常 + """ + if not self._connected or not self._session: + return False + + try: + # 使用 list_tools 作为心跳检测 + await asyncio.wait_for( + self._session.list_tools(), + timeout=10.0 + ) + self.stats.record_heartbeat() + return True + except Exception as e: + logger.warning(f"[{self.server_name}] 心跳检测失败: {e}") + # 标记为断开 + self._connected = False + self.stats.record_disconnect() + return False + + async def call_tool(self, tool_name: str, arguments: Dict[str, Any]) -> MCPCallResult: + """调用 MCP 工具""" + start_time = time.time() + + # v1.7.0: 断路器检查 + can_execute, reject_reason = self._circuit_breaker.can_execute() + if not can_execute: + return MCPCallResult( + success=False, + content=None, + error=f"⚡ {reject_reason}", + circuit_broken=True + ) + + # 半开状态下增加试探计数 + if self._circuit_breaker.state == CircuitState.HALF_OPEN: + self._circuit_breaker.half_open_calls += 1 + + if not self._connected or not self._session: + error_msg = f"服务器 {self.server_name} 未连接" + # 记录失败 + if tool_name in self._tool_stats: + self._tool_stats[tool_name].record_call(False, 0, error_msg) + self._circuit_breaker.record_failure() + return MCPCallResult(success=False, content=None, error=error_msg) + + try: + result = await asyncio.wait_for( + self._session.call_tool(tool_name, arguments=arguments), + timeout=self.call_timeout + ) + + duration_ms = (time.time() - start_time) * 1000 + + # 处理返回内容 + content_parts = [] + for content in result.content: + if hasattr(content, 'text'): + content_parts.append(content.text) + elif hasattr(content, 'data'): + content_parts.append(f"[二进制数据: {len(content.data)} bytes]") + else: + content_parts.append(str(content)) + + # 记录成功 + if tool_name in self._tool_stats: + self._tool_stats[tool_name].record_call(True, duration_ms) + + # v1.7.0: 断路器记录成功 + self._circuit_breaker.record_success() + + return MCPCallResult( + success=True, + content="\n".join(content_parts) if content_parts else "执行成功(无返回内容)", + duration_ms=duration_ms + ) + + except asyncio.TimeoutError: + duration_ms = (time.time() - start_time) * 1000 + error_msg = f"工具调用超时({self.call_timeout}秒)" + if tool_name in self._tool_stats: + self._tool_stats[tool_name].record_call(False, duration_ms, error_msg) + # v1.7.0: 断路器记录失败 + self._circuit_breaker.record_failure() + return MCPCallResult(success=False, content=None, error=error_msg, duration_ms=duration_ms) + + except Exception as e: + duration_ms = (time.time() - start_time) * 1000 + error_msg = str(e) + logger.error(f"[{self.server_name}] 调用工具 {tool_name} 失败: {e}") + if tool_name in self._tool_stats: + self._tool_stats[tool_name].record_call(False, duration_ms, error_msg) + # v1.7.0: 断路器记录失败 + self._circuit_breaker.record_failure() + # 检查是否是连接问题 + if "connection" in error_msg.lower() or "closed" in error_msg.lower(): + self._connected = False + self.stats.record_disconnect() + return MCPCallResult(success=False, content=None, error=error_msg, duration_ms=duration_ms) + + async def disconnect(self) -> None: + """断开连接""" + async with self._lock: + if self._connected: + self.stats.record_disconnect() + await self._cleanup() + + async def _cleanup(self) -> None: + """清理资源""" + self._connected = False + self._tools = [] + self._resources = [] # v1.2.0 + self._prompts = [] # v1.2.0 + self._supports_resources = False # v1.2.0 + self._supports_prompts = False # v1.2.0 + + try: + if hasattr(self, '_session_context') and self._session_context: + await self._session_context.__aexit__(None, None, None) + except Exception as e: + logger.debug(f"[{self.server_name}] 关闭会话时出错: {e}") + + try: + if hasattr(self, '_stdio_context') and self._stdio_context: + await self._stdio_context.__aexit__(None, None, None) + except Exception as e: + logger.debug(f"[{self.server_name}] 关闭 stdio 连接时出错: {e}") + + try: + if hasattr(self, '_http_context') and self._http_context: + await self._http_context.__aexit__(None, None, None) + except Exception as e: + logger.debug(f"[{self.server_name}] 关闭 HTTP 连接时出错: {e}") + + try: + if hasattr(self, '_sse_context') and self._sse_context: + await self._sse_context.__aexit__(None, None, None) + except Exception as e: + logger.debug(f"[{self.server_name}] 关闭 SSE 连接时出错: {e}") + + self._session = None + self._session_context = None + self._stdio_context = None + self._http_context = None + self._sse_context = None + self._read_stream = None + self._write_stream = None + + logger.debug(f"[{self.server_name}] 连接已关闭") + + +class MCPClientManager: + """MCP 客户端管理器,管理多个 MCP 服务器连接 + + 功能: + - 管理多个 MCP 服务器连接 + - 心跳检测和自动重连 + - 调用统计 + """ + + _instance: Optional["MCPClientManager"] = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super().__new__(cls) + cls._instance._initialized = False + return cls._instance + + def __init__(self): + if self._initialized: + return + self._initialized = True + self._clients: Dict[str, MCPClientSession] = {} + self._all_tools: Dict[str, Tuple[MCPToolInfo, MCPClientSession]] = {} + self._all_resources: Dict[str, Tuple[MCPResourceInfo, MCPClientSession]] = {} # v1.2.0 + self._all_prompts: Dict[str, Tuple[MCPPromptInfo, MCPClientSession]] = {} # v1.2.0 + self._settings: Dict[str, Any] = {} + self._lock = asyncio.Lock() + + # 心跳检测任务 + self._heartbeat_task: Optional[asyncio.Task] = None + self._heartbeat_running = False + + # 状态变化回调 + self._on_status_change: Optional[callable] = None + + # 全局统计 + self._global_stats = { + "total_tool_calls": 0, + "successful_calls": 0, + "failed_calls": 0, + "start_time": time.time(), + } + + def configure(self, settings: Dict[str, Any]) -> None: + """配置管理器""" + self._settings = settings + + def set_status_change_callback(self, callback: callable) -> None: + """设置状态变化回调函数""" + self._on_status_change = callback + + def _notify_status_change(self) -> None: + """通知状态变化""" + if self._on_status_change: + try: + self._on_status_change() + except Exception as e: + logger.debug(f"状态变化回调出错: {e}") + + @property + def all_tools(self) -> Dict[str, Tuple[MCPToolInfo, MCPClientSession]]: + """获取所有已注册的工具""" + return self._all_tools.copy() + + @property + def all_resources(self) -> Dict[str, Tuple[MCPResourceInfo, MCPClientSession]]: + """v1.2.0: 获取所有已注册的资源""" + return self._all_resources.copy() + + @property + def all_prompts(self) -> Dict[str, Tuple[MCPPromptInfo, MCPClientSession]]: + """v1.2.0: 获取所有已注册的提示模板""" + return self._all_prompts.copy() + + @property + def connected_servers(self) -> List[str]: + """获取已连接的服务器列表""" + return [name for name, client in self._clients.items() if client.is_connected] + + @property + def disconnected_servers(self) -> List[str]: + """获取已断开的服务器列表""" + return [name for name, client in self._clients.items() if not client.is_connected and client.config.enabled] + + async def add_server(self, config: MCPServerConfig) -> bool: + """添加并连接 MCP 服务器""" + async with self._lock: + if config.name in self._clients: + logger.warning(f"服务器 {config.name} 已存在") + return False + + call_timeout = self._settings.get("call_timeout", 60.0) + client = MCPClientSession(config, call_timeout) + self._clients[config.name] = client + + if not config.enabled: + logger.info(f"服务器 {config.name} 已添加但未启用") + return True + + # 尝试连接 + retry_attempts = self._settings.get("retry_attempts", 3) + retry_interval = self._settings.get("retry_interval", 5.0) + + for attempt in range(1, retry_attempts + 1): + if await client.connect(): + self._register_tools(client) + return True + + if attempt < retry_attempts: + logger.warning(f"服务器 {config.name} 连接失败,{retry_interval}秒后重试 ({attempt}/{retry_attempts})") + await asyncio.sleep(retry_interval) + + logger.error(f"服务器 {config.name} 连接失败,已达最大重试次数 ({retry_attempts})") + # 连接失败,但保留在 _clients 中以便后续重连 + return False + + def _register_tools(self, client: MCPClientSession) -> None: + """注册客户端的工具""" + tool_prefix = self._settings.get("tool_prefix", "mcp") + + for tool in client.tools: + if tool.name.startswith(f"{tool_prefix}_{client.server_name}_"): + tool_key = tool.name + else: + tool_key = f"{tool_prefix}_{client.server_name}_{tool.name}" + self._all_tools[tool_key] = (tool, client) + logger.debug(f"注册 MCP 工具: {tool_key}") + + def _unregister_tools(self, server_name: str) -> List[str]: + """注销服务器的工具,返回被注销的工具键列表""" + tool_prefix = self._settings.get("tool_prefix", "mcp") + prefix = f"{tool_prefix}_{server_name}_" + + keys_to_remove = [k for k in self._all_tools.keys() if k.startswith(prefix)] + for key in keys_to_remove: + del self._all_tools[key] + logger.debug(f"注销 MCP 工具: {key}") + return keys_to_remove + + def _register_resources(self, client: MCPClientSession) -> None: + """v1.2.0: 注册客户端的资源""" + tool_prefix = self._settings.get("tool_prefix", "mcp") + + for resource in client.resources: + # 资源键格式: mcp_{server}_{uri_safe_name} + # 将 URI 转换为安全的键名 + safe_uri = resource.uri.replace("://", "_").replace("/", "_").replace(".", "_") + resource_key = f"{tool_prefix}_{client.server_name}_res_{safe_uri}" + self._all_resources[resource_key] = (resource, client) + logger.debug(f"注册 MCP 资源: {resource_key}") + + def _unregister_resources(self, server_name: str) -> List[str]: + """v1.2.0: 注销服务器的资源""" + tool_prefix = self._settings.get("tool_prefix", "mcp") + prefix = f"{tool_prefix}_{server_name}_res_" + + keys_to_remove = [k for k in self._all_resources.keys() if k.startswith(prefix)] + for key in keys_to_remove: + del self._all_resources[key] + logger.debug(f"注销 MCP 资源: {key}") + return keys_to_remove + + def _register_prompts(self, client: MCPClientSession) -> None: + """v1.2.0: 注册客户端的提示模板""" + tool_prefix = self._settings.get("tool_prefix", "mcp") + + for prompt in client.prompts: + prompt_key = f"{tool_prefix}_{client.server_name}_prompt_{prompt.name}" + self._all_prompts[prompt_key] = (prompt, client) + logger.debug(f"注册 MCP 提示模板: {prompt_key}") + + def _unregister_prompts(self, server_name: str) -> List[str]: + """v1.2.0: 注销服务器的提示模板""" + tool_prefix = self._settings.get("tool_prefix", "mcp") + prefix = f"{tool_prefix}_{server_name}_prompt_" + + keys_to_remove = [k for k in self._all_prompts.keys() if k.startswith(prefix)] + for key in keys_to_remove: + del self._all_prompts[key] + logger.debug(f"注销 MCP 提示模板: {key}") + return keys_to_remove + + async def remove_server(self, server_name: str) -> bool: + """移除 MCP 服务器""" + async with self._lock: + if server_name not in self._clients: + return False + + client = self._clients[server_name] + await client.disconnect() + self._unregister_tools(server_name) + self._unregister_resources(server_name) # v1.2.0 + self._unregister_prompts(server_name) # v1.2.0 + del self._clients[server_name] + + logger.info(f"服务器 {server_name} 已移除") + return True + + async def reconnect_server(self, server_name: str) -> bool: + """重新连接服务器""" + if server_name not in self._clients: + return False + + client = self._clients[server_name] + + async with self._lock: + self._unregister_tools(server_name) + self._unregister_resources(server_name) # v1.2.0 + self._unregister_prompts(server_name) # v1.2.0 + await client.disconnect() + + # 尝试重连 + retry_attempts = self._settings.get("retry_attempts", 3) + retry_interval = self._settings.get("retry_interval", 5.0) + + for attempt in range(1, retry_attempts + 1): + if await client.connect(): + async with self._lock: + self._register_tools(client) + # v1.2.0: 重连后也尝试获取 resources 和 prompts + if self._settings.get("enable_resources", False): + await client.fetch_resources() + self._register_resources(client) + if self._settings.get("enable_prompts", False): + await client.fetch_prompts() + self._register_prompts(client) + client.stats.record_reconnect() + logger.info(f"服务器 {server_name} 重连成功") + return True + + if attempt < retry_attempts: + logger.warning(f"服务器 {server_name} 重连失败,{retry_interval}秒后重试 ({attempt}/{retry_attempts})") + await asyncio.sleep(retry_interval) + + logger.error(f"服务器 {server_name} 重连失败") + return False + + async def call_tool(self, tool_key: str, arguments: Dict[str, Any]) -> MCPCallResult: + """调用 MCP 工具""" + if tool_key not in self._all_tools: + return MCPCallResult( + success=False, + content=None, + error=f"工具 {tool_key} 不存在" + ) + + tool_info, client = self._all_tools[tool_key] + + # 更新全局统计 + self._global_stats["total_tool_calls"] += 1 + + result = await client.call_tool(tool_info.name, arguments) + + if result.success: + self._global_stats["successful_calls"] += 1 + else: + self._global_stats["failed_calls"] += 1 + + return result + + async def fetch_resources_for_server(self, server_name: str) -> bool: + """v1.2.0: 获取指定服务器的资源列表""" + if server_name not in self._clients: + return False + + client = self._clients[server_name] + if not client.is_connected: + return False + + success = await client.fetch_resources() + if success: + async with self._lock: + self._register_resources(client) + return success + + async def fetch_prompts_for_server(self, server_name: str) -> bool: + """v1.2.0: 获取指定服务器的提示模板列表""" + if server_name not in self._clients: + return False + + client = self._clients[server_name] + if not client.is_connected: + return False + + success = await client.fetch_prompts() + if success: + async with self._lock: + self._register_prompts(client) + return success + + async def read_resource(self, uri: str, server_name: Optional[str] = None) -> MCPCallResult: + """v1.2.0: 读取资源内容 + + Args: + uri: 资源 URI + server_name: 指定服务器名称(可选,不指定则自动查找) + """ + # 如果指定了服务器 + if server_name: + if server_name not in self._clients: + return MCPCallResult( + success=False, + content=None, + error=f"服务器 {server_name} 不存在" + ) + client = self._clients[server_name] + return await client.read_resource(uri) + + # 自动查找拥有该资源的服务器 + for resource_key, (resource_info, client) in self._all_resources.items(): + if resource_info.uri == uri: + return await client.read_resource(uri) + + # 尝试在所有支持 resources 的服务器上查找 + for client in self._clients.values(): + if client.is_connected and client.supports_resources: + result = await client.read_resource(uri) + if result.success: + return result + + return MCPCallResult( + success=False, + content=None, + error=f"未找到资源: {uri}" + ) + + async def get_prompt(self, name: str, arguments: Optional[Dict[str, str]] = None, + server_name: Optional[str] = None) -> MCPCallResult: + """v1.2.0: 获取提示模板内容 + + Args: + name: 提示模板名称 + arguments: 模板参数 + server_name: 指定服务器名称(可选) + """ + # 如果指定了服务器 + if server_name: + if server_name not in self._clients: + return MCPCallResult( + success=False, + content=None, + error=f"服务器 {server_name} 不存在" + ) + client = self._clients[server_name] + return await client.get_prompt(name, arguments) + + # 自动查找拥有该提示模板的服务器 + for prompt_key, (prompt_info, client) in self._all_prompts.items(): + if prompt_info.name == name: + return await client.get_prompt(name, arguments) + + return MCPCallResult( + success=False, + content=None, + error=f"未找到提示模板: {name}" + ) + + # ==================== 心跳检测 ==================== + + async def start_heartbeat(self) -> None: + """启动心跳检测任务""" + if self._heartbeat_running: + logger.warning("心跳检测任务已在运行") + return + + heartbeat_enabled = self._settings.get("heartbeat_enabled", True) + if not heartbeat_enabled: + logger.info("心跳检测已禁用") + return + + self._heartbeat_running = True + self._heartbeat_task = asyncio.create_task(self._heartbeat_loop()) + logger.info("心跳检测任务已启动") + + async def stop_heartbeat(self) -> None: + """停止心跳检测任务""" + self._heartbeat_running = False + if self._heartbeat_task: + self._heartbeat_task.cancel() + try: + await self._heartbeat_task + except asyncio.CancelledError: + pass + self._heartbeat_task = None + logger.info("心跳检测任务已停止") + + async def _heartbeat_loop(self) -> None: + """心跳检测循环(v1.5.2: 智能心跳间隔)""" + base_interval = self._settings.get("heartbeat_interval", 60.0) + auto_reconnect = self._settings.get("auto_reconnect", True) + max_reconnect_attempts = self._settings.get("max_reconnect_attempts", 3) + + # v1.5.2: 智能心跳配置 + adaptive_enabled = self._settings.get("heartbeat_adaptive", True) + max_multiplier = self._settings.get("heartbeat_max_multiplier", 3.0) + + # 每个服务器独立的心跳间隔(根据稳定性动态调整) + server_intervals: Dict[str, float] = {} + min_interval = max(base_interval * 0.5, 30.0) # 最小间隔 + max_interval = base_interval * max_multiplier # 最大间隔 + + mode_str = "智能" if adaptive_enabled else "固定" + logger.info(f"心跳检测循环启动,{mode_str}模式,基准间隔: {base_interval}秒") + + while self._heartbeat_running: + try: + # 使用最小的服务器间隔作为循环间隔 + current_interval = min(server_intervals.values()) if server_intervals else base_interval + current_interval = max(current_interval, min_interval) + + await asyncio.sleep(current_interval) + + if not self._heartbeat_running: + break + + current_time = time.time() + + # 检查所有已启用的服务器 + for server_name, client in list(self._clients.items()): + if not client.config.enabled: + continue + + # 初始化服务器间隔 + if server_name not in server_intervals: + server_intervals[server_name] = base_interval + + # 检查是否到达该服务器的心跳时间 + last_heartbeat = client.stats.last_heartbeat_time or 0 + if current_time - last_heartbeat < server_intervals[server_name] * 0.9: + continue # 还没到心跳时间 + + if client.is_connected: + # 检查健康状态 + healthy = await client.check_health() + if healthy: + # v1.5.2: 智能心跳 - 稳定服务器逐渐增加间隔 + if adaptive_enabled and client.stats.consecutive_failures == 0: + new_interval = min(server_intervals[server_name] * 1.2, max_interval) + if new_interval != server_intervals[server_name]: + server_intervals[server_name] = new_interval + logger.debug(f"[{server_name}] 稳定,心跳间隔调整为 {new_interval:.0f}s") + else: + logger.warning(f"[{server_name}] 心跳检测失败,连接可能已断开") + # 失败后重置为基准间隔 + if adaptive_enabled: + server_intervals[server_name] = base_interval + self._notify_status_change() + if auto_reconnect: + await self._try_reconnect(server_name, max_reconnect_attempts) + else: + # 服务器未连接,尝试重连 + if adaptive_enabled: + # 智能心跳:断开的服务器使用较短间隔 + server_intervals[server_name] = min_interval + if auto_reconnect and client.stats.consecutive_failures < max_reconnect_attempts: + logger.info(f"[{server_name}] 检测到断开,尝试重连...") + await self._try_reconnect(server_name, max_reconnect_attempts) + elif client.stats.consecutive_failures >= max_reconnect_attempts: + if adaptive_enabled: + # 达到最大重连次数,降低检测频率 + server_intervals[server_name] = max_interval + logger.debug(f"[{server_name}] 已达最大重连次数,降低检测频率") + + except asyncio.CancelledError: + break + except Exception as e: + logger.error(f"心跳检测循环出错: {e}") + await asyncio.sleep(5) + + async def _try_reconnect(self, server_name: str, max_attempts: int) -> bool: + """尝试重连服务器""" + client = self._clients.get(server_name) + if not client: + return False + + if client.stats.consecutive_failures >= max_attempts: + logger.warning(f"[{server_name}] 连续失败次数已达上限 ({max_attempts}),暂停重连") + return False + + logger.info(f"[{server_name}] 尝试重连 (失败次数: {client.stats.consecutive_failures}/{max_attempts})") + + success = await self.reconnect_server(server_name) + if not success: + client.stats.record_failure() + + self._notify_status_change() # 重连后更新状态 + return success + + # ==================== 统计和状态 ==================== + + def get_tool_stats(self, tool_key: str) -> Optional[Dict[str, Any]]: + """获取指定工具的统计信息""" + if tool_key not in self._all_tools: + return None + + tool_info, client = self._all_tools[tool_key] + stats = client.get_tool_stats(tool_info.name) + return stats.to_dict() if stats else None + + def get_all_stats(self) -> Dict[str, Any]: + """获取所有统计信息""" + server_stats = {} + tool_stats = {} + + for server_name, client in self._clients.items(): + server_stats[server_name] = client.stats.to_dict() + for tool_name, stats in client.get_all_tool_stats().items(): + full_key = f"{self._settings.get('tool_prefix', 'mcp')}_{server_name}_{tool_name}" + tool_stats[full_key] = stats.to_dict() + + uptime = time.time() - self._global_stats["start_time"] + + return { + "global": { + **self._global_stats, + "uptime_seconds": round(uptime, 2), + "calls_per_minute": round(self._global_stats["total_tool_calls"] / (uptime / 60), 2) if uptime > 0 else 0, + }, + "servers": server_stats, + "tools": tool_stats, + } + + async def shutdown(self) -> None: + """关闭所有连接""" + # 停止心跳检测 + await self.stop_heartbeat() + + async with self._lock: + for client in self._clients.values(): + await client.disconnect() + self._clients.clear() + self._all_tools.clear() + self._all_resources.clear() # v1.2.0 + self._all_prompts.clear() # v1.2.0 + logger.info("MCP 客户端管理器已关闭") + + def get_status(self) -> Dict[str, Any]: + """获取状态信息""" + return { + "total_servers": len(self._clients), + "connected_servers": len(self.connected_servers), + "disconnected_servers": len(self.disconnected_servers), + "total_tools": len(self._all_tools), + "total_resources": len(self._all_resources), # v1.2.0 + "total_prompts": len(self._all_prompts), # v1.2.0 + "heartbeat_running": self._heartbeat_running, + "servers": { + name: { + "connected": client.is_connected, + "enabled": client.config.enabled, + "tools_count": len(client.tools), + "resources_count": len(client.resources), # v1.2.0 + "prompts_count": len(client.prompts), # v1.2.0 + "supports_resources": client.supports_resources, # v1.2.0 + "supports_prompts": client.supports_prompts, # v1.2.0 + "transport": client.config.transport.value, + "consecutive_failures": client.stats.consecutive_failures, + "circuit_breaker": client.get_circuit_breaker_status(), # v1.7.0 + } + for name, client in self._clients.items() + }, + "global_stats": self._global_stats, + } + + +# 全局单例 +mcp_manager = MCPClientManager() diff --git a/plugins/MaiBot_MCPBridgePlugin/plugin.py b/plugins/MaiBot_MCPBridgePlugin/plugin.py new file mode 100644 index 00000000..06055c6b --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/plugin.py @@ -0,0 +1,3722 @@ +""" +MCP 桥接插件 v2.0.0 +将 MCP (Model Context Protocol) 服务器的工具桥接到 MaiBot + +v2.0.0 配置与架构精简(功能保持不变): +- MCP 服务器配置统一为 Claude Desktop 的 mcpServers JSON(WebUI / config.toml 同一入口) +- 兼容迁移:检测到旧版 servers.list 时自动迁移为 mcpServers(仅迁移,避免多入口混淆) +- 移除 WebUI 导入导出/快速添加服务器的旧实现(避免 tomlkit 依赖与格式混乱) + +v1.9.0 双轨制架构: +- 软流程 (ReAct): LLM 自主决策,动态多轮调用 MCP 工具,灵活应对复杂场景 +- 硬流程 (Workflow): 用户预定义的工作流,固定执行顺序,可靠可控 +- 工具链重命名为 Workflow,更清晰地表达其"预定义流程"的本质 +- 命令更新:/mcp workflow 替代 /mcp chain + +v1.8.1 工具链易用性优化: +- 快速添加工具链:WebUI 表单式配置,无需手写 JSON +- 工具链模板:提供常用工具链配置模板参考 +- 使用指南:内置变量语法和命令说明 +- 状态显示优化:详细展示工具链步骤和参数信息 + +v1.8.0 工具链支持: +- 工具链:将多个工具按顺序执行,后续工具可使用前序工具的输出 +- 自定义工具链:在 WebUI 配置工具链,自动注册为组合工具供 LLM 调用 +- 变量替换:支持 ${input.参数}、${step.输出键}、${prev} 变量 +- 工具链命令:/mcp chain 查看、测试、管理工具链 + +v1.7.0 稳定性与易用性优化: +- 断路器模式:故障服务器快速失败,避免拖慢整体响应 +- 状态实时刷新:WebUI 每 10 秒自动更新连接状态 +- 断路器状态显示:在状态面板显示熔断/试探状态 + +v1.6.0 配置导入导出: +- 新增 /mcp import 命令,支持从 Claude Desktop 格式导入配置 +- 新增 /mcp export 命令,导出为 Claude Desktop (mcpServers) 格式 +- 支持 stdio、sse、http、streamable_http 全部传输类型 +- 自动跳过同名服务器,防止重复导入 + +v1.5.4 易用性优化: +- 新增 MCP 服务器获取快捷入口(魔搭、Smithery、Glama 等) +- 优化快速入门指南,提供配置示例 +- 帮助新用户快速上手 MCP + +v1.5.3 配置优化: +- 新增智能心跳 WebUI 配置项:启用开关、最大间隔倍数 +- 支持在 WebUI 中开启/关闭智能心跳功能 + +v1.5.2 性能优化: +- 智能心跳间隔:根据服务器稳定性动态调整心跳频率 +- 稳定服务器逐渐增加间隔,减少不必要的网络请求 +- 断开的服务器使用较短间隔快速重连 + +v1.5.1 易用性优化(v2.0.0 起已移除): +- 「快速添加服务器」表单式配置(已统一为 Claude mcpServers JSON,避免多入口混淆) + +v1.5.0 性能优化: +- 服务器并行连接:多个服务器同时连接,大幅减少启动时间 +- 连接耗时统计:日志显示并行连接总耗时 + +v1.4.4 修复: +- 修复首次生成默认配置文件时多行字符串导致 TOML 解析失败的问题 +- 简化 config_schema 默认值,避免主程序 json.dumps 产生无效 TOML + +v1.4.3 修复: +- 修复 WebUI 保存配置后多行字符串格式错误导致配置文件无法读取的问题 +- 清理未使用的导入 + +v1.4.0 新增功能: +- 工具禁用管理 +- 调用链路追踪 +- 工具调用缓存 +- 工具权限控制 +""" + +import asyncio +import fnmatch +import hashlib +import json +import re +import time +import uuid +from collections import OrderedDict, deque +from dataclasses import asdict, dataclass, field +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple, Type + +from src.common.logger import get_logger +from src.plugin_system import ( + BasePlugin, + register_plugin, + BaseTool, + BaseCommand, + ComponentInfo, + ConfigField, + ToolParamType, +) +from src.plugin_system.base.config_types import section_meta +from src.plugin_system.base.component_types import ToolInfo, ComponentType, EventType +from src.plugin_system.base.base_events_handler import BaseEventHandler + +from .mcp_client import ( + MCPServerConfig, + MCPToolInfo, + MCPResourceInfo, + MCPPromptInfo, + TransportType, + mcp_manager, +) +from .core.claude_config import ( + ClaudeConfigError, + legacy_servers_list_to_claude_config, + parse_claude_mcp_config, +) +from .tool_chain import ( + ToolChainDefinition, + ToolChainStep, + ChainExecutionResult, + tool_chain_manager, +) + +logger = get_logger("mcp_bridge_plugin") + + +# ============================================================================ +# v1.4.0: 调用链路追踪 +# ============================================================================ + +@dataclass +class ToolCallRecord: + """工具调用记录""" + call_id: str + timestamp: float + tool_name: str + server_name: str + chat_id: str = "" + user_id: str = "" + user_query: str = "" + arguments: Dict = field(default_factory=dict) + raw_result: str = "" + processed_result: str = "" + duration_ms: float = 0.0 + success: bool = True + error: str = "" + post_processed: bool = False + cache_hit: bool = False + + +class ToolCallTracer: + """工具调用追踪器""" + + def __init__(self, max_records: int = 100): + self._records: deque[ToolCallRecord] = deque(maxlen=max_records) + self._enabled: bool = True + self._log_enabled: bool = False + self._log_path: Optional[Path] = None + + def configure(self, enabled: bool, max_records: int, log_enabled: bool, log_path: Optional[Path] = None) -> None: + """配置追踪器""" + self._enabled = enabled + self._records = deque(self._records, maxlen=max_records) + self._log_enabled = log_enabled + self._log_path = log_path + + def record(self, record: ToolCallRecord) -> None: + """添加调用记录""" + if not self._enabled: + return + + self._records.append(record) + + if self._log_enabled and self._log_path: + self._write_to_log(record) + + def get_recent(self, n: int = 10) -> List[ToolCallRecord]: + """获取最近 N 条记录""" + return list(self._records)[-n:] + + def get_by_tool(self, tool_name: str) -> List[ToolCallRecord]: + """按工具名筛选记录""" + return [r for r in self._records if r.tool_name == tool_name] + + def get_by_server(self, server_name: str) -> List[ToolCallRecord]: + """按服务器名筛选记录""" + return [r for r in self._records if r.server_name == server_name] + + def clear(self) -> None: + """清空记录""" + self._records.clear() + + def _write_to_log(self, record: ToolCallRecord) -> None: + """写入 JSONL 日志文件""" + try: + if self._log_path: + self._log_path.parent.mkdir(parents=True, exist_ok=True) + with open(self._log_path, "a", encoding="utf-8") as f: + f.write(json.dumps(asdict(record), ensure_ascii=False) + "\n") + except Exception as e: + logger.warning(f"写入追踪日志失败: {e}") + + @property + def total_records(self) -> int: + return len(self._records) + + +# 全局追踪器实例 +tool_call_tracer = ToolCallTracer() + + +# ============================================================================ +# v1.4.0: 工具调用缓存 +# ============================================================================ + +@dataclass +class CacheEntry: + """缓存条目""" + tool_name: str + args_hash: str + result: str + created_at: float + expires_at: float + hit_count: int = 0 + + +class ToolCallCache: + """工具调用缓存(LRU)""" + + def __init__(self, max_entries: int = 200, ttl: int = 300): + self._cache: OrderedDict[str, CacheEntry] = OrderedDict() + self._max_entries = max_entries + self._ttl = ttl + self._enabled = False + self._exclude_patterns: List[str] = [] + self._stats = {"hits": 0, "misses": 0} + + def configure(self, enabled: bool, ttl: int, max_entries: int, exclude_tools: str) -> None: + """配置缓存""" + self._enabled = enabled + self._ttl = ttl + self._max_entries = max_entries + self._exclude_patterns = [p.strip() for p in exclude_tools.strip().split("\n") if p.strip()] + + def get(self, tool_name: str, args: Dict) -> Optional[str]: + """获取缓存""" + if not self._enabled: + return None + + if self._is_excluded(tool_name): + return None + + key = self._generate_key(tool_name, args) + + if key not in self._cache: + self._stats["misses"] += 1 + return None + + entry = self._cache[key] + + # 检查是否过期 + if time.time() > entry.expires_at: + del self._cache[key] + self._stats["misses"] += 1 + return None + + # LRU: 移到末尾 + self._cache.move_to_end(key) + entry.hit_count += 1 + self._stats["hits"] += 1 + + return entry.result + + def set(self, tool_name: str, args: Dict, result: str) -> None: + """设置缓存""" + if not self._enabled: + return + + if self._is_excluded(tool_name): + return + + key = self._generate_key(tool_name, args) + now = time.time() + + entry = CacheEntry( + tool_name=tool_name, + args_hash=key, + result=result, + created_at=now, + expires_at=now + self._ttl, + ) + + # 如果已存在,更新 + if key in self._cache: + self._cache[key] = entry + self._cache.move_to_end(key) + else: + # 检查容量 + self._evict_if_needed() + self._cache[key] = entry + + def clear(self) -> None: + """清空缓存""" + self._cache.clear() + self._stats = {"hits": 0, "misses": 0} + + def _generate_key(self, tool_name: str, args: Dict) -> str: + """生成缓存键""" + args_str = json.dumps(args, sort_keys=True, ensure_ascii=False) + content = f"{tool_name}:{args_str}" + return hashlib.md5(content.encode()).hexdigest() + + def _is_excluded(self, tool_name: str) -> bool: + """检查是否在排除列表中""" + for pattern in self._exclude_patterns: + if fnmatch.fnmatch(tool_name, pattern): + return True + return False + + def _evict_if_needed(self) -> None: + """必要时淘汰条目""" + # 先清理过期的 + now = time.time() + expired_keys = [k for k, v in self._cache.items() if now > v.expires_at] + for k in expired_keys: + del self._cache[k] + + # LRU 淘汰 + while len(self._cache) >= self._max_entries: + self._cache.popitem(last=False) + + def get_stats(self) -> Dict[str, Any]: + """获取缓存统计""" + total = self._stats["hits"] + self._stats["misses"] + hit_rate = (self._stats["hits"] / total * 100) if total > 0 else 0 + return { + "enabled": self._enabled, + "entries": len(self._cache), + "max_entries": self._max_entries, + "ttl": self._ttl, + "hits": self._stats["hits"], + "misses": self._stats["misses"], + "hit_rate": f"{hit_rate:.1f}%", + } + + +# 全局缓存实例 +tool_call_cache = ToolCallCache() + + +# ============================================================================ +# v1.4.0: 工具权限控制 +# ============================================================================ + +class PermissionChecker: + """工具权限检查器""" + + def __init__(self): + self._enabled = False + self._default_mode = "allow_all" # allow_all 或 deny_all + self._rules: List[Dict] = [] + self._quick_deny_groups: set = set() + self._quick_allow_users: set = set() + + def configure( + self, + enabled: bool, + default_mode: str, + rules_json: str, + quick_deny_groups: str = "", + quick_allow_users: str = "", + ) -> None: + """配置权限检查器""" + self._enabled = enabled + self._default_mode = default_mode if default_mode in ("allow_all", "deny_all") else "allow_all" + + # 解析快捷配置 + self._quick_deny_groups = {g.strip() for g in quick_deny_groups.strip().split("\n") if g.strip()} + self._quick_allow_users = {u.strip() for u in quick_allow_users.strip().split("\n") if u.strip()} + + try: + self._rules = json.loads(rules_json) if rules_json.strip() else [] + except json.JSONDecodeError as e: + logger.warning(f"权限规则 JSON 解析失败: {e}") + self._rules = [] + + def check(self, tool_name: str, chat_id: str, user_id: str, is_group: bool) -> bool: + """检查权限 + + Args: + tool_name: 工具名称 + chat_id: 聊天 ID(群号或私聊 ID) + user_id: 用户 ID + is_group: 是否为群聊 + + Returns: + True 表示允许,False 表示拒绝 + """ + if not self._enabled: + return True + + # 快捷配置优先级最高 + # 1. 管理员白名单(始终允许) + if user_id and user_id in self._quick_allow_users: + return True + + # 2. 禁用群列表(始终拒绝) + if is_group and chat_id and chat_id in self._quick_deny_groups: + return False + + # 查找匹配的规则 + for rule in self._rules: + tool_pattern = rule.get("tool", "") + if not self._match_tool(tool_pattern, tool_name): + continue + + # 找到匹配的规则 + mode = rule.get("mode", "") + allowed = rule.get("allowed", []) + denied = rule.get("denied", []) + + # 构建当前上下文的 ID 列表 + context_ids = self._build_context_ids(chat_id, user_id, is_group) + + # 检查 denied 列表(优先级最高) + if denied: + for ctx_id in context_ids: + if self._match_id_list(denied, ctx_id): + return False + + # 检查 allowed 列表 + if allowed: + for ctx_id in context_ids: + if self._match_id_list(allowed, ctx_id): + return True + # 如果是 whitelist 模式且不在 allowed 中,拒绝 + if mode == "whitelist": + return False + + # 规则匹配但没有明确允许/拒绝,继续检查下一条规则 + + # 没有匹配的规则,使用默认模式 + return self._default_mode == "allow_all" + + def _match_tool(self, pattern: str, tool_name: str) -> bool: + """工具名通配符匹配""" + if not pattern: + return False + return fnmatch.fnmatch(tool_name, pattern) + + def _build_context_ids(self, chat_id: str, user_id: str, is_group: bool) -> List[str]: + """构建上下文 ID 列表""" + ids = [] + + # 用户级别(任何场景生效) + if user_id: + ids.append(f"qq:{user_id}:user") + + # 场景级别 + if is_group and chat_id: + ids.append(f"qq:{chat_id}:group") + elif chat_id: + ids.append(f"qq:{chat_id}:private") + + return ids + + def _match_id_list(self, id_list: List[str], context_id: str) -> bool: + """检查 ID 是否在列表中""" + for rule_id in id_list: + if fnmatch.fnmatch(context_id, rule_id): + return True + return False + + def get_rules_for_tool(self, tool_name: str) -> List[Dict]: + """获取特定工具的权限规则""" + return [r for r in self._rules if self._match_tool(r.get("tool", ""), tool_name)] + + +# 全局权限检查器实例 +permission_checker = PermissionChecker() + + +# ============================================================================ +# 工具类型转换 +# ============================================================================ + +def convert_json_type_to_tool_param_type(json_type: str) -> ToolParamType: + """将 JSON Schema 类型转换为 MaiBot 的 ToolParamType""" + type_mapping = { + "string": ToolParamType.STRING, + "integer": ToolParamType.INTEGER, + "number": ToolParamType.FLOAT, + "boolean": ToolParamType.BOOLEAN, + "array": ToolParamType.STRING, + "object": ToolParamType.STRING, + } + return type_mapping.get(json_type, ToolParamType.STRING) + + +def parse_mcp_parameters(input_schema: Dict[str, Any]) -> List[Tuple[str, ToolParamType, str, bool, Optional[List[str]]]]: + """解析 MCP 工具的参数 schema,转换为 MaiBot 的参数格式""" + parameters = [] + + if not input_schema: + # 为无参数的工具添加占位参数,避免某些模型报错 + parameters.append(("_placeholder", ToolParamType.STRING, "占位参数,无需填写", False, None)) + return parameters + + properties = input_schema.get("properties", {}) + required = input_schema.get("required", []) + + # 如果没有任何参数,添加占位参数 + if not properties: + parameters.append(("_placeholder", ToolParamType.STRING, "占位参数,无需填写", False, None)) + return parameters + + for param_name, param_info in properties.items(): + json_type = param_info.get("type", "string") + param_type = convert_json_type_to_tool_param_type(json_type) + description = param_info.get("description", f"参数 {param_name}") + + if json_type == "array": + description = f"{description} (JSON 数组格式)" + elif json_type == "object": + description = f"{description} (JSON 对象格式)" + + is_required = param_name in required + enum_values = param_info.get("enum") + + if enum_values is not None: + enum_values = [str(v) for v in enum_values] + + parameters.append((param_name, param_type, description, is_required, enum_values)) + + return parameters + + +# ============================================================================ +# MCP 工具代理 +# ============================================================================ + +class MCPToolProxy(BaseTool): + """MCP 工具代理基类""" + + name: str = "" + description: str = "" + parameters: List[Tuple[str, ToolParamType, str, bool, Optional[List[str]]]] = [] + available_for_llm: bool = True + + _mcp_tool_key: str = "" + _mcp_original_name: str = "" + _mcp_server_name: str = "" + + async def execute(self, function_args: Dict[str, Any]) -> Dict[str, Any]: + """执行 MCP 工具调用""" + global _plugin_instance + + call_id = str(uuid.uuid4())[:8] + start_time = time.time() + + # 移除 MaiBot 内部标记 + args = {k: v for k, v in function_args.items() if k != "llm_called"} + + # 解析 JSON 字符串参数 + parsed_args = {} + for key, value in args.items(): + if isinstance(value, str): + try: + if value.startswith(("[", "{")): + parsed_args[key] = json.loads(value) + else: + parsed_args[key] = value + except json.JSONDecodeError: + parsed_args[key] = value + else: + parsed_args[key] = value + + # 获取上下文信息 + chat_id, user_id, is_group, user_query = self._get_context_info() + + # v1.4.0: 权限检查 + if not permission_checker.check(self.name, chat_id, user_id, is_group): + logger.warning(f"权限拒绝: 工具 {self.name}, chat={chat_id}, user={user_id}") + return { + "name": self.name, + "content": f"⛔ 权限不足:工具 {self.name} 在当前场景下不可用" + } + + logger.debug(f"调用 MCP 工具: {self._mcp_tool_key}, 参数: {parsed_args}") + + # v1.4.0: 检查缓存 + cache_hit = False + cached_result = tool_call_cache.get(self.name, parsed_args) + + if cached_result is not None: + cache_hit = True + content = cached_result + raw_result = cached_result + success = True + error = "" + logger.debug(f"MCP 工具 {self.name} 命中缓存") + else: + # 调用 MCP + result = await mcp_manager.call_tool(self._mcp_tool_key, parsed_args) + + if result.success: + content = result.content + raw_result = content + success = True + error = "" + + # 存入缓存 + tool_call_cache.set(self.name, parsed_args, content) + else: + content = self._format_error_message(result.error, result.duration_ms) + raw_result = result.error + success = False + error = result.error + logger.warning(f"MCP 工具 {self.name} 调用失败: {result.error}") + + # v1.3.0: 后处理 + post_processed = False + processed_result = content + if success: + processed_content = await self._post_process_result(content) + if processed_content != content: + post_processed = True + processed_result = processed_content + content = processed_content + + duration_ms = (time.time() - start_time) * 1000 + + # v1.4.0: 记录调用追踪 + record = ToolCallRecord( + call_id=call_id, + timestamp=start_time, + tool_name=self.name, + server_name=self._mcp_server_name, + chat_id=chat_id, + user_id=user_id, + user_query=user_query, + arguments=parsed_args, + raw_result=raw_result[:1000] if raw_result else "", + processed_result=processed_result[:1000] if processed_result else "", + duration_ms=duration_ms, + success=success, + error=error, + post_processed=post_processed, + cache_hit=cache_hit, + ) + tool_call_tracer.record(record) + + return {"name": self.name, "content": content} + + def _get_context_info(self) -> Tuple[str, str, bool, str]: + """获取上下文信息""" + chat_id = "" + user_id = "" + is_group = False + user_query = "" + + if self.chat_stream and hasattr(self.chat_stream, "context") and self.chat_stream.context: + try: + ctx = self.chat_stream.context + if hasattr(ctx, "chat_id"): + chat_id = str(ctx.chat_id) if ctx.chat_id else "" + if hasattr(ctx, "user_id"): + user_id = str(ctx.user_id) if ctx.user_id else "" + if hasattr(ctx, "is_group"): + is_group = bool(ctx.is_group) + + last_message = ctx.get_last_message() + if last_message and hasattr(last_message, "processed_plain_text"): + user_query = last_message.processed_plain_text or "" + except Exception as e: + logger.debug(f"获取上下文信息失败: {e}") + + return chat_id, user_id, is_group, user_query + + async def _post_process_result(self, content: str) -> str: + """v1.3.0: 对工具返回结果进行后处理(摘要提炼)""" + global _plugin_instance + + if _plugin_instance is None: + return content + + settings = _plugin_instance.config.get("settings", {}) + + if not settings.get("post_process_enabled", False): + return content + + server_post_config = self._get_server_post_process_config() + + if server_post_config is not None: + if not server_post_config.get("enabled", True): + return content + + threshold = settings.get("post_process_threshold", 500) + if server_post_config and "threshold" in server_post_config: + threshold = server_post_config["threshold"] + + content_length = len(content) if content else 0 + if content_length <= threshold: + return content + + user_query = self._get_context_info()[3] + if not user_query: + return content + + max_tokens = settings.get("post_process_max_tokens", 500) + if server_post_config and "max_tokens" in server_post_config: + max_tokens = server_post_config["max_tokens"] + + prompt_template = settings.get("post_process_prompt", "") + if server_post_config and "prompt" in server_post_config: + prompt_template = server_post_config["prompt"] + + if not prompt_template: + prompt_template = """用户问题:{query} + +工具返回内容: +{result} + +请从上述内容中提取与用户问题最相关的关键信息,简洁准确地输出:""" + + try: + prompt = prompt_template.format(query=user_query, result=content) + except KeyError as e: + logger.warning(f"后处理 prompt 模板格式错误: {e}") + return content + + try: + processed_content = await self._call_post_process_llm(prompt, max_tokens, settings, server_post_config) + if processed_content: + logger.info(f"MCP 工具 {self.name} 后处理完成: {content_length} -> {len(processed_content)} 字符") + return processed_content + return content + except Exception as e: + logger.error(f"MCP 工具 {self.name} 后处理失败: {e}") + return content + + def _get_server_post_process_config(self) -> Optional[Dict[str, Any]]: + """获取当前服务器的后处理配置""" + global _plugin_instance + + if _plugin_instance is None: + return None + + servers = _plugin_instance._load_mcp_servers_config() + for server_conf in servers: + if server_conf.get("name") == self._mcp_server_name: + return server_conf.get("post_process") + + return None + + async def _call_post_process_llm( + self, + prompt: str, + max_tokens: int, + settings: Dict[str, Any], + server_config: Optional[Dict[str, Any]] + ) -> Optional[str]: + """调用 LLM 进行后处理""" + from src.config.config import model_config + from src.config.api_ada_configs import TaskConfig + from src.llm_models.utils_model import LLMRequest + + model_name = settings.get("post_process_model", "") + if server_config and "model" in server_config: + model_name = server_config["model"] + + if model_name: + task_config = TaskConfig( + model_list=[model_name], + max_tokens=max_tokens, + temperature=0.3, + slow_threshold=30.0, + ) + else: + task_config = model_config.model_task_config.utils + + llm_request = LLMRequest(model_set=task_config, request_type="mcp_post_process") + + response, (reasoning, model_used, _) = await llm_request.generate_response_async( + prompt=prompt, + max_tokens=max_tokens, + temperature=0.3, + ) + + return response.strip() if response else None + + def _format_error_message(self, error: str, duration_ms: float) -> str: + """格式化友好的错误消息""" + if not error: + return "工具调用失败(未知错误)" + + error_lower = error.lower() + + if "未连接" in error or "not connected" in error_lower: + return f"⚠️ MCP 服务器 [{self._mcp_server_name}] 未连接,请检查服务器状态或等待自动重连" + + if "超时" in error or "timeout" in error_lower: + return f"⏱️ 工具调用超时(耗时 {duration_ms:.0f}ms),服务器响应过慢,请稍后重试" + + if "connection" in error_lower and ("closed" in error_lower or "reset" in error_lower): + return f"🔌 与 MCP 服务器 [{self._mcp_server_name}] 的连接已断开,正在尝试重连..." + + if "invalid" in error_lower and "argument" in error_lower: + return f"❌ 参数错误: {error}" + + return f"❌ 工具调用失败: {error}" + + async def direct_execute(self, **function_args) -> Dict[str, Any]: + """直接执行(供其他插件调用)""" + return await self.execute(function_args) + + +def create_mcp_tool_class( + tool_key: str, + tool_info: MCPToolInfo, + tool_prefix: str, + disabled: bool = False +) -> Type[MCPToolProxy]: + """根据 MCP 工具信息动态创建 BaseTool 子类""" + parameters = parse_mcp_parameters(tool_info.input_schema) + + class_name = f"MCPTool_{tool_info.server_name}_{tool_info.name}".replace("-", "_").replace(".", "_") + tool_name = tool_key.replace("-", "_").replace(".", "_") + + description = tool_info.description + if not description.endswith(f"[来自 MCP 服务器: {tool_info.server_name}]"): + description = f"{description} [来自 MCP 服务器: {tool_info.server_name}]" + + tool_class = type( + class_name, + (MCPToolProxy,), + { + "name": tool_name, + "description": description, + "parameters": parameters, + "available_for_llm": not disabled, # v1.4.0: 禁用的工具不可被 LLM 调用 + "_mcp_tool_key": tool_key, + "_mcp_original_name": tool_info.name, + "_mcp_server_name": tool_info.server_name, + } + ) + + return tool_class + + +class MCPToolRegistry: + """MCP 工具注册表""" + + def __init__(self): + self._tool_classes: Dict[str, Type[MCPToolProxy]] = {} + self._tool_infos: Dict[str, ToolInfo] = {} + + def register_tool( + self, + tool_key: str, + tool_info: MCPToolInfo, + tool_prefix: str, + disabled: bool = False + ) -> Tuple[ToolInfo, Type[MCPToolProxy]]: + """注册 MCP 工具""" + tool_class = create_mcp_tool_class(tool_key, tool_info, tool_prefix, disabled) + + self._tool_classes[tool_key] = tool_class + + info = ToolInfo( + name=tool_class.name, + tool_description=tool_class.description, + enabled=True, + tool_parameters=tool_class.parameters, + component_type=ComponentType.TOOL, + ) + self._tool_infos[tool_key] = info + + return info, tool_class + + def unregister_tool(self, tool_key: str) -> bool: + """注销工具""" + if tool_key in self._tool_classes: + del self._tool_classes[tool_key] + del self._tool_infos[tool_key] + return True + return False + + def get_all_components(self) -> List[Tuple[ComponentInfo, Type]]: + """获取所有工具组件""" + return [(self._tool_infos[key], self._tool_classes[key]) for key in self._tool_classes.keys()] + + def clear(self) -> None: + """清空所有注册""" + self._tool_classes.clear() + self._tool_infos.clear() + + +# 全局工具注册表 +mcp_tool_registry = MCPToolRegistry() + +# 全局插件实例引用 +_plugin_instance: Optional["MCPBridgePlugin"] = None + + +# ============================================================================ +# 内置工具 +# ============================================================================ + +class MCPReadResourceTool(BaseTool): + """v1.2.0: MCP 资源读取工具""" + + name = "mcp_read_resource" + description = "读取 MCP 服务器提供的资源内容(如文件、数据库记录等)。使用前请先用 mcp_status 查看可用资源。" + parameters = [ + ("uri", ToolParamType.STRING, "资源 URI(如 file:///path/to/file 或自定义 URI)", True, None), + ("server_name", ToolParamType.STRING, "指定服务器名称(可选,不指定则自动查找)", False, None), + ] + available_for_llm = True + + async def execute(self, function_args: Dict[str, Any]) -> Dict[str, Any]: + uri = function_args.get("uri", "") + server_name = function_args.get("server_name") + + if not uri: + return {"name": self.name, "content": "❌ 请提供资源 URI"} + + result = await mcp_manager.read_resource(uri, server_name) + + if result.success: + return {"name": self.name, "content": result.content} + else: + return {"name": self.name, "content": f"❌ 读取资源失败: {result.error}"} + + async def direct_execute(self, **function_args) -> Dict[str, Any]: + return await self.execute(function_args) + + +class MCPGetPromptTool(BaseTool): + """v1.2.0: MCP 提示模板工具""" + + name = "mcp_get_prompt" + description = "获取 MCP 服务器提供的提示模板内容。使用前请先用 mcp_status 查看可用模板。" + parameters = [ + ("name", ToolParamType.STRING, "提示模板名称", True, None), + ("arguments", ToolParamType.STRING, "模板参数(JSON 对象格式)", False, None), + ("server_name", ToolParamType.STRING, "指定服务器名称(可选)", False, None), + ] + available_for_llm = True + + async def execute(self, function_args: Dict[str, Any]) -> Dict[str, Any]: + prompt_name = function_args.get("name", "") + arguments_str = function_args.get("arguments", "") + server_name = function_args.get("server_name") + + if not prompt_name: + return {"name": self.name, "content": "❌ 请提供提示模板名称"} + + arguments = None + if arguments_str: + try: + arguments = json.loads(arguments_str) + except json.JSONDecodeError: + return {"name": self.name, "content": "❌ 参数格式错误,请使用 JSON 对象格式"} + + result = await mcp_manager.get_prompt(prompt_name, arguments, server_name) + + if result.success: + return {"name": self.name, "content": result.content} + else: + return {"name": self.name, "content": f"❌ 获取提示模板失败: {result.error}"} + + async def direct_execute(self, **function_args) -> Dict[str, Any]: + return await self.execute(function_args) + + +# ============================================================================ +# v1.8.0: 工具链代理工具 +# ============================================================================ + +class ToolChainProxyBase(BaseTool): + """工具链代理基类""" + + name: str = "" + description: str = "" + parameters: List[Tuple[str, ToolParamType, str, bool, Optional[List[str]]]] = [] + available_for_llm: bool = True + + _chain_name: str = "" + + async def execute(self, function_args: Dict[str, Any]) -> Dict[str, Any]: + """执行工具链""" + # 移除内部标记 + args = {k: v for k, v in function_args.items() if k != "llm_called"} + + logger.debug(f"执行工具链 {self._chain_name},参数: {args}") + + result = await tool_chain_manager.execute_chain(self._chain_name, args) + + if result.success: + # 构建输出 + output_parts = [] + output_parts.append(result.final_output) + + # 可选:添加执行摘要 + # output_parts.append(f"\n\n---\n执行摘要:\n{result.to_summary()}") + + return {"name": self.name, "content": "\n".join(output_parts)} + else: + error_msg = f"⚠️ 工具链执行失败: {result.error}" + if result.step_results: + error_msg += f"\n\n执行详情:\n{result.to_summary()}" + return {"name": self.name, "content": error_msg} + + async def direct_execute(self, **function_args) -> Dict[str, Any]: + return await self.execute(function_args) + + +def create_chain_tool_class(chain: ToolChainDefinition) -> Type[ToolChainProxyBase]: + """根据工具链定义动态创建工具类""" + # 构建参数列表 + parameters = [] + for param_name, param_desc in chain.input_params.items(): + parameters.append((param_name, ToolParamType.STRING, param_desc, True, None)) + + # 生成类名和工具名 + class_name = f"ToolChain_{chain.name}".replace("-", "_").replace(".", "_") + tool_name = f"chain_{chain.name}".replace("-", "_").replace(".", "_") + + # 构建描述 + description = chain.description + if chain.steps: + step_names = [s.tool_name.split("_")[-1] for s in chain.steps[:3]] + description += f" (执行流程: {' → '.join(step_names)}{'...' if len(chain.steps) > 3 else ''})" + + tool_class = type( + class_name, + (ToolChainProxyBase,), + { + "name": tool_name, + "description": description, + "parameters": parameters, + "available_for_llm": True, + "_chain_name": chain.name, + } + ) + + return tool_class + + +class ToolChainRegistry: + """工具链注册表""" + + def __init__(self): + self._tool_classes: Dict[str, Type[ToolChainProxyBase]] = {} + self._tool_infos: Dict[str, ToolInfo] = {} + + def register_chain(self, chain: ToolChainDefinition) -> Tuple[ToolInfo, Type[ToolChainProxyBase]]: + """注册工具链为组合工具""" + tool_class = create_chain_tool_class(chain) + + self._tool_classes[chain.name] = tool_class + + info = ToolInfo( + name=tool_class.name, + tool_description=tool_class.description, + enabled=True, + tool_parameters=tool_class.parameters, + component_type=ComponentType.TOOL, + ) + self._tool_infos[chain.name] = info + + return info, tool_class + + def unregister_chain(self, chain_name: str) -> bool: + """注销工具链""" + if chain_name in self._tool_classes: + del self._tool_classes[chain_name] + del self._tool_infos[chain_name] + return True + return False + + def get_all_components(self) -> List[Tuple[ComponentInfo, Type]]: + """获取所有工具链组件""" + return [(self._tool_infos[key], self._tool_classes[key]) for key in self._tool_classes.keys()] + + def clear(self) -> None: + """清空所有注册""" + self._tool_classes.clear() + self._tool_infos.clear() + + +# 全局工具链注册表 +tool_chain_registry = ToolChainRegistry() + + +class MCPStatusTool(BaseTool): + """MCP 状态查询工具""" + + name = "mcp_status" + description = "查询 MCP 桥接插件的状态,包括服务器连接状态、可用工具列表、工具链列表、资源列表、提示模板列表、调用统计、追踪记录等信息" + parameters = [ + ("query_type", ToolParamType.STRING, "查询类型", False, ["status", "tools", "chains", "resources", "prompts", "stats", "trace", "cache", "all"]), + ("server_name", ToolParamType.STRING, "指定服务器名称(可选)", False, None), + ] + available_for_llm = True + + async def execute(self, function_args: Dict[str, Any]) -> Dict[str, Any]: + query_type = function_args.get("query_type", "status") + server_name = function_args.get("server_name") + + result_parts = [] + + if query_type in ("status", "all"): + result_parts.append(self._format_status(server_name)) + + if query_type in ("tools", "all"): + result_parts.append(self._format_tools(server_name)) + + if query_type in ("chains", "all"): + result_parts.append(self._format_chains()) + + if query_type in ("resources", "all"): + result_parts.append(self._format_resources(server_name)) + + if query_type in ("prompts", "all"): + result_parts.append(self._format_prompts(server_name)) + + if query_type in ("stats", "all"): + result_parts.append(self._format_stats(server_name)) + + # v1.4.0: 追踪记录 + if query_type in ("trace",): + result_parts.append(self._format_trace()) + + # v1.4.0: 缓存状态 + if query_type in ("cache",): + result_parts.append(self._format_cache()) + + return { + "name": self.name, + "content": "\n\n".join(result_parts) if result_parts else "未知的查询类型" + } + + def _format_status(self, server_name: Optional[str] = None) -> str: + status = mcp_manager.get_status() + lines = ["📊 MCP 桥接插件状态"] + lines.append(f" 总服务器数: {status['total_servers']}") + lines.append(f" 已连接: {status['connected_servers']}") + lines.append(f" 已断开: {status['disconnected_servers']}") + lines.append(f" 可用工具数: {status['total_tools']}") + lines.append(f" 心跳检测: {'运行中' if status['heartbeat_running'] else '已停止'}") + + lines.append("\n🔌 服务器详情:") + for name, info in status['servers'].items(): + if server_name and name != server_name: + continue + status_icon = "✅" if info['connected'] else "❌" + enabled_text = "" if info['enabled'] else " (已禁用)" + lines.append(f" {status_icon} {name}{enabled_text}") + lines.append(f" 传输: {info['transport']}, 工具数: {info['tools_count']}") + if info['consecutive_failures'] > 0: + lines.append(f" ⚠️ 连续失败: {info['consecutive_failures']} 次") + + return "\n".join(lines) + + def _format_tools(self, server_name: Optional[str] = None) -> str: + tools = mcp_manager.all_tools + lines = ["🔧 可用 MCP 工具"] + + by_server: Dict[str, List[str]] = {} + for tool_key, (tool_info, _) in tools.items(): + if server_name and tool_info.server_name != server_name: + continue + if tool_info.server_name not in by_server: + by_server[tool_info.server_name] = [] + by_server[tool_info.server_name].append(f" • {tool_key}: {tool_info.description[:50]}...") + + for srv_name, tool_list in by_server.items(): + lines.append(f"\n📦 {srv_name} ({len(tool_list)} 个工具):") + lines.extend(tool_list) + + if not by_server: + lines.append(" (无可用工具)") + + return "\n".join(lines) + + def _format_stats(self, server_name: Optional[str] = None) -> str: + stats = mcp_manager.get_all_stats() + lines = ["📈 调用统计"] + + g = stats['global'] + lines.append(f" 总调用次数: {g['total_tool_calls']}") + lines.append(f" 成功: {g['successful_calls']}, 失败: {g['failed_calls']}") + if g['total_tool_calls'] > 0: + success_rate = (g['successful_calls'] / g['total_tool_calls']) * 100 + lines.append(f" 成功率: {success_rate:.1f}%") + lines.append(f" 运行时间: {g['uptime_seconds']:.0f} 秒") + + return "\n".join(lines) + + def _format_resources(self, server_name: Optional[str] = None) -> str: + resources = mcp_manager.all_resources + if not resources: + return "📦 当前没有可用的 MCP 资源" + + lines = ["📦 可用 MCP 资源"] + by_server: Dict[str, List[MCPResourceInfo]] = {} + for key, (resource_info, _) in resources.items(): + if server_name and resource_info.server_name != server_name: + continue + if resource_info.server_name not in by_server: + by_server[resource_info.server_name] = [] + by_server[resource_info.server_name].append(resource_info) + + for srv_name, resource_list in by_server.items(): + lines.append(f"\n🔌 {srv_name} ({len(resource_list)} 个资源):") + for res in resource_list: + lines.append(f" • {res.name}: {res.uri}") + + return "\n".join(lines) + + def _format_prompts(self, server_name: Optional[str] = None) -> str: + prompts = mcp_manager.all_prompts + if not prompts: + return "📝 当前没有可用的 MCP 提示模板" + + lines = ["📝 可用 MCP 提示模板"] + by_server: Dict[str, List[MCPPromptInfo]] = {} + for key, (prompt_info, _) in prompts.items(): + if server_name and prompt_info.server_name != server_name: + continue + if prompt_info.server_name not in by_server: + by_server[prompt_info.server_name] = [] + by_server[prompt_info.server_name].append(prompt_info) + + for srv_name, prompt_list in by_server.items(): + lines.append(f"\n🔌 {srv_name} ({len(prompt_list)} 个模板):") + for prompt in prompt_list: + lines.append(f" • {prompt.name}") + + return "\n".join(lines) + + def _format_trace(self) -> str: + """v1.4.0: 格式化追踪记录""" + records = tool_call_tracer.get_recent(10) + if not records: + return "🔍 暂无调用追踪记录" + + lines = ["🔍 最近调用追踪记录"] + for r in reversed(records): + status = "✅" if r.success else "❌" + cache = "📦" if r.cache_hit else "" + post = "🔄" if r.post_processed else "" + lines.append(f" {status}{cache}{post} {r.tool_name} ({r.duration_ms:.0f}ms)") + if r.error: + lines.append(f" 错误: {r.error[:50]}") + + return "\n".join(lines) + + def _format_cache(self) -> str: + """v1.4.0: 格式化缓存状态""" + stats = tool_call_cache.get_stats() + lines = ["🗄️ 缓存状态"] + lines.append(f" 启用: {'是' if stats['enabled'] else '否'}") + lines.append(f" 条目数: {stats['entries']}/{stats['max_entries']}") + lines.append(f" TTL: {stats['ttl']}秒") + lines.append(f" 命中: {stats['hits']}, 未命中: {stats['misses']}") + lines.append(f" 命中率: {stats['hit_rate']}") + return "\n".join(lines) + + def _format_chains(self) -> str: + """v1.8.0: 格式化工具链列表""" + chains = tool_chain_manager.get_all_chains() + if not chains: + return "🔗 当前没有配置工具链" + + lines = ["🔗 工具链列表"] + for name, chain in chains.items(): + status = "✅" if chain.enabled else "❌" + lines.append(f"\n{status} {name}") + lines.append(f" 描述: {chain.description[:50]}...") + lines.append(f" 步骤: {len(chain.steps)} 个") + for i, step in enumerate(chain.steps[:3]): + lines.append(f" {i+1}. {step.tool_name}") + if len(chain.steps) > 3: + lines.append(f" ... 还有 {len(chain.steps) - 3} 个步骤") + if chain.input_params: + params = ", ".join(chain.input_params.keys()) + lines.append(f" 参数: {params}") + + return "\n".join(lines) + + async def direct_execute(self, **function_args) -> Dict[str, Any]: + return await self.execute(function_args) + + +# ============================================================================ +# 命令处理 +# ============================================================================ + +class MCPStatusCommand(BaseCommand): + """MCP 状态查询命令 - 通过 /mcp 命令查看服务器状态""" + + command_name = "mcp_status_command" + command_description = "查看 MCP 服务器连接状态和统计信息" + command_pattern = r"^[//]mcp(?:\s+(?Pstatus|tools|stats|reconnect|trace|cache|perm|export|search|chain))?(?:\s+(?P.+))?$" + + async def execute(self) -> Tuple[bool, Optional[str], bool]: + """执行命令""" + subcommand = self.matched_groups.get("subcommand", "status") or "status" + arg = self.matched_groups.get("arg") + + if subcommand == "reconnect": + return await self._handle_reconnect(arg) + + # v1.4.0: 追踪命令 + if subcommand == "trace": + return await self._handle_trace(arg) + + # v1.4.0: 缓存命令 + if subcommand == "cache": + return await self._handle_cache(arg) + + # v1.4.0: 权限命令 + if subcommand == "perm": + return await self._handle_perm(arg) + + # v1.6.0: 导出命令 + if subcommand == "export": + return await self._handle_export(arg) + + # v1.7.0: 工具搜索命令 + if subcommand == "search": + return await self._handle_search(arg) + + # v1.8.0: 工具链命令 + if subcommand == "chain": + return await self._handle_chain(arg) + + result = self._format_output(subcommand, arg) + await self.send_text(result) + return (True, None, True) + + def _find_similar_servers(self, name: str, max_results: int = 3) -> List[str]: + """查找相似的服务器名称""" + name_lower = name.lower() + all_servers = list(mcp_manager._clients.keys()) + + # 简单的相似度匹配:包含关系或前缀匹配 + similar = [] + for srv in all_servers: + srv_lower = srv.lower() + if name_lower in srv_lower or srv_lower in name_lower: + similar.append(srv) + elif srv_lower.startswith(name_lower[:3]) if len(name_lower) >= 3 else False: + similar.append(srv) + + return similar[:max_results] + + async def _handle_reconnect(self, server_name: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """处理重连请求""" + if server_name: + if server_name not in mcp_manager._clients: + # 提示相似的服务器名 + similar = self._find_similar_servers(server_name) + msg = f"❌ 服务器 '{server_name}' 不存在" + if similar: + msg += f"\n💡 你是不是想找: {', '.join(similar)}" + await self.send_text(msg) + return (True, None, True) + + await self.send_text(f"🔄 正在重连服务器 {server_name}...") + success = await mcp_manager.reconnect_server(server_name) + if success: + await self.send_text(f"✅ 服务器 {server_name} 重连成功") + else: + await self.send_text(f"❌ 服务器 {server_name} 重连失败") + else: + disconnected = mcp_manager.disconnected_servers + if not disconnected: + await self.send_text("✅ 所有服务器都已连接") + return (True, None, True) + + await self.send_text(f"🔄 正在重连 {len(disconnected)} 个断开的服务器...") + for srv in disconnected: + success = await mcp_manager.reconnect_server(srv) + status = "✅" if success else "❌" + await self.send_text(f"{status} {srv}") + + return (True, None, True) + + async def _handle_trace(self, arg: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """v1.4.0: 处理追踪命令""" + if arg and arg.isdigit(): + # /mcp trace 20 - 最近 N 条 + n = int(arg) + records = tool_call_tracer.get_recent(n) + elif arg: + # /mcp trace - 特定工具 + records = tool_call_tracer.get_by_tool(arg) + else: + # /mcp trace - 最近 10 条 + records = tool_call_tracer.get_recent(10) + + if not records: + await self.send_text("🔍 暂无调用追踪记录\n\n用法: /mcp trace [数量|工具名]") + return (True, None, True) + + lines = [f"🔍 调用追踪记录 ({len(records)} 条)"] + lines.append("-" * 30) + for i, r in enumerate(reversed(records)): + status_icon = "✅" if r.success else "❌" + cache_tag = " [缓存]" if r.cache_hit else "" + post_tag = " [后处理]" if r.post_processed else "" + ts = time.strftime("%H:%M:%S", time.localtime(r.timestamp)) + lines.append(f"{status_icon} [{ts}] {r.tool_name}") + lines.append(f" {r.duration_ms:.0f}ms | {r.server_name}{cache_tag}{post_tag}") + if r.error: + lines.append(f" 错误: {r.error[:50]}") + if i < len(records) - 1: + lines.append("") + + await self.send_text("\n".join(lines)) + return (True, None, True) + + async def _handle_cache(self, arg: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """v1.4.0: 处理缓存命令""" + if arg == "clear": + tool_call_cache.clear() + await self.send_text("✅ 缓存已清空") + return (True, None, True) + + stats = tool_call_cache.get_stats() + lines = ["🗄️ 缓存状态"] + lines.append(f"├ 启用: {'是' if stats['enabled'] else '否'}") + lines.append(f"├ 条目: {stats['entries']}/{stats['max_entries']}") + lines.append(f"├ TTL: {stats['ttl']}秒") + lines.append(f"├ 命中: {stats['hits']}") + lines.append(f"├ 未命中: {stats['misses']}") + lines.append(f"└ 命中率: {stats['hit_rate']}") + + await self.send_text("\n".join(lines)) + return (True, None, True) + + async def _handle_perm(self, arg: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """v1.4.0: 处理权限命令""" + global _plugin_instance + + if _plugin_instance is None: + await self.send_text("❌ 插件未初始化") + return (True, None, True) + + perm_config = _plugin_instance.config.get("permissions", {}) + enabled = perm_config.get("perm_enabled", False) + default_mode = perm_config.get("perm_default_mode", "allow_all") + + if arg: + # 查看特定工具的权限 + rules = permission_checker.get_rules_for_tool(arg) + if not rules: + await self.send_text(f"🔐 工具 {arg} 无特定权限规则\n默认模式: {default_mode}") + else: + lines = [f"🔐 工具 {arg} 的权限规则:"] + for r in rules: + lines.append(f" • 模式: {r.get('mode', 'default')}") + if r.get("allowed"): + lines.append(f" 允许: {', '.join(r['allowed'][:3])}...") + if r.get("denied"): + lines.append(f" 拒绝: {', '.join(r['denied'][:3])}...") + await self.send_text("\n".join(lines)) + else: + # 查看权限配置概览 + lines = ["🔐 权限控制配置"] + lines.append(f"├ 启用: {'是' if enabled else '否'}") + lines.append(f"├ 默认模式: {default_mode}") + # 快捷配置 + deny_count = len(permission_checker._quick_deny_groups) + allow_count = len(permission_checker._quick_allow_users) + if deny_count > 0: + lines.append(f"├ 禁用群: {deny_count} 个") + if allow_count > 0: + lines.append(f"├ 管理员白名单: {allow_count} 人") + lines.append(f"└ 高级规则: {len(permission_checker._rules)} 条") + await self.send_text("\n".join(lines)) + + return (True, None, True) + + async def _handle_export(self, format_type: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """v1.6.0: 处理导出命令""" + global _plugin_instance + + if _plugin_instance is None: + await self.send_text("❌ 插件未初始化") + return (True, None, True) + + servers_section = _plugin_instance.config.get("servers", {}) + if not isinstance(servers_section, dict): + servers_section = {} + + claude_json = str(servers_section.get("claude_config_json", "") or "") + if not claude_json.strip(): + legacy_list = str(servers_section.get("list", "") or "") + claude_json = legacy_servers_list_to_claude_config(legacy_list) or "" + + if not claude_json.strip(): + await self.send_text("📤 当前没有配置任何服务器") + return (True, None, True) + + try: + pretty = json.dumps(json.loads(claude_json), ensure_ascii=False, indent=2) + except Exception: + pretty = claude_json + + lines = ["📤 导出为 Claude Desktop 格式(mcpServers):"] + if format_type and format_type.strip() and format_type.strip().lower() != "claude": + lines.append("(v2.0 已精简为仅 Claude 格式,忽略其他格式参数)") + lines.append("") + lines.append(pretty) + await self.send_text("\n".join(lines)) + + return (True, None, True) + + async def _handle_search(self, query: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """v1.7.0: 处理工具搜索命令""" + if not query or not query.strip(): + # 显示使用帮助 + help_text = """🔍 工具搜索 + +用法: /mcp search <关键词> + +示例: + /mcp search time 搜索包含 time 的工具 + /mcp search fetch 搜索包含 fetch 的工具 + /mcp search * 列出所有工具 + +支持模糊匹配工具名称和描述""" + await self.send_text(help_text) + return (True, None, True) + + query = query.strip().lower() + tools = mcp_manager.all_tools + + if not tools: + await self.send_text("🔍 当前没有可用的 MCP 工具") + return (True, None, True) + + # 搜索匹配的工具 + matched = [] + for tool_key, (tool_info, client) in tools.items(): + tool_name = tool_key.lower() + tool_desc = (tool_info.description or "").lower() + + # * 表示列出所有 + if query == "*": + matched.append((tool_key, tool_info, client)) + elif query in tool_name or query in tool_desc: + matched.append((tool_key, tool_info, client)) + + if not matched: + await self.send_text(f"🔍 未找到匹配 '{query}' 的工具") + return (True, None, True) + + # 按服务器分组显示 + by_server: Dict[str, List[Tuple[str, Any]]] = {} + for tool_key, tool_info, client in matched: + server_name = tool_info.server_name + if server_name not in by_server: + by_server[server_name] = [] + by_server[server_name].append((tool_key, tool_info)) + + # 如果只有一个服务器或结果较少,显示全部;否则折叠 + single_server = len(by_server) == 1 + lines = [f"🔍 搜索结果: {len(matched)} 个工具匹配 '{query}'"] + + for srv_name, tool_list in by_server.items(): + lines.append(f"\n📦 {srv_name} ({len(tool_list)} 个):") + + # 单服务器或结果少于 15 个时显示全部 + show_all = single_server or len(matched) <= 15 + display_limit = len(tool_list) if show_all else 5 + + for tool_key, tool_info in tool_list[:display_limit]: + desc = tool_info.description[:40] + "..." if len(tool_info.description) > 40 else tool_info.description + lines.append(f" • {tool_key}") + lines.append(f" {desc}") + if len(tool_list) > display_limit: + lines.append(f" ... 还有 {len(tool_list) - display_limit} 个,用 /mcp search {query} {srv_name} 筛选") + + await self.send_text("\n".join(lines)) + return (True, None, True) + + async def _handle_chain(self, arg: Optional[str] = None) -> Tuple[bool, Optional[str], bool]: + """v1.8.0: 处理工具链命令""" + if not arg or not arg.strip(): + # 显示工具链列表和帮助 + chains = tool_chain_manager.get_all_chains() + + lines = ["🔗 工具链管理"] + lines.append("") + + if chains: + lines.append(f"已配置 {len(chains)} 个工具链:") + for name, chain in chains.items(): + status = "✅" if chain.enabled else "❌" + steps_count = len(chain.steps) + lines.append(f" {status} {name} ({steps_count} 步)") + else: + lines.append("当前没有配置工具链") + + lines.append("") + lines.append("命令:") + lines.append(" /mcp chain list 查看所有工具链") + lines.append(" /mcp chain <名称> 查看工具链详情") + lines.append(" /mcp chain test <名称> <参数JSON> 测试执行") + lines.append(" /mcp chain reload 重新加载配置") + lines.append("") + lines.append("💡 在 WebUI「工具链」配置区编辑工具链") + + await self.send_text("\n".join(lines)) + return (True, None, True) + + parts = arg.strip().split(maxsplit=2) + sub_action = parts[0].lower() + + if sub_action == "list": + # 列出所有工具链 + chains = tool_chain_manager.get_all_chains() + if not chains: + await self.send_text("🔗 当前没有配置工具链") + return (True, None, True) + + lines = [f"🔗 工具链列表 ({len(chains)} 个)"] + for name, chain in chains.items(): + status = "✅" if chain.enabled else "❌" + lines.append(f"\n{status} {name}") + lines.append(f" {chain.description[:60]}...") + lines.append(f" 步骤: {' → '.join([s.tool_name.split('_')[-1] for s in chain.steps[:4]])}") + if chain.input_params: + lines.append(f" 参数: {', '.join(chain.input_params.keys())}") + + await self.send_text("\n".join(lines)) + return (True, None, True) + + elif sub_action == "reload": + # 重新加载工具链配置 + global _plugin_instance + if _plugin_instance: + _plugin_instance._load_tool_chains() + chains = tool_chain_manager.get_all_chains() + from src.plugin_system.core.component_registry import component_registry + registered = 0 + for name, chain in tool_chain_manager.get_enabled_chains().items(): + tool_name = f"chain_{name}".replace("-", "_").replace(".", "_") + if component_registry.get_component_info(tool_name, ComponentType.TOOL): + registered += 1 + lines = [f"✅ 已重新加载工具链配置"] + lines.append(f"📋 配置数: {len(chains)} 个") + lines.append(f"🔧 已注册: {registered} 个(可被 LLM 调用)") + if chains: + lines.append("") + lines.append("工具链列表:") + for name, chain in chains.items(): + status = "✅" if chain.enabled else "❌" + lines.append(f" {status} chain_{name}") + await self.send_text("\n".join(lines)) + else: + await self.send_text("❌ 插件未初始化") + return (True, None, True) + + elif sub_action == "test" and len(parts) >= 2: + # 测试执行工具链 + chain_name = parts[1] + args_json = parts[2] if len(parts) > 2 else "{}" + + chain = tool_chain_manager.get_chain(chain_name) + if not chain: + await self.send_text(f"❌ 工具链 '{chain_name}' 不存在") + return (True, None, True) + + try: + input_args = json.loads(args_json) + except json.JSONDecodeError: + await self.send_text("❌ 参数 JSON 格式错误") + return (True, None, True) + + await self.send_text(f"🔄 正在执行工具链 {chain_name}...") + + result = await tool_chain_manager.execute_chain(chain_name, input_args) + + lines = [] + if result.success: + lines.append(f"✅ 工具链执行成功 ({result.total_duration_ms:.0f}ms)") + lines.append("") + lines.append("执行详情:") + lines.append(result.to_summary()) + lines.append("") + lines.append("最终输出:") + output_preview = result.final_output[:500] + if len(result.final_output) > 500: + output_preview += "..." + lines.append(output_preview) + else: + lines.append(f"❌ 工具链执行失败") + lines.append(f"错误: {result.error}") + if result.step_results: + lines.append("") + lines.append("执行详情:") + lines.append(result.to_summary()) + + await self.send_text("\n".join(lines)) + return (True, None, True) + + else: + # 查看特定工具链详情 + chain_name = sub_action + chain = tool_chain_manager.get_chain(chain_name) + + if not chain: + # 尝试模糊匹配 + all_chains = tool_chain_manager.get_all_chains() + similar = [n for n in all_chains.keys() if chain_name.lower() in n.lower()] + msg = f"❌ 工具链 '{chain_name}' 不存在" + if similar: + msg += f"\n💡 你是不是想找: {', '.join(similar[:3])}" + await self.send_text(msg) + return (True, None, True) + + lines = [f"🔗 工具链: {chain.name}"] + lines.append(f"状态: {'✅ 启用' if chain.enabled else '❌ 禁用'}") + lines.append(f"描述: {chain.description}") + lines.append("") + + if chain.input_params: + lines.append("📥 输入参数:") + for param, desc in chain.input_params.items(): + lines.append(f" • {param}: {desc}") + lines.append("") + + lines.append(f"📋 执行步骤 ({len(chain.steps)} 个):") + for i, step in enumerate(chain.steps): + optional_tag = " (可选)" if step.optional else "" + lines.append(f" {i+1}. {step.tool_name}{optional_tag}") + if step.description: + lines.append(f" {step.description}") + if step.output_key: + lines.append(f" 输出键: {step.output_key}") + if step.args_template: + args_preview = json.dumps(step.args_template, ensure_ascii=False)[:60] + lines.append(f" 参数: {args_preview}...") + + lines.append("") + lines.append(f"💡 测试: /mcp chain test {chain.name} " + '{"参数": "值"}') + + await self.send_text("\n".join(lines)) + return (True, None, True) + + def _format_output(self, subcommand: str, server_name: str = None) -> str: + """格式化输出""" + status = mcp_manager.get_status() + stats = mcp_manager.get_all_stats() + lines = [] + + if subcommand in ("status", "all"): + lines.append("📊 MCP 桥接插件状态") + lines.append(f"├ 服务器: {status['connected_servers']}/{status['total_servers']} 已连接") + lines.append(f"├ 工具数: {status['total_tools']}") + lines.append(f"└ 心跳: {'运行中' if status['heartbeat_running'] else '已停止'}") + + if status["servers"]: + lines.append("\n🔌 服务器列表:") + for name, info in status["servers"].items(): + if server_name and name != server_name: + continue + icon = "✅" if info["connected"] else "❌" + enabled = "" if info["enabled"] else " (禁用)" + lines.append(f" {icon} {name}{enabled}") + lines.append(f" {info['transport']} | {info['tools_count']} 工具") + # 显示断路器状态 + cb = info.get("circuit_breaker", {}) + cb_state = cb.get("state", "closed") + if cb_state == "open": + lines.append(f" ⚡ 断路器熔断中") + elif cb_state == "half_open": + lines.append(f" ⚡ 断路器试探中") + if info["consecutive_failures"] > 0: + lines.append(f" ⚠️ 连续失败 {info['consecutive_failures']} 次") + + if subcommand in ("tools", "all"): + tools = mcp_manager.all_tools + if tools: + lines.append("\n🔧 可用工具:") + by_server = {} + for key, (info, _) in tools.items(): + if server_name and info.server_name != server_name: + continue + by_server.setdefault(info.server_name, []).append(info.name) + + # 如果指定了服务器名,显示全部工具;否则折叠显示 + show_all = server_name is not None + + for srv, tool_list in by_server.items(): + lines.append(f" 📦 {srv} ({len(tool_list)})") + if show_all: + # 指定服务器时显示全部 + for t in tool_list: + lines.append(f" • {t}") + else: + # 未指定时折叠显示 + for t in tool_list[:5]: + lines.append(f" • {t}") + if len(tool_list) > 5: + lines.append(f" ... 还有 {len(tool_list) - 5} 个,用 /mcp tools {srv} 查看全部") + + if subcommand in ("stats", "all"): + g = stats["global"] + lines.append("\n📈 调用统计:") + lines.append(f" 总调用: {g['total_tool_calls']}") + if g["total_tool_calls"] > 0: + rate = (g["successful_calls"] / g["total_tool_calls"]) * 100 + lines.append(f" 成功率: {rate:.1f}%") + lines.append(f" 运行: {g['uptime_seconds']:.0f}秒") + + if not lines: + lines.append("📖 MCP 桥接插件命令帮助") + lines.append("") + lines.append("状态查询:") + lines.append(" /mcp 查看连接状态") + lines.append(" /mcp tools 查看所有工具") + lines.append(" /mcp tools <服务器> 查看指定服务器工具") + lines.append(" /mcp stats 查看调用统计") + lines.append("") + lines.append("工具搜索:") + lines.append(" /mcp search <关键词> 搜索工具") + lines.append(" /mcp search * 列出所有工具") + lines.append("") + lines.append("服务器管理:") + lines.append(" /mcp reconnect 重连断开的服务器") + lines.append(" /mcp reconnect <名称> 重连指定服务器") + lines.append("") + lines.append("服务器配置(Claude):") + lines.append(" /mcp import 合并 Claude mcpServers 配置") + lines.append(" /mcp export 导出当前 mcpServers 配置") + lines.append("") + lines.append("工具链:") + lines.append(" /mcp chain 查看工具链列表") + lines.append(" /mcp chain <名称> 查看工具链详情") + lines.append(" /mcp chain test <名称> <参数> 测试执行") + lines.append("") + lines.append("其他:") + lines.append(" /mcp trace 查看调用追踪") + lines.append(" /mcp cache 查看缓存状态") + lines.append(" /mcp perm 查看权限配置") + + return "\n".join(lines) + + +class MCPImportCommand(BaseCommand): + """v1.6.0: MCP 配置导入命令 - 支持从 Claude Desktop 格式导入""" + + command_name = "mcp_import_command" + command_description = "从 Claude Desktop 或其他格式导入 MCP 服务器配置" + # 匹配 /mcp import 后面的所有内容(包括多行 JSON) + command_pattern = r"^[//]mcp\s+import(?:\s+(?P.+))?$" + + async def execute(self) -> Tuple[bool, Optional[str], bool]: + """执行导入命令""" + global _plugin_instance + + if _plugin_instance is None: + await self.send_text("❌ 插件未初始化") + return (True, None, True) + + content = self.matched_groups.get("content", "") + + if not content or not content.strip(): + # 显示使用帮助 + help_text = """📥 MCP 配置导入 + +用法: /mcp import + +支持的格式: +• Claude Desktop 格式 (mcpServers 对象) +• 兼容旧版:MaiBot servers 列表数组(将自动迁移为 mcpServers) + +示例: +/mcp import {"mcpServers":{"time":{"command":"uvx","args":["mcp-server-time"]}}} + +/mcp import {"mcpServers":{"api":{"url":"https://example.com/mcp","transport":"sse"}}}""" + await self.send_text(help_text) + return (True, None, True) + + raw_text = content.strip() + + # 解析输入:支持 Claude mcpServers 或旧版 servers 列表数组 + try: + data = json.loads(raw_text) + except json.JSONDecodeError as e: + await self.send_text(f"❌ JSON 解析失败: {e}") + return (True, None, True) + + if isinstance(data, list): + migrated = legacy_servers_list_to_claude_config(raw_text) + if not migrated: + await self.send_text("❌ 旧版 servers 列表解析失败,无法迁移") + return (True, None, True) + data = json.loads(migrated) + + if not isinstance(data, dict): + await self.send_text("❌ 配置必须是 JSON 对象(包含 mcpServers)") + return (True, None, True) + + incoming_mapping = data.get("mcpServers", data) + if not isinstance(incoming_mapping, dict): + await self.send_text("❌ mcpServers 必须是 JSON 对象") + return (True, None, True) + + # 校验输入配置 + try: + parse_claude_mcp_config(json.dumps({"mcpServers": incoming_mapping}, ensure_ascii=False)) + except ClaudeConfigError as e: + await self.send_text(f"❌ 配置校验失败: {e}") + return (True, None, True) + + servers_section = _plugin_instance.config.get("servers", {}) + if not isinstance(servers_section, dict): + servers_section = {} + + existing_json = str(servers_section.get("claude_config_json", "") or "") + if not existing_json.strip(): + legacy_list = str(servers_section.get("list", "") or "") + existing_json = legacy_servers_list_to_claude_config(legacy_list) or "" + + existing_mapping: Dict[str, Any] = {} + if existing_json.strip(): + try: + parsed = json.loads(existing_json) + mapping = parsed.get("mcpServers", parsed) + if isinstance(mapping, dict): + existing_mapping = mapping + except Exception: + existing_mapping = {} + + added: List[str] = [] + skipped: List[str] = [] + + for name, conf in incoming_mapping.items(): + if name in existing_mapping: + skipped.append(str(name)) + continue + existing_mapping[str(name)] = conf + added.append(str(name)) + + if "servers" not in _plugin_instance.config: + _plugin_instance.config["servers"] = {} + + _plugin_instance.config["servers"]["claude_config_json"] = json.dumps( + {"mcpServers": existing_mapping}, ensure_ascii=False, indent=2 + ) + + # 持久化到配置文件(使用插件基类的写入逻辑) + try: + config_path = Path(_plugin_instance.plugin_dir) / _plugin_instance.config_file_name + _plugin_instance._save_config_to_file(_plugin_instance.config, str(config_path)) + except Exception as e: + logger.warning(f"保存配置文件失败: {e}") + + lines = [] + if added: + lines.append(f"✅ 成功导入 {len(added)} 个服务器:") + for n in added[:20]: + lines.append(f" • {n}") + if len(added) > 20: + lines.append(f" ... 还有 {len(added) - 20} 个") + else: + lines.append("⚠️ 没有新服务器可导入") + + if skipped: + lines.append(f"\n⏭️ 跳过 {len(skipped)} 个已存在的服务器") + + lines.append("\n💡 发送 /mcp reconnect 使配置生效") + + await self.send_text("\n".join(lines)) + return (True, None, True) + + +# ============================================================================ +# 事件处理器 +# ============================================================================ + +class MCPStartupHandler(BaseEventHandler): + """MCP 启动事件处理器""" + + event_type = EventType.ON_START + handler_name = "mcp_startup_handler" + handler_description = "MCP 桥接插件启动处理器" + weight = 0 + intercept_message = False + + async def execute(self, message: Optional[Any]) -> Tuple[bool, bool, Optional[str], None, None]: + """处理启动事件""" + global _plugin_instance + + if _plugin_instance is None: + logger.warning("MCP 桥接插件实例未初始化") + return (False, True, None, None, None) + + logger.info("MCP 桥接插件收到 ON_START 事件,开始连接 MCP 服务器...") + await _plugin_instance._async_connect_servers() + + await mcp_manager.start_heartbeat() + + return (True, True, None, None, None) + + +class MCPStopHandler(BaseEventHandler): + """MCP 停止事件处理器""" + + event_type = EventType.ON_STOP + handler_name = "mcp_stop_handler" + handler_description = "MCP 桥接插件停止处理器" + weight = 0 + intercept_message = False + + async def execute(self, message: Optional[Any]) -> Tuple[bool, bool, Optional[str], None, None]: + """处理停止事件""" + global _plugin_instance + + logger.info("MCP 桥接插件收到 ON_STOP 事件,正在关闭...") + + if _plugin_instance is not None: + await _plugin_instance._stop_status_refresher() + + await mcp_manager.shutdown() + mcp_tool_registry.clear() + + logger.info("MCP 桥接插件已关闭所有连接") + return (True, True, None, None, None) + + +# ============================================================================ +# 主插件类 +# ============================================================================ + +@register_plugin +class MCPBridgePlugin(BasePlugin): + """MCP 桥接插件 v2.0.0 - 将 MCP 服务器的工具桥接到 MaiBot""" + + plugin_name: str = "mcp_bridge_plugin" + enable_plugin: bool = False # 默认禁用,用户需在 WebUI 手动启用 + dependencies: List[str] = [] + python_dependencies: List[str] = ["mcp"] + config_file_name: str = "config.toml" + + config_section_descriptions = { + "guide": section_meta("📖 快速入门", order=1), + "plugin": section_meta("🔘 插件开关", order=2), + "servers": section_meta("🔌 MCP Servers(Claude)", order=3), + "tool_chains": section_meta("🔗 Workflow(硬流程/工具链)", order=4), + "react": section_meta("🔄 ReAct(软流程)", collapsed=True, order=5), + "status": section_meta("📊 运行状态", order=10), + "tools": section_meta("🔧 工具管理", collapsed=True, order=20), + "permissions": section_meta("🔐 权限控制", collapsed=True, order=21), + "settings": section_meta("⚙️ 高级设置", collapsed=True, order=30), + } + + config_schema: dict = { + # 新手引导区(只读) + "guide": { + "quick_start": ConfigField( + type=str, + default="1. 获取 MCP 服务器 2. 在「MCP Servers(Claude)」粘贴 mcpServers 配置 3. 保存后发送 /mcp reconnect 4. (可选)在「Workflow/ ReAct」配置流程", + description="三步开始使用", + label="🚀 快速入门", + disabled=True, + order=1, + ), + "mcp_sources": ConfigField( + type=str, + default="https://modelscope.cn/mcp (魔搭·推荐) | https://smithery.ai | https://glama.ai | https://mcp.so", + description="复制链接到浏览器打开,获取免费 MCP 服务器", + label="🌐 获取 MCP 服务器", + disabled=True, + hint="魔搭 ModelScope 国内免费推荐,将 mcpServers 配置粘贴到「MCP Servers(Claude)」即可", + order=2, + ), + "example_config": ConfigField( + type=str, + default='{"mcpServers":{"time":{"url":"https://mcp.api-inference.modelscope.cn/server/mcp-server-time"}}}', + description="复制到 MCP Servers(Claude)可直接使用(免费时间服务器)", + label="📝 配置示例", + disabled=True, + order=3, + ), + }, + "plugin": { + "enabled": ConfigField( + type=bool, + default=False, + description="是否启用插件(默认关闭)", + label="启用插件", + ), + }, + "settings": { + "tool_prefix": ConfigField( + type=str, + default="mcp", + description="🏷️ 工具前缀 - 生成的工具名格式: {前缀}_{服务器名}_{工具名}", + label="🏷️ 工具前缀", + placeholder="mcp", + order=1, + ), + "connect_timeout": ConfigField( + type=float, + default=30.0, + description="⏱️ 连接超时(秒)", + label="⏱️ 连接超时(秒)", + min=5.0, + max=120.0, + step=5.0, + order=2, + ), + "call_timeout": ConfigField( + type=float, + default=60.0, + description="⏱️ 调用超时(秒)", + label="⏱️ 调用超时(秒)", + min=10.0, + max=300.0, + step=10.0, + order=3, + ), + "auto_connect": ConfigField( + type=bool, + default=True, + description="🔄 启动时自动连接所有已启用的服务器", + label="🔄 自动连接", + order=4, + ), + "retry_attempts": ConfigField( + type=int, + default=3, + description="🔁 连接失败时的重试次数", + label="🔁 重试次数", + min=0, + max=10, + order=5, + ), + "retry_interval": ConfigField( + type=float, + default=5.0, + description="⏳ 重试间隔(秒)", + label="⏳ 重试间隔(秒)", + min=1.0, + max=60.0, + step=1.0, + order=6, + ), + "heartbeat_enabled": ConfigField( + type=bool, + default=True, + description="💓 定期检测服务器连接状态", + label="💓 启用心跳检测", + order=7, + ), + "heartbeat_interval": ConfigField( + type=float, + default=60.0, + description="💓 基准心跳间隔(秒)", + label="💓 心跳间隔(秒)", + min=10.0, + max=300.0, + step=10.0, + hint="智能心跳会根据服务器稳定性自动调整", + order=8, + ), + "heartbeat_adaptive": ConfigField( + type=bool, + default=True, + description="🧠 根据服务器稳定性自动调整心跳间隔", + label="🧠 智能心跳", + hint="稳定服务器逐渐增加间隔,断开的服务器缩短间隔", + order=9, + ), + "heartbeat_max_multiplier": ConfigField( + type=float, + default=3.0, + description="稳定服务器的最大间隔倍数", + label="📈 最大间隔倍数", + min=1.5, + max=5.0, + step=0.5, + hint="稳定服务器心跳间隔最高可达 基准间隔 × 此值", + order=10, + ), + "auto_reconnect": ConfigField( + type=bool, + default=True, + description="🔄 检测到断开时自动尝试重连", + label="🔄 自动重连", + order=11, + ), + "max_reconnect_attempts": ConfigField( + type=int, + default=3, + description="🔄 连续重连失败后暂停重连", + label="🔄 最大重连次数", + min=1, + max=10, + order=12, + ), + # v1.7.0: 状态刷新配置 + "status_refresh_enabled": ConfigField( + type=bool, + default=True, + description="📊 定期更新 WebUI 状态显示", + label="📊 启用状态实时刷新", + hint="关闭后 WebUI 状态仅在启动时更新", + order=13, + ), + "status_refresh_interval": ConfigField( + type=float, + default=10.0, + description="📊 状态刷新间隔(秒)", + label="📊 状态刷新间隔(秒)", + min=5.0, + max=60.0, + step=5.0, + hint="值越小刷新越频繁,但会增加少量 CPU 消耗", + order=14, + ), + "enable_resources": ConfigField( + type=bool, + default=False, + description="📦 允许读取 MCP 服务器提供的资源", + label="📦 启用 Resources(实验性)", + order=11, + ), + "enable_prompts": ConfigField( + type=bool, + default=False, + description="📝 允许使用 MCP 服务器提供的提示模板", + label="📝 启用 Prompts(实验性)", + order=12, + ), + # v1.3.0 后处理配置 + "post_process_enabled": ConfigField( + type=bool, + default=False, + description="🔄 使用 LLM 对长结果进行摘要提炼", + label="🔄 启用结果后处理", + order=20, + ), + "post_process_threshold": ConfigField( + type=int, + default=500, + description="📏 结果长度超过此值才触发后处理", + label="📏 后处理阈值(字符)", + min=100, + max=5000, + step=100, + order=21, + ), + "post_process_max_tokens": ConfigField( + type=int, + default=500, + description="📝 LLM 摘要输出的最大 token 数", + label="📝 后处理最大输出 token", + min=100, + max=2000, + step=50, + order=22, + ), + "post_process_model": ConfigField( + type=str, + default="", + description="🤖 指定用于后处理的模型名称", + label="🤖 后处理模型(可选)", + placeholder="留空则使用 Utils 模型组", + order=23, + ), + "post_process_prompt": ConfigField( + type=str, + default="用户问题:{query}\\n\\n工具返回内容:\\n{result}\\n\\n请从上述内容中提取与用户问题最相关的关键信息,简洁准确地输出:", + description="📋 后处理提示词模板", + label="📋 后处理提示词模板", + input_type="textarea", + rows=8, + order=24, + ), + # v1.4.0 追踪配置 + "trace_enabled": ConfigField( + type=bool, + default=True, + description="🔍 记录工具调用详情", + label="🔍 启用调用追踪", + order=30, + ), + "trace_max_records": ConfigField( + type=int, + default=100, + description="内存中保留的最大记录数", + label="📊 追踪记录上限", + min=10, + max=1000, + order=31, + ), + "trace_log_enabled": ConfigField( + type=bool, + default=False, + description="是否将追踪记录写入日志文件", + label="📝 追踪日志文件", + hint="启用后记录写入 plugins/MaiBot_MCPBridgePlugin/logs/trace.jsonl", + order=32, + ), + # v1.4.0 缓存配置 + "cache_enabled": ConfigField( + type=bool, + default=False, + description="🗄️ 缓存相同参数的调用结果", + label="🗄️ 启用调用缓存", + hint="相同参数的调用会返回缓存结果,减少重复请求", + order=40, + ), + "cache_ttl": ConfigField( + type=int, + default=300, + description="缓存有效期(秒)", + label="⏱️ 缓存有效期(秒)", + min=60, + max=3600, + order=41, + ), + "cache_max_entries": ConfigField( + type=int, + default=200, + description="最大缓存条目数(超出后 LRU 淘汰)", + label="📦 最大缓存条目", + min=50, + max=1000, + order=42, + ), + "cache_exclude_tools": ConfigField( + type=str, + default="", + description="不缓存的工具(每行一个,支持通配符 *)", + label="🚫 缓存排除列表", + input_type="textarea", + rows=4, + hint="时间类、随机类工具建议排除,如 mcp_time_*", + order=43, + ), + }, + # v1.4.0 工具管理 + "tools": { + "tool_list": ConfigField( + type=str, + default="(启动后自动生成)", + description="当前已注册的 MCP 工具列表(只读)", + label="📋 工具清单", + input_type="textarea", + disabled=True, + rows=12, + hint="从此处复制工具名到下方禁用列表或工具链配置", + order=1, + ), + "disabled_tools": ConfigField( + type=str, + default="", + description="要禁用的工具名(每行一个)", + label="🚫 禁用工具列表", + input_type="textarea", + rows=6, + hint="从上方工具清单复制工具名,每行一个。禁用后该工具不会被 LLM 调用", + order=2, + ), + }, + # v1.8.0 工具链配置 + "tool_chains": { + "chains_enabled": ConfigField( + type=bool, + default=True, + description="🔗 启用工具链功能", + label="🔗 启用工具链", + hint="工具链可将多个工具按顺序执行,后续工具可使用前序工具的输出", + order=1, + ), + # 工具链使用指南 + "chains_guide": ConfigField( + type=str, + default="""工具链将多个 MCP 工具串联执行,后续步骤可使用前序步骤的输出 + +📌 变量语法: + ${input.参数名} - 用户输入的参数 + ${step.输出键} - 某步骤的输出(需设置 output_key) + ${prev} - 上一步的输出 + ${prev.字段} - 上一步输出(JSON)的某字段 + ${step.输出键.0.字段} / ${step.输出键[0].字段} - 访问数组下标 + ${step.输出键['return'][0]['location']} - 支持 bracket 写法 + +📌 测试命令: + /mcp chain list - 查看所有工具链 + /mcp chain 链名 {"参数":"值"} - 测试执行""", + description="工具链使用说明", + label="📖 使用指南", + input_type="textarea", + disabled=True, + rows=10, + order=2, + ), + # 快速添加工具链(表单式) + "quick_chain_name": ConfigField( + type=str, + default="", + description="工具链名称(英文,如 search_and_summarize)", + label="➕ 快速添加 - 名称", + placeholder="my_tool_chain", + hint="必填,将作为 LLM 可调用的工具名", + order=10, + ), + "quick_chain_desc": ConfigField( + type=str, + default="", + description="工具链描述(供 LLM 理解何时使用)", + label="➕ 快速添加 - 描述", + placeholder="先搜索内容,再获取详情并总结", + hint="必填,清晰描述工具链的用途", + order=11, + ), + "quick_chain_params": ConfigField( + type=str, + default="", + description="输入参数(每行一个,格式: 参数名=描述)", + label="➕ 快速添加 - 输入参数", + input_type="textarea", + rows=3, + placeholder="query=搜索关键词\nmax_results=最大结果数", + hint="定义用户需要提供的参数", + order=12, + ), + "quick_chain_steps": ConfigField( + type=str, + default="", + description="执行步骤(每行一个,格式: 工具名|参数JSON|输出键)", + label="➕ 快速添加 - 执行步骤", + input_type="textarea", + rows=5, + placeholder='mcp_server_search|{"keyword":"${input.query}"}|search_result\nmcp_server_detail|{"id":"${prev}"}|\n# 访问数组示例:\n# mcp_geo|{"q":"${input.query}"}|geo\n# mcp_next|{"location":"${step.geo.return.0.location}"}|', + hint="格式: 工具名|参数模板|输出键(输出键可选,用于后续步骤引用 ${step.xxx})", + order=13, + ), + "quick_chain_add": ConfigField( + type=str, + default="", + description="填写上方信息后,在此输入 ADD 并保存即可添加", + label="➕ 确认添加", + placeholder="输入 ADD 并保存", + hint="添加后会自动合并到下方工具链列表", + order=14, + ), + # 工具链模板 + "chains_templates": ConfigField( + type=str, + default="""📋 常用工具链模板(复制到下方列表使用): + +1️⃣ 搜索+详情模板: +{ + "name": "search_and_detail", + "description": "搜索内容并获取详情", + "input_params": {"query": "搜索关键词"}, + "steps": [ + {"tool_name": "搜索工具名", "args_template": {"keyword": "${input.query}"}, "output_key": "results"}, + {"tool_name": "详情工具名", "args_template": {"id": "${prev}"}} + ] +} + +2️⃣ 获取+处理模板: +{ + "name": "fetch_and_process", + "description": "获取数据并处理", + "input_params": {"url": "目标URL"}, + "steps": [ + {"tool_name": "获取工具名", "args_template": {"url": "${input.url}"}, "output_key": "data"}, + {"tool_name": "处理工具名", "args_template": {"content": "${step.data}"}} + ] +} + +3️⃣ 多步骤可选模板: +{ + "name": "multi_step_chain", + "description": "多步骤处理,部分可选", + "input_params": {"input": "输入内容"}, + "steps": [ + {"tool_name": "步骤1工具", "args_template": {"data": "${input.input}"}, "output_key": "step1"}, + {"tool_name": "步骤2工具", "args_template": {"data": "${prev}"}, "output_key": "step2", "optional": true}, + {"tool_name": "步骤3工具", "args_template": {"data": "${step.step1}"}} + ] +}""", + description="工具链配置模板参考", + label="📝 配置模板", + input_type="textarea", + disabled=True, + rows=15, + order=20, + ), + "chains_list": ConfigField( + type=str, + default="[]", + description="工具链配置(JSON 数组格式)", + label="📋 工具链列表", + input_type="textarea", + rows=20, + placeholder='''[ + { + "name": "search_and_detail", + "description": "先搜索再获取详情", + "input_params": {"query": "搜索关键词"}, + "steps": [ + {"tool_name": "mcp_server_search", "args_template": {"keyword": "${input.query}"}, "output_key": "search_result"}, + {"tool_name": "mcp_server_get_detail", "args_template": {"id": "${step.search_result}"}} + ] + } +]''', + hint="每个工具链包含 name、description、input_params、steps", + order=30, + ), + "chains_status": ConfigField( + type=str, + default="(启动后自动生成)", + description="当前已注册的工具链状态(只读)", + label="📊 工具链状态", + input_type="textarea", + disabled=True, + rows=8, + order=40, + ), + }, + # v1.9.0 ReAct 软流程配置 + "react": { + "react_enabled": ConfigField( + type=bool, + default=False, + description="🔄 将 MCP 工具注册到记忆检索 ReAct 系统", + label="🔄 启用 ReAct 集成", + hint="启用后,MaiBot 的 ReAct Agent 可在记忆检索时调用 MCP 工具", + order=1, + ), + "react_guide": ConfigField( + type=str, + default="""ReAct 软流程说明: + +📌 什么是 ReAct? +ReAct (Reasoning + Acting) 是 LLM 自主决策的多轮工具调用模式。 +与 Workflow 硬流程不同,ReAct 由 LLM 动态决定调用哪些工具。 + +📌 工作原理: +1. 用户提问 → LLM 分析需要什么信息 +2. LLM 选择调用工具 → 获取结果 +3. LLM 观察结果 → 决定是否需要更多信息 +4. 重复 2-3 直到信息足够 → 生成最终回答 + +📌 与 Workflow 的区别: +- ReAct (软流程): LLM 自主决策,灵活但不可预测 +- Workflow (硬流程): 用户预定义,固定流程,可靠可控 + +📌 使用场景: +- 复杂问题需要多步推理 +- 不确定需要调用哪些工具 +- 需要根据中间结果动态调整""", + description="ReAct 软流程使用说明", + label="📖 使用指南", + input_type="textarea", + disabled=True, + rows=15, + order=2, + ), + "filter_mode": ConfigField( + type=str, + default="whitelist", + description="过滤模式", + label="📋 过滤模式", + choices=["whitelist", "blacklist"], + hint="whitelist: 只注册列出的工具;blacklist: 排除列出的工具", + order=3, + ), + "tool_filter": ConfigField( + type=str, + default="", + description="工具过滤列表(每行一个,支持通配符 * 和精确匹配)", + label="🔍 工具过滤列表", + input_type="textarea", + rows=6, + placeholder="""# 精确匹配示例: +mcp_bing_web_search_bing_search +mcp_mcmod_search_mod + +# 通配符示例: +mcp_*_search_* +mcp_bing_*""", + hint="白名单模式: 只注册列出的工具;黑名单模式: 排除列出的工具。支持 # 注释", + order=4, + ), + "react_status": ConfigField( + type=str, + default="(启动后自动生成)", + description="当前已注册到 ReAct 的工具状态(只读)", + label="📊 ReAct 工具状态", + input_type="textarea", + disabled=True, + rows=6, + order=10, + ), + }, + # v1.4.0 权限控制 + "permissions": { + "perm_enabled": ConfigField( + type=bool, + default=False, + description="🔐 按群/用户限制工具使用", + label="🔐 启用权限控制", + order=1, + ), + "perm_default_mode": ConfigField( + type=str, + default="allow_all", + description="默认模式:allow_all(默认允许)或 deny_all(默认禁止)", + label="📋 默认模式", + placeholder="allow_all", + hint="allow_all: 未配置的默认允许;deny_all: 未配置的默认禁止", + order=2, + ), + # 快捷配置(简化版) + "quick_deny_groups": ConfigField( + type=str, + default="", + description="禁止使用所有 MCP 工具的群号(每行一个)", + label="🚫 禁用群列表(快捷)", + input_type="textarea", + rows=4, + hint="填入群号,该群将无法使用任何 MCP 工具", + order=3, + ), + "quick_allow_users": ConfigField( + type=str, + default="", + description="始终允许使用所有工具的用户 QQ 号(管理员白名单,每行一个)", + label="✅ 管理员白名单(快捷)", + input_type="textarea", + rows=3, + hint="填入 QQ 号,该用户在任何场景都可使用 MCP 工具", + order=4, + ), + # 高级配置 + "perm_rules": ConfigField( + type=str, + default="[]", + description="高级权限规则(JSON 格式,可针对特定工具配置)", + label="📜 高级权限规则(可选)", + input_type="textarea", + rows=10, + placeholder='''[ + {"tool": "mcp_*_delete_*", "denied": ["qq:123456:group"]} +]''', + hint="格式: qq:ID:group/private/user,工具名支持通配符 *", + order=10, + ), + }, + # v2.0: 服务器配置统一为 Claude Desktop mcpServers 规范(JSON) + "servers": { + "claude_config_json": ConfigField( + type=str, + default='{"mcpServers":{}}', + description="Claude Desktop 规范的 MCP 配置(JSON)", + label="🔌 MCP Servers(Claude 规范)", + input_type="textarea", + rows=18, + hint="仅支持 Claude Desktop 的 mcpServers JSON。每个服务器需包含 command(stdio) 或 url(remote)。", + order=1, + ), + "claude_config_guide": ConfigField( + type=str, + default="""示例: +{ + "mcpServers": { + "fetch": { "command": "uvx", "args": ["mcp-server-fetch"] }, + "time": { "url": "https://mcp.api-inference.modelscope.cn/server/mcp-server-time" } + } +} + +可选字段: +- enabled: true/false +- headers: {"Authorization":"Bearer ..."} +- env: {"KEY":"VALUE"} +- transport/type: "streamable_http" | "http" | "sse"(remote 可选,默认 streamable_http) +""", + description="配置说明(只读)", + label="📖 配置说明", + input_type="textarea", + disabled=True, + rows=12, + order=2, + ), + }, + "status": { + "connection_status": ConfigField( + type=str, + default="未初始化", + description="当前 MCP 服务器连接状态和工具列表", + label="📊 连接状态", + input_type="textarea", + disabled=True, + rows=15, + hint="此状态仅在插件启动时更新。查询实时状态请发送 /mcp 命令", + order=1, + ), + }, + } + + @staticmethod + def _fix_config_multiline_strings(config_path: Path) -> bool: + """修复配置文件中的多行字符串格式问题 + + 处理两种情况: + 1. 带转义 \\n 的单行字符串(json.dumps 生成) + 2. 跨越多行但使用普通双引号的字符串(控制字符错误) + + Returns: + bool: 是否进行了修复 + """ + if not config_path.exists(): + return False + + try: + content = config_path.read_text(encoding="utf-8") + + # 情况1: 修复带转义 \n 的单行字符串 + # 匹配: key = "内容包含\n的字符串" + pattern1 = r'^(\s*\w+\s*=\s*)"((?:[^"\\]|\\.)*\\n(?:[^"\\]|\\.)*)"(\s*)$' + + # 情况2: 修复跨越多行的普通双引号字符串 + # 匹配: key = "第一行 + # 第二行 + # 第三行" + pattern2_start = r'^(\s*\w+\s*=\s*)"([^"]*?)$' # 开始行 + pattern2_end = r'^([^"]*)"(\s*)$' # 结束行 + + lines = content.split("\n") + fixed_lines = [] + modified = False + + i = 0 + while i < len(lines): + line = lines[i] + + # 情况1: 单行带转义换行符 + match1 = re.match(pattern1, line) + if match1: + prefix = match1.group(1) + value = match1.group(2) + suffix = match1.group(3) + # 将转义的换行符还原为实际换行符 + unescaped = value.replace("\\n", "\n").replace("\\t", "\t").replace('\\"', '"').replace("\\\\", "\\") + fixed_line = f'{prefix}"""{unescaped}"""{suffix}' + fixed_lines.append(fixed_line) + modified = True + i += 1 + continue + + # 情况2: 跨越多行的字符串 + match2_start = re.match(pattern2_start, line) + if match2_start: + prefix = match2_start.group(1) + first_part = match2_start.group(2) + + # 收集后续行直到找到结束引号 + multiline_parts = [first_part] + j = i + 1 + found_end = False + + while j < len(lines): + next_line = lines[j] + match2_end = re.match(pattern2_end, next_line) + if match2_end: + multiline_parts.append(match2_end.group(1)) + suffix = match2_end.group(2) + found_end = True + j += 1 + break + else: + multiline_parts.append(next_line) + j += 1 + + if found_end and len(multiline_parts) > 1: + # 合并为三引号字符串 + full_value = "\n".join(multiline_parts) + fixed_line = f'{prefix}"""{full_value}"""{suffix}' + fixed_lines.append(fixed_line) + modified = True + i = j + continue + + fixed_lines.append(line) + i += 1 + + if modified: + config_path.write_text("\n".join(fixed_lines), encoding="utf-8") + logger.info("已自动修复配置文件中的多行字符串格式") + return True + + return False + except Exception as e: + logger.warning(f"修复配置文件格式失败: {e}") + return False + + def __init__(self, *args, **kwargs): + global _plugin_instance + + # 在父类初始化前尝试修复配置文件格式 + config_path = Path(__file__).parent / "config.toml" + self._fix_config_multiline_strings(config_path) + + super().__init__(*args, **kwargs) + self._initialized = False + self._status_refresh_running = False + self._status_refresh_task: Optional[asyncio.Task] = None + self._last_persisted_display_hash: str = "" + self._last_servers_config_error: str = "" + _plugin_instance = self + + # 配置 MCP 管理器 + settings = self.config.get("settings", {}) + mcp_manager.configure(settings) + + # v1.4.0: 配置追踪器 + trace_log_path = Path(__file__).parent / "logs" / "trace.jsonl" + tool_call_tracer.configure( + enabled=settings.get("trace_enabled", True), + max_records=settings.get("trace_max_records", 100), + log_enabled=settings.get("trace_log_enabled", False), + log_path=trace_log_path, + ) + + # v1.4.0: 配置缓存 + tool_call_cache.configure( + enabled=settings.get("cache_enabled", False), + ttl=settings.get("cache_ttl", 300), + max_entries=settings.get("cache_max_entries", 200), + exclude_tools=settings.get("cache_exclude_tools", ""), + ) + + # v1.4.0: 配置权限检查器 + perm_config = self.config.get("permissions", {}) + permission_checker.configure( + enabled=perm_config.get("perm_enabled", False), + default_mode=perm_config.get("perm_default_mode", "allow_all"), + rules_json=perm_config.get("perm_rules", "[]"), + quick_deny_groups=perm_config.get("quick_deny_groups", ""), + quick_allow_users=perm_config.get("quick_allow_users", ""), + ) + + # 注册状态变化回调 + mcp_manager.set_status_change_callback(self._update_status_display) + + # v2.0: 服务器配置统一由 servers.claude_config_json 提供(不再通过 WebUI 导入/快速添加写入旧 servers.list) + + # v1.8.0: 初始化工具链管理器 + tool_chain_manager.set_executor(mcp_manager) + self._load_tool_chains() + + def _persist_runtime_displays(self) -> None: + """将 WebUI 只读展示字段写回配置文件,使 WebUI 能正确显示运行状态。""" + try: + config_path = Path(self.plugin_dir) / self.config_file_name + + payload = { + "status.connection_status": str(self.config.get("status", {}).get("connection_status", "") or ""), + "tools.tool_list": str(self.config.get("tools", {}).get("tool_list", "") or ""), + "tool_chains.chains_status": str(self.config.get("tool_chains", {}).get("chains_status", "") or ""), + "react.react_status": str(self.config.get("react", {}).get("react_status", "") or ""), + } + digest = hashlib.sha256(json.dumps(payload, ensure_ascii=False).encode("utf-8")).hexdigest() + if digest == self._last_persisted_display_hash: + return + + self._save_config_to_file(self.config, str(config_path)) + self._last_persisted_display_hash = digest + except Exception as e: + logger.debug(f"写回运行状态到配置文件失败: {e}") + + def _process_quick_add_chain(self) -> None: + """v1.8.0: 处理快速添加工具链表单""" + chains_config = self.config.get("tool_chains", {}) + + # 检查是否触发添加 + add_trigger = chains_config.get("quick_chain_add", "").strip().upper() + if add_trigger != "ADD": + return + + # 获取表单数据 + chain_name = chains_config.get("quick_chain_name", "").strip() + chain_desc = chains_config.get("quick_chain_desc", "").strip() + params_str = chains_config.get("quick_chain_params", "").strip() + steps_str = chains_config.get("quick_chain_steps", "").strip() + + # 验证必填字段 + if not chain_name: + logger.warning("快速添加工具链: 名称不能为空") + self._clear_quick_chain_fields() + return + + if not chain_desc: + logger.warning("快速添加工具链: 描述不能为空") + self._clear_quick_chain_fields() + return + + if not steps_str: + logger.warning("快速添加工具链: 步骤不能为空") + self._clear_quick_chain_fields() + return + + # 解析输入参数 + input_params = {} + if params_str: + for line in params_str.split("\n"): + line = line.strip() + if not line or "=" not in line: + continue + parts = line.split("=", 1) + param_name = parts[0].strip() + param_desc = parts[1].strip() if len(parts) > 1 else param_name + input_params[param_name] = param_desc + + # 解析步骤 + steps = [] + for line in steps_str.split("\n"): + line = line.strip() + if not line: + continue + + parts = line.split("|") + if len(parts) < 2: + logger.warning(f"快速添加工具链: 步骤格式错误: {line}") + continue + + tool_name = parts[0].strip() + args_str = parts[1].strip() if len(parts) > 1 else "{}" + output_key = parts[2].strip() if len(parts) > 2 else "" + + # 解析参数 JSON + try: + args_template = json.loads(args_str) if args_str else {} + except json.JSONDecodeError: + logger.warning(f"快速添加工具链: 参数 JSON 格式错误: {args_str}") + args_template = {} + + steps.append({ + "tool_name": tool_name, + "args_template": args_template, + "output_key": output_key, + }) + + if not steps: + logger.warning("快速添加工具链: 没有有效的步骤") + self._clear_quick_chain_fields() + return + + # 构建新工具链 + new_chain = { + "name": chain_name, + "description": chain_desc, + "input_params": input_params, + "steps": steps, + "enabled": True, + } + + # 获取现有工具链列表 + chains_json = chains_config.get("chains_list", "[]") + try: + chains_list = json.loads(chains_json) if chains_json.strip() else [] + except json.JSONDecodeError: + chains_list = [] + + # 检查是否已存在同名工具链 + for existing in chains_list: + if existing.get("name") == chain_name: + logger.info(f"快速添加: 工具链 {chain_name} 已存在,将更新") + chains_list.remove(existing) + break + + # 添加新工具链 + chains_list.append(new_chain) + new_chains_json = json.dumps(chains_list, ensure_ascii=False, indent=2) + + # 更新配置 + self.config["tool_chains"]["chains_list"] = new_chains_json + + # 清空表单字段 + self._clear_quick_chain_fields() + + # 保存到配置文件 + self._save_chains_list(new_chains_json) + + logger.info(f"快速添加: 已添加工具链 {chain_name} ({len(steps)} 个步骤)") + + def _clear_quick_chain_fields(self) -> None: + """清空快速添加工具链表单字段""" + if "tool_chains" not in self.config: + self.config["tool_chains"] = {} + self.config["tool_chains"]["quick_chain_name"] = "" + self.config["tool_chains"]["quick_chain_desc"] = "" + self.config["tool_chains"]["quick_chain_params"] = "" + self.config["tool_chains"]["quick_chain_steps"] = "" + self.config["tool_chains"]["quick_chain_add"] = "" + + def _save_chains_list(self, chains_json: str) -> None: + """保存工具链列表到配置文件""" + try: + config_path = Path(self.plugin_dir) / self.config_file_name + self._save_config_to_file(self.config, str(config_path)) + logger.info("工具链列表已保存到配置文件") + except Exception as e: + logger.warning(f"保存工具链列表失败: {e}") + + def _load_tool_chains(self) -> None: + """v1.8.0: 加载工具链配置""" + # 先处理快速添加 + self._process_quick_add_chain() + + chains_config = self.config.get("tool_chains", {}) + if not isinstance(chains_config, dict): + chains_config = {} + + # 兼容旧版本:部分版本可能使用 tool_chain 或其他字段名 + if not chains_config: + legacy_section = self.config.get("tool_chain") + if isinstance(legacy_section, dict): + chains_config = legacy_section + self.config["tool_chains"] = legacy_section + + # 兼容旧版本:chains_list 字段名变化 + chains_json = str(chains_config.get("chains_list", "") or "") + if not chains_json.strip(): + for legacy_key in ("list", "chains", "workflow_list", "workflows", "toolchains"): + legacy_val = chains_config.get(legacy_key) + if legacy_val is None: + continue + + if isinstance(legacy_val, str) and legacy_val.strip(): + chains_json = legacy_val + break + + if isinstance(legacy_val, list): + chains_json = json.dumps(legacy_val, ensure_ascii=False, indent=2) + break + + if isinstance(legacy_val, dict): + chains_json = json.dumps([legacy_val], ensure_ascii=False, indent=2) + break + + if chains_json.strip(): + if "tool_chains" not in self.config or not isinstance(self.config.get("tool_chains"), dict): + self.config["tool_chains"] = {} + self.config["tool_chains"]["chains_list"] = chains_json + logger.info("检测到旧版 Workflow 配置字段,已自动迁移为 tool_chains.chains_list(请在 WebUI 保存一次以固化)") + + chains_config = self.config.get("tool_chains", {}) + if not isinstance(chains_config, dict): + chains_config = {} + + if not chains_config.get("chains_enabled", True): + logger.info("工具链功能已禁用") + return + + chains_json = str(chains_config.get("chains_list", "[]") or "") + if not chains_json or not chains_json.strip(): + return + + # 清空现有工具链 + tool_chain_manager.clear() + tool_chain_registry.clear() + + # 加载新配置 + loaded, errors = tool_chain_manager.load_from_json(chains_json) + + if errors: + for err in errors: + logger.warning(f"工具链配置错误: {err}") + + if loaded > 0: + logger.info(f"已加载 {loaded} 个工具链") + # 注册工具链到组件系统 + self._register_tool_chains() + self._update_chains_status_display() + + def _register_tool_chains(self) -> None: + """v1.8.1: 将工具链注册到 MaiBot 组件系统,使 LLM 可调用""" + from src.plugin_system.core.component_registry import component_registry + + chain_count = 0 + for chain_name, chain in tool_chain_manager.get_enabled_chains().items(): + try: + expected_tool_name = f"chain_{chain.name}".replace("-", "_").replace(".", "_") + if component_registry.get_component_info(expected_tool_name, ComponentType.TOOL): + chain_count += 1 + logger.debug(f"🔗 工具链已存在,跳过重复注册: {expected_tool_name}") + continue + + info, tool_class = tool_chain_registry.register_chain(chain) + info.plugin_name = self.plugin_name + + if component_registry.register_component(info, tool_class): + chain_count += 1 + logger.info(f"🔗 注册工具链: {tool_class.name}") + else: + logger.warning(f"⚠️ 工具链注册被跳过(可能已存在): {tool_class.name}") + except Exception as e: + logger.error(f"注册工具链 {chain_name} 失败: {e}") + + if chain_count > 0: + logger.info(f"已注册 {chain_count} 个工具链到组件系统") + + def _register_tools_to_react(self) -> int: + """v1.9.0: 将 MCP 工具注册到记忆检索 ReAct 系统(软流程) + + 这样 MaiBot 的 ReAct Agent 在检索记忆时可以调用 MCP 工具, + 实现 LLM 自主决策的多轮工具调用。 + + Returns: + int: 成功注册的工具数量 + """ + try: + from src.memory_system.retrieval_tools import register_memory_retrieval_tool + except ImportError: + logger.warning("无法导入记忆检索工具注册模块,跳过 ReAct 工具注册") + return 0 + + react_config = self.config.get("react", {}) + filter_mode = react_config.get("filter_mode", "whitelist") + tool_filter = react_config.get("tool_filter", "").strip() + + # 解析过滤列表(支持 # 注释) + filter_patterns = [] + for line in tool_filter.split("\n"): + line = line.strip() + if line and not line.startswith("#"): + filter_patterns.append(line) + + registered_count = 0 + disabled_tools = self._get_disabled_tools() + registered_tools = [] # 记录已注册的工具名 + + for tool_key, (tool_info, _) in mcp_manager.all_tools.items(): + tool_name = tool_key.replace("-", "_").replace(".", "_") + + # 跳过禁用的工具 + if tool_name in disabled_tools: + continue + + # 应用过滤器 + if filter_patterns: + matched = any( + fnmatch.fnmatch(tool_name, p) or tool_name == p + for p in filter_patterns + ) + + if filter_mode == "whitelist": + # 白名单模式:只注册匹配的 + if not matched: + continue + else: + # 黑名单模式:排除匹配的 + if matched: + continue + + try: + # 转换参数格式 + parameters = self._convert_mcp_params_to_react_format(tool_info.input_schema) + + # 创建异步执行函数(使用闭包捕获 tool_key) + def make_execute_func(tk: str): + async def execute_func(**kwargs) -> str: + result = await mcp_manager.call_tool(tk, kwargs) + if result.success: + return result.content or "(无返回内容)" + else: + return f"工具调用失败: {result.error}" + return execute_func + + execute_func = make_execute_func(tool_key) + + # 注册到 ReAct 系统 + register_memory_retrieval_tool( + name=f"mcp_{tool_name}", + description=f"{tool_info.description} [MCP: {tool_info.server_name}]", + parameters=parameters, + execute_func=execute_func, + ) + + registered_count += 1 + registered_tools.append(f"mcp_{tool_name}") + logger.debug(f"🔄 注册 ReAct 工具: mcp_{tool_name}") + + except Exception as e: + logger.warning(f"注册 ReAct 工具 {tool_name} 失败: {e}") + + if registered_count > 0: + mode_str = "白名单" if filter_mode == "whitelist" else "黑名单" + logger.info(f"已注册 {registered_count} 个 MCP 工具到 ReAct 系统 (过滤模式: {mode_str})") + + # 更新状态显示 + self._update_react_status_display(registered_tools, filter_mode, filter_patterns) + + return registered_count + + def _update_react_status_display(self, registered_tools: List[str], filter_mode: str, filter_patterns: List[str]) -> None: + """更新 ReAct 工具状态显示""" + if not registered_tools: + status_text = "(未注册任何工具)" + else: + mode_str = "白名单" if filter_mode == "whitelist" else "黑名单" + lines = [f"📊 已注册 {len(registered_tools)} 个工具 (模式: {mode_str})"] + if filter_patterns: + lines.append(f"过滤规则: {len(filter_patterns)} 条") + lines.append("") + for tool in registered_tools[:20]: + lines.append(f" • {tool}") + if len(registered_tools) > 20: + lines.append(f" ... 还有 {len(registered_tools) - 20} 个") + status_text = "\n".join(lines) + + # 更新内存配置 + if "react" not in self.config: + self.config["react"] = {} + self.config["react"]["react_status"] = status_text + + def _convert_mcp_params_to_react_format(self, input_schema: Dict) -> List[Dict[str, Any]]: + """将 MCP 工具参数转换为 ReAct 工具参数格式""" + parameters = [] + + if not input_schema: + return parameters + + properties = input_schema.get("properties", {}) + required = input_schema.get("required", []) + + for param_name, param_info in properties.items(): + param_type = param_info.get("type", "string") + description = param_info.get("description", f"参数 {param_name}") + is_required = param_name in required + + parameters.append({ + "name": param_name, + "type": param_type, + "description": description, + "required": is_required, + }) + + return parameters + + def _update_chains_status_display(self) -> None: + """v1.8.0: 更新工具链状态显示""" + chains = tool_chain_manager.get_all_chains() + + if not chains: + status_text = "(无工具链配置)" + else: + lines = [f"📊 已配置 {len(chains)} 个工具链:\n"] + for name, chain in chains.items(): + status = "✅" if chain.enabled else "❌" + # 显示工具链基本信息 + lines.append(f"{status} chain_{name}") + lines.append(f" 描述: {chain.description[:40]}{'...' if len(chain.description) > 40 else ''}") + + # 显示输入参数 + if chain.input_params: + params = ", ".join(chain.input_params.keys()) + lines.append(f" 参数: {params}") + + # 显示步骤 + lines.append(f" 步骤: {len(chain.steps)} 个") + for i, step in enumerate(chain.steps): + opt = " (可选)" if step.optional else "" + out = f" → {step.output_key}" if step.output_key else "" + lines.append(f" {i+1}. {step.tool_name}{out}{opt}") + lines.append("") + + status_text = "\n".join(lines) + + # 更新内存配置 + if "tool_chains" not in self.config: + self.config["tool_chains"] = {} + self.config["tool_chains"]["chains_status"] = status_text + + def _get_disabled_tools(self) -> set: + """v1.4.0: 获取禁用的工具列表""" + tools_config = self.config.get("tools", {}) + disabled_str = tools_config.get("disabled_tools", "") + return {t.strip() for t in disabled_str.strip().split("\n") if t.strip()} + + async def _async_connect_servers(self) -> None: + """异步连接所有配置的 MCP 服务器(v1.5.0: 并行连接优化)""" + import asyncio + settings = self.config.get("settings", {}) + + servers_config = self._load_mcp_servers_config() + + if not servers_config: + logger.warning("未配置任何 MCP 服务器") + self._initialized = True + self._update_status_display() + self._update_tool_list_display() + self._update_chains_status_display() + self._start_status_refresher() + self._persist_runtime_displays() + return + + auto_connect = settings.get("auto_connect", True) + if not auto_connect: + logger.info("auto_connect 已禁用,跳过自动连接") + self._initialized = True + self._update_status_display() + self._update_tool_list_display() + self._update_chains_status_display() + self._start_status_refresher() + self._persist_runtime_displays() + return + + tool_prefix = settings.get("tool_prefix", "mcp") + disabled_tools = self._get_disabled_tools() + enable_resources = settings.get("enable_resources", False) + enable_prompts = settings.get("enable_prompts", False) + + # 解析所有服务器配置 + enabled_configs: List[MCPServerConfig] = [] + for idx, server_conf in enumerate(servers_config): + server_name = server_conf.get("name", f"unknown_{idx}") + + if not server_conf.get("enabled", True): + logger.info(f"服务器 {server_name} 已禁用,跳过") + continue + + try: + config = self._parse_server_config(server_conf) + enabled_configs.append(config) + except Exception as e: + logger.error(f"解析服务器 {server_name} 配置失败: {e}") + + if not enabled_configs: + logger.warning("没有已启用的 MCP 服务器") + self._initialized = True + self._update_status_display() + self._update_tool_list_display() + self._update_chains_status_display() + self._start_status_refresher() + self._persist_runtime_displays() + return + + logger.info(f"准备并行连接 {len(enabled_configs)} 个 MCP 服务器") + + # v1.5.0: 并行连接所有服务器 + async def connect_single_server(config: MCPServerConfig) -> Tuple[MCPServerConfig, bool]: + """连接单个服务器""" + logger.info(f"正在连接服务器: {config.name} ({config.transport.value})") + try: + success = await mcp_manager.add_server(config) + if success: + logger.info(f"✅ 服务器 {config.name} 连接成功") + # 获取资源和提示模板 + if enable_resources: + try: + await mcp_manager.fetch_resources_for_server(config.name) + except Exception as e: + logger.warning(f"服务器 {config.name} 获取资源列表失败: {e}") + if enable_prompts: + try: + await mcp_manager.fetch_prompts_for_server(config.name) + except Exception as e: + logger.warning(f"服务器 {config.name} 获取提示模板列表失败: {e}") + else: + logger.warning(f"❌ 服务器 {config.name} 连接失败") + return config, success + except Exception as e: + logger.error(f"❌ 服务器 {config.name} 连接异常: {e}") + return config, False + + # 并行执行所有连接 + start_time = time.time() + results = await asyncio.gather( + *[connect_single_server(cfg) for cfg in enabled_configs], + return_exceptions=True + ) + connect_duration = time.time() - start_time + + # 统计连接结果 + success_count = 0 + failed_count = 0 + for result in results: + if isinstance(result, Exception): + failed_count += 1 + logger.error(f"连接任务异常: {result}") + elif isinstance(result, tuple): + _, success = result + if success: + success_count += 1 + else: + failed_count += 1 + + logger.info(f"并行连接完成: {success_count} 成功, {failed_count} 失败, 耗时 {connect_duration:.2f}s") + + # 注册所有工具 + from src.plugin_system.core.component_registry import component_registry + registered_count = 0 + + for tool_key, (tool_info, _) in mcp_manager.all_tools.items(): + tool_name = tool_key.replace("-", "_").replace(".", "_") + is_disabled = tool_name in disabled_tools + + info, tool_class = mcp_tool_registry.register_tool( + tool_key, tool_info, tool_prefix, disabled=is_disabled + ) + info.plugin_name = self.plugin_name + + if component_registry.register_component(info, tool_class): + registered_count += 1 + status = "🚫" if is_disabled else "✅" + logger.info(f"{status} 注册 MCP 工具: {tool_class.name}") + else: + logger.warning(f"❌ 注册 MCP 工具失败: {tool_class.name}") + + chains_config = self.config.get("tool_chains", {}) + chains_enabled = bool(chains_config.get("chains_enabled", True)) if isinstance(chains_config, dict) else True + chain_count = len(tool_chain_manager.get_enabled_chains()) if chains_enabled else 0 + + # v1.9.0: 注册 MCP 工具到记忆检索 ReAct 系统(软流程) + react_count = 0 + react_config = self.config.get("react", {}) + if react_config.get("react_enabled", False): + react_count = self._register_tools_to_react() + + self._initialized = True + logger.info(f"MCP 桥接插件初始化完成,已注册 {registered_count} 个工具,{chain_count} 个工具链,{react_count} 个 ReAct 工具") + + # 更新状态显示 + self._update_status_display() + self._update_tool_list_display() + self._update_chains_status_display() + self._start_status_refresher() + self._persist_runtime_displays() + + def _start_status_refresher(self) -> None: + """启动 WebUI 状态刷新任务(不写入磁盘)""" + task = getattr(self, "_status_refresh_task", None) + if task and not task.done(): + return + + self._status_refresh_running = True + self._status_refresh_task = asyncio.create_task(self._status_refresh_loop()) + + async def _stop_status_refresher(self) -> None: + """停止 WebUI 状态刷新任务""" + self._status_refresh_running = False + task = getattr(self, "_status_refresh_task", None) + if task: + task.cancel() + try: + await task + except asyncio.CancelledError: + pass + self._status_refresh_task = None + + async def _status_refresh_loop(self) -> None: + """定期刷新 WebUI 展示字段(状态/工具列表/工具链状态)""" + while getattr(self, "_status_refresh_running", False): + try: + settings = self.config.get("settings", {}) + enabled = bool(settings.get("status_refresh_enabled", True)) + interval = float(settings.get("status_refresh_interval", 10.0) or 10.0) + interval = max(5.0, min(interval, 60.0)) + + if enabled and self._initialized: + self._update_status_display() + self._update_tool_list_display() + self._update_chains_status_display() + self._persist_runtime_displays() + + await asyncio.sleep(interval if enabled else 5.0) + except asyncio.CancelledError: + break + except Exception as e: + logger.debug(f"状态刷新任务异常: {e}") + await asyncio.sleep(5.0) + + def _load_mcp_servers_config(self) -> List[Dict[str, Any]]: + """v2.0: 从 Claude mcpServers JSON 加载服务器配置。 + + - 唯一主入口:config.servers.claude_config_json + - 兼容:若旧版 servers.list 存在且 claude_config_json 为空,会自动迁移并写回内存配置 + """ + servers_section = self.config.get("servers", {}) + if not isinstance(servers_section, dict): + servers_section = {} + + claude_json = str(servers_section.get("claude_config_json", "") or "") + + if not claude_json.strip(): + legacy_list = str(servers_section.get("list", "") or "") + migrated = legacy_servers_list_to_claude_config(legacy_list) + if migrated: + claude_json = migrated + if "servers" not in self.config: + self.config["servers"] = {} + self.config["servers"]["claude_config_json"] = migrated + logger.info("检测到旧版 servers.list,已自动迁移为 Claude mcpServers(请在 WebUI 保存一次以固化)") + + if not claude_json.strip(): + self._last_servers_config_error = "未配置任何 MCP 服务器(请在 WebUI 的「MCP Servers(Claude)」粘贴 mcpServers JSON)" + return [] + + try: + servers = parse_claude_mcp_config(claude_json) + except ClaudeConfigError as e: + self._last_servers_config_error = str(e) + logger.error(f"Claude mcpServers 配置解析失败: {e}") + return [] + except Exception as e: + self._last_servers_config_error = str(e) + logger.error(f"Claude mcpServers 配置解析异常: {e}") + return [] + + self._last_servers_config_error = "" + + # 保留未知字段(如 post_process)供旧功能使用 + raw_mapping: Dict[str, Any] = {} + try: + parsed = json.loads(claude_json) + mapping = parsed.get("mcpServers", parsed) + if isinstance(mapping, dict): + raw_mapping = mapping + except Exception: + raw_mapping = {} + + configs: List[Dict[str, Any]] = [] + for srv in servers: + raw = raw_mapping.get(srv.name, {}) + cfg: Dict[str, Any] = raw.copy() if isinstance(raw, dict) else {} + cfg.update( + { + "name": srv.name, + "enabled": srv.enabled, + "transport": srv.transport, + "command": srv.command, + "args": srv.args, + "env": srv.env, + "url": srv.url, + "headers": srv.headers, + } + ) + configs.append(cfg) + + return configs + + def _parse_server_config(self, conf: Dict) -> MCPServerConfig: + """解析服务器配置字典""" + transport_str = conf.get("transport", "stdio").lower() + + transport_map = { + "stdio": TransportType.STDIO, + "sse": TransportType.SSE, + "http": TransportType.HTTP, + "streamable_http": TransportType.STREAMABLE_HTTP, + } + transport = transport_map.get(transport_str, TransportType.STDIO) + + return MCPServerConfig( + name=conf.get("name", "unnamed"), + enabled=conf.get("enabled", True), + transport=transport, + command=conf.get("command", ""), + args=conf.get("args", []), + env=conf.get("env", {}), + url=conf.get("url", ""), + headers=conf.get("headers", {}), # v1.4.2: 鉴权头支持 + ) + + def _update_tool_list_display(self) -> None: + """v1.4.0: 更新工具列表显示""" + tools = mcp_manager.all_tools + disabled_tools = self._get_disabled_tools() + + lines = [] + by_server: Dict[str, List[str]] = {} + + for tool_key, (tool_info, _) in tools.items(): + tool_name = tool_key.replace("-", "_").replace(".", "_") + if tool_info.server_name not in by_server: + by_server[tool_info.server_name] = [] + + is_disabled = tool_name in disabled_tools + status = " ❌" if is_disabled else "" + by_server[tool_info.server_name].append(f" • {tool_name}{status}") + + for srv_name, tool_list in by_server.items(): + lines.append(f"📦 {srv_name} ({len(tool_list)}个工具):") + lines.extend(tool_list) + lines.append("") + + if not by_server: + lines.append("(无已注册工具)") + + tool_list_text = "\n".join(lines) + + # 更新内存配置 + if "tools" not in self.config: + self.config["tools"] = {} + self.config["tools"]["tool_list"] = tool_list_text + + def _update_status_display(self) -> None: + """更新配置文件中的状态显示字段""" + status = mcp_manager.get_status() + settings = self.config.get("settings", {}) + lines = [] + + cfg_err = str(getattr(self, "_last_servers_config_error", "") or "").strip() + if cfg_err: + lines.append(f"⚠️ 配置: {cfg_err}") + lines.append("") + + lines.append(f"服务器: {status['connected_servers']}/{status['total_servers']} 已连接") + lines.append(f"工具数: {status['total_tools']}") + if settings.get("enable_resources", False): + lines.append(f"资源数: {status.get('total_resources', 0)}") + if settings.get("enable_prompts", False): + lines.append(f"模板数: {status.get('total_prompts', 0)}") + lines.append(f"心跳: {'运行中' if status['heartbeat_running'] else '已停止'}") + lines.append("") + + tools = mcp_manager.all_tools + + for name, info in status.get("servers", {}).items(): + icon = "✅" if info["connected"] else "❌" + lines.append(f"{icon} {name} ({info['transport']})") + + # v1.7.0: 显示断路器状态 + cb_status = info.get("circuit_breaker", {}) + cb_state = cb_status.get("state", "closed") + if cb_state == "open": + lines.append(" ⚡ 断路器: 熔断中") + elif cb_state == "half_open": + lines.append(" ⚡ 断路器: 试探中") + + server_tools = [t.name for key, (t, _) in tools.items() if t.server_name == name] + if server_tools: + for tool_name in server_tools: + lines.append(f" • {tool_name}") + else: + lines.append(" (无工具)") + + if not status.get("servers"): + lines.append("(无服务器)") + + status_text = "\n".join(lines) + + if "status" not in self.config: + self.config["status"] = {} + self.config["status"]["connection_status"] = status_text + + def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]: + """返回插件的所有组件""" + components: List[Tuple[ComponentInfo, Type]] = [] + + # 事件处理器 + components.append((MCPStartupHandler.get_handler_info(), MCPStartupHandler)) + components.append((MCPStopHandler.get_handler_info(), MCPStopHandler)) + + # 命令 + components.append((MCPStatusCommand.get_command_info(), MCPStatusCommand)) + components.append((MCPImportCommand.get_command_info(), MCPImportCommand)) + + # 内置工具 + status_tool_info = ToolInfo( + name=MCPStatusTool.name, + tool_description=MCPStatusTool.description, + enabled=True, + tool_parameters=MCPStatusTool.parameters, + component_type=ComponentType.TOOL, + ) + components.append((status_tool_info, MCPStatusTool)) + + settings = self.config.get("settings", {}) + + if settings.get("enable_resources", False): + read_resource_info = ToolInfo( + name=MCPReadResourceTool.name, + tool_description=MCPReadResourceTool.description, + enabled=True, + tool_parameters=MCPReadResourceTool.parameters, + component_type=ComponentType.TOOL, + ) + components.append((read_resource_info, MCPReadResourceTool)) + + if settings.get("enable_prompts", False): + get_prompt_info = ToolInfo( + name=MCPGetPromptTool.name, + tool_description=MCPGetPromptTool.description, + enabled=True, + tool_parameters=MCPGetPromptTool.parameters, + component_type=ComponentType.TOOL, + ) + components.append((get_prompt_info, MCPGetPromptTool)) + + return components + + def get_status(self) -> Dict[str, Any]: + """获取插件状态""" + return { + "initialized": self._initialized, + "mcp_manager": mcp_manager.get_status(), + "registered_tools": len(mcp_tool_registry._tool_classes), + "trace_records": tool_call_tracer.total_records, + "cache_stats": tool_call_cache.get_stats(), + } + + def get_stats(self) -> Dict[str, Any]: + """获取详细统计信息""" + return mcp_manager.get_all_stats() diff --git a/plugins/MaiBot_MCPBridgePlugin/requirements.txt b/plugins/MaiBot_MCPBridgePlugin/requirements.txt new file mode 100644 index 00000000..7580f09e --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/requirements.txt @@ -0,0 +1,2 @@ +# MCP 桥接插件依赖 +mcp>=1.0.0 diff --git a/plugins/MaiBot_MCPBridgePlugin/tool_chain.py b/plugins/MaiBot_MCPBridgePlugin/tool_chain.py new file mode 100644 index 00000000..2be515f1 --- /dev/null +++ b/plugins/MaiBot_MCPBridgePlugin/tool_chain.py @@ -0,0 +1,582 @@ +""" +MCP Workflow 模块 v1.9.0 +支持用户自定义工作流(硬流程),将多个 MCP 工具按顺序执行 + +双轨制架构: +- 软流程 (ReAct): LLM 自主决策,动态多轮调用工具,灵活但不可预测 +- 硬流程 (Workflow): 用户预定义的工作流,固定流程,可靠可控 + +功能: +- Workflow 定义和管理 +- 顺序执行多个工具(硬流程) +- 支持变量替换(使用前序工具的输出) +- 自动注册为组合工具供 LLM 调用 +- 与 ReAct 软流程互补,用户可选择合适的执行方式 +""" + +import asyncio +import json +import re +import time +from dataclasses import dataclass, field +from typing import Any, Dict, List, Optional, Tuple, Type + +try: + from src.common.logger import get_logger + logger = get_logger("mcp_tool_chain") +except ImportError: + import logging + logger = logging.getLogger("mcp_tool_chain") + + +@dataclass +class ToolChainStep: + """工具链步骤""" + tool_name: str # 要调用的工具名(如 mcp_server_tool) + args_template: Dict[str, Any] = field(default_factory=dict) # 参数模板,支持变量替换 + output_key: str = "" # 输出存储的键名,供后续步骤引用 + description: str = "" # 步骤描述 + optional: bool = False # 是否可选(失败时继续执行) + + def to_dict(self) -> Dict[str, Any]: + return { + "tool_name": self.tool_name, + "args_template": self.args_template, + "output_key": self.output_key, + "description": self.description, + "optional": self.optional, + } + + @classmethod + def from_dict(cls, data: Dict[str, Any]) -> "ToolChainStep": + return cls( + tool_name=data.get("tool_name", ""), + args_template=data.get("args_template", {}), + output_key=data.get("output_key", ""), + description=data.get("description", ""), + optional=data.get("optional", False), + ) + + +@dataclass +class ToolChainDefinition: + """工具链定义""" + name: str # 工具链名称(将作为组合工具的名称) + description: str # 工具链描述(供 LLM 理解) + steps: List[ToolChainStep] = field(default_factory=list) # 执行步骤 + input_params: Dict[str, str] = field(default_factory=dict) # 输入参数定义 {参数名: 描述} + enabled: bool = True # 是否启用 + + def to_dict(self) -> Dict[str, Any]: + return { + "name": self.name, + "description": self.description, + "steps": [step.to_dict() for step in self.steps], + "input_params": self.input_params, + "enabled": self.enabled, + } + + @classmethod + def from_dict(cls, data: Dict[str, Any]) -> "ToolChainDefinition": + steps = [ToolChainStep.from_dict(s) for s in data.get("steps", [])] + return cls( + name=data.get("name", ""), + description=data.get("description", ""), + steps=steps, + input_params=data.get("input_params", {}), + enabled=data.get("enabled", True), + ) + + +@dataclass +class ChainExecutionResult: + """工具链执行结果""" + success: bool + final_output: str # 最终输出(最后一个步骤的结果) + step_results: List[Dict[str, Any]] = field(default_factory=list) # 每个步骤的结果 + error: str = "" + total_duration_ms: float = 0.0 + + def to_summary(self) -> str: + """生成执行摘要""" + lines = [] + for i, step in enumerate(self.step_results): + status = "✅" if step.get("success") else "❌" + tool = step.get("tool_name", "unknown") + duration = step.get("duration_ms", 0) + lines.append(f"{status} 步骤{i+1}: {tool} ({duration:.0f}ms)") + if not step.get("success") and step.get("error"): + lines.append(f" 错误: {step['error'][:50]}") + return "\n".join(lines) + + +class ToolChainExecutor: + """工具链执行器""" + + # 变量替换模式: ${step.output_key} 或 ${input.param_name} 或 ${prev} + VAR_PATTERN = re.compile(r'\$\{([^}]+)\}') + + def __init__(self, mcp_manager): + self._mcp_manager = mcp_manager + + def _resolve_tool_key(self, tool_name: str) -> Optional[str]: + """解析工具名,返回有效的 tool_key + + 支持: + - 直接使用 tool_key(如 mcp_server_tool) + - 使用注册后的工具名(会自动转换 - 和 . 为 _) + """ + all_tools = self._mcp_manager.all_tools + + # 直接匹配 + if tool_name in all_tools: + return tool_name + + # 尝试转换后匹配(用户可能使用了注册后的名称) + normalized = tool_name.replace("-", "_").replace(".", "_") + if normalized in all_tools: + return normalized + + # 尝试查找包含该名称的工具 + for key in all_tools.keys(): + if key.endswith(f"_{tool_name}") or key.endswith(f"_{normalized}"): + return key + + return None + + async def execute( + self, + chain: ToolChainDefinition, + input_args: Dict[str, Any], + ) -> ChainExecutionResult: + """执行工具链 + + Args: + chain: 工具链定义 + input_args: 用户输入的参数 + + Returns: + ChainExecutionResult: 执行结果 + """ + start_time = time.time() + step_results = [] + context = { + "input": input_args or {}, # 用户输入,确保不为 None + "step": {}, # 各步骤输出,按 output_key 存储 + "prev": "", # 上一步的输出 + } + + final_output = "" + + # 验证必需的输入参数 + missing_params = [] + for param_name in chain.input_params.keys(): + if param_name not in context["input"]: + missing_params.append(param_name) + + if missing_params: + return ChainExecutionResult( + success=False, + final_output="", + error=f"缺少必需参数: {', '.join(missing_params)}", + total_duration_ms=(time.time() - start_time) * 1000, + ) + + for i, step in enumerate(chain.steps): + step_start = time.time() + step_result = { + "step_index": i, + "tool_name": step.tool_name, + "success": False, + "output": "", + "error": "", + "duration_ms": 0, + } + + try: + # 替换参数中的变量 + resolved_args = self._resolve_args(step.args_template, context) + step_result["resolved_args"] = resolved_args + + # 解析工具名 + tool_key = self._resolve_tool_key(step.tool_name) + if not tool_key: + step_result["error"] = f"工具 {step.tool_name} 不存在" + logger.warning(f"工具链步骤 {i+1}: 工具 {step.tool_name} 不存在") + + if not step.optional: + step_results.append(step_result) + return ChainExecutionResult( + success=False, + final_output="", + step_results=step_results, + error=f"步骤 {i+1}: 工具 {step.tool_name} 不存在", + total_duration_ms=(time.time() - start_time) * 1000, + ) + step_results.append(step_result) + continue + + logger.debug(f"工具链步骤 {i+1}: 调用 {tool_key},参数: {resolved_args}") + + # 调用工具 + result = await self._mcp_manager.call_tool(tool_key, resolved_args) + + step_duration = (time.time() - step_start) * 1000 + step_result["duration_ms"] = step_duration + + if result.success: + step_result["success"] = True + # 确保 content 不为 None + content = result.content if result.content is not None else "" + step_result["output"] = content + + # 更新上下文 + context["prev"] = content + if step.output_key: + context["step"][step.output_key] = content + + final_output = content + content_preview = content[:100] if content else "(空)" + logger.debug(f"工具链步骤 {i+1} 成功: {content_preview}...") + else: + step_result["error"] = result.error or "未知错误" + logger.warning(f"工具链步骤 {i+1} 失败: {result.error}") + + if not step.optional: + step_results.append(step_result) + return ChainExecutionResult( + success=False, + final_output="", + step_results=step_results, + error=f"步骤 {i+1} ({step.tool_name}) 失败: {result.error}", + total_duration_ms=(time.time() - start_time) * 1000, + ) + + except Exception as e: + step_duration = (time.time() - step_start) * 1000 + step_result["duration_ms"] = step_duration + step_result["error"] = str(e) + logger.error(f"工具链步骤 {i+1} 异常: {e}") + + if not step.optional: + step_results.append(step_result) + return ChainExecutionResult( + success=False, + final_output="", + step_results=step_results, + error=f"步骤 {i+1} ({step.tool_name}) 异常: {e}", + total_duration_ms=(time.time() - start_time) * 1000, + ) + + step_results.append(step_result) + + total_duration = (time.time() - start_time) * 1000 + + return ChainExecutionResult( + success=True, + final_output=final_output, + step_results=step_results, + total_duration_ms=total_duration, + ) + + def _resolve_args(self, args_template: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]: + """解析参数模板,替换变量 + + 支持的变量格式: + - ${input.param_name}: 用户输入的参数 + - ${step.output_key}: 某个步骤的输出 + - ${prev}: 上一步的输出 + - ${prev.field}: 上一步输出(JSON)的某个字段 + """ + resolved = {} + + for key, value in args_template.items(): + if isinstance(value, str): + resolved[key] = self._substitute_vars(value, context) + elif isinstance(value, dict): + resolved[key] = self._resolve_args(value, context) + elif isinstance(value, list): + resolved[key] = [ + self._substitute_vars(v, context) if isinstance(v, str) else v + for v in value + ] + else: + resolved[key] = value + + return resolved + + def _substitute_vars(self, template: str, context: Dict[str, Any]) -> str: + """替换字符串中的变量""" + def replacer(match): + var_path = match.group(1) + return self._get_var_value(var_path, context) + + return self.VAR_PATTERN.sub(replacer, template) + + def _get_var_value(self, var_path: str, context: Dict[str, Any]) -> str: + """获取变量值 + + Args: + var_path: 变量路径,如 "input.query", "step.search_result", "prev", "prev.id" + context: 上下文 + """ + parts = self._parse_var_path(var_path) + + if not parts: + return "" + + # 获取根对象 + root = parts[0] + if root not in context: + logger.warning(f"变量 {var_path} 的根 '{root}' 不存在") + return "" + + value = context[root] + + # 遍历路径 + for part in parts[1:]: + if isinstance(value, str): + parsed = self._try_parse_json(value) + if parsed is not None: + value = parsed + + if isinstance(value, dict): + value = value.get(part, "") + elif isinstance(value, list): + if part.isdigit(): + idx = int(part) + value = value[idx] if 0 <= idx < len(value) else "" + else: + value = "" + else: + value = "" + + # 确保返回字符串 + if isinstance(value, (dict, list)): + return json.dumps(value, ensure_ascii=False) + if value is None: + return "" + if value == "": + return "" + return str(value) + + def _try_parse_json(self, value: str) -> Optional[Any]: + """尝试将字符串解析为 JSON 对象,失败则返回 None。""" + if not value: + return None + try: + return json.loads(value) + except json.JSONDecodeError: + return None + + def _parse_var_path(self, var_path: str) -> List[str]: + """解析变量路径,支持点号与下标写法。 + + 支持: + - step.geo.return.0.location + - step.geo.return[0].location + - step.geo['return'][0]['location'] + """ + if not var_path: + return [] + + tokens: List[str] = [] + buf: List[str] = [] + in_bracket = False + in_quote = False + quote_char = "" + + def flush_buf() -> None: + if buf: + token = "".join(buf).strip() + if token: + tokens.append(token) + buf.clear() + + i = 0 + while i < len(var_path): + ch = var_path[i] + + if not in_bracket and ch == ".": + flush_buf() + i += 1 + continue + + if not in_bracket and ch == "[": + flush_buf() + in_bracket = True + in_quote = False + quote_char = "" + i += 1 + continue + + if in_bracket and not in_quote and ch == "]": + flush_buf() + in_bracket = False + i += 1 + continue + + if in_bracket and ch in ("'", '"'): + if not in_quote: + in_quote = True + quote_char = ch + i += 1 + continue + if quote_char == ch: + in_quote = False + quote_char = "" + i += 1 + continue + + if in_bracket and not in_quote: + if ch.isspace(): + i += 1 + continue + if ch == ",": + i += 1 + continue + + buf.append(ch) + i += 1 + + flush_buf() + + if in_bracket or in_quote: + return [p for p in var_path.split(".") if p] + + return tokens + + +class ToolChainManager: + """工具链管理器""" + + _instance: Optional["ToolChainManager"] = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super().__new__(cls) + cls._instance._initialized = False + return cls._instance + + def __init__(self): + if self._initialized: + return + self._initialized = True + self._chains: Dict[str, ToolChainDefinition] = {} + self._executor: Optional[ToolChainExecutor] = None + + def set_executor(self, mcp_manager) -> None: + """设置执行器""" + self._executor = ToolChainExecutor(mcp_manager) + + def add_chain(self, chain: ToolChainDefinition) -> bool: + """添加工具链""" + if not chain.name: + logger.error("工具链名称不能为空") + return False + + if chain.name in self._chains: + logger.warning(f"工具链 {chain.name} 已存在,将被覆盖") + + self._chains[chain.name] = chain + logger.info(f"已添加工具链: {chain.name} ({len(chain.steps)} 个步骤)") + return True + + def remove_chain(self, name: str) -> bool: + """移除工具链""" + if name in self._chains: + del self._chains[name] + logger.info(f"已移除工具链: {name}") + return True + return False + + def get_chain(self, name: str) -> Optional[ToolChainDefinition]: + """获取工具链""" + return self._chains.get(name) + + def get_all_chains(self) -> Dict[str, ToolChainDefinition]: + """获取所有工具链""" + return self._chains.copy() + + def get_enabled_chains(self) -> Dict[str, ToolChainDefinition]: + """获取所有启用的工具链""" + return {name: chain for name, chain in self._chains.items() if chain.enabled} + + async def execute_chain( + self, + chain_name: str, + input_args: Dict[str, Any], + ) -> ChainExecutionResult: + """执行工具链""" + chain = self._chains.get(chain_name) + if not chain: + return ChainExecutionResult( + success=False, + final_output="", + error=f"工具链 {chain_name} 不存在", + ) + + if not chain.enabled: + return ChainExecutionResult( + success=False, + final_output="", + error=f"工具链 {chain_name} 已禁用", + ) + + if not self._executor: + return ChainExecutionResult( + success=False, + final_output="", + error="工具链执行器未初始化", + ) + + return await self._executor.execute(chain, input_args) + + def load_from_json(self, json_str: str) -> Tuple[int, List[str]]: + """从 JSON 字符串加载工具链配置 + + Returns: + (成功加载数量, 错误列表) + """ + errors = [] + loaded = 0 + + try: + data = json.loads(json_str) if json_str.strip() else [] + except json.JSONDecodeError as e: + return 0, [f"JSON 解析失败: {e}"] + + if not isinstance(data, list): + data = [data] + + for i, item in enumerate(data): + try: + chain = ToolChainDefinition.from_dict(item) + if not chain.name: + errors.append(f"第 {i+1} 个工具链缺少名称") + continue + if not chain.steps: + errors.append(f"工具链 {chain.name} 没有步骤") + continue + + self.add_chain(chain) + loaded += 1 + except Exception as e: + errors.append(f"第 {i+1} 个工具链解析失败: {e}") + + return loaded, errors + + def export_to_json(self, pretty: bool = True) -> str: + """导出所有工具链为 JSON""" + chains_data = [chain.to_dict() for chain in self._chains.values()] + if pretty: + return json.dumps(chains_data, ensure_ascii=False, indent=2) + return json.dumps(chains_data, ensure_ascii=False) + + def clear(self) -> None: + """清空所有工具链""" + self._chains.clear() + + +# 全局工具链管理器实例 +tool_chain_manager = ToolChainManager() diff --git a/plugins/emoji_manage_plugin/_manifest.json b/plugins/emoji_manage_plugin/_manifest.json index ee8d8318..68f5c679 100644 --- a/plugins/emoji_manage_plugin/_manifest.json +++ b/plugins/emoji_manage_plugin/_manifest.json @@ -8,18 +8,22 @@ "url": "https://github.com/SengokuCola" }, "license": "GPL-v3.0-or-later", - "host_application": { "min_version": "0.10.4" }, "homepage_url": "https://github.com/SengokuCola/BetterEmoji", "repository_url": "https://github.com/SengokuCola/BetterEmoji", - "keywords": ["emoji", "manage", "plugin"], - "categories": ["Examples", "Tutorial"], - + "keywords": [ + "emoji", + "manage", + "plugin" + ], + "categories": [ + "Examples", + "Tutorial" + ], "default_locale": "zh-CN", "locales_path": "_locales", - "plugin_info": { "is_built_in": false, "plugin_type": "emoji_manage", @@ -31,10 +35,17 @@ }, { "type": "action", - "name": "bye_greeting", + "name": "bye_greeting", "description": "向用户发送告别消息", - "activation_modes": ["keyword"], - "keywords": ["再见", "bye", "88", "拜拜"] + "activation_modes": [ + "keyword" + ], + "keywords": [ + "再见", + "bye", + "88", + "拜拜" + ] }, { "type": "command", @@ -49,5 +60,6 @@ "配置文件示例", "新手教程代码" ] - } + }, + "id": "SengokuCola.BetterEmoji" } \ No newline at end of file diff --git a/plugins/hello_world_plugin/_manifest.json b/plugins/hello_world_plugin/_manifest.json index b1a4c4eb..25234a00 100644 --- a/plugins/hello_world_plugin/_manifest.json +++ b/plugins/hello_world_plugin/_manifest.json @@ -8,18 +8,24 @@ "url": "https://github.com/MaiM-with-u" }, "license": "GPL-v3.0-or-later", - "host_application": { "min_version": "0.8.0" }, "homepage_url": "https://github.com/MaiM-with-u/maibot", "repository_url": "https://github.com/MaiM-with-u/maibot", - "keywords": ["demo", "example", "hello", "greeting", "tutorial"], - "categories": ["Examples", "Tutorial"], - + "keywords": [ + "demo", + "example", + "hello", + "greeting", + "tutorial" + ], + "categories": [ + "Examples", + "Tutorial" + ], "default_locale": "zh-CN", "locales_path": "_locales", - "plugin_info": { "is_built_in": false, "plugin_type": "example", @@ -31,10 +37,17 @@ }, { "type": "action", - "name": "bye_greeting", + "name": "bye_greeting", "description": "向用户发送告别消息", - "activation_modes": ["keyword"], - "keywords": ["再见", "bye", "88", "拜拜"] + "activation_modes": [ + "keyword" + ], + "keywords": [ + "再见", + "bye", + "88", + "拜拜" + ] }, { "type": "command", @@ -49,5 +62,6 @@ "配置文件示例", "新手教程代码" ] - } + }, + "id": "MaiBot开发团队.maibot" } \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fb613e19..85dd74e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "MaiBot" -version = "0.11.0" +version = "0.11.6" description = "MaiCore 是一个基于大语言模型的可交互智能体" requires-python = ">=3.10" dependencies = [ @@ -14,6 +14,7 @@ dependencies = [ "json-repair>=0.47.6", "maim-message", "matplotlib>=3.10.3", + "msgpack>=1.1.2", "numpy>=2.2.6", "openai>=1.95.0", "pandas>=2.3.1", @@ -23,6 +24,7 @@ dependencies = [ "pydantic>=2.11.7", "pypinyin>=0.54.0", "python-dotenv>=1.1.1", + "python-multipart>=0.0.20", "quick-algo>=0.1.3", "rich>=14.0.0", "ruff>=0.12.2", @@ -32,9 +34,14 @@ dependencies = [ "tomlkit>=0.13.3", "urllib3>=2.5.0", "uvicorn>=0.35.0", + "zstandard>=0.25.0", ] +[tool.uv] +index-url = "https://pypi.tuna.tsinghua.edu.cn/simple" + + [tool.ruff] include = ["*.py"] diff --git a/requirements.txt b/requirements.txt index 8a0d22c2..56c944e8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,6 +17,7 @@ pyarrow>=20.0.0 pydantic>=2.11.7 pypinyin>=0.54.0 python-dotenv>=1.1.1 +python-multipart>=0.0.20 quick-algo>=0.1.3 rich>=14.0.0 ruff>=0.12.2 diff --git a/scripts/delete_lpmm_items.py b/scripts/delete_lpmm_items.py new file mode 100644 index 00000000..2eb37ded --- /dev/null +++ b/scripts/delete_lpmm_items.py @@ -0,0 +1,386 @@ +import argparse +import sys +from pathlib import Path +from typing import List, Tuple, Dict, Any +import json +import os + +# 强制使用 utf-8,避免控制台编码报错 +try: + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8") + if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8") +except Exception: + pass + +# 确保能找到 src 包 +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +from src.chat.knowledge.embedding_store import EmbeddingManager +from src.chat.knowledge.kg_manager import KGManager +from src.common.logger import get_logger +from src.chat.knowledge.utils.hash import get_sha256 + +logger = get_logger("delete_lpmm_items") + + +def read_hashes(file_path: Path) -> List[str]: + """读取哈希列表,跳过空行""" + hashes: List[str] = [] + for line in file_path.read_text(encoding="utf-8").splitlines(): + val = line.strip() + if not val: + continue + hashes.append(val) + return hashes + + +def read_openie_hashes(file_path: Path) -> List[str]: + """从 OpenIE JSON 中提取 idx 作为段落哈希""" + data: Dict[str, Any] = json.loads(file_path.read_text(encoding="utf-8")) + docs = data.get("docs", []) if isinstance(data, dict) else [] + hashes: List[str] = [] + for doc in docs: + idx = doc.get("idx") if isinstance(doc, dict) else None + if isinstance(idx, str) and idx.strip(): + hashes.append(idx.strip()) + return hashes + + +def normalize_paragraph_keys(raw_hashes: List[str]) -> Tuple[List[str], List[str]]: + """将输入规范为完整键和纯哈希两份列表""" + keys: List[str] = [] + hashes: List[str] = [] + for h in raw_hashes: + if h.startswith("paragraph-"): + keys.append(h) + hashes.append(h.replace("paragraph-", "", 1)) + else: + keys.append(f"paragraph-{h}") + hashes.append(h) + return keys, hashes + + +def main(): + parser = argparse.ArgumentParser(description="Delete paragraphs from LPMM knowledge base (vectors + graph).") + parser.add_argument("--hash-file", help="文本文件路径,每行一个 paragraph 哈希或带前缀键") + parser.add_argument("--openie-file", help="OpenIE 输出文件(JSON),将其 docs.idx 作为待删段落哈希") + parser.add_argument("--raw-file", help="原始 txt 语料文件(按空行分段),可结合 --raw-index 使用") + parser.add_argument( + "--raw-index", + help="在 --raw-file 中要删除的段落索引,1 基,支持逗号分隔,例如 1,3", + ) + parser.add_argument("--search-text", help="在当前段落库中按子串搜索匹配段落并交互选择删除") + parser.add_argument( + "--search-limit", + type=int, + default=10, + help="--search-text 模式下最多展示的候选段落数量", + ) + parser.add_argument("--delete-entities", action="store_true", help="同时删除 OpenIE 文件中的实体节点/嵌入") + parser.add_argument("--delete-relations", action="store_true", help="同时删除 OpenIE 文件中的关系嵌入") + parser.add_argument("--remove-orphan-entities", action="store_true", help="删除删除后孤立的实体节点") + parser.add_argument("--dry-run", action="store_true", help="仅预览将删除的项,不实际修改") + parser.add_argument("--yes", action="store_true", help="跳过交互确认,直接执行删除(谨慎使用)") + parser.add_argument( + "--max-delete-nodes", + type=int, + default=2000, + help="单次最大允许删除的节点数量(段落+实体),超过则需要显式确认或调整该参数", + ) + parser.add_argument( + "--non-interactive", + action="store_true", + help=( + "非交互模式:不再通过 input() 询问任何信息;" + "在该模式下,如果需要交互(例如 --search-text 未指定具体条目、未提供 --yes)," + "会直接报错退出。" + ), + ) + args = parser.parse_args() + + # 至少需要一种来源 + if not (args.hash_file or args.openie_file or args.raw_file or args.search_text): + logger.error("必须指定 --hash-file / --openie-file / --raw-file / --search-text 之一") + sys.exit(1) + + raw_hashes: List[str] = [] + raw_entities: List[str] = [] + raw_relations: List[str] = [] + + if args.hash_file: + hash_file = Path(args.hash_file) + if not hash_file.exists(): + logger.error(f"哈希文件不存在: {hash_file}") + sys.exit(1) + raw_hashes.extend(read_hashes(hash_file)) + + if args.openie_file: + openie_path = Path(args.openie_file) + if not openie_path.exists(): + logger.error(f"OpenIE 文件不存在: {openie_path}") + sys.exit(1) + # 段落 + raw_hashes.extend(read_openie_hashes(openie_path)) + # 实体/关系(实体同时包含 extracted_entities 与三元组主语/宾语,以匹配 KG 构图逻辑) + try: + data = json.loads(openie_path.read_text(encoding="utf-8")) + docs = data.get("docs", []) if isinstance(data, dict) else [] + for doc in docs: + if not isinstance(doc, dict): + continue + ents = doc.get("extracted_entities", []) + if isinstance(ents, list): + raw_entities.extend([e for e in ents if isinstance(e, str)]) + triples = doc.get("extracted_triples", []) + if isinstance(triples, list): + for t in triples: + if isinstance(t, list) and len(t) == 3: + subj, _, obj = t + if isinstance(subj, str): + raw_entities.append(subj) + if isinstance(obj, str): + raw_entities.append(obj) + raw_relations.append(str(tuple(t))) + except Exception as e: + logger.error(f"读取 OpenIE 文件失败: {e}") + sys.exit(1) + + # 从原始 txt 语料按段落索引选择删除 + if args.raw_file: + raw_path = Path(args.raw_file) + if not raw_path.exists(): + logger.error(f"原始语料文件不存在: {raw_path}") + sys.exit(1) + text = raw_path.read_text(encoding="utf-8") + paragraphs: List[str] = [] + buf = [] + for line in text.splitlines(): + if line.strip() == "": + if buf: + paragraphs.append("\n".join(buf).strip()) + buf = [] + else: + buf.append(line) + if buf: + paragraphs.append("\n".join(buf).strip()) + + if not paragraphs: + logger.error(f"原始语料文件 {raw_path} 中没有解析到任何段落") + sys.exit(1) + + if not args.raw_index: + logger.info(f"{raw_path} 共解析出 {len(paragraphs)} 个段落,请通过 --raw-index 指定要删除的段落,例如 --raw-index 1,3") + sys.exit(1) + + # 解析索引列表(1-based) + try: + idx_list = [int(x.strip()) for x in str(args.raw_index).split(",") if x.strip()] + except ValueError: + logger.error(f"--raw-index 解析失败: {args.raw_index}") + sys.exit(1) + + for idx in idx_list: + if idx < 1 or idx > len(paragraphs): + logger.error(f"--raw-index 包含无效索引 {idx}(有效范围 1~{len(paragraphs)})") + sys.exit(1) + + logger.info("根据原始语料选择段落:") + for idx in idx_list: + para = paragraphs[idx - 1] + h = get_sha256(para) + logger.info(f"- 第 {idx} 段,hash={h},内容预览:{para[:80]}") + raw_hashes.append(h) + + # 在现有库中按子串搜索候选段落并交互选择 + if args.search_text: + search_text = args.search_text.strip() + if not search_text: + logger.error("--search-text 不能为空") + sys.exit(1) + logger.info(f"正在根据关键字在现有段落库中搜索:{search_text!r}") + em_search = EmbeddingManager() + try: + em_search.load_from_file() + except Exception as e: + logger.error(f"加载嵌入库失败,无法使用 --search-text 功能: {e}") + sys.exit(1) + + candidates = [] + for key, item in em_search.paragraphs_embedding_store.store.items(): + if search_text in item.str: + candidates.append((key, item.str)) + if len(candidates) >= args.search_limit: + break + + if not candidates: + logger.info("未在现有段落库中找到包含该关键字的段落") + else: + logger.info("找到以下候选段落(输入序号选择要删除的条目,可用逗号分隔,多选):") + for i, (key, text) in enumerate(candidates, start=1): + logger.info(f"{i}. {key} | {text[:80]}") + if args.non_interactive: + logger.error( + "当前处于非交互模式,无法通过输入序号选择要删除的候选段落;" + "如需脚本化删除,请改用 --hash-file / --openie-file / --raw-file 等方式。" + ) + sys.exit(1) + choice = input("请输入要删除的序号列表(如 1,3),或直接回车取消:").strip() + if choice: + try: + idxs = [int(x.strip()) for x in choice.split(",") if x.strip()] + except ValueError: + logger.error("输入的序号列表无法解析,已取消 --search-text 删除") + else: + for i in idxs: + if 1 <= i <= len(candidates): + key, _ = candidates[i - 1] + # key 已是完整的 paragraph-xxx + if key.startswith("paragraph-"): + raw_hashes.append(key.split("paragraph-", 1)[1]) + else: + logger.warning(f"忽略无效序号: {i}") + + # 去重但保持顺序 + seen = set() + raw_hashes = [h for h in raw_hashes if not (h in seen or seen.add(h))] + + if not raw_hashes: + logger.error("未读取到任何待删哈希,无操作") + sys.exit(1) + + keys, pg_hashes = normalize_paragraph_keys(raw_hashes) + + ent_hashes: List[str] = [] + rel_hashes: List[str] = [] + if args.delete_entities and raw_entities: + ent_hashes = [get_sha256(e) for e in raw_entities] + if args.delete_relations and raw_relations: + rel_hashes = [get_sha256(r) for r in raw_relations] + + logger.info("=== 删除操作预备 ===") + logger.info("请确保已备份 data/embedding 与 data/rag,必要时可使用 --dry-run 预览") + logger.info(f"待删除段落数量: {len(keys)}") + logger.info(f"示例: {keys[:5]}") + if ent_hashes: + logger.info(f"待删除实体数量: {len(ent_hashes)}") + if rel_hashes: + logger.info(f"待删除关系数量: {len(rel_hashes)}") + + total_nodes_to_delete = len(pg_hashes) + (len(ent_hashes) if args.delete_entities else 0) + logger.info(f"本次预计删除节点总数(段落+实体): {total_nodes_to_delete}") + + if args.dry_run: + logger.info("dry-run 模式,未执行删除") + return + + # 大批次删除保护 + if total_nodes_to_delete > args.max_delete_nodes and not args.yes: + logger.error( + f"本次预计删除节点 {total_nodes_to_delete} 个,超过阈值 {args.max_delete_nodes}。" + " 为避免误删,请降低批次规模或使用 --max-delete-nodes 调整阈值,并加上 --yes 明确确认。" + ) + sys.exit(1) + + # 交互确认 + if not args.yes: + if args.non_interactive: + logger.error( + "当前处于非交互模式且未指定 --yes,出于安全考虑,删除操作已被拒绝。\n" + "如确认需要在非交互模式下执行删除,请显式添加 --yes 参数。" + ) + sys.exit(1) + confirm = input("确认删除上述数据?输入大写 YES 以继续,其他任意键取消: ").strip() + if confirm != "YES": + logger.info("用户取消删除操作") + return + + # 加载嵌入与图 + embed_manager = EmbeddingManager() + kg_manager = KGManager() + + try: + embed_manager.load_from_file() + kg_manager.load_from_file() + except Exception as e: + logger.error(f"加载现有知识库失败: {e}") + sys.exit(1) + + # 记录删除前全局统计,便于对比 + before_para_vec = len(embed_manager.paragraphs_embedding_store.store) + before_ent_vec = len(embed_manager.entities_embedding_store.store) + before_rel_vec = len(embed_manager.relation_embedding_store.store) + before_nodes = len(kg_manager.graph.get_node_list()) + before_edges = len(kg_manager.graph.get_edge_list()) + logger.info( + f"删除前统计: 段落向量={before_para_vec}, 实体向量={before_ent_vec}, 关系向量={before_rel_vec}, " + f"KG节点={before_nodes}, KG边={before_edges}" + ) + + # 删除向量 + deleted, skipped = embed_manager.paragraphs_embedding_store.delete_items(keys) + embed_manager.stored_pg_hashes = set(embed_manager.paragraphs_embedding_store.store.keys()) + logger.info(f"段落向量删除完成,删除: {deleted}, 跳过: {skipped}") + ent_deleted = ent_skipped = rel_deleted = rel_skipped = 0 + if ent_hashes: + ent_keys = [f"entity-{h}" for h in ent_hashes] + ent_deleted, ent_skipped = embed_manager.entities_embedding_store.delete_items(ent_keys) + logger.info(f"实体向量删除完成,删除: {ent_deleted}, 跳过: {ent_skipped}") + if rel_hashes: + rel_keys = [f"relation-{h}" for h in rel_hashes] + rel_deleted, rel_skipped = embed_manager.relation_embedding_store.delete_items(rel_keys) + logger.info(f"关系向量删除完成,删除: {rel_deleted}, 跳过: {rel_skipped}") + + # 删除图节点/边 + kg_result = kg_manager.delete_paragraphs( + pg_hashes, + ent_hashes=ent_hashes if args.delete_entities else None, + remove_orphan_entities=args.remove_orphan_entities, + ) + logger.info( + f"KG 删除完成,删除: {kg_result.get('deleted', 0)}, 跳过: {kg_result.get('skipped', 0)}, " + f"孤立实体清理: {kg_result.get('orphan_removed', 0)}" + ) + + # 重建索引并保存 + logger.info("重建 Faiss 索引并保存嵌入文件...") + embed_manager.rebuild_faiss_index() + embed_manager.save_to_file() + + logger.info("保存 KG 数据...") + kg_manager.save_to_file() + + # 删除后统计 + after_para_vec = len(embed_manager.paragraphs_embedding_store.store) + after_ent_vec = len(embed_manager.entities_embedding_store.store) + after_rel_vec = len(embed_manager.relation_embedding_store.store) + after_nodes = len(kg_manager.graph.get_node_list()) + after_edges = len(kg_manager.graph.get_edge_list()) + + logger.info( + "删除后统计: 段落向量=%d(%+d), 实体向量=%d(%+d), 关系向量=%d(%+d), KG节点=%d(%+d), KG边=%d(%+d)" + % ( + after_para_vec, + after_para_vec - before_para_vec, + after_ent_vec, + after_ent_vec - before_ent_vec, + after_rel_vec, + after_rel_vec - before_rel_vec, + after_nodes, + after_nodes - before_nodes, + after_edges, + after_edges - before_edges, + ) + ) + + logger.info("删除流程完成") + print( + "\n[NOTICE] 删除脚本执行完毕。如主程序(聊天 / WebUI)已在运行," + "请重启主程序,或在主程序内部调用一次 lpmm_start_up() 以应用最新 LPMM 知识库。" + ) + print("[NOTICE] 如果不清楚 lpmm_start_up 是什么,直接重启主程序即可。") + + +if __name__ == "__main__": + main() diff --git a/scripts/expression_merge_simulation.py b/scripts/expression_merge_simulation.py new file mode 100644 index 00000000..4470e22f --- /dev/null +++ b/scripts/expression_merge_simulation.py @@ -0,0 +1,567 @@ +""" +模拟 Expression 合并过程 + +用法: + python scripts/expression_merge_simulation.py + 或指定 chat_id: + python scripts/expression_merge_simulation.py --chat-id + 或指定相似度阈值: + python scripts/expression_merge_simulation.py --similarity-threshold 0.8 +""" + +import sys +import os +import json +import argparse +import asyncio +import random +from typing import List, Dict, Tuple, Optional +from collections import defaultdict +from datetime import datetime + +# Add project root to Python path +project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, project_root) + +# Import after setting up path (required for project imports) +from src.common.database.database_model import Expression, ChatStreams # noqa: E402 +from src.bw_learner.learner_utils import calculate_style_similarity # noqa: E402 +from src.llm_models.utils_model import LLMRequest # noqa: E402 +from src.config.config import model_config # noqa: E402 + + +def get_chat_name(chat_id: str) -> str: + """根据 chat_id 获取聊天名称""" + try: + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == chat_id) + if chat_stream is None: + return f"未知聊天 ({chat_id[:8]}...)" + + if chat_stream.group_name: + return f"{chat_stream.group_name}" + elif chat_stream.user_nickname: + return f"{chat_stream.user_nickname}的私聊" + else: + return f"未知聊天 ({chat_id[:8]}...)" + except Exception: + return f"查询失败 ({chat_id[:8]}...)" + + +def parse_content_list(stored_list: Optional[str]) -> List[str]: + """解析 content_list JSON 字符串为列表""" + if not stored_list: + return [] + try: + data = json.loads(stored_list) + except json.JSONDecodeError: + return [] + return [str(item) for item in data if isinstance(item, str)] if isinstance(data, list) else [] + + +def parse_style_list(stored_list: Optional[str]) -> List[str]: + """解析 style_list JSON 字符串为列表""" + if not stored_list: + return [] + try: + data = json.loads(stored_list) + except json.JSONDecodeError: + return [] + return [str(item) for item in data if isinstance(item, str)] if isinstance(data, list) else [] + + +def find_exact_style_match( + expressions: List[Expression], + target_style: str, + chat_id: str, + exclude_ids: set +) -> Optional[Expression]: + """ + 查找具有完全匹配 style 的 Expression 记录 + 检查 style 字段和 style_list 中的每一项 + """ + for expr in expressions: + if expr.chat_id != chat_id or expr.id in exclude_ids: + continue + + # 检查 style 字段 + if expr.style == target_style: + return expr + + # 检查 style_list 中的每一项 + style_list = parse_style_list(expr.style_list) + if target_style in style_list: + return expr + + return None + + +def find_similar_style_expression( + expressions: List[Expression], + target_style: str, + chat_id: str, + similarity_threshold: float, + exclude_ids: set +) -> Optional[Tuple[Expression, float]]: + """ + 查找具有相似 style 的 Expression 记录 + 检查 style 字段和 style_list 中的每一项 + + Returns: + (Expression, similarity) 或 None + """ + best_match = None + best_similarity = 0.0 + + for expr in expressions: + if expr.chat_id != chat_id or expr.id in exclude_ids: + continue + + # 检查 style 字段 + similarity = calculate_style_similarity(target_style, expr.style) + if similarity >= similarity_threshold and similarity > best_similarity: + best_similarity = similarity + best_match = expr + + # 检查 style_list 中的每一项 + style_list = parse_style_list(expr.style_list) + for existing_style in style_list: + similarity = calculate_style_similarity(target_style, existing_style) + if similarity >= similarity_threshold and similarity > best_similarity: + best_similarity = similarity + best_match = expr + + if best_match: + return (best_match, best_similarity) + return None + + +async def compose_situation_text(content_list: List[str], summary_model: LLMRequest) -> str: + """组合 situation 文本,尝试使用 LLM 总结""" + sanitized = [c.strip() for c in content_list if c.strip()] + if not sanitized: + return "" + + if len(sanitized) == 1: + return sanitized[0] + + # 尝试使用 LLM 总结 + prompt = ( + "请阅读以下多个聊天情境描述,并将它们概括成一句简短的话," + "长度不超过20个字,保留共同特点:\n" + f"{chr(10).join(f'- {s}' for s in sanitized[-10:])}\n只输出概括内容。" + ) + + try: + summary, _ = await summary_model.generate_response_async(prompt, temperature=0.2) + summary = summary.strip() + if summary: + return summary + except Exception as e: + print(f" ⚠️ LLM 总结 situation 失败: {e}") + + # 如果总结失败,返回用 "/" 连接的字符串 + return "/".join(sanitized) + + +async def compose_style_text(style_list: List[str], summary_model: LLMRequest) -> str: + """组合 style 文本,尝试使用 LLM 总结""" + sanitized = [s.strip() for s in style_list if s.strip()] + if not sanitized: + return "" + + if len(sanitized) == 1: + return sanitized[0] + + # 尝试使用 LLM 总结 + prompt = ( + "请阅读以下多个语言风格/表达方式,并将它们概括成一句简短的话," + "长度不超过20个字,保留共同特点:\n" + f"{chr(10).join(f'- {s}' for s in sanitized[-10:])}\n只输出概括内容。" + ) + + try: + summary, _ = await summary_model.generate_response_async(prompt, temperature=0.2) + + print(f"Prompt:{prompt} Summary:{summary}") + + summary = summary.strip() + if summary: + return summary + except Exception as e: + print(f" ⚠️ LLM 总结 style 失败: {e}") + + # 如果总结失败,返回第一个 + return sanitized[0] + + +async def simulate_merge( + expressions: List[Expression], + similarity_threshold: float = 0.75, + use_llm: bool = False, + max_samples: int = 10, +) -> Dict: + """ + 模拟合并过程 + + Args: + expressions: Expression 列表(从数据库读出的原始记录) + similarity_threshold: style 相似度阈值 + use_llm: 是否使用 LLM 进行实际总结 + max_samples: 最多随机抽取的 Expression 数量(为 0 或 None 时表示不限制) + + Returns: + 包含合并统计信息的字典 + """ + # 如果样本太多,随机抽取一部分进行模拟,避免运行时间过长 + if max_samples and len(expressions) > max_samples: + expressions = random.sample(expressions, max_samples) + + # 按 chat_id 分组 + expressions_by_chat = defaultdict(list) + for expr in expressions: + expressions_by_chat[expr.chat_id].append(expr) + + # 初始化 LLM 模型(如果需要) + summary_model = None + if use_llm: + try: + summary_model = LLMRequest( + model_set=model_config.model_task_config.utils_small, + request_type="expression.summary" + ) + print("✅ LLM 模型已初始化,将进行实际总结") + except Exception as e: + print(f"⚠️ LLM 模型初始化失败: {e},将跳过 LLM 总结") + use_llm = False + + merge_stats = { + "total_expressions": len(expressions), + "total_chats": len(expressions_by_chat), + "exact_matches": 0, + "similar_matches": 0, + "new_records": 0, + "merge_details": [], + "chat_stats": {}, + "use_llm": use_llm + } + + # 为每个 chat_id 模拟合并 + for chat_id, chat_expressions in expressions_by_chat.items(): + chat_name = get_chat_name(chat_id) + chat_stat = { + "chat_id": chat_id, + "chat_name": chat_name, + "total": len(chat_expressions), + "exact_matches": 0, + "similar_matches": 0, + "new_records": 0, + "merges": [] + } + + processed_ids = set() + + for expr in chat_expressions: + if expr.id in processed_ids: + continue + + target_style = expr.style + target_situation = expr.situation + + # 第一层:检查完全匹配 + exact_match = find_exact_style_match( + chat_expressions, + target_style, + chat_id, + {expr.id} + ) + + if exact_match: + # 完全匹配(不使用 LLM 总结) + # 模拟合并后的 content_list 和 style_list + target_content_list = parse_content_list(exact_match.content_list) + target_content_list.append(target_situation) + + target_style_list = parse_style_list(exact_match.style_list) + if exact_match.style and exact_match.style not in target_style_list: + target_style_list.append(exact_match.style) + if target_style not in target_style_list: + target_style_list.append(target_style) + + merge_info = { + "type": "exact", + "source_id": expr.id, + "target_id": exact_match.id, + "source_style": target_style, + "target_style": exact_match.style, + "source_situation": target_situation, + "target_situation": exact_match.situation, + "similarity": 1.0, + "merged_content_list": target_content_list, + "merged_style_list": target_style_list, + "merged_situation": exact_match.situation, # 完全匹配时保持原 situation + "merged_style": exact_match.style # 完全匹配时保持原 style + } + chat_stat["exact_matches"] += 1 + chat_stat["merges"].append(merge_info) + merge_stats["exact_matches"] += 1 + processed_ids.add(expr.id) + continue + + # 第二层:检查相似匹配 + similar_match = find_similar_style_expression( + chat_expressions, + target_style, + chat_id, + similarity_threshold, + {expr.id} + ) + + if similar_match: + match_expr, similarity = similar_match + # 相似匹配(使用 LLM 总结) + # 模拟合并后的 content_list 和 style_list + target_content_list = parse_content_list(match_expr.content_list) + target_content_list.append(target_situation) + + target_style_list = parse_style_list(match_expr.style_list) + if match_expr.style and match_expr.style not in target_style_list: + target_style_list.append(match_expr.style) + if target_style not in target_style_list: + target_style_list.append(target_style) + + # 使用 LLM 总结(如果启用) + merged_situation = match_expr.situation + merged_style = match_expr.style or target_style + + if use_llm and summary_model: + try: + merged_situation = await compose_situation_text(target_content_list, summary_model) + merged_style = await compose_style_text(target_style_list, summary_model) + except Exception as e: + print(f" ⚠️ 处理记录 {expr.id} 时 LLM 总结失败: {e}") + # 如果总结失败,使用 fallback + merged_situation = "/".join([c.strip() for c in target_content_list if c.strip()]) or match_expr.situation + merged_style = target_style_list[0] if target_style_list else (match_expr.style or target_style) + else: + # 不使用 LLM 时,使用简单拼接 + merged_situation = "/".join([c.strip() for c in target_content_list if c.strip()]) or match_expr.situation + merged_style = target_style_list[0] if target_style_list else (match_expr.style or target_style) + + merge_info = { + "type": "similar", + "source_id": expr.id, + "target_id": match_expr.id, + "source_style": target_style, + "target_style": match_expr.style, + "source_situation": target_situation, + "target_situation": match_expr.situation, + "similarity": similarity, + "merged_content_list": target_content_list, + "merged_style_list": target_style_list, + "merged_situation": merged_situation, + "merged_style": merged_style, + "llm_used": use_llm and summary_model is not None + } + chat_stat["similar_matches"] += 1 + chat_stat["merges"].append(merge_info) + merge_stats["similar_matches"] += 1 + processed_ids.add(expr.id) + continue + + # 没有匹配,作为新记录 + chat_stat["new_records"] += 1 + merge_stats["new_records"] += 1 + processed_ids.add(expr.id) + + merge_stats["chat_stats"][chat_id] = chat_stat + merge_stats["merge_details"].extend(chat_stat["merges"]) + + return merge_stats + + +def print_merge_results(stats: Dict, show_details: bool = True, max_details: int = 50): + """打印合并结果""" + print("\n" + "=" * 80) + print("Expression 合并模拟结果") + print("=" * 80) + + print("\n📊 总体统计:") + print(f" 总 Expression 数: {stats['total_expressions']}") + print(f" 总聊天数: {stats['total_chats']}") + print(f" 完全匹配合并: {stats['exact_matches']}") + print(f" 相似匹配合并: {stats['similar_matches']}") + print(f" 新记录(无匹配): {stats['new_records']}") + if stats.get('use_llm'): + print(" LLM 总结: 已启用") + else: + print(" LLM 总结: 未启用(仅模拟)") + + total_merges = stats['exact_matches'] + stats['similar_matches'] + if stats['total_expressions'] > 0: + merge_ratio = (total_merges / stats['total_expressions']) * 100 + print(f" 合并比例: {merge_ratio:.1f}%") + + # 按聊天分组显示 + print("\n📋 按聊天分组统计:") + for chat_id, chat_stat in stats['chat_stats'].items(): + print(f"\n {chat_stat['chat_name']} ({chat_id[:8]}...):") + print(f" 总数: {chat_stat['total']}") + print(f" 完全匹配: {chat_stat['exact_matches']}") + print(f" 相似匹配: {chat_stat['similar_matches']}") + print(f" 新记录: {chat_stat['new_records']}") + + # 显示合并详情 + if show_details and stats['merge_details']: + print(f"\n📝 合并详情 (显示前 {min(max_details, len(stats['merge_details']))} 条):") + print() + + for idx, merge in enumerate(stats['merge_details'][:max_details], 1): + merge_type = "完全匹配" if merge['type'] == 'exact' else f"相似匹配 (相似度: {merge['similarity']:.3f})" + print(f" {idx}. {merge_type}") + print(f" 源记录 ID: {merge['source_id']}") + print(f" 目标记录 ID: {merge['target_id']}") + print(f" 源 Style: {merge['source_style'][:50]}") + print(f" 目标 Style: {merge['target_style'][:50]}") + print(f" 源 Situation: {merge['source_situation'][:50]}") + print(f" 目标 Situation: {merge['target_situation'][:50]}") + + # 显示合并后的结果 + if 'merged_situation' in merge: + print(f" → 合并后 Situation: {merge['merged_situation'][:50]}") + if 'merged_style' in merge: + print(f" → 合并后 Style: {merge['merged_style'][:50]}") + if merge.get('llm_used'): + print(" → LLM 总结: 已使用") + elif merge['type'] == 'similar': + print(" → LLM 总结: 未使用(模拟模式)") + + # 显示合并后的列表 + if 'merged_content_list' in merge and len(merge['merged_content_list']) > 1: + print(f" → Content List ({len(merge['merged_content_list'])} 项): {', '.join(merge['merged_content_list'][:3])}") + if len(merge['merged_content_list']) > 3: + print(f" ... 还有 {len(merge['merged_content_list']) - 3} 项") + if 'merged_style_list' in merge and len(merge['merged_style_list']) > 1: + print(f" → Style List ({len(merge['merged_style_list'])} 项): {', '.join(merge['merged_style_list'][:3])}") + if len(merge['merged_style_list']) > 3: + print(f" ... 还有 {len(merge['merged_style_list']) - 3} 项") + print() + + if len(stats['merge_details']) > max_details: + print(f" ... 还有 {len(stats['merge_details']) - max_details} 条合并记录未显示") + + +def main(): + """主函数""" + parser = argparse.ArgumentParser(description="模拟 Expression 合并过程") + parser.add_argument( + "--chat-id", + type=str, + default=None, + help="指定要分析的 chat_id(不指定则分析所有)" + ) + parser.add_argument( + "--similarity-threshold", + type=float, + default=0.75, + help="相似度阈值 (0-1, 默认: 0.75)" + ) + parser.add_argument( + "--no-details", + action="store_true", + help="不显示详细信息,只显示统计" + ) + parser.add_argument( + "--max-details", + type=int, + default=50, + help="最多显示的合并详情数 (默认: 50)" + ) + parser.add_argument( + "--output", + type=str, + default=None, + help="输出文件路径 (默认: 自动生成带时间戳的文件)" + ) + parser.add_argument( + "--use-llm", + action="store_true", + help="启用 LLM 进行实际总结(默认: 仅模拟,不调用 LLM)" + ) + parser.add_argument( + "--max-samples", + type=int, + default=10, + help="最多随机抽取的 Expression 数量 (默认: 10,设置为 0 表示不限制)" + ) + + args = parser.parse_args() + + # 验证阈值 + if not 0 <= args.similarity_threshold <= 1: + print("错误: similarity-threshold 必须在 0-1 之间") + return + + # 确定输出文件路径 + if args.output: + output_file = args.output + else: + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + output_dir = os.path.join(project_root, "data", "temp") + os.makedirs(output_dir, exist_ok=True) + output_file = os.path.join(output_dir, f"expression_merge_simulation_{timestamp}.txt") + + # 查询 Expression 记录 + print("正在从数据库加载Expression数据...") + try: + if args.chat_id: + expressions = list(Expression.select().where(Expression.chat_id == args.chat_id)) + print(f"✅ 成功加载 {len(expressions)} 条Expression记录 (chat_id: {args.chat_id})") + else: + expressions = list(Expression.select()) + print(f"✅ 成功加载 {len(expressions)} 条Expression记录") + except Exception as e: + print(f"❌ 加载数据失败: {e}") + return + + if not expressions: + print("❌ 数据库中没有找到Expression记录") + return + + # 执行合并模拟 + print(f"\n正在模拟合并过程(相似度阈值: {args.similarity_threshold},最大样本数: {args.max_samples})...") + if args.use_llm: + print("⚠️ 已启用 LLM 总结,将进行实际的 API 调用") + else: + print("ℹ️ 未启用 LLM 总结,仅进行模拟(使用 --use-llm 启用实际 LLM 调用)") + + stats = asyncio.run( + simulate_merge( + expressions, + similarity_threshold=args.similarity_threshold, + use_llm=args.use_llm, + max_samples=args.max_samples, + ) + ) + + # 输出结果 + original_stdout = sys.stdout + try: + with open(output_file, "w", encoding="utf-8") as f: + sys.stdout = f + print_merge_results(stats, show_details=not args.no_details, max_details=args.max_details) + sys.stdout = original_stdout + + # 同时在控制台输出 + print_merge_results(stats, show_details=not args.no_details, max_details=args.max_details) + + except Exception as e: + sys.stdout = original_stdout + print(f"❌ 写入文件失败: {e}") + return + + print(f"\n✅ 模拟结果已保存到: {output_file}") + + +if __name__ == "__main__": + main() + diff --git a/scripts/expression_similarity_analysis.py b/scripts/expression_similarity_analysis.py new file mode 100644 index 00000000..aa1b149e --- /dev/null +++ b/scripts/expression_similarity_analysis.py @@ -0,0 +1,559 @@ +""" +分析expression库中situation和style的相似度 + +用法: + python scripts/expression_similarity_analysis.py + 或指定阈值: + python scripts/expression_similarity_analysis.py --situation-threshold 0.8 --style-threshold 0.7 +""" + +import sys +import os +import argparse +from typing import List, Tuple +from collections import defaultdict +from difflib import SequenceMatcher +from datetime import datetime + +# Add project root to Python path +project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, project_root) + +# Import after setting up path (required for project imports) +from src.common.database.database_model import Expression, ChatStreams # noqa: E402 +from src.config.config import global_config # noqa: E402 +from src.chat.message_receive.chat_stream import get_chat_manager # noqa: E402 + + +class TeeOutput: + """同时输出到控制台和文件的类""" + def __init__(self, file_path: str): + self.file = open(file_path, "w", encoding="utf-8") + self.console = sys.stdout + + def write(self, text: str): + """写入文本到控制台和文件""" + self.console.write(text) + self.file.write(text) + self.file.flush() # 立即刷新到文件 + + def flush(self): + """刷新输出""" + self.console.flush() + self.file.flush() + + def close(self): + """关闭文件""" + if self.file: + self.file.close() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + return False + + +def _parse_stream_config_to_chat_id(stream_config_str: str) -> str | None: + """ + 解析'platform:id:type'为chat_id,直接复用 ChatManager 的逻辑 + """ + try: + parts = stream_config_str.split(":") + if len(parts) != 3: + return None + platform = parts[0] + id_str = parts[1] + stream_type = parts[2] + is_group = stream_type == "group" + return get_chat_manager().get_stream_id(platform, str(id_str), is_group=is_group) + except Exception: + return None + + +def build_chat_id_groups() -> dict[str, set[str]]: + """ + 根据expression_groups配置,构建chat_id到相关chat_id集合的映射 + + Returns: + dict: {chat_id: set of related chat_ids (including itself)} + """ + groups = global_config.expression.expression_groups + chat_id_groups: dict[str, set[str]] = {} + + # 检查是否存在全局共享组(包含"*"的组) + global_group_exists = any("*" in group for group in groups) + + if global_group_exists: + # 如果存在全局共享组,收集所有配置中的chat_id + all_chat_ids = set() + for group in groups: + for stream_config_str in group: + if stream_config_str == "*": + continue + if chat_id_candidate := _parse_stream_config_to_chat_id(stream_config_str): + all_chat_ids.add(chat_id_candidate) + + # 所有chat_id都互相相关 + for chat_id in all_chat_ids: + chat_id_groups[chat_id] = all_chat_ids.copy() + else: + # 处理普通组 + for group in groups: + group_chat_ids = set() + for stream_config_str in group: + if chat_id_candidate := _parse_stream_config_to_chat_id(stream_config_str): + group_chat_ids.add(chat_id_candidate) + + # 组内的所有chat_id都互相相关 + for chat_id in group_chat_ids: + if chat_id not in chat_id_groups: + chat_id_groups[chat_id] = set() + chat_id_groups[chat_id].update(group_chat_ids) + + # 确保每个chat_id至少包含自身 + for chat_id in chat_id_groups: + chat_id_groups[chat_id].add(chat_id) + + return chat_id_groups + + +def are_chat_ids_related(chat_id1: str, chat_id2: str, chat_id_groups: dict[str, set[str]]) -> bool: + """ + 判断两个chat_id是否相关(相同或同组) + + Args: + chat_id1: 第一个chat_id + chat_id2: 第二个chat_id + chat_id_groups: chat_id到相关chat_id集合的映射 + + Returns: + bool: 如果两个chat_id相同或同组,返回True + """ + if chat_id1 == chat_id2: + return True + + # 如果chat_id1在映射中,检查chat_id2是否在其相关集合中 + if chat_id1 in chat_id_groups: + return chat_id2 in chat_id_groups[chat_id1] + + # 如果chat_id1不在映射中,说明它不在任何组中,只与自己相关 + return False + + +def get_chat_name(chat_id: str) -> str: + """根据 chat_id 获取聊天名称""" + try: + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == chat_id) + if chat_stream is None: + return f"未知聊天 ({chat_id[:8]}...)" + + if chat_stream.group_name: + return f"{chat_stream.group_name}" + elif chat_stream.user_nickname: + return f"{chat_stream.user_nickname}的私聊" + else: + return f"未知聊天 ({chat_id[:8]}...)" + except Exception: + return f"查询失败 ({chat_id[:8]}...)" + + +def text_similarity(text1: str, text2: str) -> float: + """ + 计算两个文本的相似度 + 使用SequenceMatcher计算相似度,返回0-1之间的值 + 在计算前会移除"使用"和"句式"这两个词 + """ + if not text1 or not text2: + return 0.0 + + # 移除"使用"和"句式"这两个词 + def remove_ignored_words(text: str) -> str: + """移除需要忽略的词""" + text = text.replace("使用", "") + text = text.replace("句式", "") + return text.strip() + + cleaned_text1 = remove_ignored_words(text1) + cleaned_text2 = remove_ignored_words(text2) + + # 如果清理后文本为空,返回0 + if not cleaned_text1 or not cleaned_text2: + return 0.0 + + return SequenceMatcher(None, cleaned_text1, cleaned_text2).ratio() + + +def find_similar_pairs( + expressions: List[Expression], + field_name: str, + threshold: float, + max_pairs: int = None +) -> List[Tuple[int, int, float, str, str]]: + """ + 找出相似的expression对 + + Args: + expressions: Expression对象列表 + field_name: 要比较的字段名 ('situation' 或 'style') + threshold: 相似度阈值 (0-1) + max_pairs: 最多返回的对数,None表示返回所有 + + Returns: + List of (index1, index2, similarity, text1, text2) tuples + """ + similar_pairs = [] + n = len(expressions) + + print(f"正在分析 {field_name} 字段的相似度...") + print(f"总共需要比较 {n * (n - 1) // 2} 对...") + + for i in range(n): + if (i + 1) % 100 == 0: + print(f" 已处理 {i + 1}/{n} 个项目...") + + expr1 = expressions[i] + text1 = getattr(expr1, field_name, "") + + for j in range(i + 1, n): + expr2 = expressions[j] + text2 = getattr(expr2, field_name, "") + + similarity = text_similarity(text1, text2) + + if similarity >= threshold: + similar_pairs.append((i, j, similarity, text1, text2)) + + # 按相似度降序排序 + similar_pairs.sort(key=lambda x: x[2], reverse=True) + + if max_pairs: + similar_pairs = similar_pairs[:max_pairs] + + return similar_pairs + + +def group_similar_items( + expressions: List[Expression], + field_name: str, + threshold: float, + chat_id_groups: dict[str, set[str]] +) -> List[List[int]]: + """ + 将相似的expression分组(仅比较相同chat_id或同组的项目) + + Args: + expressions: Expression对象列表 + field_name: 要比较的字段名 ('situation' 或 'style') + threshold: 相似度阈值 (0-1) + chat_id_groups: chat_id到相关chat_id集合的映射 + + Returns: + List of groups, each group is a list of indices + """ + n = len(expressions) + # 使用并查集的思想来分组 + parent = list(range(n)) + + def find(x): + if parent[x] != x: + parent[x] = find(parent[x]) + return parent[x] + + def union(x, y): + px, py = find(x), find(y) + if px != py: + parent[px] = py + + print(f"正在对 {field_name} 字段进行分组(仅比较相同chat_id或同组的项目)...") + + # 统计需要比较的对数 + total_pairs = 0 + for i in range(n): + for j in range(i + 1, n): + if are_chat_ids_related(expressions[i].chat_id, expressions[j].chat_id, chat_id_groups): + total_pairs += 1 + + print(f"总共需要比较 {total_pairs} 对(已过滤不同chat_id且不同组的项目)...") + + compared_pairs = 0 + for i in range(n): + if (i + 1) % 100 == 0: + print(f" 已处理 {i + 1}/{n} 个项目...") + + expr1 = expressions[i] + text1 = getattr(expr1, field_name, "") + + for j in range(i + 1, n): + expr2 = expressions[j] + + # 只比较相同chat_id或同组的项目 + if not are_chat_ids_related(expr1.chat_id, expr2.chat_id, chat_id_groups): + continue + + compared_pairs += 1 + text2 = getattr(expr2, field_name, "") + + similarity = text_similarity(text1, text2) + + if similarity >= threshold: + union(i, j) + + # 收集分组 + groups = defaultdict(list) + for i in range(n): + root = find(i) + groups[root].append(i) + + # 只返回包含多个项目的组 + result = [group for group in groups.values() if len(group) > 1] + result.sort(key=len, reverse=True) + + return result + + +def print_similarity_analysis( + expressions: List[Expression], + field_name: str, + threshold: float, + chat_id_groups: dict[str, set[str]], + show_details: bool = True, + max_groups: int = 20 +): + """打印相似度分析结果""" + print("\n" + "=" * 80) + print(f"{field_name.upper()} 相似度分析 (阈值: {threshold})") + print("=" * 80) + + # 分组分析 + groups = group_similar_items(expressions, field_name, threshold, chat_id_groups) + + total_items = len(expressions) + similar_items_count = sum(len(group) for group in groups) + unique_groups = len(groups) + + print("\n📊 统计信息:") + print(f" 总项目数: {total_items}") + print(f" 相似项目数: {similar_items_count} ({similar_items_count / total_items * 100:.1f}%)") + print(f" 相似组数: {unique_groups}") + print(f" 平均每组项目数: {similar_items_count / unique_groups:.1f}" if unique_groups > 0 else " 平均每组项目数: 0") + + if not groups: + print(f"\n未找到相似度 >= {threshold} 的项目组") + return + + print(f"\n📋 相似组详情 (显示前 {min(max_groups, len(groups))} 组):") + print() + + for group_idx, group in enumerate(groups[:max_groups], 1): + print(f"组 {group_idx} (共 {len(group)} 个项目):") + + if show_details: + # 显示组内所有项目的详细信息 + for idx in group: + expr = expressions[idx] + text = getattr(expr, field_name, "") + chat_name = get_chat_name(expr.chat_id) + + # 截断过长的文本 + display_text = text[:60] + "..." if len(text) > 60 else text + + print(f" [{expr.id}] {display_text}") + print(f" 聊天: {chat_name}, Count: {expr.count}") + + # 计算组内平均相似度 + if len(group) > 1: + similarities = [] + above_threshold_pairs = [] # 存储满足阈值的相似对 + above_threshold_count = 0 + for i in range(len(group)): + for j in range(i + 1, len(group)): + text1 = getattr(expressions[group[i]], field_name, "") + text2 = getattr(expressions[group[j]], field_name, "") + sim = text_similarity(text1, text2) + similarities.append(sim) + if sim >= threshold: + above_threshold_count += 1 + # 存储满足阈值的对的信息 + expr1 = expressions[group[i]] + expr2 = expressions[group[j]] + display_text1 = text1[:40] + "..." if len(text1) > 40 else text1 + display_text2 = text2[:40] + "..." if len(text2) > 40 else text2 + above_threshold_pairs.append(( + expr1.id, display_text1, + expr2.id, display_text2, + sim + )) + + if similarities: + avg_sim = sum(similarities) / len(similarities) + min_sim = min(similarities) + max_sim = max(similarities) + above_threshold_ratio = above_threshold_count / len(similarities) * 100 + print(f" 平均相似度: {avg_sim:.3f} (范围: {min_sim:.3f} - {max_sim:.3f})") + print(f" 满足阈值({threshold})的比例: {above_threshold_ratio:.1f}% ({above_threshold_count}/{len(similarities)})") + + # 显示满足阈值的相似对(这些是直接连接,导致它们被分到一组) + if above_threshold_pairs: + print(" ⚠️ 直接相似的对 (这些对导致它们被分到一组):") + # 按相似度降序排序 + above_threshold_pairs.sort(key=lambda x: x[4], reverse=True) + for idx1, text1, idx2, text2, sim in above_threshold_pairs[:10]: # 最多显示10对 + print(f" [{idx1}] ↔ [{idx2}]: {sim:.3f}") + print(f" \"{text1}\" ↔ \"{text2}\"") + if len(above_threshold_pairs) > 10: + print(f" ... 还有 {len(above_threshold_pairs) - 10} 对满足阈值") + else: + print(f" ⚠️ 警告: 组内没有任何对满足阈值({threshold:.2f}),可能是通过传递性连接") + else: + # 只显示组内第一个项目作为示例 + expr = expressions[group[0]] + text = getattr(expr, field_name, "") + display_text = text[:60] + "..." if len(text) > 60 else text + print(f" 示例: {display_text}") + print(f" ... 还有 {len(group) - 1} 个相似项目") + + print() + + if len(groups) > max_groups: + print(f"... 还有 {len(groups) - max_groups} 组未显示") + + +def main(): + """主函数""" + parser = argparse.ArgumentParser(description="分析expression库中situation和style的相似度") + parser.add_argument( + "--situation-threshold", + type=float, + default=0.7, + help="situation相似度阈值 (0-1, 默认: 0.7)" + ) + parser.add_argument( + "--style-threshold", + type=float, + default=0.7, + help="style相似度阈值 (0-1, 默认: 0.7)" + ) + parser.add_argument( + "--no-details", + action="store_true", + help="不显示详细信息,只显示统计" + ) + parser.add_argument( + "--max-groups", + type=int, + default=20, + help="最多显示的组数 (默认: 20)" + ) + parser.add_argument( + "--output", + type=str, + default=None, + help="输出文件路径 (默认: 自动生成带时间戳的文件)" + ) + + args = parser.parse_args() + + # 验证阈值 + if not 0 <= args.situation_threshold <= 1: + print("错误: situation-threshold 必须在 0-1 之间") + return + if not 0 <= args.style_threshold <= 1: + print("错误: style-threshold 必须在 0-1 之间") + return + + # 确定输出文件路径 + if args.output: + output_file = args.output + else: + # 自动生成带时间戳的输出文件 + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + output_dir = os.path.join(project_root, "data", "temp") + os.makedirs(output_dir, exist_ok=True) + output_file = os.path.join(output_dir, f"expression_similarity_analysis_{timestamp}.txt") + + # 使用TeeOutput同时输出到控制台和文件 + with TeeOutput(output_file) as tee: + # 临时替换sys.stdout + original_stdout = sys.stdout + sys.stdout = tee + + try: + print("=" * 80) + print("Expression 相似度分析工具") + print("=" * 80) + print(f"输出文件: {output_file}") + print() + + _run_analysis(args) + + finally: + # 恢复原始stdout + sys.stdout = original_stdout + + print(f"\n✅ 分析结果已保存到: {output_file}") + + +def _run_analysis(args): + """执行分析的主逻辑""" + + # 查询所有Expression记录 + print("正在从数据库加载Expression数据...") + try: + expressions = list(Expression.select()) + except Exception as e: + print(f"❌ 加载数据失败: {e}") + return + + if not expressions: + print("❌ 数据库中没有找到Expression记录") + return + + print(f"✅ 成功加载 {len(expressions)} 条Expression记录") + print() + + # 构建chat_id分组映射 + print("正在构建chat_id分组映射(根据expression_groups配置)...") + try: + chat_id_groups = build_chat_id_groups() + print(f"✅ 成功构建 {len(chat_id_groups)} 个chat_id的分组映射") + if chat_id_groups: + # 统计分组信息 + total_related = sum(len(related) for related in chat_id_groups.values()) + avg_related = total_related / len(chat_id_groups) + print(f" 平均每个chat_id与 {avg_related:.1f} 个chat_id相关(包括自身)") + print() + except Exception as e: + print(f"⚠️ 构建chat_id分组映射失败: {e}") + print(" 将使用默认行为:只比较相同chat_id的项目") + chat_id_groups = {} + + # 分析situation相似度 + print_similarity_analysis( + expressions, + "situation", + args.situation_threshold, + chat_id_groups, + show_details=not args.no_details, + max_groups=args.max_groups + ) + + # 分析style相似度 + print_similarity_analysis( + expressions, + "style", + args.style_threshold, + chat_id_groups, + show_details=not args.no_details, + max_groups=args.max_groups + ) + + print("\n" + "=" * 80) + print("分析完成!") + print("=" * 80) + + +if __name__ == "__main__": + main() + diff --git a/scripts/import_openie.py b/scripts/import_openie.py index f9405f59..4057a52c 100644 --- a/scripts/import_openie.py +++ b/scripts/import_openie.py @@ -4,10 +4,12 @@ # print("未找到quick_algo库,无法使用quick_algo算法") # print("请安装quick_algo库 - 在lib.quick_algo中,执行命令:python setup.py build_ext --inplace") +import argparse import sys import os import asyncio from time import sleep +from typing import Optional sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) from src.chat.knowledge.embedding_store import EmbeddingManager @@ -71,7 +73,12 @@ def hash_deduplicate( return new_raw_paragraphs, new_triple_list_data -def handle_import_openie(openie_data: OpenIE, embed_manager: EmbeddingManager, kg_manager: KGManager) -> bool: +def handle_import_openie( + openie_data: OpenIE, + embed_manager: EmbeddingManager, + kg_manager: KGManager, + non_interactive: bool = False, +) -> bool: # sourcery skip: extract-method # 从OpenIE数据中提取段落原文与三元组列表 # 索引的段落原文 @@ -124,8 +131,13 @@ def handle_import_openie(openie_data: OpenIE, embed_manager: EmbeddingManager, k logger.info("所有数据均完整,没有发现缺失字段。") return False # 新增:提示用户是否删除非法文段继续导入 - # 将print移到所有logger.error之后,确保不会被冲掉 + # 在非交互模式下,不再询问用户,而是直接报错终止 logger.info(f"\n检测到非法文段,共{len(missing_idxs)}条。") + if non_interactive: + logger.error( + "检测到非法文段且当前处于非交互模式,无法询问是否删除非法文段,导入终止。" + ) + sys.exit(1) logger.info("\n是否删除所有非法文段后继续导入?(y/n): ", end="") user_choice = input().strip().lower() if user_choice != "y": @@ -174,20 +186,25 @@ def handle_import_openie(openie_data: OpenIE, embed_manager: EmbeddingManager, k return True -async def main_async(): # sourcery skip: dict-comprehension +async def main_async(non_interactive: bool = False) -> bool: # sourcery skip: dict-comprehension # 新增确认提示 - print("=== 重要操作确认 ===") - print("OpenIE导入时会大量发送请求,可能会撞到请求速度上限,请注意选用的模型") - print("同之前样例:在本地模型下,在70分钟内我们发送了约8万条请求,在网络允许下,速度会更快") - print("推荐使用硅基流动的Pro/BAAI/bge-m3") - print("每百万Token费用为0.7元") - print("知识导入时,会消耗大量系统资源,建议在较好配置电脑上运行") - print("同上样例,导入时10700K几乎跑满,14900HX占用80%,峰值内存占用约3G") - confirm = input("确认继续执行?(y/n): ").strip().lower() - if confirm != "y": - logger.info("用户取消操作") - print("操作已取消") - sys.exit(1) + if non_interactive: + logger.warning( + "当前处于非交互模式,将跳过导入开销确认提示,直接开始执行 OpenIE 导入。" + ) + else: + print("=== 重要操作确认 ===") + print("OpenIE导入时会大量发送请求,可能会撞到请求速度上限,请注意选用的模型") + print("同之前样例:在本地模型下,在70分钟内我们发送了约8万条请求,在网络允许下,速度会更快") + print("推荐使用硅基流动的Pro/BAAI/bge-m3") + print("每百万Token费用为0.7元") + print("知识导入时,会消耗大量系统资源,建议在较好配置电脑上运行") + print("同上样例,导入时10700K几乎跑满,14900HX占用80%,峰值内存占用约3G") + confirm = input("确认继续执行?(y/n): ").strip().lower() + if confirm != "y": + logger.info("用户取消操作") + print("操作已取消") + sys.exit(1) print("\n" + "=" * 40 + "\n") ensure_openie_dir() # 确保OpenIE目录存在 logger.info("----开始导入openie数据----\n") @@ -235,14 +252,27 @@ async def main_async(): # sourcery skip: dict-comprehension except Exception as e: logger.error(f"导入OpenIE数据文件时发生错误:{e}") return False - if handle_import_openie(openie_data, embed_manager, kg_manager) is False: + if handle_import_openie(openie_data, embed_manager, kg_manager, non_interactive=non_interactive) is False: logger.error("处理OpenIE数据时发生错误") return False - return None + return True -def main(): - """主函数 - 设置新的事件循环并运行异步主函数""" +def main(argv: Optional[list[str]] = None) -> None: + """主函数 - 解析参数并运行异步主流程。""" + parser = argparse.ArgumentParser( + description=( + "OpenIE 导入脚本:读取 data/openie 中的 OpenIE JSON 批次," + "将其导入到 LPMM 的向量库与知识图中。" + ) + ) + parser.add_argument( + "--non-interactive", + action="store_true", + help="非交互模式:跳过导入确认提示以及非法文段删除询问,遇到非法文段时直接报错退出。", + ) + args = parser.parse_args(argv) + # 检查是否有现有的事件循环 try: loop = asyncio.get_running_loop() @@ -255,13 +285,22 @@ def main(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) + ok: bool = False try: # 在新的事件循环中运行异步主函数 - loop.run_until_complete(main_async()) + ok = loop.run_until_complete(main_async(non_interactive=args.non_interactive)) + print( + "\n[NOTICE] OpenIE 导入脚本执行完毕。如主程序(聊天 / WebUI)已在运行," + "请重启主程序,或在主程序内部调用一次 lpmm_start_up() 以应用最新 LPMM 知识库。" + ) + print("[NOTICE] 如果不清楚 lpmm_start_up 是什么,直接重启主程序即可。") finally: # 确保事件循环被正确关闭 if not loop.is_closed(): loop.close() + if not ok: + # 统一错误码,方便在非交互场景下检测失败 + sys.exit(1) if __name__ == "__main__": diff --git a/scripts/info_extraction.py b/scripts/info_extraction.py index 9ef8c098..b5068b0f 100644 --- a/scripts/info_extraction.py +++ b/scripts/info_extraction.py @@ -1,3 +1,4 @@ +import argparse import json import os import signal @@ -5,6 +6,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed from threading import Lock, Event import sys import datetime +from typing import Optional sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) # 添加项目根目录到 sys.path @@ -115,22 +117,34 @@ def signal_handler(_signum, _frame): sys.exit(0) -def main(): # sourcery skip: comprehension-to-generator, extract-method +def _run(non_interactive: bool = False) -> None: # sourcery skip: comprehension-to-generator, extract-method # 设置信号处理器 signal.signal(signal.SIGINT, signal_handler) ensure_dirs() # 确保目录存在 # 新增用户确认提示 - print("=== 重要操作确认,请认真阅读以下内容哦 ===") - print("实体提取操作将会花费较多api余额和时间,建议在空闲时段执行。") - print("举例:600万字全剧情,提取选用deepseek v3 0324,消耗约40元,约3小时。") - print("建议使用硅基流动的非Pro模型") - print("或者使用可以用赠金抵扣的Pro模型") - print("请确保账户余额充足,并且在执行前确认无误。") - confirm = input("确认继续执行?(y/n): ").strip().lower() - if confirm != "y": - logger.info("用户取消操作") - print("操作已取消") - sys.exit(1) + if non_interactive: + logger.warning( + "当前处于非交互模式,将跳过费用与时长确认提示,直接开始进行实体提取操作。" + ) + else: + print("=== 重要操作确认,请认真阅读以下内容哦 ===") + print("实体提取操作将会花费较多api余额和时间,建议在空闲时段执行。") + print("举例:600万字全剧情,提取选用deepseek v3 0324,消耗约40元,约3小时。") + print("建议使用硅基流动的非Pro模型") + print("或者使用可以用赠金抵扣的Pro模型") + print("请确保账户余额充足,并且在执行前确认无误。") + confirm = input("确认继续执行?(y/n): ").strip().lower() + if confirm != "y": + logger.info("用户取消操作") + print("操作已取消") + sys.exit(1) + + # 友好提示:说明“网络错误(可重试)”日志属于正常自动重试行为,避免用户误以为任务失败 + print( + "\n提示:在提取过程中,如果看到模型出现“网络错误(可重试)”等日志," + "表示系统正在自动重试请求,一般不会影响整体导入结果,请耐心等待即可。\n" + ) + print("\n" + "=" * 40 + "\n") ensure_dirs() # 确保目录存在 logger.info("--------进行信息提取--------\n") @@ -215,5 +229,22 @@ def main(): # sourcery skip: comprehension-to-generator, extract-method logger.info(f"提取失败的文段SHA256:{failed_sha256}") +def main(argv: Optional[list[str]] = None) -> None: + parser = argparse.ArgumentParser( + description=( + "LPMM 信息提取脚本:从 data/lpmm_raw_data/*.txt 中读取原始段落," + "调用 LLM 提取实体和三元组,并生成 OpenIE JSON 批次文件。" + ) + ) + parser.add_argument( + "--non-interactive", + action="store_true", + help="非交互模式:跳过费用确认提示,直接开始执行;适用于 CI / 定时任务等场景。", + ) + args = parser.parse_args(argv) + + _run(non_interactive=args.non_interactive) + + if __name__ == "__main__": main() diff --git a/scripts/inspect_lpmm_batch.py b/scripts/inspect_lpmm_batch.py new file mode 100644 index 00000000..2ed719cf --- /dev/null +++ b/scripts/inspect_lpmm_batch.py @@ -0,0 +1,132 @@ +import argparse +import json +import os +import sys +from pathlib import Path +from typing import List, Tuple + +# 确保能导入 src.* +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +from src.chat.knowledge.utils.hash import get_sha256 +from src.chat.knowledge.embedding_store import EmbeddingManager +from src.chat.knowledge.kg_manager import KGManager +from src.common.logger import get_logger + +logger = get_logger("inspect_lpmm_batch") + + +def load_openie_hashes(path: Path) -> Tuple[List[str], List[str], List[str]]: + """从 OpenIE JSON 中提取段落 / 实体 / 关系的哈希 + + 注意:实体既包括 extracted_entities 中的条目,也包括三元组中的主语/宾语, + 以与 KG 构图逻辑保持一致。 + """ + with path.open("r", encoding="utf-8") as f: + data = json.load(f) + + pg_hashes: List[str] = [] + ent_hashes: List[str] = [] + rel_hashes: List[str] = [] + + for doc in data.get("docs", []): + if not isinstance(doc, dict): + continue + idx = doc.get("idx") + if isinstance(idx, str) and idx.strip(): + pg_hashes.append(idx.strip()) + + ents = doc.get("extracted_entities", []) + if isinstance(ents, list): + for e in ents: + if isinstance(e, str): + ent_hashes.append(get_sha256(e)) + + triples = doc.get("extracted_triples", []) + if isinstance(triples, list): + for t in triples: + if isinstance(t, list) and len(t) == 3: + # 主语/宾语作为实体参与构图 + subj, _, obj = t + if isinstance(subj, str): + ent_hashes.append(get_sha256(subj)) + if isinstance(obj, str): + ent_hashes.append(get_sha256(obj)) + rel_hashes.append(get_sha256(str(tuple(t)))) + + # 去重但保留顺序 + def unique(seq: List[str]) -> List[str]: + seen = set() + return [x for x in seq if not (x in seen or seen.add(x))] + + return unique(pg_hashes), unique(ent_hashes), unique(rel_hashes) + + +def main() -> None: + parser = argparse.ArgumentParser( + description="检查指定 OpenIE 文件对应批次在当前向量库与 KG 中的存在情况(用于验证删除效果)。" + ) + parser.add_argument("--openie-file", required=True, help="OpenIE 输出 JSON 文件路径") + args = parser.parse_args() + + openie_path = Path(args.openie_file) + if not openie_path.exists(): + logger.error(f"OpenIE 文件不存在: {openie_path}") + sys.exit(1) + + pg_hashes, ent_hashes, rel_hashes = load_openie_hashes(openie_path) + logger.info( + f"从 {openie_path.name} 解析到 段落 {len(pg_hashes)} 条,实体 {len(ent_hashes)} 个,关系 {len(rel_hashes)} 条" + ) + + # 加载当前嵌入与 KG + em = EmbeddingManager() + kg = KGManager() + try: + em.load_from_file() + kg.load_from_file() + except Exception as e: + logger.error(f"加载当前知识库失败: {e}") + sys.exit(1) + + graph_nodes = set(kg.graph.get_node_list()) + + # 检查段落 + pg_keys = [f"paragraph-{h}" for h in pg_hashes] + pg_in_vec = sum(1 for k in pg_keys if k in em.paragraphs_embedding_store.store) + pg_in_kg = sum(1 for k in pg_keys if k in graph_nodes) + + # 检查实体 + ent_keys = [f"entity-{h}" for h in ent_hashes] + ent_in_vec = sum(1 for k in ent_keys if k in em.entities_embedding_store.store) + ent_in_kg = sum(1 for k in ent_keys if k in graph_nodes) + + # 检查关系(只针对向量库) + rel_keys = [f"relation-{h}" for h in rel_hashes] + rel_in_vec = sum(1 for k in rel_keys if k in em.relation_embedding_store.store) + + print("==== 批次存在情况(删除前/后对比用) ====") + print(f"段落: 总计 {len(pg_keys)}, 向量库剩余 {pg_in_vec}, KG 中剩余 {pg_in_kg}") + print(f"实体: 总计 {len(ent_keys)}, 向量库剩余 {ent_in_vec}, KG 中剩余 {ent_in_kg}") + print(f"关系: 总计 {len(rel_keys)}, 向量库剩余 {rel_in_vec}") + + # 打印少量仍存在的样例,便于检查内容是否正常 + sample_pg = [k for k in pg_keys if k in graph_nodes][:3] + if sample_pg: + print("\n仍在 KG 中的段落节点示例:") + for k in sample_pg: + nd = kg.graph[k] + content = nd["content"] if "content" in nd else k + print(f"- {k}: {content[:80]}") + + sample_ent = [k for k in ent_keys if k in graph_nodes][:3] + if sample_ent: + print("\n仍在 KG 中的实体节点示例:") + for k in sample_ent: + nd = kg.graph[k] + content = nd["content"] if "content" in nd else k + print(f"- {k}: {content[:80]}") + + +if __name__ == "__main__": + main() diff --git a/scripts/inspect_lpmm_global.py b/scripts/inspect_lpmm_global.py new file mode 100644 index 00000000..13b80e14 --- /dev/null +++ b/scripts/inspect_lpmm_global.py @@ -0,0 +1,71 @@ +import os +import sys +from typing import Set + +# 保证可以导入 src.* +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +from src.chat.knowledge.embedding_store import EmbeddingManager +from src.chat.knowledge.kg_manager import KGManager +from src.common.logger import get_logger + +logger = get_logger("inspect_lpmm_global") + + +def main() -> None: + """检查当前整库(所有批次)的向量与 KG 状态,用于观察删除对剩余数据的影响。""" + em = EmbeddingManager() + kg = KGManager() + + try: + em.load_from_file() + kg.load_from_file() + except Exception as e: + logger.error(f"加载当前知识库失败: {e}") + sys.exit(1) + + # 向量库统计 + para_cnt = len(em.paragraphs_embedding_store.store) + ent_cnt_vec = len(em.entities_embedding_store.store) + rel_cnt_vec = len(em.relation_embedding_store.store) + + # KG 统计 + nodes = kg.graph.get_node_list() + edges = kg.graph.get_edge_list() + node_set: Set[str] = set(nodes) + + para_nodes = [n for n in nodes if n.startswith("paragraph-")] + ent_nodes = [n for n in nodes if n.startswith("entity-")] + + print("==== 向量库统计 ====") + print(f"段落向量条数: {para_cnt}") + print(f"实体向量条数: {ent_cnt_vec}") + print(f"关系向量条数: {rel_cnt_vec}") + + print("\n==== KG 图统计 ====") + print(f"节点总数: {len(nodes)}") + print(f"边总数: {len(edges)}") + print(f"段落节点数: {len(para_nodes)}") + print(f"实体节点数: {len(ent_nodes)}") + + # ent_appear_cnt 状态 + ent_cnt_meta = len(kg.ent_appear_cnt) + print(f"\n实体计数表条目数: {ent_cnt_meta}") + + # 抽样查看剩余段落/实体内容 + print("\n==== 剩余段落示例(最多 3 条) ====") + for nid in para_nodes[:3]: + nd = kg.graph[nid] + content = nd["content"] if "content" in nd else nid + print(f"- {nid}: {content[:80]}") + + print("\n==== 剩余实体示例(最多 5 条) ====") + for nid in ent_nodes[:5]: + nd = kg.graph[nid] + content = nd["content"] if "content" in nd else nid + print(f"- {nid}: {content[:80]}") + + +if __name__ == "__main__": + main() + diff --git a/scripts/lpmm_manager.py b/scripts/lpmm_manager.py new file mode 100644 index 00000000..9ca42254 --- /dev/null +++ b/scripts/lpmm_manager.py @@ -0,0 +1,541 @@ +import argparse +import os +import re +import sys +from datetime import datetime +from pathlib import Path +from typing import Optional, List + +# 尽量统一控制台编码为 utf-8,避免中文输出报错 +try: + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8") + if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8") +except Exception: + pass + +# 确保能导入 src.* 以及同目录脚本 +CURRENT_DIR = os.path.dirname(__file__) +PROJECT_ROOT = os.path.abspath(os.path.join(CURRENT_DIR, "..")) +if PROJECT_ROOT not in sys.path: + sys.path.append(PROJECT_ROOT) + +from src.common.logger import get_logger # type: ignore +from src.config.config import global_config, model_config # type: ignore + +# 引入各功能脚本的入口函数 +from import_openie import main as import_openie_main # type: ignore +from info_extraction import main as info_extraction_main # type: ignore +from delete_lpmm_items import main as delete_lpmm_items_main # type: ignore +from inspect_lpmm_batch import main as inspect_lpmm_batch_main # type: ignore +from inspect_lpmm_global import main as inspect_lpmm_global_main # type: ignore +from refresh_lpmm_knowledge import main as refresh_lpmm_knowledge_main # type: ignore +from test_lpmm_retrieval import main as test_lpmm_retrieval_main # type: ignore +from raw_data_preprocessor import load_raw_data # type: ignore + + +logger = get_logger("lpmm_manager") + + +ACTION_INFO = { + "prepare_raw": "预处理 data/lpmm_raw_data/*.txt,按空行切分为段落并做去重统计", + "info_extract": "原始 txt -> OpenIE 信息抽取(调用 info_extraction.py)", + "import_openie": "导入 OpenIE 批次到向量库与知识图(调用 import_openie.py)", + "delete": "删除/回滚知识(调用 delete_lpmm_items.py)", + "batch_inspect": "检查指定 OpenIE 批次在当前库中的存在情况(调用 inspect_lpmm_batch.py)", + "global_inspect": "查看当前整库向量与 KG 状态(调用 inspect_lpmm_global.py)", + "refresh": "刷新 LPMM 磁盘数据到内存(调用 refresh_lpmm_knowledge.py)", + "test": "运行 LPMM 检索效果回归测试(调用 test_lpmm_retrieval.py)", + "embedding_helper": "嵌入模型迁移辅助:查看当前嵌入模型/维度并归档 embedding_model_test.json", + "full_import": "一键执行:信息抽取 -> 导入 OpenIE -> 刷新", +} + + +def _with_overridden_argv(extra_args: List[str], target_main) -> None: + """在不修改子脚本的前提下,临时覆盖 sys.argv 以透传参数。""" + old_argv = list(sys.argv) + try: + # 第 0 个元素为“程序名”,后续元素为实际参数 + # 这里不再插入类似 delete_lpmm_items.py 的占位,避免被 argparse 误识别为位置参数 + sys.argv = [old_argv[0]] + extra_args + target_main() + finally: + sys.argv = old_argv + + +def _check_before_info_extract(non_interactive: bool = False) -> bool: + """信息抽取前的轻量级检查。""" + raw_dir = Path(PROJECT_ROOT) / "data" / "lpmm_raw_data" + txt_files = list(raw_dir.glob("*.txt")) + if not txt_files: + msg = ( + f"[WARN] 未在 {raw_dir} 下找到任何 .txt 原始语料文件," + "info_extraction 可能立即退出或无数据可处理。" + ) + print(msg) + if non_interactive: + logger.error( + "非交互模式下要求原始语料目录中已存在可用的 .txt 文件,请先准备好数据再重试。" + ) + return False + cont = input("仍然继续执行信息提取吗?(y/n): ").strip().lower() + return cont == "y" + return True + + +def _check_before_import_openie(non_interactive: bool = False) -> bool: + """导入 OpenIE 前的轻量级检查。""" + openie_dir = Path(PROJECT_ROOT) / "data" / "openie" + json_files = list(openie_dir.glob("*.json")) + if not json_files: + msg = ( + f"[WARN] 未在 {openie_dir} 下找到任何 OpenIE JSON 文件," + "import_openie 可能会因为找不到批次而失败。" + ) + print(msg) + if non_interactive: + logger.error( + "非交互模式下要求 data/openie 目录中已存在可用的 OpenIE JSON 文件,请先执行信息提取脚本。" + ) + return False + cont = input("仍然继续执行导入吗?(y/n): ").strip().lower() + return cont == "y" + return True + + +def _warn_if_lpmm_disabled() -> None: + """在部分操作前提醒 lpmm_knowledge.enable 状态。""" + try: + if not getattr(global_config.lpmm_knowledge, "enable", False): + print( + "[WARN] 当前配置 lpmm_knowledge.enable = false," + "刷新或检索测试可能无法在聊天侧真正启用 LPMM。" + ) + except Exception: + # 配置异常时不阻断主流程,仅忽略提示 + pass + + +def run_action(action: str, extra_args: Optional[List[str]] = None) -> None: + """根据动作名称调度到对应脚本。 + + 这里不重复解析子参数,而是直接调用各脚本的 main(), + 让子脚本保留原有的交互/参数行为。 + """ + logger.info("开始执行操作: %s", action) + + extra_args = extra_args or [] + + try: + if action == "prepare_raw": + logger.info("开始预处理原始语料 (data/lpmm_raw_data/*.txt)...") + sha_list, raw_data = load_raw_data() + print( + f"\n[PREPARE_RAW] 完成原始语料预处理:共 {len(raw_data)} 条段落," + f"去重后哈希数 {len(sha_list)}。" + ) + elif action == "info_extract": + if not _check_before_info_extract("--non-interactive" in extra_args): + print("已根据用户选择,取消执行信息提取。") + return + _with_overridden_argv(extra_args, info_extraction_main) + elif action == "import_openie": + if not _check_before_import_openie("--non-interactive" in extra_args): + print("已根据用户选择,取消执行导入。") + return + _with_overridden_argv(extra_args, import_openie_main) + elif action == "delete": + _with_overridden_argv(extra_args, delete_lpmm_items_main) + elif action == "batch_inspect": + _with_overridden_argv(extra_args, inspect_lpmm_batch_main) + elif action == "global_inspect": + _with_overridden_argv(extra_args, inspect_lpmm_global_main) + elif action == "refresh": + _warn_if_lpmm_disabled() + _with_overridden_argv(extra_args, refresh_lpmm_knowledge_main) + elif action == "test": + _warn_if_lpmm_disabled() + _with_overridden_argv(extra_args, test_lpmm_retrieval_main) + elif action == "embedding_helper": + # 嵌入模型迁移辅助:查看当前嵌入模型/维度并归档 embedding_model_test.json + _run_embedding_helper() + elif action == "full_import": + # 一键流水线:预处理原始语料 -> 信息抽取 -> 导入 -> 刷新 + logger.info("开始 full_import:预处理原始语料 -> 信息抽取 -> 导入 -> 刷新") + sha_list, raw_data = load_raw_data() + print( + f"\n[FULL_IMPORT] 原始语料预处理完成:共 {len(raw_data)} 条段落," + f"去重后哈希数 {len(sha_list)}。" + ) + non_interactive = "--non-interactive" in extra_args + if not _check_before_info_extract(non_interactive): + print("已根据用户选择,取消 full_import(信息提取阶段被取消)。") + return + # 使用与单步 info_extract 相同的参数透传机制,确保 --non-interactive 等生效 + _with_overridden_argv(extra_args, info_extraction_main) + if not _check_before_import_openie(non_interactive): + print("已根据用户选择,取消 full_import(导入阶段被取消)。") + return + _with_overridden_argv(extra_args, import_openie_main) + _warn_if_lpmm_disabled() + _with_overridden_argv(extra_args, refresh_lpmm_knowledge_main) + else: + logger.error("未知操作: %s", action) + except KeyboardInterrupt: + logger.info("用户中断当前操作(Ctrl+C)") + except SystemExit: + # 子脚本里大量使用 sys.exit,直接透传即可 + raise + except Exception as exc: # pragma: no cover - 防御性兜底 + logger.error("执行操作 %s 时发生未捕获异常: %s", action, exc) + raise + + +def print_menu() -> None: + print("\n===== LPMM 管理菜单 =====") + for idx, key in enumerate( + [ + "prepare_raw", + "info_extract", + "import_openie", + "delete", + "batch_inspect", + "global_inspect", + "refresh", + "test", + "embedding_helper", + "full_import", + ], + start=1, + ): + desc = ACTION_INFO.get(key, "") + print(f"{idx}. {key:14s} - {desc}") + print("0. 退出") + print("=========================") + + +def interactive_loop() -> None: + """交互式选择模式。""" + key_order = [ + "prepare_raw", + "info_extract", + "import_openie", + "delete", + "batch_inspect", + "global_inspect", + "refresh", + "test", + "embedding_helper", + "full_import", + ] + + while True: + print_menu() + choice = input("请输入选项编号(0-10):").strip() + + if choice in ("0", "q", "Q", "quit", "exit"): + print("已退出 LPMM 管理器。") + return + + try: + idx = int(choice) + except ValueError: + print("输入无效,请输入 0-10 之间的数字。") + continue + + if not (1 <= idx <= len(key_order)): + print("输入编号超出范围,请重新输入。") + continue + + action = key_order[idx - 1] + print(f"\n你选择了: {action} - {ACTION_INFO.get(action, '')}") + confirm = input("确认执行该操作?(y/n): ").strip().lower() + if confirm != "y": + print("已取消当前操作。\n") + continue + + # 通过交互式问题,尽量帮用户补全对应脚本的常用参数 + extra_args: List[str] = [] + if action == "delete": + extra_args = _interactive_build_delete_args() + elif action == "batch_inspect": + extra_args = _interactive_build_batch_inspect_args() + elif action == "test": + extra_args = _interactive_build_test_args() + else: + extra_args = [] + + run_action(action, extra_args=extra_args) + print("\n当前操作已结束,回到主菜单。\n") + + +def _interactive_choose_openie_file(prompt: str) -> Optional[str]: + """在 data/openie 下列出可选 JSON 文件,并返回用户选择的路径。""" + openie_dir = Path(PROJECT_ROOT) / "data" / "openie" + files = sorted(openie_dir.glob("*.json")) + if not files: + print(f"[WARN] 在 {openie_dir} 下没有找到任何 OpenIE JSON 文件。") + return input(prompt).strip() or None + + print("\n可选的 OpenIE 批次文件:") + for i, f in enumerate(files, start=1): + print(f"{i}. {f.name}") + print("0. 手动输入完整路径") + + while True: + choice = input("请选择文件编号:").strip() + if choice == "0": + manual = input(prompt).strip() + return manual or None + try: + idx = int(choice) + except ValueError: + print("请输入合法的编号。") + continue + if 1 <= idx <= len(files): + return str(files[idx - 1]) + print("编号超出范围,请重试。") + + +def _interactive_build_delete_args() -> List[str]: + """为 delete_lpmm_items 构造常见参数,减少二次交互。""" + print( + "\n[DELETE] 请选择删除方式:\n" + "1. 按哈希文件删除 (--hash-file)\n" + "2. 按 OpenIE 批次删除 (--openie-file)\n" + "3. 按原始语料文件 + 段落索引删除 (--raw-file + --raw-index)\n" + "4. 按关键字搜索现有段落 (--search-text)\n" + "回车跳过,由子脚本自行交互。" + ) + mode = input("输入选项编号(1-4,或回车跳过):").strip() + args: List[str] = [] + + if mode == "1": + path = input("请输入哈希文件路径(每行一个 hash):").strip() + if path: + args += ["--hash-file", path] + elif mode == "2": + path = _interactive_choose_openie_file("请输入 OpenIE JSON 文件路径:") + if path: + args += ["--openie-file", path] + elif mode == "3": + raw_file = input("请输入原始语料 txt 文件路径:").strip() + raw_index = input("请输入要删除的段落索引(如 1,3):").strip() + if raw_file and raw_index: + args += ["--raw-file", raw_file, "--raw-index", raw_index] + elif mode == "4": + text = input("请输入用于搜索的关键字(出现在段落原文中):").strip() + if text: + args += ["--search-text", text] + else: + # 留空则完全交给子脚本交互 + return [] + + # 进一步询问与安全相关的布尔选项 + print( + "\n[DELETE] 接下来是一些安全相关选项的说明:\n" + "- 删除实体向量/节点:会一并清理与这些段落关联的实体节点及其向量;\n" + "- 删除关系向量:在上面的基础上,额外清理关系向量(一般与删除实体一同使用);\n" + "- 删除孤立实体节点:删除后若实体不再连接任何段落,将其从图中移除,避免残留孤点;\n" + "- dry-run:只预览将要删除的内容,不真正修改任何数据;\n" + "- 跳过交互确认(--yes):直接执行删除操作,适合脚本化或已充分确认的场景;\n" + "- 单次最大删除节点数上限:防止一次性删除规模过大,起到误操作保护作用;\n" + "- 一般情况下建议同时删除实体向量/节点/关系向量/节点,以确保知识图谱的完整性。" + ) + + # 快速选项:按推荐方式清理所有相关实体/关系 + quick_all = input( + "是否使用推荐策略:同时删除关联的实体向量/节点、关系向量,并清理孤立实体?(Y/n): " + ).strip().lower() + if quick_all in ("", "y", "yes"): + args.extend(["--delete-entities", "--delete-relations", "--remove-orphan-entities"]) + else: + # 仅当未使用快速方案时,再逐项询问 + if input("是否同时删除实体向量/节点?(y/N): ").strip().lower() == "y": + args.append("--delete-entities") + if input("是否同时删除关系向量?(y/N): ").strip().lower() == "y": + args.append("--delete-relations") + + if input("是否删除孤立实体节点?(y/N): ").strip().lower() == "y": + args.append("--remove-orphan-entities") + + if input("是否以 dry-run 预览而不真正删除?(y/N): ").strip().lower() == "y": + args.append("--dry-run") + else: + if input("是否跳过交互确认直接删除?(默认否,请谨慎) (y/N): ").strip().lower() == "y": + args.append("--yes") + + max_nodes = input("单次最大删除节点数上限(回车使用默认 2000):").strip() + if max_nodes: + args += ["--max-delete-nodes", max_nodes] + + return args + + +def _interactive_build_batch_inspect_args() -> List[str]: + """为 inspect_lpmm_batch 构造 --openie-file 参数。""" + path = _interactive_choose_openie_file( + "请输入要检查的 OpenIE JSON 文件路径(回车跳过,由子脚本自行交互):" + ) + if not path: + return [] + return ["--openie-file", path] + + +def _interactive_build_test_args() -> List[str]: + """为 test_lpmm_retrieval 构造自定义测试用例参数。""" + print( + "\n[TEST] 你可以:\n" + "- 直接回车使用内置的默认测试用例;\n" + "- 或者输入一条自定义问题,并指定期望命中的关键字。" + ) + query = input("请输入自定义测试问题(回车则使用默认用例):").strip() + if not query: + return [] + + expect = input("请输入期望命中的关键字(可选,多项用逗号分隔):").strip() + args: List[str] = ["--query", query] + if expect: + for kw in expect.split(","): + kw = kw.strip() + if kw: + args.extend(["--expect-keyword", kw]) + return args + + +def _run_embedding_helper() -> None: + """嵌入模型迁移辅助:展示当前配置,并安全归档 embedding_model_test.json。""" + from src.chat.knowledge.embedding_store import EMBEDDING_TEST_FILE # type: ignore + + # 1. 读取当前配置中的嵌入维度与模型信息 + current_dim = getattr(getattr(global_config, "lpmm_knowledge", None), "embedding_dimension", None) + embed_task = getattr(model_config.model_task_config, "embedding", None) + model_ids: List[str] = [] + if embed_task is not None: + model_ids = getattr(embed_task, "model_list", []) or [] + primary_model = model_ids[0] if model_ids else "unknown" + safe_model_name = re.sub(r"[^0-9A-Za-z_.-]+", "_", primary_model) or "unknown" + + print("\n===== 嵌入模型迁移辅助 (embedding_helper) =====") + print(f"- 当前嵌入模型标识(model_task_config.embedding.model_list[0]): {primary_model}") + print(f"- 当前配置中的嵌入维度 (lpmm_knowledge.embedding_dimension): {current_dim}") + print(f"- 测试文件路径: {EMBEDDING_TEST_FILE}") + + new_dim = input( + "\n如果你计划更换嵌入模型,请在此输入“新的嵌入维度”(仅用于记录与提示,回车则跳过):" + ).strip() + if new_dim and not new_dim.isdigit(): + print("输入的维度不是纯数字,已取消操作。") + return + + print( + "\n[重要提示]\n" + "- 修改嵌入模型或维度会导致当前磁盘中的旧知识库(data/embedding 下的向量)与新模型不兼容;\n" + "- 这通常意味着你需要清空旧的向量/图数据,并重新执行 LPMM 导入流水线;\n" + "- 请仅在你**确定要切换嵌入模型/维度**时再继续。\n" + ) + confirm = input("是否已充分评估风险,并准备切换嵌入模型/维度?(y/N): ").strip().lower() + if confirm != "y": + print("已根据你的选择取消嵌入模型迁移辅助操作。") + return + + print( + "\n接下来请手动完成以下操作(脚本不会自动修改配置或删除知识库):\n" + f"1. 在配置文件中,将 lpmm_knowledge.embedding_dimension 从 {current_dim} 修改为你计划使用的新维度" + + (f"(例如 {new_dim})" if new_dim else "") # 仅作为示例 + + ";\n" + "2. 根据需要,清空 data/embedding 与相关 KG 数据(data/rag 等),然后重新执行导入流水线;\n" + "3. 本脚本将帮助你归档当前的 embedding_model_test.json,避免旧测试文件干扰新模型的校验。\n" + ) + + # 2. 归档 embedding_model_test.json + test_path = Path(EMBEDDING_TEST_FILE) + if not test_path.exists(): + print(f"\n[INFO] 未在 {test_path} 发现 embedding_model_test.json,无需归档。") + return + + ts = datetime.now().strftime("%Y%m%d-%H%M%S") + archive_name = f"embedding_model_test-{safe_model_name}-{ts}.json" + archive_path = test_path.with_name(archive_name) + + # 若不巧重名,简单追加后缀避免覆盖 + suffix_id = 1 + while archive_path.exists(): + archive_name = f"embedding_model_test-{safe_model_name}-{ts}-{suffix_id}.json" + archive_path = test_path.with_name(archive_name) + suffix_id += 1 + + try: + test_path.rename(archive_path) + except Exception as exc: # pragma: no cover - 防御性兜底 + logger.error("归档 embedding_model_test.json 失败: %s", exc) + print(f"[ERROR] 归档 embedding_model_test.json 失败,请检查文件权限与路径。错误详情已写入日志。") + return + + print( + f"\n[OK] 已将 {test_path.name} 重命名为 {archive_path.name}。\n" + f"- 归档位置: {archive_path}\n" + "- 之后再次运行涉及嵌入模型的一致性校验时,将会基于当前配置与新模型生成新的测试文件。\n" + "- 在完成配置修改与知识库重导入前,请不要手动再创建名为 embedding_model_test.json 的文件。" + ) + + +def parse_args(argv: Optional[list[str]] = None) -> tuple[argparse.Namespace, List[str]]: + parser = argparse.ArgumentParser( + description=( + "LPMM 管理脚本:集中入口管理 LPMM 的导入 / 删除 / 自检 / 刷新 / 测试等功能。\n" + "可以通过 --interactive 进入菜单模式,也可以使用 --action 直接执行单个操作。" + ) + ) + parser.add_argument( + "-i", + "--interactive", + action="store_true", + help="进入交互式菜单模式(推荐给手动运维使用)", + ) + parser.add_argument( + "-a", + "--action", + choices=list(ACTION_INFO.keys()), + help="直接执行指定操作(非交互模式)", + ) + parser.add_argument( + "--non-interactive", + action="store_true", + help=( + "启用非交互模式:lpmm_manager 自身不会再通过 input() 询问是否继续前置检查;" + "并会将 --non-interactive 透传给子脚本,以避免子脚本中的交互式确认。" + ), + ) + # 允许在管理脚本之后继续跟随子脚本参数,例如: + # python lpmm_manager.py -a delete -- --hash-file xxx --yes + args, unknown = parser.parse_known_args(argv) + return args, unknown + + +def main(argv: Optional[list[str]] = None) -> None: + args, extra_args = parse_args(argv) + + # 如果指定了 non-interactive,则不能进入交互式菜单 + if args.non_interactive and args.interactive: + logger.error("不能同时指定 --interactive 与 --non-interactive,请二选一。") + sys.exit(1) + + # 没有指定 action 或显式要求交互 -> 进入菜单 + if args.interactive or not args.action: + interactive_loop() + return + + # 在非交互模式下,将 --non-interactive 透传给子脚本,避免其内部出现 input() 交互 + if args.non_interactive: + extra_args = ["--non-interactive"] + extra_args + + # 非交互模式:直接执行指定操作 + run_action(args.action, extra_args=extra_args) + + +if __name__ == "__main__": + main() + + diff --git a/scripts/raw_data_preprocessor.py b/scripts/raw_data_preprocessor.py index b5762198..6cca59d3 100644 --- a/scripts/raw_data_preprocessor.py +++ b/scripts/raw_data_preprocessor.py @@ -1,9 +1,9 @@ import os from pathlib import Path import sys # 新增系统模块导入 -from src.chat.knowledge.utils.hash import get_sha256 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +from src.chat.knowledge.utils.hash import get_sha256 from src.common.logger import get_logger logger = get_logger("lpmm") @@ -59,10 +59,11 @@ def load_raw_data() -> tuple[list[str], list[str]]: - raw_data: 原始数据列表 - sha256_list: 原始数据的SHA256集合 """ - raw_data = _process_multi_files() + raw_paragraphs = _process_multi_files() sha256_list = [] sha256_set = set() - for item in raw_data: + raw_data: list[str] = [] + for item in raw_paragraphs: if not isinstance(item, str): logger.warning(f"数据类型错误:{item}") continue diff --git a/scripts/refresh_lpmm_knowledge.py b/scripts/refresh_lpmm_knowledge.py new file mode 100644 index 00000000..e70093a8 --- /dev/null +++ b/scripts/refresh_lpmm_knowledge.py @@ -0,0 +1,66 @@ +import os +import sys + +try: + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8") + if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8") +except Exception: + pass + +# 确保能导入 src.* +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +from src.common.logger import get_logger +from src.config.config import global_config +from src.chat.knowledge import lpmm_start_up, get_qa_manager + +logger = get_logger("refresh_lpmm_knowledge") + + +def main() -> None: + logger.info("开始刷新 LPMM 知识库(重新加载向量库与 KG)...") + + if not global_config.lpmm_knowledge.enable: + logger.warning( + "当前配置中 lpmm_knowledge.enable = false,本次仅刷新磁盘数据与内存结构," + "但聊天侧如未启用 LPMM 仍不会在问答中使用知识库。" + ) + + # 调用标准启动逻辑,内部会加载 data/embedding 与 data/rag + lpmm_start_up() + + qa_manager = get_qa_manager() + if qa_manager is None: + logger.error("刷新后 qa_manager 仍为 None,请检查是否已经成功导入过 LPMM 知识库。") + return + + # 简要输出当前知识库规模,方便人工确认 + embed_manager = qa_manager.embed_manager + kg_manager = qa_manager.kg_manager + + para_vec = len(embed_manager.paragraphs_embedding_store.store) + ent_vec = len(embed_manager.entities_embedding_store.store) + rel_vec = len(embed_manager.relation_embedding_store.store) + nodes = len(kg_manager.graph.get_node_list()) + edges = len(kg_manager.graph.get_edge_list()) + + logger.info("LPMM 知识库刷新完成,当前规模:") + logger.info( + "段落向量=%d, 实体向量=%d, 关系向量=%d, KG节点=%d, KG边=%d", + para_vec, + ent_vec, + rel_vec, + nodes, + edges, + ) + + print("\n[REFRESH] 刷新完成,请注意:") + print("- 本脚本是在独立进程内执行的,用于验证磁盘数据可以正常加载。") + print("- 若主程序已在运行且未在内部调用 lpmm_start_up() 重新初始化,仍需重启或新增管理入口来热刷新。") + print("- 如果不清楚 lpmm_start_up 是什么,只需要重启主程序即可。") + + +if __name__ == "__main__": + main() diff --git a/scripts/replyer_action_stats.py b/scripts/replyer_action_stats.py new file mode 100644 index 00000000..8d8904bf --- /dev/null +++ b/scripts/replyer_action_stats.py @@ -0,0 +1,303 @@ +""" +统计和展示 replyer 动作选择记录 + +用法: + python scripts/replyer_action_stats.py +""" + +import json +import os +import sys +from collections import Counter, defaultdict +from datetime import datetime +from typing import Dict, List, Any +from pathlib import Path + +# Add project root to Python path +project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, project_root) + +try: + from src.common.database.database_model import ChatStreams + from src.chat.message_receive.chat_stream import get_chat_manager +except ImportError: + ChatStreams = None + get_chat_manager = None + + +def get_chat_name(chat_id: str) -> str: + """根据 chat_id 获取聊天名称""" + try: + if ChatStreams: + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == chat_id) + if chat_stream: + if chat_stream.group_name: + return f"{chat_stream.group_name}" + elif chat_stream.user_nickname: + return f"{chat_stream.user_nickname}的私聊" + + if get_chat_manager: + chat_manager = get_chat_manager() + stream_name = chat_manager.get_stream_name(chat_id) + if stream_name: + return stream_name + + return f"未知聊天 ({chat_id[:8]}...)" + except Exception: + return f"查询失败 ({chat_id[:8]}...)" + + +def load_records(temp_dir: str = "data/temp") -> List[Dict[str, Any]]: + """加载所有 replyer 动作记录""" + records = [] + temp_path = Path(temp_dir) + + if not temp_path.exists(): + print(f"目录不存在: {temp_dir}") + return records + + # 查找所有 replyer_action_*.json 文件 + pattern = "replyer_action_*.json" + for file_path in temp_path.glob(pattern): + try: + with open(file_path, "r", encoding="utf-8") as f: + data = json.load(f) + records.append(data) + except Exception as e: + print(f"读取文件失败 {file_path}: {e}") + + # 按时间戳排序 + records.sort(key=lambda x: x.get("timestamp", "")) + return records + + +def format_timestamp(ts: str) -> str: + """格式化时间戳""" + try: + dt = datetime.fromisoformat(ts) + return dt.strftime("%Y-%m-%d %H:%M:%S") + except Exception: + return ts + + +def calculate_time_distribution(records: List[Dict[str, Any]]) -> Dict[str, int]: + """计算时间分布""" + now = datetime.now() + distribution = { + "今天": 0, + "昨天": 0, + "3天内": 0, + "7天内": 0, + "30天内": 0, + "更早": 0, + } + + for record in records: + try: + ts = record.get("timestamp", "") + if not ts: + continue + dt = datetime.fromisoformat(ts) + diff = (now - dt).days + + if diff == 0: + distribution["今天"] += 1 + elif diff == 1: + distribution["昨天"] += 1 + elif diff < 3: + distribution["3天内"] += 1 + elif diff < 7: + distribution["7天内"] += 1 + elif diff < 30: + distribution["30天内"] += 1 + else: + distribution["更早"] += 1 + except Exception: + pass + + return distribution + + +def print_statistics(records: List[Dict[str, Any]]): + """打印统计信息""" + if not records: + print("没有找到任何记录") + return + + print("=" * 80) + print("Replyer 动作选择记录统计") + print("=" * 80) + print() + + # 总记录数 + total_count = len(records) + print(f"📊 总记录数: {total_count}") + print() + + # 时间范围 + timestamps = [r.get("timestamp", "") for r in records if r.get("timestamp")] + if timestamps: + first_time = format_timestamp(min(timestamps)) + last_time = format_timestamp(max(timestamps)) + print(f"📅 时间范围: {first_time} ~ {last_time}") + print() + + # 按 think_level 统计 + think_levels = [r.get("think_level", 0) for r in records] + think_level_counter = Counter(think_levels) + print("🧠 思考深度分布:") + for level in sorted(think_level_counter.keys()): + count = think_level_counter[level] + percentage = (count / total_count) * 100 + level_name = {0: "不需要思考", 1: "简单思考", 2: "深度思考"}.get(level, f"未知({level})") + print(f" Level {level} ({level_name}): {count} 次 ({percentage:.1f}%)") + print() + + # 按 chat_id 统计(总体) + chat_counter = Counter([r.get("chat_id", "未知") for r in records]) + print(f"💬 聊天分布 (共 {len(chat_counter)} 个聊天):") + # 只显示前10个 + for chat_id, count in chat_counter.most_common(10): + chat_name = get_chat_name(chat_id) + percentage = (count / total_count) * 100 + print(f" {chat_name}: {count} 次 ({percentage:.1f}%)") + if len(chat_counter) > 10: + print(f" ... 还有 {len(chat_counter) - 10} 个聊天") + print() + + # 每个 chat_id 的详细统计 + print("=" * 80) + print("每个聊天的详细统计") + print("=" * 80) + print() + + # 按 chat_id 分组记录 + records_by_chat = defaultdict(list) + for record in records: + chat_id = record.get("chat_id", "未知") + records_by_chat[chat_id].append(record) + + # 按记录数排序 + sorted_chats = sorted(records_by_chat.items(), key=lambda x: len(x[1]), reverse=True) + + for chat_id, chat_records in sorted_chats: + chat_name = get_chat_name(chat_id) + chat_count = len(chat_records) + chat_percentage = (chat_count / total_count) * 100 + + print(f"📱 {chat_name} ({chat_id[:8]}...)") + print(f" 总记录数: {chat_count} ({chat_percentage:.1f}%)") + + # 该聊天的 think_level 分布 + chat_think_levels = [r.get("think_level", 0) for r in chat_records] + chat_think_counter = Counter(chat_think_levels) + print(" 思考深度分布:") + for level in sorted(chat_think_counter.keys()): + level_count = chat_think_counter[level] + level_percentage = (level_count / chat_count) * 100 + level_name = {0: "不需要思考", 1: "简单思考", 2: "深度思考"}.get(level, f"未知({level})") + print(f" Level {level} ({level_name}): {level_count} 次 ({level_percentage:.1f}%)") + + # 该聊天的时间范围 + chat_timestamps = [r.get("timestamp", "") for r in chat_records if r.get("timestamp")] + if chat_timestamps: + first_time = format_timestamp(min(chat_timestamps)) + last_time = format_timestamp(max(chat_timestamps)) + print(f" 时间范围: {first_time} ~ {last_time}") + + # 该聊天的时间分布 + chat_time_dist = calculate_time_distribution(chat_records) + print(" 时间分布:") + for period, count in chat_time_dist.items(): + if count > 0: + period_percentage = (count / chat_count) * 100 + print(f" {period}: {count} 次 ({period_percentage:.1f}%)") + + # 显示该聊天最近的一条理由示例 + if chat_records: + latest_record = chat_records[-1] + reason = latest_record.get("reason", "无理由") + if len(reason) > 120: + reason = reason[:120] + "..." + timestamp = format_timestamp(latest_record.get("timestamp", "")) + think_level = latest_record.get("think_level", 0) + print(f" 最新记录 [{timestamp}] (Level {think_level}): {reason}") + + print() + + # 时间分布 + time_dist = calculate_time_distribution(records) + print("⏰ 时间分布:") + for period, count in time_dist.items(): + if count > 0: + percentage = (count / total_count) * 100 + print(f" {period}: {count} 次 ({percentage:.1f}%)") + print() + + # 显示一些示例理由 + print("📝 示例理由 (最近5条):") + recent_records = records[-5:] + for i, record in enumerate(recent_records, 1): + reason = record.get("reason", "无理由") + think_level = record.get("think_level", 0) + timestamp = format_timestamp(record.get("timestamp", "")) + chat_id = record.get("chat_id", "未知") + chat_name = get_chat_name(chat_id) + + # 截断过长的理由 + if len(reason) > 100: + reason = reason[:100] + "..." + + print(f" {i}. [{timestamp}] {chat_name} (Level {think_level})") + print(f" {reason}") + print() + + # 按 think_level 分组显示理由示例 + print("=" * 80) + print("按思考深度分类的示例理由") + print("=" * 80) + print() + + for level in [0, 1, 2]: + level_records = [r for r in records if r.get("think_level") == level] + if not level_records: + continue + + level_name = {0: "不需要思考", 1: "简单思考", 2: "深度思考"}.get(level, f"未知({level})") + print(f"Level {level} ({level_name}) - 共 {len(level_records)} 条:") + + # 显示3个示例(选择最近的) + examples = level_records[-3:] if len(level_records) >= 3 else level_records + for i, record in enumerate(examples, 1): + reason = record.get("reason", "无理由") + if len(reason) > 150: + reason = reason[:150] + "..." + timestamp = format_timestamp(record.get("timestamp", "")) + chat_id = record.get("chat_id", "未知") + chat_name = get_chat_name(chat_id) + print(f" {i}. [{timestamp}] {chat_name}") + print(f" {reason}") + print() + + # 统计信息汇总 + print("=" * 80) + print("统计汇总") + print("=" * 80) + print(f"总记录数: {total_count}") + print(f"涉及聊天数: {len(chat_counter)}") + if chat_counter: + avg_count = total_count / len(chat_counter) + print(f"平均每个聊天记录数: {avg_count:.1f}") + else: + print("平均每个聊天记录数: N/A") + print() + + +def main(): + """主函数""" + records = load_records() + print_statistics(records) + + +if __name__ == "__main__": + main() diff --git a/scripts/test_lpmm_retrieval.py b/scripts/test_lpmm_retrieval.py new file mode 100644 index 00000000..c6aeccda --- /dev/null +++ b/scripts/test_lpmm_retrieval.py @@ -0,0 +1,122 @@ +import argparse +import asyncio +import os +import sys +from typing import List, Dict, Any, Optional + +# 强制使用 utf-8,避免控制台编码报错影响 Embedding 加载 +try: + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8") + if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8") +except Exception: + pass + +# 确保能导入 src.* +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +from src.common.logger import get_logger +from src.config.config import global_config +from src.chat.knowledge import lpmm_start_up +from src.memory_system.retrieval_tools.query_lpmm_knowledge import query_lpmm_knowledge + +logger = get_logger("test_lpmm_retrieval") + + +DEFAULT_TEST_CASES: List[Dict[str, Any]] = [ + { + "name": "回滚一批知识", + "query": "LPMM是什么?", + "expect_keywords": ["哈希列表", "删除脚本", "OpenIE"], + }, + { + "name": "调整 LPMM 检索参数", + "query": "不同用词习惯带来的检索偏差该如何解决", + "expect_keywords": ["bot_config.toml", "lpmm_knowledge", "qa_paragraph_search_top_k"], + }, +] + + +async def run_tests(test_cases: Optional[List[Dict[str, Any]]] = None) -> None: + """简单测试 LPMM 知识库检索能力""" + if not global_config.lpmm_knowledge.enable: + logger.warning("当前配置中 lpmm_knowledge.enable 为 False,检索测试可能直接返回“未启用”。") + + logger.info("开始初始化 LPMM 知识库...") + lpmm_start_up() + logger.info("LPMM 知识库初始化完成,开始执行测试用例。") + + cases = test_cases if test_cases is not None else DEFAULT_TEST_CASES + + for case in cases: + name = case["name"] + query = case["query"] + expect_keywords: List[str] = case.get("expect_keywords", []) + + print("\n" + "=" * 60) + print(f"[TEST] {name}") + print(f"[Q] {query}") + + result = await query_lpmm_knowledge(query, limit=3) + + print("\n[RAW RESULT]") + print(result) + + status = "UNKNOWN" + hit_keywords: List[str] = [] + + if isinstance(result, str): + if "未启用" in result or "未初始化" in result or "查询失败" in result: + status = "ERROR" + elif "未找到与" in result: + status = "NO_HIT" + else: + if expect_keywords: + hit_keywords = [kw for kw in expect_keywords if kw in result] + status = "PASS" if hit_keywords else "WARN" + else: + status = "PASS" + + print("\n[CHECK]") + print(f"Status: {status}") + if expect_keywords: + print(f"Expected keywords: {expect_keywords}") + print(f"Hit keywords: {hit_keywords}") + + print("\n" + "=" * 60) + print("LPMM 检索测试完成。请根据每条用例的 Status 和命中关键词判断检索效果是否符合预期。") + + +def main() -> None: + parser = argparse.ArgumentParser( + description=( + "测试 LPMM 知识库检索能力。\n" + "如不提供参数,则执行内置的默认用例;\n" + "也可以通过 --query 与 --expect-keyword 自定义一条测试用例。" + ) + ) + parser.add_argument( + "--query", + help="自定义测试问题(单条)。提供该参数时,将仅运行这一条用例。", + ) + parser.add_argument( + "--expect-keyword", + action="append", + help="期望在检索结果中出现的关键字,可重复多次指定;仅在提供 --query 时生效。", + ) + args = parser.parse_args() + + if args.query: + custom_case = { + "name": "custom", + "query": args.query, + "expect_keywords": args.expect_keyword or [], + } + asyncio.run(run_tests([custom_case])) + else: + asyncio.run(run_tests()) + + +if __name__ == "__main__": + main() diff --git a/src/bw_learner/expression_learner.py b/src/bw_learner/expression_learner.py new file mode 100644 index 00000000..32a98f44 --- /dev/null +++ b/src/bw_learner/expression_learner.py @@ -0,0 +1,794 @@ +import time +import json +import os +import re +import asyncio +from typing import List, Optional, Tuple, Any, Dict +from src.common.logger import get_logger +from src.common.database.database_model import Expression +from src.llm_models.utils_model import LLMRequest +from src.config.config import model_config, global_config +from src.chat.utils.chat_message_builder import ( + build_anonymous_messages, +) +from src.chat.utils.prompt_builder import Prompt, global_prompt_manager +from src.chat.message_receive.chat_stream import get_chat_manager +from src.bw_learner.learner_utils import ( + filter_message_content, + is_bot_message, + build_context_paragraph, + contains_bot_self_name, + calculate_style_similarity, +) +from src.bw_learner.jargon_miner import miner_manager +from json_repair import repair_json + + +# MAX_EXPRESSION_COUNT = 300 + +logger = get_logger("expressor") + + +def init_prompt() -> None: + learn_style_prompt = """{chat_str} +你的名字是{bot_name},现在请你完成两个提取任务 +任务1:请从上面这段群聊中用户的语言风格和说话方式 +1. 只考虑文字,不要考虑表情包和图片 +2. 不要总结SELF的发言,因为这是你自己的发言,不要重复学习你自己的发言 +3. 不要涉及具体的人名,也不要涉及具体名词 +4. 思考有没有特殊的梗,一并总结成语言风格 +5. 例子仅供参考,请严格根据群聊内容总结!!! +注意:总结成如下格式的规律,总结的内容要详细,但具有概括性: +例如:当"AAAAA"时,可以"BBBBB", AAAAA代表某个场景,不超过20个字。BBBBB代表对应的语言风格,特定句式或表达方式,不超过20个字。 +表达方式在3-5个左右,不要超过10个 + + +任务2:请从上面这段聊天内容中提取"可能是黑话"的候选项(黑话/俚语/网络缩写/口头禅)。 +- 必须为对话中真实出现过的短词或短语 +- 必须是你无法理解含义的词语,没有明确含义的词语,请不要选择有明确含义,或者含义清晰的词语 +- 排除:人名、@、表情包/图片中的内容、纯标点、常规功能词(如的、了、呢、啊等) +- 每个词条长度建议 2-8 个字符(不强制),尽量短小 +- 请你提取出可能的黑话,最多30个黑话,请尽量提取所有 + +黑话必须为以下几种类型: +- 由字母构成的,汉语拼音首字母的简写词,例如:nb、yyds、xswl +- 英文词语的缩写,用英文字母概括一个词汇或含义,例如:CPU、GPU、API +- 中文词语的缩写,用几个汉字概括一个词汇或含义,例如:社死、内卷 + +输出要求: +将表达方式,语言风格和黑话以 JSON 数组输出,每个元素为一个对象,结构如下(注意字段名): +注意请不要输出重复内容,请对表达方式和黑话进行去重。 + +[ + {{"situation": "AAAAA", "style": "BBBBB", "source_id": "3"}}, + {{"situation": "CCCC", "style": "DDDD", "source_id": "7"}} + {{"situation": "对某件事表示十分惊叹", "style": "使用 我嘞个xxxx", "source_id": "[消息编号]"}}, + {{"situation": "表示讽刺的赞同,不讲道理", "style": "对对对", "source_id": "[消息编号]"}}, + {{"situation": "当涉及游戏相关时,夸赞,略带戏谑意味", "style": "使用 这么强!", "source_id": "[消息编号]"}}, + {{"content": "词条", "source_id": "12"}}, + {{"content": "词条2", "source_id": "5"}} +] + +其中: +表达方式条目: +- situation:表示“在什么情境下”的简短概括(不超过20个字) +- style:表示对应的语言风格或常用表达(不超过20个字) +- source_id:该表达方式对应的“来源行编号”,即上方聊天记录中方括号里的数字(例如 [3]),请只输出数字本身,不要包含方括号 +黑话jargon条目: +- content:表示黑话的内容 +- source_id:该黑话对应的“来源行编号”,即上方聊天记录中方括号里的数字(例如 [3]),请只输出数字本身,不要包含方括号 + +现在请你输出 JSON: +""" + Prompt(learn_style_prompt, "learn_style_prompt") + + +class ExpressionLearner: + def __init__(self, chat_id: str) -> None: + self.express_learn_model: LLMRequest = LLMRequest( + model_set=model_config.model_task_config.utils, request_type="expression.learner" + ) + self.summary_model: LLMRequest = LLMRequest( + model_set=model_config.model_task_config.utils_small, request_type="expression.summary" + ) + self.chat_id = chat_id + self.chat_stream = get_chat_manager().get_stream(chat_id) + self.chat_name = get_chat_manager().get_stream_name(chat_id) or chat_id + + # 学习锁,防止并发执行学习任务 + self._learning_lock = asyncio.Lock() + + async def learn_and_store( + self, + messages: List[Any], + ) -> List[Tuple[str, str, str]]: + """ + 学习并存储表达方式 + + Args: + messages: 外部传入的消息列表(必需) + num: 学习数量 + timestamp_start: 学习开始的时间戳,如果为None则使用self.last_learning_time + """ + if not messages: + return None + + random_msg = messages + + # 学习用(开启行编号,便于溯源) + random_msg_str: str = await build_anonymous_messages(random_msg, show_ids=True) + + prompt: str = await global_prompt_manager.format_prompt( + "learn_style_prompt", + bot_name=global_config.bot.nickname, + chat_str=random_msg_str, + ) + + # print(f"random_msg_str:{random_msg_str}") + # logger.info(f"学习{type_str}的prompt: {prompt}") + + try: + response, _ = await self.express_learn_model.generate_response_async(prompt, temperature=0.3) + except Exception as e: + logger.error(f"学习表达方式失败,模型生成出错: {e}") + return None + + # 解析 LLM 返回的表达方式列表和黑话列表(包含来源行编号) + expressions: List[Tuple[str, str, str]] + jargon_entries: List[Tuple[str, str]] # (content, source_id) + expressions, jargon_entries = self.parse_expression_response(response) + expressions = self._filter_self_reference_styles(expressions) + + # 检查表达方式数量,如果超过10个则放弃本次表达学习 + if len(expressions) > 10: + logger.info(f"表达方式提取数量超过10个(实际{len(expressions)}个),放弃本次表达学习") + expressions = [] + + # 检查黑话数量,如果超过30个则放弃本次黑话学习 + if len(jargon_entries) > 30: + logger.info(f"黑话提取数量超过30个(实际{len(jargon_entries)}个),放弃本次黑话学习") + jargon_entries = [] + + # 处理黑话条目,路由到 jargon_miner(即使没有表达方式也要处理黑话) + if jargon_entries: + await self._process_jargon_entries(jargon_entries, random_msg) + + # 如果没有表达方式,直接返回 + if not expressions: + logger.info("过滤后没有可用的表达方式(style 与机器人名称重复)") + return [] + + logger.info(f"学习的prompt: {prompt}") + logger.info(f"学习的expressions: {expressions}") + logger.info(f"学习的jargon_entries: {jargon_entries}") + logger.info(f"学习的response: {response}") + + # 直接根据 source_id 在 random_msg 中溯源,获取 context + filtered_expressions: List[Tuple[str, str, str]] = [] # (situation, style, context) + + for situation, style, source_id in expressions: + source_id_str = (source_id or "").strip() + if not source_id_str.isdigit(): + # 无效的来源行编号,跳过 + continue + + line_index = int(source_id_str) - 1 # build_anonymous_messages 的编号从 1 开始 + if line_index < 0 or line_index >= len(random_msg): + # 超出范围,跳过 + continue + + # 当前行的原始内容 + current_msg = random_msg[line_index] + + # 过滤掉从bot自己发言中提取到的表达方式 + if is_bot_message(current_msg): + continue + + context = filter_message_content(current_msg.processed_plain_text or "") + if not context: + continue + + # 过滤掉包含 SELF 的内容(不学习) + if "SELF" in (situation or "") or "SELF" in (style or "") or "SELF" in context: + logger.info( + f"跳过包含 SELF 的表达方式: situation={situation}, style={style}, source_id={source_id}" + ) + continue + + filtered_expressions.append((situation, style, context)) + + learnt_expressions = filtered_expressions + + if learnt_expressions is None: + logger.info("没有学习到表达风格") + return [] + + # 展示学到的表达方式 + learnt_expressions_str = "" + for ( + situation, + style, + _context, + ) in learnt_expressions: + learnt_expressions_str += f"{situation}->{style}\n" + logger.info(f"在 {self.chat_name} 学习到表达风格:\n{learnt_expressions_str}") + + current_time = time.time() + + # 存储到数据库 Expression 表 + for ( + situation, + style, + context, + ) in learnt_expressions: + await self._upsert_expression_record( + situation=situation, + style=style, + context=context, + current_time=current_time, + ) + + return learnt_expressions + + def parse_expression_response(self, response: str) -> Tuple[List[Tuple[str, str, str]], List[Tuple[str, str]]]: + """ + 解析 LLM 返回的表达风格总结和黑话 JSON,提取两个列表。 + + 期望的 JSON 结构: + [ + {"situation": "AAAAA", "style": "BBBBB", "source_id": "3"}, // 表达方式 + {"content": "词条", "source_id": "12"}, // 黑话 + ... + ] + + Returns: + Tuple[List[Tuple[str, str, str]], List[Tuple[str, str]]]: + 第一个列表是表达方式 (situation, style, source_id) + 第二个列表是黑话 (content, source_id) + """ + if not response: + return [], [] + + raw = response.strip() + + # 尝试提取 ```json 代码块 + json_block_pattern = r"```json\s*(.*?)\s*```" + match = re.search(json_block_pattern, raw, re.DOTALL) + if match: + raw = match.group(1).strip() + else: + # 去掉可能存在的通用 ``` 包裹 + raw = re.sub(r"^```\s*", "", raw, flags=re.MULTILINE) + raw = re.sub(r"```\s*$", "", raw, flags=re.MULTILINE) + raw = raw.strip() + + parsed = None + expressions: List[Tuple[str, str, str]] = [] # (situation, style, source_id) + jargon_entries: List[Tuple[str, str]] = [] # (content, source_id) + + try: + # 优先尝试直接解析 + if raw.startswith("[") and raw.endswith("]"): + parsed = json.loads(raw) + else: + repaired = repair_json(raw) + if isinstance(repaired, str): + parsed = json.loads(repaired) + else: + parsed = repaired + except Exception as parse_error: + # 如果解析失败,尝试修复中文引号问题 + # 使用状态机方法,在 JSON 字符串值内部将中文引号替换为转义的英文引号 + try: + + def fix_chinese_quotes_in_json(text): + """使用状态机修复 JSON 字符串值中的中文引号""" + result = [] + i = 0 + in_string = False + escape_next = False + + while i < len(text): + char = text[i] + + if escape_next: + # 当前字符是转义字符后的字符,直接添加 + result.append(char) + escape_next = False + i += 1 + continue + + if char == "\\": + # 转义字符 + result.append(char) + escape_next = True + i += 1 + continue + + if char == '"' and not escape_next: + # 遇到英文引号,切换字符串状态 + in_string = not in_string + result.append(char) + i += 1 + continue + + if in_string: + # 在字符串值内部,将中文引号替换为转义的英文引号 + if char == '"': # 中文左引号 U+201C + result.append('\\"') + elif char == '"': # 中文右引号 U+201D + result.append('\\"') + else: + result.append(char) + else: + # 不在字符串内,直接添加 + result.append(char) + + i += 1 + + return "".join(result) + + fixed_raw = fix_chinese_quotes_in_json(raw) + + # 再次尝试解析 + if fixed_raw.startswith("[") and fixed_raw.endswith("]"): + parsed = json.loads(fixed_raw) + else: + repaired = repair_json(fixed_raw) + if isinstance(repaired, str): + parsed = json.loads(repaired) + else: + parsed = repaired + except Exception as fix_error: + logger.error(f"解析表达风格 JSON 失败,初始错误: {type(parse_error).__name__}: {str(parse_error)}") + logger.error(f"修复中文引号后仍失败,错误: {type(fix_error).__name__}: {str(fix_error)}") + logger.error(f"解析表达风格 JSON 失败,原始响应:{response}") + logger.error(f"处理后的 JSON 字符串(前500字符):{raw[:500]}") + return [], [] + + if isinstance(parsed, dict): + parsed_list = [parsed] + elif isinstance(parsed, list): + parsed_list = parsed + else: + logger.error(f"表达风格解析结果类型异常: {type(parsed)}, 内容: {parsed}") + return [], [] + + for item in parsed_list: + if not isinstance(item, dict): + continue + + # 检查是否是表达方式条目(有 situation 和 style) + situation = str(item.get("situation", "")).strip() + style = str(item.get("style", "")).strip() + source_id = str(item.get("source_id", "")).strip() + + if situation and style and source_id: + # 表达方式条目 + expressions.append((situation, style, source_id)) + elif item.get("content"): + # 黑话条目(有 content 字段) + content = str(item.get("content", "")).strip() + source_id = str(item.get("source_id", "")).strip() + if content and source_id: + jargon_entries.append((content, source_id)) + + return expressions, jargon_entries + + def _filter_self_reference_styles(self, expressions: List[Tuple[str, str, str]]) -> List[Tuple[str, str, str]]: + """ + 过滤掉style与机器人名称/昵称重复的表达 + """ + banned_names = set() + bot_nickname = (global_config.bot.nickname or "").strip() + if bot_nickname: + banned_names.add(bot_nickname) + + alias_names = global_config.bot.alias_names or [] + for alias in alias_names: + alias = alias.strip() + if alias: + banned_names.add(alias) + + banned_casefold = {name.casefold() for name in banned_names if name} + + filtered: List[Tuple[str, str, str]] = [] + removed_count = 0 + for situation, style, source_id in expressions: + normalized_style = (style or "").strip() + if normalized_style and normalized_style.casefold() not in banned_casefold: + filtered.append((situation, style, source_id)) + else: + removed_count += 1 + + if removed_count: + logger.debug(f"已过滤 {removed_count} 条style与机器人名称重复的表达方式") + + return filtered + + async def _upsert_expression_record( + self, + situation: str, + style: str, + context: str, + current_time: float, + ) -> None: + # 第一层:检查是否有完全一致的 style(检查 style 字段和 style_list) + expr_obj = await self._find_exact_style_match(style) + + if expr_obj: + # 找到完全匹配的 style,合并到现有记录(不使用 LLM 总结) + await self._update_existing_expression( + expr_obj=expr_obj, + situation=situation, + style=style, + context=context, + current_time=current_time, + use_llm_summary=False, + ) + return + + # 第二层:检查是否有相似的 style(相似度 >= 0.75,检查 style 字段和 style_list) + similar_expr_obj = await self._find_similar_style_expression(style, similarity_threshold=0.75) + + if similar_expr_obj: + # 找到相似的 style,合并到现有记录(使用 LLM 总结) + await self._update_existing_expression( + expr_obj=similar_expr_obj, + situation=situation, + style=style, + context=context, + current_time=current_time, + use_llm_summary=True, + ) + return + + # 没有找到匹配的记录,创建新记录 + await self._create_expression_record( + situation=situation, + style=style, + context=context, + current_time=current_time, + ) + + async def _create_expression_record( + self, + situation: str, + style: str, + context: str, + current_time: float, + ) -> None: + content_list = [situation] + # 创建新记录时,直接使用原始的 situation,不进行总结 + formatted_situation = situation + + Expression.create( + situation=formatted_situation, + style=style, + content_list=json.dumps(content_list, ensure_ascii=False), + style_list=None, # 新记录初始时 style_list 为空 + count=1, + last_active_time=current_time, + chat_id=self.chat_id, + create_date=current_time, + context=context, + ) + + async def _update_existing_expression( + self, + expr_obj: Expression, + situation: str, + style: str, + context: str, + current_time: float, + use_llm_summary: bool = True, + ) -> None: + """ + 更新现有 Expression 记录(style 完全匹配或相似的情况) + 将新的 situation 添加到 content_list,将新的 style 添加到 style_list(如果不同) + + Args: + use_llm_summary: 是否使用 LLM 进行总结,完全匹配时为 False,相似匹配时为 True + """ + # 更新 content_list(添加新的 situation) + content_list = self._parse_content_list(expr_obj.content_list) + content_list.append(situation) + expr_obj.content_list = json.dumps(content_list, ensure_ascii=False) + + # 更新 style_list(如果 style 不同,添加到 style_list) + style_list = self._parse_style_list(expr_obj.style_list) + # 将原有的 style 也加入 style_list(如果还没有的话) + if expr_obj.style and expr_obj.style not in style_list: + style_list.append(expr_obj.style) + # 如果新的 style 不在 style_list 中,添加它 + if style not in style_list: + style_list.append(style) + expr_obj.style_list = json.dumps(style_list, ensure_ascii=False) + + # 更新其他字段 + expr_obj.count = (expr_obj.count or 0) + 1 + expr_obj.last_active_time = current_time + expr_obj.context = context + + if use_llm_summary: + # 相似匹配时,使用 LLM 重新组合 situation 和 style + new_situation = await self._compose_situation_text( + content_list=content_list, + count=expr_obj.count, + fallback=expr_obj.situation, + ) + expr_obj.situation = new_situation + + new_style = await self._compose_style_text( + style_list=style_list, + count=expr_obj.count, + fallback=expr_obj.style or style, + ) + expr_obj.style = new_style + else: + # 完全匹配时,不进行 LLM 总结,保持原有的 situation 和 style 不变 + # 只更新 content_list 和 style_list + pass + + expr_obj.save() + + def _parse_content_list(self, stored_list: Optional[str]) -> List[str]: + if not stored_list: + return [] + try: + data = json.loads(stored_list) + except json.JSONDecodeError: + return [] + return [str(item) for item in data if isinstance(item, str)] if isinstance(data, list) else [] + + def _parse_style_list(self, stored_list: Optional[str]) -> List[str]: + """解析 style_list JSON 字符串为列表,逻辑与 _parse_content_list 相同""" + if not stored_list: + return [] + try: + data = json.loads(stored_list) + except json.JSONDecodeError: + return [] + return [str(item) for item in data if isinstance(item, str)] if isinstance(data, list) else [] + + async def _find_exact_style_match(self, style: str) -> Optional[Expression]: + """ + 查找具有完全匹配 style 的 Expression 记录 + 只检查 style_list 中的每一项(不检查 style 字段,因为 style 可能是总结后的概括性描述) + + Args: + style: 要查找的 style + + Returns: + 找到的 Expression 对象,如果没有找到则返回 None + """ + # 查询同一 chat_id 的所有记录 + all_expressions = Expression.select().where(Expression.chat_id == self.chat_id) + + for expr in all_expressions: + # 只检查 style_list 中的每一项 + style_list = self._parse_style_list(expr.style_list) + if style in style_list: + return expr + + return None + + async def _find_similar_style_expression(self, style: str, similarity_threshold: float = 0.75) -> Optional[Expression]: + """ + 查找具有相似 style 的 Expression 记录 + 只检查 style_list 中的每一项(不检查 style 字段,因为 style 可能是总结后的概括性描述) + + Args: + style: 要查找的 style + similarity_threshold: 相似度阈值,默认 0.75 + + Returns: + 找到的最相似的 Expression 对象,如果没有找到则返回 None + """ + # 查询同一 chat_id 的所有记录 + all_expressions = Expression.select().where(Expression.chat_id == self.chat_id) + + best_match = None + best_similarity = 0.0 + + for expr in all_expressions: + # 只检查 style_list 中的每一项 + style_list = self._parse_style_list(expr.style_list) + for existing_style in style_list: + similarity = calculate_style_similarity(style, existing_style) + if similarity >= similarity_threshold and similarity > best_similarity: + best_similarity = similarity + best_match = expr + + if best_match: + logger.debug(f"找到相似的 style: 相似度={best_similarity:.3f}, 现有='{best_match.style}', 新='{style}'") + + return best_match + + async def _compose_situation_text(self, content_list: List[str], count: int, fallback: str = "") -> str: + sanitized = [c.strip() for c in content_list if c.strip()] + summary = await self._summarize_situations(sanitized) + if summary: + return summary + return "/".join(sanitized) if sanitized else fallback + + async def _compose_style_text(self, style_list: List[str], count: int, fallback: str = "") -> str: + """ + 组合 style 文本,如果 style_list 有多个元素则尝试总结 + """ + sanitized = [s.strip() for s in style_list if s.strip()] + if len(sanitized) > 1: + # 只有当有多个 style 时才尝试总结 + summary = await self._summarize_styles(sanitized) + if summary: + return summary + # 如果只有一个或总结失败,返回第一个或 fallback + return sanitized[0] if sanitized else fallback + + async def _summarize_styles(self, styles: List[str]) -> Optional[str]: + """总结多个 style,生成一个概括性的 style 描述""" + if not styles or len(styles) <= 1: + return None + + # 计算输入列表中最长项目的长度 + max_input_length = max(len(s) for s in styles) if styles else 0 + max_summary_length = max_input_length * 2 + + # 最多重试3次 + max_retries = 3 + retry_count = 0 + + while retry_count < max_retries: + # 如果是重试,在 prompt 中强调要更简洁 + length_hint = f"长度不超过{max_summary_length}个字符," if retry_count > 0 else "长度不超过20个字," + + prompt = ( + "请阅读以下多个语言风格/表达方式,对其进行总结。" + "不要对其进行语义概括,而是尽可能找出其中不变的部分或共同表达,尽量使用原文" + f"{length_hint}保留共同特点:\n" + f"{chr(10).join(f'- {s}' for s in styles[-10:])}\n只输出概括内容。不要输出其他内容" + ) + + try: + summary, _ = await self.summary_model.generate_response_async(prompt, temperature=0.2) + summary = summary.strip() + if summary: + # 检查总结长度是否超过限制 + if len(summary) <= max_summary_length: + return summary + else: + retry_count += 1 + logger.debug( + f"总结长度 {len(summary)} 超过限制 {max_summary_length} " + f"(输入最长项长度: {max_input_length}),重试第 {retry_count} 次" + ) + continue + except Exception as e: + logger.error(f"概括表达风格失败: {e}") + return None + + # 如果重试多次后仍然超过长度,返回 None(不进行总结) + logger.warning( + f"总结多次后仍超过长度限制,放弃总结。" + f"输入最长项长度: {max_input_length}, 最大允许长度: {max_summary_length}" + ) + return None + + async def _summarize_situations(self, situations: List[str]) -> Optional[str]: + if not situations: + return None + + prompt = ( + "请阅读以下多个聊天情境描述,并将它们概括成一句简短的话," + "长度不超过20个字,保留共同特点:\n" + f"{chr(10).join(f'- {s}' for s in situations[-10:])}\n只输出概括内容。" + ) + + try: + summary, _ = await self.summary_model.generate_response_async(prompt, temperature=0.2) + summary = summary.strip() + if summary: + return summary + except Exception as e: + logger.error(f"概括表达情境失败: {e}") + return None + + async def _process_jargon_entries(self, jargon_entries: List[Tuple[str, str]], messages: List[Any]) -> None: + """ + 处理从 expression learner 提取的黑话条目,路由到 jargon_miner + + Args: + jargon_entries: 黑话条目列表,每个元素是 (content, source_id) + messages: 消息列表,用于构建上下文 + """ + if not jargon_entries or not messages: + return + + # 获取 jargon_miner 实例 + jargon_miner = miner_manager.get_miner(self.chat_id) + + # 构建黑话条目格式,与 jargon_miner.run_once 中的格式一致 + entries: List[Dict[str, List[str]]] = [] + + for content, source_id in jargon_entries: + content = content.strip() + if not content: + continue + + # 过滤掉包含 SELF 的黑话,不学习 + if "SELF" in content: + logger.info(f"跳过包含 SELF 的黑话: {content}") + continue + + # 检查是否包含机器人名称 + if contains_bot_self_name(content): + logger.info(f"跳过包含机器人昵称/别名的黑话: {content}") + continue + + # 解析 source_id + source_id_str = (source_id or "").strip() + if not source_id_str.isdigit(): + logger.warning(f"黑话条目 source_id 无效: content={content}, source_id={source_id_str}") + continue + + # build_anonymous_messages 的编号从 1 开始 + line_index = int(source_id_str) - 1 + if line_index < 0 or line_index >= len(messages): + logger.warning(f"黑话条目 source_id 超出范围: content={content}, source_id={source_id_str}") + continue + + # 检查是否是机器人自己的消息 + target_msg = messages[line_index] + if is_bot_message(target_msg): + logger.info(f"跳过引用机器人自身消息的黑话: content={content}, source_id={source_id_str}") + continue + + # 构建上下文段落 + context_paragraph = build_context_paragraph(messages, line_index) + if not context_paragraph: + logger.warning(f"黑话条目上下文为空: content={content}, source_id={source_id_str}") + continue + + entries.append({"content": content, "raw_content": [context_paragraph]}) + + if not entries: + return + + # 调用 jargon_miner 处理这些条目 + await jargon_miner.process_extracted_entries(entries) + + +init_prompt() + + +class ExpressionLearnerManager: + def __init__(self): + self.expression_learners = {} + + self._ensure_expression_directories() + + def get_expression_learner(self, chat_id: str) -> ExpressionLearner: + if chat_id not in self.expression_learners: + self.expression_learners[chat_id] = ExpressionLearner(chat_id) + return self.expression_learners[chat_id] + + def _ensure_expression_directories(self): + """ + 确保表达方式相关的目录结构存在 + """ + base_dir = os.path.join("data", "expression") + directories_to_create = [ + base_dir, + os.path.join(base_dir, "learnt_style"), + os.path.join(base_dir, "learnt_grammar"), + ] + + for directory in directories_to_create: + try: + os.makedirs(directory, exist_ok=True) + logger.debug(f"确保目录存在: {directory}") + except Exception as e: + logger.error(f"创建目录失败 {directory}: {e}") + + +expression_learner_manager = ExpressionLearnerManager() diff --git a/src/bw_learner/expression_reflector.py b/src/bw_learner/expression_reflector.py new file mode 100644 index 00000000..c627b5b7 --- /dev/null +++ b/src/bw_learner/expression_reflector.py @@ -0,0 +1,250 @@ +import random +import time +from typing import Optional, Dict + +from src.common.logger import get_logger +from src.common.database.database_model import Expression +from src.config.config import global_config +from src.chat.message_receive.chat_stream import get_chat_manager +from src.plugin_system.apis import send_api + +logger = get_logger("expression_reflector") + + +class ExpressionReflector: + """表达反思器,管理单个聊天流的表达反思提问""" + + def __init__(self, chat_id: str): + self.chat_id = chat_id + self.last_ask_time: float = 0.0 + + async def check_and_ask(self) -> bool: + """ + 检查是否需要提问表达反思,如果需要则提问 + + Returns: + bool: 是否执行了提问 + """ + try: + logger.debug(f"[Expression Reflection] 开始检查是否需要提问 (stream_id: {self.chat_id})") + + if not global_config.expression.reflect: + logger.debug("[Expression Reflection] 表达反思功能未启用,跳过") + return False + + operator_config = global_config.expression.reflect_operator_id + if not operator_config: + logger.debug("[Expression Reflection] Operator ID 未配置,跳过") + return False + + # 检查是否在允许列表中 + allow_reflect = global_config.expression.allow_reflect + if allow_reflect: + # 将 allow_reflect 中的 platform:id:type 格式转换为 chat_id 列表 + allow_reflect_chat_ids = [] + for stream_config in allow_reflect: + parsed_chat_id = global_config.expression._parse_stream_config_to_chat_id(stream_config) + if parsed_chat_id: + allow_reflect_chat_ids.append(parsed_chat_id) + else: + logger.warning(f"[Expression Reflection] 无法解析 allow_reflect 配置项: {stream_config}") + + if self.chat_id not in allow_reflect_chat_ids: + logger.info(f"[Expression Reflection] 当前聊天流 {self.chat_id} 不在允许列表中,跳过") + return False + + # 检查上一次提问时间 + current_time = time.time() + time_since_last_ask = current_time - self.last_ask_time + + # 5-10分钟间隔,随机选择 + min_interval = 10 * 60 # 5分钟 + max_interval = 15 * 60 # 10分钟 + interval = random.uniform(min_interval, max_interval) + + logger.info( + f"[Expression Reflection] 上次提问时间: {self.last_ask_time:.2f}, 当前时间: {current_time:.2f}, 已过时间: {time_since_last_ask:.2f}秒 ({time_since_last_ask / 60:.2f}分钟), 需要间隔: {interval:.2f}秒 ({interval / 60:.2f}分钟)" + ) + + if time_since_last_ask < interval: + remaining_time = interval - time_since_last_ask + logger.info( + f"[Expression Reflection] 距离上次提问时间不足,还需等待 {remaining_time:.2f}秒 ({remaining_time / 60:.2f}分钟),跳过" + ) + return False + + # 检查是否已经有针对该 Operator 的 Tracker 在运行 + logger.info(f"[Expression Reflection] 检查 Operator {operator_config} 是否已有活跃的 Tracker") + if await _check_tracker_exists(operator_config): + logger.info(f"[Expression Reflection] Operator {operator_config} 已有活跃的 Tracker,跳过本次提问") + return False + + # 获取未检查的表达 + try: + logger.info("[Expression Reflection] 查询未检查且未拒绝的表达") + expressions = Expression.select().where((~Expression.checked) & (~Expression.rejected)).limit(50) + + expr_list = list(expressions) + logger.info(f"[Expression Reflection] 找到 {len(expr_list)} 个候选表达") + + if not expr_list: + logger.info("[Expression Reflection] 没有可用的表达,跳过") + return False + + target_expr: Expression = random.choice(expr_list) + logger.info( + f"[Expression Reflection] 随机选择了表达 ID: {target_expr.id}, Situation: {target_expr.situation}, Style: {target_expr.style}" + ) + + # 生成询问文本 + ask_text = _generate_ask_text(target_expr) + if not ask_text: + logger.warning("[Expression Reflection] 生成询问文本失败,跳过") + return False + + logger.info(f"[Expression Reflection] 准备向 Operator {operator_config} 发送提问") + # 发送给 Operator + await _send_to_operator(operator_config, ask_text, target_expr) + + # 更新上一次提问时间 + self.last_ask_time = current_time + logger.info(f"[Expression Reflection] 提问成功,已更新上次提问时间为 {current_time:.2f}") + + return True + + except Exception as e: + logger.error(f"[Expression Reflection] 检查或提问过程中出错: {e}") + import traceback + + logger.error(traceback.format_exc()) + return False + except Exception as e: + logger.error(f"[Expression Reflection] 检查或提问过程中出错: {e}") + import traceback + + logger.error(traceback.format_exc()) + return False + + +class ExpressionReflectorManager: + """表达反思管理器,管理多个聊天流的表达反思实例""" + + def __init__(self): + self.reflectors: Dict[str, ExpressionReflector] = {} + + def get_or_create_reflector(self, chat_id: str) -> ExpressionReflector: + """获取或创建指定聊天流的表达反思实例""" + if chat_id not in self.reflectors: + self.reflectors[chat_id] = ExpressionReflector(chat_id) + return self.reflectors[chat_id] + + +# 创建全局实例 +expression_reflector_manager = ExpressionReflectorManager() + + +async def _check_tracker_exists(operator_config: str) -> bool: + """检查指定 Operator 是否已有活跃的 Tracker""" + from src.bw_learner.reflect_tracker import reflect_tracker_manager + + chat_manager = get_chat_manager() + chat_stream = None + + # 尝试解析配置字符串 "platform:id:type" + parts = operator_config.split(":") + if len(parts) == 3: + platform = parts[0] + id_str = parts[1] + stream_type = parts[2] + + user_info = None + group_info = None + + from maim_message import UserInfo, GroupInfo + + if stream_type == "group": + group_info = GroupInfo(group_id=id_str, platform=platform) + user_info = UserInfo(user_id="system", user_nickname="System", platform=platform) + elif stream_type == "private": + user_info = UserInfo(user_id=id_str, platform=platform, user_nickname="Operator") + else: + return False + + if user_info: + try: + chat_stream = await chat_manager.get_or_create_stream(platform, user_info, group_info) + except Exception as e: + logger.error(f"Failed to get or create chat stream for checking tracker: {e}") + return False + else: + chat_stream = chat_manager.get_stream(operator_config) + + if not chat_stream: + return False + + return reflect_tracker_manager.get_tracker(chat_stream.stream_id) is not None + + +def _generate_ask_text(expr: Expression) -> Optional[str]: + try: + ask_text = ( + f"我正在学习新的表达方式,请帮我看看这个是否合适?\n\n" + f"**学习到的表达信息**\n" + f"- 情景 (Situation): {expr.situation}\n" + f"- 风格 (Style): {expr.style}\n" + ) + return ask_text + except Exception as e: + logger.error(f"Failed to generate ask text: {e}") + return None + + +async def _send_to_operator(operator_config: str, text: str, expr: Expression): + chat_manager = get_chat_manager() + chat_stream = None + + # 尝试解析配置字符串 "platform:id:type" + parts = operator_config.split(":") + if len(parts) == 3: + platform = parts[0] + id_str = parts[1] + stream_type = parts[2] + + user_info = None + group_info = None + + from maim_message import UserInfo, GroupInfo + + if stream_type == "group": + group_info = GroupInfo(group_id=id_str, platform=platform) + user_info = UserInfo(user_id="system", user_nickname="System", platform=platform) + elif stream_type == "private": + user_info = UserInfo(user_id=id_str, platform=platform, user_nickname="Operator") + else: + logger.warning(f"Unknown stream type in operator config: {stream_type}") + return + + if user_info: + try: + chat_stream = await chat_manager.get_or_create_stream(platform, user_info, group_info) + except Exception as e: + logger.error(f"Failed to get or create chat stream for operator {operator_config}: {e}") + return + else: + chat_stream = chat_manager.get_stream(operator_config) + + if not chat_stream: + logger.warning(f"Could not find or create chat stream for operator: {operator_config}") + return + + stream_id = chat_stream.stream_id + + # 注册 Tracker + from src.bw_learner.reflect_tracker import ReflectTracker, reflect_tracker_manager + + tracker = ReflectTracker(chat_stream=chat_stream, expression=expr, created_time=time.time()) + reflect_tracker_manager.add_tracker(stream_id, tracker) + + # 发送消息 + await send_api.text_to_stream(text=text, stream_id=stream_id, typing=True) + logger.info(f"Sent expression reflect query to operator {operator_config} for expr {expr.id}") diff --git a/src/express/expression_selector.py b/src/bw_learner/expression_selector.py similarity index 56% rename from src/express/expression_selector.py rename to src/bw_learner/expression_selector.py index b4e25f36..4140d102 100644 --- a/src/express/expression_selector.py +++ b/src/bw_learner/expression_selector.py @@ -1,6 +1,5 @@ import json import time -import hashlib from typing import List, Dict, Optional, Any, Tuple from json_repair import repair_json @@ -10,7 +9,8 @@ from src.config.config import global_config, model_config from src.common.logger import get_logger from src.common.database.database_model import Expression from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.express.express_utils import weighted_sample +from src.bw_learner.learner_utils import weighted_sample +from src.chat.message_receive.chat_stream import get_chat_manager logger = get_logger("expression_selector") @@ -67,7 +67,7 @@ class ExpressionSelector: @staticmethod def _parse_stream_config_to_chat_id(stream_config_str: str) -> Optional[str]: - """解析'platform:id:type'为chat_id(与get_stream_id一致)""" + """解析'platform:id:type'为chat_id,直接使用 ChatManager 提供的接口""" try: parts = stream_config_str.split(":") if len(parts) != 3: @@ -76,12 +76,8 @@ class ExpressionSelector: id_str = parts[1] stream_type = parts[2] is_group = stream_type == "group" - if is_group: - components = [platform, str(id_str)] - else: - components = [platform, str(id_str), "private"] - key = "_".join(components) - return hashlib.md5(key.encode()).hexdigest() + # 统一通过 chat_manager 生成 stream_id,避免各处自行实现哈希逻辑 + return get_chat_manager().get_stream_id(platform, str(id_str), is_group=is_group) except Exception: return None @@ -111,6 +107,85 @@ class ExpressionSelector: return group_chat_ids return [chat_id] + def _select_expressions_simple(self, chat_id: str, max_num: int) -> Tuple[List[Dict[str, Any]], List[int]]: + """ + 简单模式:只选择 count > 1 的项目,要求至少有10个才进行选择,随机选5个,不进行LLM选择 + + Args: + chat_id: 聊天流ID + max_num: 最大选择数量(此参数在此模式下不使用,固定选择5个) + + Returns: + Tuple[List[Dict[str, Any]], List[int]]: 选中的表达方式列表和ID列表 + """ + try: + # 支持多chat_id合并抽选 + related_chat_ids = self.get_related_chat_ids(chat_id) + + # 查询所有相关chat_id的表达方式,排除 rejected=1 的,且只选择 count > 1 的 + style_query = Expression.select().where( + (Expression.chat_id.in_(related_chat_ids)) & (~Expression.rejected) & (Expression.count > 1) + ) + + style_exprs = [ + { + "id": expr.id, + "situation": expr.situation, + "style": expr.style, + "last_active_time": expr.last_active_time, + "source_id": expr.chat_id, + "create_date": expr.create_date if expr.create_date is not None else expr.last_active_time, + "count": expr.count if getattr(expr, "count", None) is not None else 1, + "checked": expr.checked if getattr(expr, "checked", None) is not None else False, + } + for expr in style_query + ] + + # 要求至少有一定数量的 count > 1 的表达方式才进行“完整简单模式”选择 + min_required = 8 + if len(style_exprs) < min_required: + # 高 count 样本不足:如果还有候选,就降级为随机选 3 个;如果一个都没有,则直接返回空 + if not style_exprs: + logger.info( + f"聊天流 {chat_id} 没有满足 count > 1 且未被拒绝的表达方式,简单模式不进行选择" + ) + # 完全没有高 count 样本时,退化为全量随机抽样(不进入LLM流程) + fallback_num = min(3, max_num) if max_num > 0 else 3 + fallback_selected = self._random_expressions(chat_id, fallback_num) + if fallback_selected: + self.update_expressions_last_active_time(fallback_selected) + selected_ids = [expr["id"] for expr in fallback_selected] + logger.info( + f"聊天流 {chat_id} 使用简单模式降级随机抽选 {len(fallback_selected)} 个表达(无 count>1 样本)" + ) + return fallback_selected, selected_ids + return [], [] + logger.info( + f"聊天流 {chat_id} count > 1 的表达方式不足 {min_required} 个(实际 {len(style_exprs)} 个)," + f"简单模式降级为随机选择 3 个" + ) + select_count = min(3, len(style_exprs)) + else: + # 高 count 数量达标时,固定选择 5 个 + select_count = 5 + import random + + selected_style = random.sample(style_exprs, select_count) + + # 更新last_active_time + if selected_style: + self.update_expressions_last_active_time(selected_style) + + selected_ids = [expr["id"] for expr in selected_style] + logger.debug( + f"think_level=0: 从 {len(style_exprs)} 个 count>1 的表达方式中随机选择了 {len(selected_style)} 个" + ) + return selected_style, selected_ids + + except Exception as e: + logger.error(f"简单模式选择表达方式失败: {e}") + return [], [] + def _random_expressions(self, chat_id: str, total_num: int) -> List[Dict[str, Any]]: """ 随机选择表达方式 @@ -126,8 +201,8 @@ class ExpressionSelector: # 支持多chat_id合并抽选 related_chat_ids = self.get_related_chat_ids(chat_id) - # 优化:一次性查询所有相关chat_id的表达方式 - style_query = Expression.select().where((Expression.chat_id.in_(related_chat_ids))) + # 优化:一次性查询所有相关chat_id的表达方式,排除 rejected=1 的表达 + style_query = Expression.select().where((Expression.chat_id.in_(related_chat_ids)) & (~Expression.rejected)) style_exprs = [ { @@ -138,6 +213,7 @@ class ExpressionSelector: "source_id": expr.chat_id, "create_date": expr.create_date if expr.create_date is not None else expr.last_active_time, "count": expr.count if getattr(expr, "count", None) is not None else 1, + "checked": expr.checked if getattr(expr, "checked", None) is not None else False, } for expr in style_query ] @@ -148,7 +224,6 @@ class ExpressionSelector: else: selected_style = [] - logger.info(f"随机选择,为聊天室 {chat_id} 选择了 {len(selected_style)} 个表达方式") return selected_style except Exception as e: @@ -162,6 +237,7 @@ class ExpressionSelector: max_num: int = 10, target_message: Optional[str] = None, reply_reason: Optional[str] = None, + think_level: int = 1, ) -> Tuple[List[Dict[str, Any]], List[int]]: """ 选择适合的表达方式(使用classic模式:随机选择+LLM选择) @@ -172,6 +248,7 @@ class ExpressionSelector: max_num: 最大选择数量 target_message: 目标消息内容 reply_reason: planner给出的回复理由 + think_level: 思考级别,0/1 Returns: Tuple[List[Dict[str, Any]], List[int]]: 选中的表达方式列表和ID列表 @@ -182,8 +259,10 @@ class ExpressionSelector: return [], [] # 使用classic模式(随机选择+LLM选择) - logger.debug(f"使用classic模式为聊天流 {chat_id} 选择表达方式") - return await self._select_expressions_classic(chat_id, chat_info, max_num, target_message, reply_reason) + logger.debug(f"使用classic模式为聊天流 {chat_id} 选择表达方式,think_level={think_level}") + return await self._select_expressions_classic( + chat_id, chat_info, max_num, target_message, reply_reason, think_level + ) async def _select_expressions_classic( self, @@ -192,6 +271,7 @@ class ExpressionSelector: max_num: int = 10, target_message: Optional[str] = None, reply_reason: Optional[str] = None, + think_level: int = 1, ) -> Tuple[List[Dict[str, Any]], List[int]]: """ classic模式:随机选择+LLM选择 @@ -202,24 +282,91 @@ class ExpressionSelector: max_num: 最大选择数量 target_message: 目标消息内容 reply_reason: planner给出的回复理由 + think_level: 思考级别,0/1 Returns: Tuple[List[Dict[str, Any]], List[int]]: 选中的表达方式列表和ID列表 """ try: - # 1. 使用随机抽样选择表达方式 - style_exprs = self._random_expressions(chat_id, 20) + # think_level == 0: 只选择 count > 1 的项目,随机选10个,不进行LLM选择 + if think_level == 0: + return self._select_expressions_simple(chat_id, max_num) - if len(style_exprs) < 10: - logger.info(f"聊天流 {chat_id} 表达方式正在积累中") + # think_level == 1: 先选高count,再从所有表达方式中随机抽样 + # 1. 获取所有表达方式并分离 count > 1 和 count <= 1 的 + related_chat_ids = self.get_related_chat_ids(chat_id) + style_query = Expression.select().where((Expression.chat_id.in_(related_chat_ids)) & (~Expression.rejected)) + + all_style_exprs = [ + { + "id": expr.id, + "situation": expr.situation, + "style": expr.style, + "last_active_time": expr.last_active_time, + "source_id": expr.chat_id, + "create_date": expr.create_date if expr.create_date is not None else expr.last_active_time, + "count": expr.count if getattr(expr, "count", None) is not None else 1, + "checked": expr.checked if getattr(expr, "checked", None) is not None else False, + } + for expr in style_query + ] + + # 分离 count > 1 和 count <= 1 的表达方式 + high_count_exprs = [expr for expr in all_style_exprs if (expr.get("count", 1) or 1) > 1] + + # 根据 think_level 设置要求(仅支持 0/1,0 已在上方返回) + min_high_count = 10 + min_total_count = 10 + select_high_count = 5 + select_random_count = 5 + + # 检查数量要求 + # 对于高 count 表达:如果数量不足,不再直接停止,而是仅跳过“高 count 优先选择” + if len(high_count_exprs) < min_high_count: + logger.info( + f"聊天流 {chat_id} count > 1 的表达方式不足 {min_high_count} 个(实际 {len(high_count_exprs)} 个)," + f"将跳过高 count 优先选择,仅从全部表达中随机抽样" + ) + high_count_valid = False + else: + high_count_valid = True + + # 总量不足仍然直接返回,避免样本过少导致选择质量过低 + if len(all_style_exprs) < min_total_count: + logger.info( + f"聊天流 {chat_id} 总表达方式不足 {min_total_count} 个(实际 {len(all_style_exprs)} 个),不进行选择" + ) return [], [] + # 先选取高count的表达方式(如果数量达标) + if high_count_valid: + selected_high = weighted_sample(high_count_exprs, min(len(high_count_exprs), select_high_count)) + else: + selected_high = [] + + # 然后从所有表达方式中随机抽样(使用加权抽样) + remaining_num = select_random_count + selected_random = weighted_sample(all_style_exprs, min(len(all_style_exprs), remaining_num)) + + # 合并候选池(去重,避免重复) + candidate_exprs = selected_high.copy() + candidate_ids = {expr["id"] for expr in candidate_exprs} + for expr in selected_random: + if expr["id"] not in candidate_ids: + candidate_exprs.append(expr) + candidate_ids.add(expr["id"]) + + # 打乱顺序,避免高count的都在前面 + import random + + random.shuffle(candidate_exprs) + # 2. 构建所有表达方式的索引和情境列表 all_expressions: List[Dict[str, Any]] = [] all_situations: List[str] = [] # 添加style表达方式 - for expr in style_exprs: + for expr in candidate_exprs: expr = expr.copy() all_expressions.append(expr) all_situations.append(f"{len(all_expressions)}.当 {expr['situation']} 时,使用 {expr['style']}") @@ -231,7 +378,7 @@ class ExpressionSelector: all_situations_str = "\n".join(all_situations) if target_message: - target_message_str = f",现在你想要对这条消息进行回复:“{target_message}”" + target_message_str = f',现在你想要对这条消息进行回复:"{target_message}"' target_message_extra_block = "4.考虑你要回复的目标消息" else: target_message_str = "" @@ -260,7 +407,8 @@ class ExpressionSelector: # 4. 调用LLM content, (reasoning_content, model_name, _) = await self.llm_model.generate_response_async(prompt=prompt) - # print(prompt) + print(prompt) + print(content) if not content: logger.warning("LLM返回空结果") @@ -291,7 +439,7 @@ class ExpressionSelector: if valid_expressions: self.update_expressions_last_active_time(valid_expressions) - logger.info(f"classic模式从{len(all_expressions)}个情境中选择了{len(valid_expressions)}个") + logger.debug(f"从{len(all_expressions)}个情境中选择了{len(valid_expressions)}个") return valid_expressions, selected_ids except Exception as e: diff --git a/src/bw_learner/jargon_explainer.py b/src/bw_learner/jargon_explainer.py new file mode 100644 index 00000000..207a080a --- /dev/null +++ b/src/bw_learner/jargon_explainer.py @@ -0,0 +1,365 @@ +import re +import time +from typing import List, Dict, Optional, Any + +from src.common.logger import get_logger +from src.common.database.database_model import Jargon +from src.llm_models.utils_model import LLMRequest +from src.config.config import model_config, global_config +from src.chat.utils.prompt_builder import Prompt, global_prompt_manager +from src.bw_learner.jargon_miner import search_jargon +from src.bw_learner.learner_utils import ( + is_bot_message, + contains_bot_self_name, + parse_chat_id_list, + chat_id_list_contains, +) + +logger = get_logger("jargon") + + +def _init_explainer_prompts() -> None: + """初始化黑话解释器相关的prompt""" + # Prompt:概括黑话解释结果 + summarize_prompt_str = """上下文聊天内容: +{chat_context} + +在上下文中提取到的黑话及其含义: +{jargon_explanations} + +请根据上述信息,对黑话解释进行概括和整理。 +- 如果上下文中有黑话出现,请简要说明这些黑话在上下文中的使用情况 +- 将所有黑话解释整理成简洁、易读的一段话 +- 输出格式要自然,适合作为回复参考信息 +请输出概括后的黑话解释(直接输出一段平文本,不要标题,无特殊格式或markdown格式,不要使用JSON格式): +""" + Prompt(summarize_prompt_str, "jargon_explainer_summarize_prompt") + + +_init_explainer_prompts() + + +class JargonExplainer: + """黑话解释器,用于在回复前识别和解释上下文中的黑话""" + + def __init__(self, chat_id: str) -> None: + self.chat_id = chat_id + self.llm = LLMRequest( + model_set=model_config.model_task_config.utils, + request_type="jargon.explain", + ) + + def match_jargon_from_messages(self, messages: List[Any]) -> List[Dict[str, str]]: + """ + 通过直接匹配数据库中的jargon字符串来提取黑话 + + Args: + messages: 消息列表 + + Returns: + List[Dict[str, str]]: 提取到的黑话列表,每个元素包含content + """ + start_time = time.time() + + if not messages: + return [] + + # 收集所有消息的文本内容 + message_texts: List[str] = [] + for msg in messages: + # 跳过机器人自己的消息 + if is_bot_message(msg): + continue + + msg_text = ( + getattr(msg, "display_message", None) or getattr(msg, "processed_plain_text", None) or "" + ).strip() + if msg_text: + message_texts.append(msg_text) + + if not message_texts: + return [] + + # 合并所有消息文本 + combined_text = " ".join(message_texts) + + # 查询所有有meaning的jargon记录 + query = Jargon.select().where((Jargon.meaning.is_null(False)) & (Jargon.meaning != "")) + + # 根据all_global配置决定查询逻辑 + if global_config.expression.all_global_jargon: + # 开启all_global:只查询is_global=True的记录 + query = query.where(Jargon.is_global) + else: + # 关闭all_global:查询is_global=True或chat_id列表包含当前chat_id的记录 + # 这里先查询所有,然后在Python层面过滤 + pass + + # 按count降序排序,优先匹配出现频率高的 + query = query.order_by(Jargon.count.desc()) + + # 执行查询并匹配 + matched_jargon: Dict[str, Dict[str, str]] = {} + query_time = time.time() + + for jargon in query: + content = jargon.content or "" + if not content or not content.strip(): + continue + + # 跳过包含机器人昵称的词条 + if contains_bot_self_name(content): + continue + + # 检查chat_id(如果all_global=False) + if not global_config.expression.all_global_jargon: + if jargon.is_global: + # 全局黑话,包含 + pass + else: + # 检查chat_id列表是否包含当前chat_id + chat_id_list = parse_chat_id_list(jargon.chat_id) + if not chat_id_list_contains(chat_id_list, self.chat_id): + continue + + # 在文本中查找匹配(大小写不敏感) + pattern = re.escape(content) + # 使用单词边界或中文字符边界来匹配,避免部分匹配 + # 对于中文,使用Unicode字符类;对于英文,使用单词边界 + if re.search(r"[\u4e00-\u9fff]", content): + # 包含中文,使用更宽松的匹配 + search_pattern = pattern + else: + # 纯英文/数字,使用单词边界 + search_pattern = r"\b" + pattern + r"\b" + + if re.search(search_pattern, combined_text, re.IGNORECASE): + # 找到匹配,记录(去重) + if content not in matched_jargon: + matched_jargon[content] = {"content": content} + + match_time = time.time() + total_time = match_time - start_time + query_duration = query_time - start_time + match_duration = match_time - query_time + + logger.debug( + f"黑话匹配完成: 查询耗时 {query_duration:.3f}s, 匹配耗时 {match_duration:.3f}s, " + f"总耗时 {total_time:.3f}s, 匹配到 {len(matched_jargon)} 个黑话" + ) + + return list(matched_jargon.values()) + + async def explain_jargon(self, messages: List[Any], chat_context: str) -> Optional[str]: + """ + 解释上下文中的黑话 + + Args: + messages: 消息列表 + chat_context: 聊天上下文的文本表示 + + Returns: + Optional[str]: 黑话解释的概括文本,如果没有黑话则返回None + """ + if not messages: + return None + + # 直接匹配方式:从数据库中查询jargon并在消息中匹配 + jargon_entries = self.match_jargon_from_messages(messages) + + if not jargon_entries: + return None + + # 去重(按content) + unique_jargon: Dict[str, Dict[str, str]] = {} + for entry in jargon_entries: + content = entry["content"] + if content not in unique_jargon: + unique_jargon[content] = entry + + jargon_list = list(unique_jargon.values()) + logger.info(f"从上下文中提取到 {len(jargon_list)} 个黑话: {[j['content'] for j in jargon_list]}") + + # 查询每个黑话的含义 + jargon_explanations: List[str] = [] + for entry in jargon_list: + content = entry["content"] + + # 根据是否开启全局黑话,决定查询方式 + if global_config.expression.all_global_jargon: + # 开启全局黑话:查询所有is_global=True的记录 + results = search_jargon( + keyword=content, + chat_id=None, # 不指定chat_id,查询全局黑话 + limit=1, + case_sensitive=False, + fuzzy=False, # 精确匹配 + ) + else: + # 关闭全局黑话:优先查询当前聊天或全局的黑话 + results = search_jargon( + keyword=content, + chat_id=self.chat_id, + limit=1, + case_sensitive=False, + fuzzy=False, # 精确匹配 + ) + + if results and len(results) > 0: + meaning = results[0].get("meaning", "").strip() + if meaning: + jargon_explanations.append(f"- {content}: {meaning}") + else: + logger.info(f"黑话 {content} 没有找到含义") + else: + logger.info(f"黑话 {content} 未在数据库中找到") + + if not jargon_explanations: + logger.info("没有找到任何黑话的含义,跳过解释") + return None + + # 拼接所有黑话解释 + explanations_text = "\n".join(jargon_explanations) + + # 使用LLM概括黑话解释 + summarize_prompt = await global_prompt_manager.format_prompt( + "jargon_explainer_summarize_prompt", + chat_context=chat_context, + jargon_explanations=explanations_text, + ) + + summary, _ = await self.llm.generate_response_async(summarize_prompt, temperature=0.3) + if not summary: + # 如果LLM概括失败,直接返回原始解释 + return f"上下文中的黑话解释:\n{explanations_text}" + + summary = summary.strip() + if not summary: + return f"上下文中的黑话解释:\n{explanations_text}" + + return summary + + +async def explain_jargon_in_context(chat_id: str, messages: List[Any], chat_context: str) -> Optional[str]: + """ + 解释上下文中的黑话(便捷函数) + + Args: + chat_id: 聊天ID + messages: 消息列表 + chat_context: 聊天上下文的文本表示 + + Returns: + Optional[str]: 黑话解释的概括文本,如果没有黑话则返回None + """ + explainer = JargonExplainer(chat_id) + return await explainer.explain_jargon(messages, chat_context) + + +def match_jargon_from_text(chat_text: str, chat_id: str) -> List[str]: + """直接在聊天文本中匹配已知的jargon,返回出现过的黑话列表 + + Args: + chat_text: 要匹配的聊天文本 + chat_id: 聊天ID + + Returns: + List[str]: 匹配到的黑话列表 + """ + if not chat_text or not chat_text.strip(): + return [] + + query = Jargon.select().where((Jargon.meaning.is_null(False)) & (Jargon.meaning != "")) + if global_config.expression.all_global_jargon: + query = query.where(Jargon.is_global) + + query = query.order_by(Jargon.count.desc()) + + matched: Dict[str, None] = {} + + for jargon in query: + content = (jargon.content or "").strip() + if not content: + continue + + if not global_config.expression.all_global_jargon and not jargon.is_global: + chat_id_list = parse_chat_id_list(jargon.chat_id) + if not chat_id_list_contains(chat_id_list, chat_id): + continue + + pattern = re.escape(content) + if re.search(r"[\u4e00-\u9fff]", content): + search_pattern = pattern + else: + search_pattern = r"\b" + pattern + r"\b" + + if re.search(search_pattern, chat_text, re.IGNORECASE): + matched[content] = None + + logger.info(f"匹配到 {len(matched)} 个黑话") + + return list(matched.keys()) + + +async def retrieve_concepts_with_jargon(concepts: List[str], chat_id: str) -> str: + """对概念列表进行jargon检索 + + Args: + concepts: 概念列表 + chat_id: 聊天ID + + Returns: + str: 检索结果字符串 + """ + if not concepts: + return "" + + results = [] + exact_matches = [] # 收集所有精确匹配的概念 + for concept in concepts: + concept = concept.strip() + if not concept: + continue + + # 先尝试精确匹配 + jargon_results = search_jargon(keyword=concept, chat_id=chat_id, limit=10, case_sensitive=False, fuzzy=False) + + is_fuzzy_match = False + + # 如果精确匹配未找到,尝试模糊搜索 + if not jargon_results: + jargon_results = search_jargon(keyword=concept, chat_id=chat_id, limit=10, case_sensitive=False, fuzzy=True) + is_fuzzy_match = True + + if jargon_results: + # 找到结果 + if is_fuzzy_match: + # 模糊匹配 + output_parts = [f"未精确匹配到'{concept}'"] + for result in jargon_results: + found_content = result.get("content", "").strip() + meaning = result.get("meaning", "").strip() + if found_content and meaning: + output_parts.append(f"找到 '{found_content}' 的含义为:{meaning}") + results.append(",".join(output_parts)) + logger.info(f"在jargon库中找到匹配(模糊搜索): {concept},找到{len(jargon_results)}条结果") + else: + # 精确匹配 + output_parts = [] + for result in jargon_results: + meaning = result.get("meaning", "").strip() + if meaning: + output_parts.append(f"'{concept}' 为黑话或者网络简写,含义为:{meaning}") + results.append(";".join(output_parts) if len(output_parts) > 1 else output_parts[0]) + exact_matches.append(concept) # 收集精确匹配的概念,稍后统一打印 + else: + # 未找到,不返回占位信息,只记录日志 + logger.info(f"在jargon库中未找到匹配: {concept}") + + # 合并所有精确匹配的日志 + if exact_matches: + logger.info(f"找到黑话: {', '.join(exact_matches)},共找到{len(exact_matches)}条结果") + + if results: + return "【概念检索结果】\n" + "\n".join(results) + "\n" + return "" diff --git a/src/bw_learner/jargon_miner.py b/src/bw_learner/jargon_miner.py new file mode 100644 index 00000000..f1580fc4 --- /dev/null +++ b/src/bw_learner/jargon_miner.py @@ -0,0 +1,986 @@ +import json +import asyncio +import random +from collections import OrderedDict +from typing import List, Dict, Optional, Any, Callable +from json_repair import repair_json +from peewee import fn + +from src.common.logger import get_logger +from src.common.database.database_model import Jargon +from src.llm_models.utils_model import LLMRequest +from src.config.config import model_config, global_config +from src.chat.message_receive.chat_stream import get_chat_manager +from src.chat.utils.chat_message_builder import ( + build_readable_messages_with_id, +) +from src.chat.utils.prompt_builder import Prompt, global_prompt_manager +from src.bw_learner.learner_utils import ( + is_bot_message, + build_context_paragraph, + contains_bot_self_name, + parse_chat_id_list, + chat_id_list_contains, + update_chat_id_list, +) + + +logger = get_logger("jargon") + + +def _is_single_char_jargon(content: str) -> bool: + """ + 判断是否是单字黑话(单个汉字、英文或数字) + + Args: + content: 词条内容 + + Returns: + bool: 如果是单字黑话返回True,否则返回False + """ + if not content or len(content) != 1: + return False + + char = content[0] + # 判断是否是单个汉字、单个英文字母或单个数字 + return ( + "\u4e00" <= char <= "\u9fff" # 汉字 + or "a" <= char <= "z" # 小写字母 + or "A" <= char <= "Z" # 大写字母 + or "0" <= char <= "9" # 数字 + ) + + +def _init_prompt() -> None: + prompt_str = """ +**聊天内容,其中的{bot_name}的发言内容是你自己的发言,[msg_id] 是消息ID** +{chat_str} + +请从上面这段聊天内容中提取"可能是黑话"的候选项(黑话/俚语/网络缩写/口头禅)。 +- 必须为对话中真实出现过的短词或短语 +- 必须是你无法理解含义的词语,没有明确含义的词语,请不要选择有明确含义,或者含义清晰的词语 +- 排除:人名、@、表情包/图片中的内容、纯标点、常规功能词(如的、了、呢、啊等) +- 每个词条长度建议 2-8 个字符(不强制),尽量短小 + +黑话必须为以下几种类型: +- 由字母构成的,汉语拼音首字母的简写词,例如:nb、yyds、xswl +- 英文词语的缩写,用英文字母概括一个词汇或含义,例如:CPU、GPU、API +- 中文词语的缩写,用几个汉字概括一个词汇或含义,例如:社死、内卷 + +以 JSON 数组输出,元素为对象(严格按以下结构): +请你提取出可能的黑话,最多30个黑话,请尽量提取所有 +[ + {{"content": "词条", "msg_id": "m12"}}, // msg_id 必须与上方聊天中展示的ID完全一致 + {{"content": "词条2", "msg_id": "m15"}} +] + +现在请输出: +""" + Prompt(prompt_str, "extract_jargon_prompt") + + +def _init_inference_prompts() -> None: + """初始化含义推断相关的prompt""" + # Prompt 1: 基于raw_content和content推断 + prompt1_str = """ +**词条内容** +{content} +**词条出现的上下文。其中的{bot_name}的发言内容是你自己的发言** +{raw_content_list} +{previous_meaning_section} + +请根据上下文,推断"{content}"这个词条的含义。 +- 如果这是一个黑话、俚语或网络用语,请推断其含义 +- 如果含义明确(常规词汇),也请说明 +- {bot_name} 的发言内容可能包含错误,请不要参考其发言内容 +- 如果上下文信息不足,无法推断含义,请设置 no_info 为 true +{previous_meaning_instruction} + +以 JSON 格式输出: +{{ + "meaning": "详细含义说明(包含使用场景、来源、具体解释等)", + "no_info": false +}} +注意:如果信息不足无法推断,请设置 "no_info": true,此时 meaning 可以为空字符串 +""" + Prompt(prompt1_str, "jargon_inference_with_context_prompt") + + # Prompt 2: 仅基于content推断 + prompt2_str = """ +**词条内容** +{content} + +请仅根据这个词条本身,推断其含义。 +- 如果这是一个黑话、俚语或网络用语,请推断其含义 +- 如果含义明确(常规词汇),也请说明 + +以 JSON 格式输出: +{{ + "meaning": "详细含义说明(包含使用场景、来源、具体解释等)" +}} +""" + Prompt(prompt2_str, "jargon_inference_content_only_prompt") + + # Prompt 3: 比较两个推断结果 + prompt3_str = """ +**推断结果1(基于上下文)** +{inference1} + +**推断结果2(仅基于词条)** +{inference2} + +请比较这两个推断结果,判断它们是否相同或类似。 +- 如果两个推断结果的"含义"相同或类似,说明这个词条不是黑话(含义明确) +- 如果两个推断结果有差异,说明这个词条可能是黑话(需要上下文才能理解) + +以 JSON 格式输出: +{{ + "is_similar": true/false, + "reason": "判断理由" +}} +""" + Prompt(prompt3_str, "jargon_compare_inference_prompt") + + +_init_prompt() +_init_inference_prompts() + + +def _should_infer_meaning(jargon_obj: Jargon) -> bool: + """ + 判断是否需要进行含义推断 + 在 count 达到 3,6, 10, 20, 40, 60, 100 时进行推断 + 并且count必须大于last_inference_count,避免重启后重复判定 + 如果is_complete为True,不再进行推断 + """ + # 如果已完成所有推断,不再推断 + if jargon_obj.is_complete: + return False + + count = jargon_obj.count or 0 + last_inference = jargon_obj.last_inference_count or 0 + + # 阈值列表:3,6, 10, 20, 40, 60, 100 + thresholds = [2, 4, 8, 12, 24, 60, 100] + + if count < thresholds[0]: + return False + + # 如果count没有超过上次判定值,不需要判定 + if count <= last_inference: + return False + + # 找到第一个大于last_inference的阈值 + next_threshold = None + for threshold in thresholds: + if threshold > last_inference: + next_threshold = threshold + break + + # 如果没有找到下一个阈值,说明已经超过100,不应该再推断 + if next_threshold is None: + return False + + # 检查count是否达到或超过这个阈值 + return count >= next_threshold + + +class JargonMiner: + def __init__(self, chat_id: str) -> None: + self.chat_id = chat_id + + self.llm = LLMRequest( + model_set=model_config.model_task_config.utils, + request_type="jargon.extract", + ) + + self.llm_inference = LLMRequest( + model_set=model_config.model_task_config.utils, + request_type="jargon.inference", + ) + + # 初始化stream_name作为类属性,避免重复提取 + chat_manager = get_chat_manager() + stream_name = chat_manager.get_stream_name(self.chat_id) + self.stream_name = stream_name if stream_name else self.chat_id + self.cache_limit = 50 + self.cache: OrderedDict[str, None] = OrderedDict() + + # 黑话提取锁,防止并发执行 + self._extraction_lock = asyncio.Lock() + + def _add_to_cache(self, content: str) -> None: + """将提取到的黑话加入缓存,保持LRU语义""" + if not content: + return + + key = content.strip() + if not key: + return + + # 单字黑话(单个汉字、英文或数字)不记录到缓存 + if _is_single_char_jargon(key): + return + + if key in self.cache: + self.cache.move_to_end(key) + else: + self.cache[key] = None + if len(self.cache) > self.cache_limit: + self.cache.popitem(last=False) + + def _collect_cached_entries(self, messages: List[Any]) -> List[Dict[str, List[str]]]: + """检查缓存中的黑话是否出现在当前消息窗口,生成对应上下文""" + if not self.cache or not messages: + return [] + + cached_entries: List[Dict[str, List[str]]] = [] + processed_pairs = set() + + for idx, msg in enumerate(messages): + msg_text = ( + getattr(msg, "display_message", None) or getattr(msg, "processed_plain_text", None) or "" + ).strip() + if not msg_text or is_bot_message(msg): + continue + + for content in self.cache.keys(): + if not content: + continue + if (content, idx) in processed_pairs: + continue + if content in msg_text: + paragraph = build_context_paragraph(messages, idx) + if not paragraph: + continue + cached_entries.append({"content": content, "raw_content": [paragraph]}) + processed_pairs.add((content, idx)) + + return cached_entries + + async def _infer_meaning_by_id(self, jargon_id: int) -> None: + """通过ID加载对象并推断""" + try: + jargon_obj = Jargon.get_by_id(jargon_id) + # 再次检查is_complete,因为可能在异步任务执行时已被标记为完成 + if jargon_obj.is_complete: + logger.debug(f"jargon {jargon_obj.content} 已完成所有推断,跳过") + return + await self.infer_meaning(jargon_obj) + except Exception as e: + logger.error(f"通过ID推断jargon失败: {e}") + + async def infer_meaning(self, jargon_obj: Jargon) -> None: + """ + 对jargon进行含义推断 + """ + try: + content = jargon_obj.content + raw_content_str = jargon_obj.raw_content or "" + + # 解析raw_content列表 + raw_content_list = [] + if raw_content_str: + try: + raw_content_list = ( + json.loads(raw_content_str) if isinstance(raw_content_str, str) else raw_content_str + ) + if not isinstance(raw_content_list, list): + raw_content_list = [raw_content_list] if raw_content_list else [] + except (json.JSONDecodeError, TypeError): + raw_content_list = [raw_content_str] if raw_content_str else [] + + if not raw_content_list: + logger.warning(f"jargon {content} 没有raw_content,跳过推断") + return + + # 获取当前count和上一次的meaning + current_count = jargon_obj.count or 0 + previous_meaning = jargon_obj.meaning or "" + + # 当count为24, 60时,随机移除一半的raw_content项目 + if current_count in [24, 60] and len(raw_content_list) > 1: + # 计算要保留的数量(至少保留1个) + keep_count = max(1, len(raw_content_list) // 2) + raw_content_list = random.sample(raw_content_list, keep_count) + logger.info( + f"jargon {content} count={current_count},随机移除后剩余 {len(raw_content_list)} 个raw_content项目" + ) + + # 步骤1: 基于raw_content和content推断 + raw_content_text = "\n".join(raw_content_list) + + # 当count为24, 60, 100时,在prompt中放入上一次推断出的meaning作为参考 + previous_meaning_section = "" + previous_meaning_instruction = "" + if current_count in [24, 60, 100] and previous_meaning: + previous_meaning_section = f""" +**上一次推断的含义(仅供参考)** +{previous_meaning} +""" + previous_meaning_instruction = ( + "- 请参考上一次推断的含义,结合新的上下文信息,给出更准确或更新的推断结果" + ) + + prompt1 = await global_prompt_manager.format_prompt( + "jargon_inference_with_context_prompt", + content=content, + bot_name=global_config.bot.nickname, + raw_content_list=raw_content_text, + previous_meaning_section=previous_meaning_section, + previous_meaning_instruction=previous_meaning_instruction, + ) + + response1, _ = await self.llm_inference.generate_response_async(prompt1, temperature=0.3) + if not response1: + logger.warning(f"jargon {content} 推断1失败:无响应") + return + + # 解析推断1结果 + inference1 = None + try: + resp1 = response1.strip() + if resp1.startswith("{") and resp1.endswith("}"): + inference1 = json.loads(resp1) + else: + repaired = repair_json(resp1) + inference1 = json.loads(repaired) if isinstance(repaired, str) else repaired + if not isinstance(inference1, dict): + logger.warning(f"jargon {content} 推断1结果格式错误") + return + except Exception as e: + logger.error(f"jargon {content} 推断1解析失败: {e}") + return + + # 检查推断1是否表示信息不足无法推断 + no_info = inference1.get("no_info", False) + meaning1 = inference1.get("meaning", "").strip() + if no_info or not meaning1: + logger.info(f"jargon {content} 推断1表示信息不足无法推断,放弃本次推断,待下次更新") + # 更新最后一次判定的count值,避免在同一阈值重复尝试 + jargon_obj.last_inference_count = jargon_obj.count or 0 + jargon_obj.save() + return + + # 步骤2: 仅基于content推断 + prompt2 = await global_prompt_manager.format_prompt( + "jargon_inference_content_only_prompt", + content=content, + ) + + response2, _ = await self.llm_inference.generate_response_async(prompt2, temperature=0.3) + if not response2: + logger.warning(f"jargon {content} 推断2失败:无响应") + return + + # 解析推断2结果 + inference2 = None + try: + resp2 = response2.strip() + if resp2.startswith("{") and resp2.endswith("}"): + inference2 = json.loads(resp2) + else: + repaired = repair_json(resp2) + inference2 = json.loads(repaired) if isinstance(repaired, str) else repaired + if not isinstance(inference2, dict): + logger.warning(f"jargon {content} 推断2结果格式错误") + return + except Exception as e: + logger.error(f"jargon {content} 推断2解析失败: {e}") + return + + # logger.info(f"jargon {content} 推断2提示词: {prompt2}") + # logger.info(f"jargon {content} 推断2结果: {response2}") + # logger.info(f"jargon {content} 推断1提示词: {prompt1}") + # logger.info(f"jargon {content} 推断1结果: {response1}") + + if global_config.debug.show_jargon_prompt: + logger.info(f"jargon {content} 推断2提示词: {prompt2}") + logger.info(f"jargon {content} 推断2结果: {response2}") + logger.info(f"jargon {content} 推断1提示词: {prompt1}") + logger.info(f"jargon {content} 推断1结果: {response1}") + else: + logger.debug(f"jargon {content} 推断2提示词: {prompt2}") + logger.debug(f"jargon {content} 推断2结果: {response2}") + logger.debug(f"jargon {content} 推断1提示词: {prompt1}") + logger.debug(f"jargon {content} 推断1结果: {response1}") + + # 步骤3: 比较两个推断结果 + prompt3 = await global_prompt_manager.format_prompt( + "jargon_compare_inference_prompt", + inference1=json.dumps(inference1, ensure_ascii=False), + inference2=json.dumps(inference2, ensure_ascii=False), + ) + + if global_config.debug.show_jargon_prompt: + logger.info(f"jargon {content} 比较提示词: {prompt3}") + + response3, _ = await self.llm_inference.generate_response_async(prompt3, temperature=0.3) + if not response3: + logger.warning(f"jargon {content} 比较失败:无响应") + return + + # 解析比较结果 + comparison = None + try: + resp3 = response3.strip() + if resp3.startswith("{") and resp3.endswith("}"): + comparison = json.loads(resp3) + else: + repaired = repair_json(resp3) + comparison = json.loads(repaired) if isinstance(repaired, str) else repaired + if not isinstance(comparison, dict): + logger.warning(f"jargon {content} 比较结果格式错误") + return + except Exception as e: + logger.error(f"jargon {content} 比较解析失败: {e}") + return + + # 判断是否为黑话 + is_similar = comparison.get("is_similar", False) + is_jargon = not is_similar # 如果相似,说明不是黑话;如果有差异,说明是黑话 + + # 更新数据库记录 + jargon_obj.is_jargon = is_jargon + if is_jargon: + # 是黑话,使用推断1的结果(基于上下文,更准确) + jargon_obj.meaning = inference1.get("meaning", "") + else: + # 不是黑话,清空含义,不再存储任何内容 + jargon_obj.meaning = "" + + # 更新最后一次判定的count值,避免重启后重复判定 + jargon_obj.last_inference_count = jargon_obj.count or 0 + + # 如果count>=100,标记为完成,不再进行推断 + if (jargon_obj.count or 0) >= 100: + jargon_obj.is_complete = True + + jargon_obj.save() + logger.debug( + f"jargon {content} 推断完成: is_jargon={is_jargon}, meaning={jargon_obj.meaning}, last_inference_count={jargon_obj.last_inference_count}, is_complete={jargon_obj.is_complete}" + ) + + # 固定输出推断结果,格式化为可读形式 + if is_jargon: + # 是黑话,输出格式:[聊天名]xxx的含义是 xxxxxxxxxxx + meaning = jargon_obj.meaning or "无详细说明" + is_global = jargon_obj.is_global + if is_global: + logger.info(f"[黑话]{content}的含义是 {meaning}") + else: + logger.info(f"[{self.stream_name}]{content}的含义是 {meaning}") + else: + # 不是黑话,输出格式:[聊天名]xxx 不是黑话 + logger.info(f"[{self.stream_name}]{content} 不是黑话") + + except Exception as e: + logger.error(f"jargon推断失败: {e}") + import traceback + + traceback.print_exc() + + async def run_once( + self, + messages: List[Any], + person_name_filter: Optional[Callable[[str], bool]] = None + ) -> None: + """ + 运行一次黑话提取 + + Args: + messages: 外部传入的消息列表(必需) + person_name_filter: 可选的过滤函数,用于检查内容是否包含人物名称 + """ + # 使用异步锁防止并发执行 + async with self._extraction_lock: + try: + if not messages: + return + + # 按时间排序,确保编号与上下文一致 + messages = sorted(messages, key=lambda msg: msg.time or 0) + + chat_str, message_id_list = build_readable_messages_with_id( + messages=messages, + replace_bot_name=True, + timestamp_mode="relative", + truncate=False, + show_actions=False, + show_pic=True, + pic_single=True, + ) + if not chat_str.strip(): + return + + msg_id_to_index: Dict[str, int] = {} + for idx, (msg_id, _msg) in enumerate(message_id_list or []): + if not msg_id: + continue + msg_id_to_index[msg_id] = idx + if not msg_id_to_index: + logger.warning("未能生成消息ID映射,跳过本次提取") + return + + prompt: str = await global_prompt_manager.format_prompt( + "extract_jargon_prompt", + bot_name=global_config.bot.nickname, + chat_str=chat_str, + ) + + response, _ = await self.llm.generate_response_async(prompt, temperature=0.2) + if not response: + return + + if global_config.debug.show_jargon_prompt: + logger.info(f"jargon提取提示词: {prompt}") + logger.info(f"jargon提取结果: {response}") + + # 解析为JSON + entries: List[dict] = [] + try: + resp = response.strip() + parsed = None + if resp.startswith("[") and resp.endswith("]"): + parsed = json.loads(resp) + else: + repaired = repair_json(resp) + if isinstance(repaired, str): + parsed = json.loads(repaired) + else: + parsed = repaired + + if isinstance(parsed, dict): + parsed = [parsed] + + if not isinstance(parsed, list): + return + + for item in parsed: + if not isinstance(item, dict): + continue + + content = str(item.get("content", "")).strip() + msg_id_value = item.get("msg_id") + + if not content: + continue + + if contains_bot_self_name(content): + logger.info(f"解析阶段跳过包含机器人昵称/别名的词条: {content}") + continue + + # 检查是否包含人物名称 + if person_name_filter and person_name_filter(content): + logger.info(f"解析阶段跳过包含人物名称的词条: {content}") + continue + + msg_id_str = str(msg_id_value or "").strip() + if not msg_id_str: + logger.warning(f"解析jargon失败:msg_id缺失,content={content}") + continue + + msg_index = msg_id_to_index.get(msg_id_str) + if msg_index is None: + logger.warning(f"解析jargon失败:msg_id未找到,content={content}, msg_id={msg_id_str}") + continue + + target_msg = messages[msg_index] + if is_bot_message(target_msg): + logger.info(f"解析阶段跳过引用机器人自身消息的词条: content={content}, msg_id={msg_id_str}") + continue + + context_paragraph = build_context_paragraph(messages, msg_index) + if not context_paragraph: + logger.warning(f"解析jargon失败:上下文为空,content={content}, msg_id={msg_id_str}") + continue + + entries.append({"content": content, "raw_content": [context_paragraph]}) + cached_entries = self._collect_cached_entries(messages) + if cached_entries: + entries.extend(cached_entries) + except Exception as e: + logger.error(f"解析jargon JSON失败: {e}; 原始: {response}") + return + + if not entries: + return + + # 去重并合并raw_content(按 content 聚合) + merged_entries: OrderedDict[str, Dict[str, List[str]]] = OrderedDict() + for entry in entries: + content_key = entry["content"] + raw_list = entry.get("raw_content", []) or [] + if content_key in merged_entries: + merged_entries[content_key]["raw_content"].extend(raw_list) + else: + merged_entries[content_key] = { + "content": content_key, + "raw_content": list(raw_list), + } + + uniq_entries = [] + for merged_entry in merged_entries.values(): + raw_content_list = merged_entry["raw_content"] + if raw_content_list: + merged_entry["raw_content"] = list(dict.fromkeys(raw_content_list)) + uniq_entries.append(merged_entry) + + saved = 0 + updated = 0 + for entry in uniq_entries: + content = entry["content"] + raw_content_list = entry["raw_content"] # 已经是列表 + + try: + # 查询所有content匹配的记录 + query = Jargon.select().where(Jargon.content == content) + + # 查找匹配的记录 + matched_obj = None + for obj in query: + if global_config.expression.all_global_jargon: + # 开启all_global:所有content匹配的记录都可以 + matched_obj = obj + break + else: + # 关闭all_global:需要检查chat_id列表是否包含目标chat_id + chat_id_list = parse_chat_id_list(obj.chat_id) + if chat_id_list_contains(chat_id_list, self.chat_id): + matched_obj = obj + break + + if matched_obj: + obj = matched_obj + try: + obj.count = (obj.count or 0) + 1 + except Exception: + obj.count = 1 + + # 合并raw_content列表:读取现有列表,追加新值,去重 + existing_raw_content = [] + if obj.raw_content: + try: + existing_raw_content = ( + json.loads(obj.raw_content) + if isinstance(obj.raw_content, str) + else obj.raw_content + ) + if not isinstance(existing_raw_content, list): + existing_raw_content = [existing_raw_content] if existing_raw_content else [] + except (json.JSONDecodeError, TypeError): + existing_raw_content = [obj.raw_content] if obj.raw_content else [] + + # 合并并去重 + merged_list = list(dict.fromkeys(existing_raw_content + raw_content_list)) + obj.raw_content = json.dumps(merged_list, ensure_ascii=False) + + # 更新chat_id列表:增加当前chat_id的计数 + chat_id_list = parse_chat_id_list(obj.chat_id) + updated_chat_id_list = update_chat_id_list(chat_id_list, self.chat_id, increment=1) + obj.chat_id = json.dumps(updated_chat_id_list, ensure_ascii=False) + + # 开启all_global时,确保记录标记为is_global=True + if global_config.expression.all_global_jargon: + obj.is_global = True + # 关闭all_global时,保持原有is_global不变(不修改) + + obj.save() + + # 检查是否需要推断(达到阈值且超过上次判定值) + if _should_infer_meaning(obj): + # 异步触发推断,不阻塞主流程 + # 重新加载对象以确保数据最新 + jargon_id = obj.id + asyncio.create_task(self._infer_meaning_by_id(jargon_id)) + + updated += 1 + else: + # 没找到匹配记录,创建新记录 + if global_config.expression.all_global_jargon: + # 开启all_global:新记录默认为is_global=True + is_global_new = True + else: + # 关闭all_global:新记录is_global=False + is_global_new = False + + # 使用新格式创建chat_id列表:[[chat_id, count]] + chat_id_list = [[self.chat_id, 1]] + chat_id_json = json.dumps(chat_id_list, ensure_ascii=False) + + Jargon.create( + content=content, + raw_content=json.dumps(raw_content_list, ensure_ascii=False), + chat_id=chat_id_json, + is_global=is_global_new, + count=1, + ) + saved += 1 + except Exception as e: + logger.error(f"保存jargon失败: chat_id={self.chat_id}, content={content}, err={e}") + continue + finally: + self._add_to_cache(content) + + # 固定输出提取的jargon结果,格式化为可读形式(只要有提取结果就输出) + if uniq_entries: + # 收集所有提取的jargon内容 + jargon_list = [entry["content"] for entry in uniq_entries] + jargon_str = ",".join(jargon_list) + + # 输出格式化的结果(使用logger.info会自动应用jargon模块的颜色) + logger.info(f"[{self.stream_name}]疑似黑话: {jargon_str}") + + if saved or updated: + logger.info(f"jargon写入: 新增 {saved} 条,更新 {updated} 条,chat_id={self.chat_id}") + except Exception as e: + logger.error(f"JargonMiner 运行失败: {e}") + # 即使失败也保持时间戳更新,避免频繁重试 + + async def process_extracted_entries( + self, + entries: List[Dict[str, List[str]]], + person_name_filter: Optional[Callable[[str], bool]] = None + ) -> None: + """ + 处理已提取的黑话条目(从 expression_learner 路由过来的) + + Args: + entries: 黑话条目列表,每个元素格式为 {"content": "...", "raw_content": [...]} + person_name_filter: 可选的过滤函数,用于检查内容是否包含人物名称 + """ + if not entries: + return + + try: + # 去重并合并raw_content(按 content 聚合) + merged_entries: OrderedDict[str, Dict[str, List[str]]] = OrderedDict() + for entry in entries: + content_key = entry["content"] + + # 检查是否包含人物名称 + # logger.info(f"process_extracted_entries 检查是否包含人物名称: {content_key}") + # logger.info(f"person_name_filter: {person_name_filter}") + if person_name_filter and person_name_filter(content_key): + logger.info(f"process_extracted_entries 跳过包含人物名称的黑话: {content_key}") + continue + + raw_list = entry.get("raw_content", []) or [] + if content_key in merged_entries: + merged_entries[content_key]["raw_content"].extend(raw_list) + else: + merged_entries[content_key] = { + "content": content_key, + "raw_content": list(raw_list), + } + + uniq_entries = [] + for merged_entry in merged_entries.values(): + raw_content_list = merged_entry["raw_content"] + if raw_content_list: + merged_entry["raw_content"] = list(dict.fromkeys(raw_content_list)) + uniq_entries.append(merged_entry) + + saved = 0 + updated = 0 + for entry in uniq_entries: + content = entry["content"] + raw_content_list = entry["raw_content"] # 已经是列表 + + try: + # 查询所有content匹配的记录 + query = Jargon.select().where(Jargon.content == content) + + # 查找匹配的记录 + matched_obj = None + for obj in query: + if global_config.expression.all_global_jargon: + # 开启all_global:所有content匹配的记录都可以 + matched_obj = obj + break + else: + # 关闭all_global:需要检查chat_id列表是否包含目标chat_id + chat_id_list = parse_chat_id_list(obj.chat_id) + if chat_id_list_contains(chat_id_list, self.chat_id): + matched_obj = obj + break + + if matched_obj: + obj = matched_obj + try: + obj.count = (obj.count or 0) + 1 + except Exception: + obj.count = 1 + + # 合并raw_content列表:读取现有列表,追加新值,去重 + existing_raw_content = [] + if obj.raw_content: + try: + existing_raw_content = ( + json.loads(obj.raw_content) if isinstance(obj.raw_content, str) else obj.raw_content + ) + if not isinstance(existing_raw_content, list): + existing_raw_content = [existing_raw_content] if existing_raw_content else [] + except (json.JSONDecodeError, TypeError): + existing_raw_content = [obj.raw_content] if obj.raw_content else [] + + # 合并并去重 + merged_list = list(dict.fromkeys(existing_raw_content + raw_content_list)) + obj.raw_content = json.dumps(merged_list, ensure_ascii=False) + + # 更新chat_id列表:增加当前chat_id的计数 + chat_id_list = parse_chat_id_list(obj.chat_id) + updated_chat_id_list = update_chat_id_list(chat_id_list, self.chat_id, increment=1) + obj.chat_id = json.dumps(updated_chat_id_list, ensure_ascii=False) + + # 开启all_global时,确保记录标记为is_global=True + if global_config.expression.all_global_jargon: + obj.is_global = True + # 关闭all_global时,保持原有is_global不变(不修改) + + obj.save() + + # 检查是否需要推断(达到阈值且超过上次判定值) + if _should_infer_meaning(obj): + # 异步触发推断,不阻塞主流程 + # 重新加载对象以确保数据最新 + jargon_id = obj.id + asyncio.create_task(self._infer_meaning_by_id(jargon_id)) + + updated += 1 + else: + # 没找到匹配记录,创建新记录 + if global_config.expression.all_global_jargon: + # 开启all_global:新记录默认为is_global=True + is_global_new = True + else: + # 关闭all_global:新记录is_global=False + is_global_new = False + + # 使用新格式创建chat_id列表:[[chat_id, count]] + chat_id_list = [[self.chat_id, 1]] + chat_id_json = json.dumps(chat_id_list, ensure_ascii=False) + + Jargon.create( + content=content, + raw_content=json.dumps(raw_content_list, ensure_ascii=False), + chat_id=chat_id_json, + is_global=is_global_new, + count=1, + ) + saved += 1 + except Exception as e: + logger.error(f"保存jargon失败: chat_id={self.chat_id}, content={content}, err={e}") + continue + finally: + self._add_to_cache(content) + + # 固定输出提取的jargon结果,格式化为可读形式(只要有提取结果就输出) + if uniq_entries: + # 收集所有提取的jargon内容 + jargon_list = [entry["content"] for entry in uniq_entries] + jargon_str = ",".join(jargon_list) + + # 输出格式化的结果(使用logger.info会自动应用jargon模块的颜色) + logger.info(f"[{self.stream_name}]疑似黑话: {jargon_str}") + + if saved or updated: + logger.debug(f"jargon写入: 新增 {saved} 条,更新 {updated} 条,chat_id={self.chat_id}") + except Exception as e: + logger.error(f"处理已提取的黑话条目失败: {e}") + + +class JargonMinerManager: + def __init__(self) -> None: + self._miners: dict[str, JargonMiner] = {} + + def get_miner(self, chat_id: str) -> JargonMiner: + if chat_id not in self._miners: + self._miners[chat_id] = JargonMiner(chat_id) + return self._miners[chat_id] + + +miner_manager = JargonMinerManager() + + +def search_jargon( + keyword: str, chat_id: Optional[str] = None, limit: int = 10, case_sensitive: bool = False, fuzzy: bool = True +) -> List[Dict[str, str]]: + """ + 搜索jargon,支持大小写不敏感和模糊搜索 + + Args: + keyword: 搜索关键词 + chat_id: 可选的聊天ID + - 如果开启了all_global:此参数被忽略,查询所有is_global=True的记录 + - 如果关闭了all_global:如果提供则优先搜索该聊天或global的jargon + limit: 返回结果数量限制,默认10 + case_sensitive: 是否大小写敏感,默认False(不敏感) + fuzzy: 是否模糊搜索,默认True(使用LIKE匹配) + + Returns: + List[Dict[str, str]]: 包含content, meaning的字典列表 + """ + if not keyword or not keyword.strip(): + return [] + + keyword = keyword.strip() + + # 构建查询(选择所有需要的字段,以便后续过滤) + query = Jargon.select() + + # 构建搜索条件 + if case_sensitive: + # 大小写敏感 + if fuzzy: + # 模糊搜索 + search_condition = Jargon.content.contains(keyword) + else: + # 精确匹配 + search_condition = Jargon.content == keyword + else: + # 大小写不敏感 + if fuzzy: + # 模糊搜索(使用LOWER函数) + search_condition = fn.LOWER(Jargon.content).contains(keyword.lower()) + else: + # 精确匹配(使用LOWER函数) + search_condition = fn.LOWER(Jargon.content) == keyword.lower() + + query = query.where(search_condition) + + # 根据all_global配置决定查询逻辑 + if global_config.expression.all_global_jargon: + # 开启all_global:所有记录都是全局的,查询所有is_global=True的记录(无视chat_id) + query = query.where(Jargon.is_global) + # 注意:对于all_global=False的情况,chat_id过滤在Python层面进行,以便兼容新旧格式 + + # 注意:meaning的过滤移到Python层面,因为我们需要先过滤chat_id + + # 按count降序排序,优先返回出现频率高的 + query = query.order_by(Jargon.count.desc()) + + # 限制结果数量(先多取一些,因为后面可能过滤) + query = query.limit(limit * 2) + + # 执行查询并返回结果,过滤chat_id + results = [] + for jargon in query: + # 如果提供了chat_id且all_global=False,需要检查chat_id列表是否包含目标chat_id + if chat_id and not global_config.expression.all_global_jargon: + chat_id_list = parse_chat_id_list(jargon.chat_id) + # 如果记录是is_global=True,或者chat_id列表包含目标chat_id,则包含 + if not jargon.is_global and not chat_id_list_contains(chat_id_list, chat_id): + continue + + # 只返回有meaning的记录 + if not jargon.meaning or jargon.meaning.strip() == "": + continue + + results.append({"content": jargon.content or "", "meaning": jargon.meaning or ""}) + + # 达到限制数量后停止 + if len(results) >= limit: + break + + return results diff --git a/src/bw_learner/learner_utils.py b/src/bw_learner/learner_utils.py new file mode 100644 index 00000000..e871dde7 --- /dev/null +++ b/src/bw_learner/learner_utils.py @@ -0,0 +1,380 @@ +import re +import difflib +import random +import json +from datetime import datetime +from typing import Optional, List, Dict, Any + +from src.common.logger import get_logger +from src.config.config import global_config +from src.chat.utils.chat_message_builder import ( + build_readable_messages, +) +from src.chat.utils.utils import parse_platform_accounts + + +logger = get_logger("learner_utils") + + +def filter_message_content(content: Optional[str]) -> str: + """ + 过滤消息内容,移除回复、@、图片等格式 + + Args: + content: 原始消息内容 + + Returns: + str: 过滤后的内容 + """ + if not content: + return "" + + # 移除以[回复开头、]结尾的部分,包括后面的",说:"部分 + content = re.sub(r"\[回复.*?\],说:\s*", "", content) + # 移除@<...>格式的内容 + content = re.sub(r"@<[^>]*>", "", content) + # 移除[picid:...]格式的图片ID + content = re.sub(r"\[picid:[^\]]*\]", "", content) + # 移除[表情包:...]格式的内容 + content = re.sub(r"\[表情包:[^\]]*\]", "", content) + + return content.strip() + + +def calculate_similarity(text1: str, text2: str) -> float: + """ + 计算两个文本的相似度,返回0-1之间的值 + 使用SequenceMatcher计算相似度 + + Args: + text1: 第一个文本 + text2: 第二个文本 + + Returns: + float: 相似度值,范围0-1 + """ + return difflib.SequenceMatcher(None, text1, text2).ratio() + + +def calculate_style_similarity(style1: str, style2: str) -> float: + """ + 计算两个 style 的相似度,返回0-1之间的值 + 在计算前会移除"使用"和"句式"这两个词(参考 expression_similarity_analysis.py) + + Args: + style1: 第一个 style + style2: 第二个 style + + Returns: + float: 相似度值,范围0-1 + """ + if not style1 or not style2: + return 0.0 + + # 移除"使用"和"句式"这两个词 + def remove_ignored_words(text: str) -> str: + """移除需要忽略的词""" + text = text.replace("使用", "") + text = text.replace("句式", "") + return text.strip() + + cleaned_style1 = remove_ignored_words(style1) + cleaned_style2 = remove_ignored_words(style2) + + # 如果清理后文本为空,返回0 + if not cleaned_style1 or not cleaned_style2: + return 0.0 + + return difflib.SequenceMatcher(None, cleaned_style1, cleaned_style2).ratio() + + +def format_create_date(timestamp: float) -> str: + """ + 将时间戳格式化为可读的日期字符串 + + Args: + timestamp: 时间戳 + + Returns: + str: 格式化后的日期字符串 + """ + try: + return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S") + except (ValueError, OSError): + return "未知时间" + + +def _compute_weights(population: List[Dict]) -> List[float]: + """ + 根据表达的count计算权重,范围限定在1~5之间。 + count越高,权重越高,但最多为基础权重的5倍。 + 如果表达已checked,权重会再乘以3倍。 + """ + if not population: + return [] + + counts = [] + checked_flags = [] + for item in population: + count = item.get("count", 1) + try: + count_value = float(count) + except (TypeError, ValueError): + count_value = 1.0 + counts.append(max(count_value, 0.0)) + # 获取checked状态 + checked = item.get("checked", False) + checked_flags.append(bool(checked)) + + min_count = min(counts) + max_count = max(counts) + + if max_count == min_count: + base_weights = [1.0 for _ in counts] + else: + base_weights = [] + for count_value in counts: + # 线性映射到[1,5]区间 + normalized = (count_value - min_count) / (max_count - min_count) + base_weights.append(1.0 + normalized * 4.0) # 1~5 + + # 如果checked,权重乘以3 + weights = [] + for base_weight, checked in zip(base_weights, checked_flags, strict=False): + if checked: + weights.append(base_weight * 3.0) + else: + weights.append(base_weight) + return weights + + +def weighted_sample(population: List[Dict], k: int) -> List[Dict]: + """ + 随机抽样函数 + + Args: + population: 总体数据列表 + k: 需要抽取的数量 + + Returns: + List[Dict]: 抽取的数据列表 + """ + if not population or k <= 0: + return [] + + if len(population) <= k: + return population.copy() + + selected: List[Dict] = [] + population_copy = population.copy() + + for _ in range(min(k, len(population_copy))): + weights = _compute_weights(population_copy) + total_weight = sum(weights) + if total_weight <= 0: + # 回退到均匀随机 + idx = random.randint(0, len(population_copy) - 1) + selected.append(population_copy.pop(idx)) + continue + + threshold = random.uniform(0, total_weight) + cumulative = 0.0 + for idx, weight in enumerate(weights): + cumulative += weight + if threshold <= cumulative: + selected.append(population_copy.pop(idx)) + break + + return selected + + +def parse_chat_id_list(chat_id_value: Any) -> List[List[Any]]: + """ + 解析chat_id字段,兼容旧格式(字符串)和新格式(JSON列表) + + Args: + chat_id_value: 可能是字符串(旧格式)或JSON字符串(新格式) + + Returns: + List[List[Any]]: 格式为 [[chat_id, count], ...] 的列表 + """ + if not chat_id_value: + return [] + + # 如果是字符串,尝试解析为JSON + if isinstance(chat_id_value, str): + # 尝试解析JSON + try: + parsed = json.loads(chat_id_value) + if isinstance(parsed, list): + # 新格式:已经是列表 + return parsed + elif isinstance(parsed, str): + # 解析后还是字符串,说明是旧格式 + return [[parsed, 1]] + else: + # 其他类型,当作旧格式处理 + return [[str(chat_id_value), 1]] + except (json.JSONDecodeError, TypeError): + # 解析失败,当作旧格式(纯字符串) + return [[str(chat_id_value), 1]] + elif isinstance(chat_id_value, list): + # 已经是列表格式 + return chat_id_value + else: + # 其他类型,转换为旧格式 + return [[str(chat_id_value), 1]] + + +def update_chat_id_list(chat_id_list: List[List[Any]], target_chat_id: str, increment: int = 1) -> List[List[Any]]: + """ + 更新chat_id列表,如果target_chat_id已存在则增加计数,否则添加新条目 + + Args: + chat_id_list: 当前的chat_id列表,格式为 [[chat_id, count], ...] + target_chat_id: 要更新或添加的chat_id + increment: 增加的计数,默认为1 + + Returns: + List[List[Any]]: 更新后的chat_id列表 + """ + item = _find_chat_id_item(chat_id_list, target_chat_id) + if item is not None: + # 找到匹配的chat_id,增加计数 + if len(item) >= 2: + item[1] = (item[1] if isinstance(item[1], (int, float)) else 0) + increment + else: + item.append(increment) + else: + # 未找到,添加新条目 + chat_id_list.append([target_chat_id, increment]) + + return chat_id_list + + +def _find_chat_id_item(chat_id_list: List[List[Any]], target_chat_id: str) -> Optional[List[Any]]: + """ + 在chat_id列表中查找匹配的项(辅助函数) + + Args: + chat_id_list: chat_id列表,格式为 [[chat_id, count], ...] + target_chat_id: 要查找的chat_id + + Returns: + 如果找到则返回匹配的项,否则返回None + """ + for item in chat_id_list: + if isinstance(item, list) and len(item) >= 1 and str(item[0]) == str(target_chat_id): + return item + return None + + +def chat_id_list_contains(chat_id_list: List[List[Any]], target_chat_id: str) -> bool: + """ + 检查chat_id列表中是否包含指定的chat_id + + Args: + chat_id_list: chat_id列表,格式为 [[chat_id, count], ...] + target_chat_id: 要查找的chat_id + + Returns: + bool: 如果包含则返回True + """ + return _find_chat_id_item(chat_id_list, target_chat_id) is not None + + +def contains_bot_self_name(content: str) -> bool: + """ + 判断词条是否包含机器人的昵称或别名 + """ + if not content: + return False + + bot_config = getattr(global_config, "bot", None) + if not bot_config: + return False + + target = content.strip().lower() + nickname = str(getattr(bot_config, "nickname", "") or "").strip().lower() + alias_names = [str(alias or "").strip().lower() for alias in getattr(bot_config, "alias_names", []) or []] + + candidates = [name for name in [nickname, *alias_names] if name] + + return any(name in target for name in candidates) + + +def build_context_paragraph(messages: List[Any], center_index: int) -> Optional[str]: + """ + 构建包含中心消息上下文的段落(前3条+后3条),使用标准的 readable builder 输出 + """ + if not messages or center_index < 0 or center_index >= len(messages): + return None + + context_start = max(0, center_index - 3) + context_end = min(len(messages), center_index + 1 + 3) + context_messages = messages[context_start:context_end] + + if not context_messages: + return None + + try: + paragraph = build_readable_messages( + messages=context_messages, + replace_bot_name=True, + timestamp_mode="relative", + read_mark=0.0, + truncate=False, + show_actions=False, + show_pic=True, + message_id_list=None, + remove_emoji_stickers=False, + pic_single=True, + ) + except Exception as e: + logger.warning(f"构建上下文段落失败: {e}") + return None + + paragraph = paragraph.strip() + return paragraph or None + + +def is_bot_message(msg: Any) -> bool: + """判断消息是否来自机器人自身""" + if msg is None: + return False + + bot_config = getattr(global_config, "bot", None) + if not bot_config: + return False + + platform = ( + str(getattr(msg, "user_platform", "") or getattr(getattr(msg, "user_info", None), "platform", "") or "") + .strip() + .lower() + ) + user_id = str(getattr(msg, "user_id", "") or getattr(getattr(msg, "user_info", None), "user_id", "") or "").strip() + + if not platform or not user_id: + return False + + platform_accounts = {} + try: + platform_accounts = parse_platform_accounts(getattr(bot_config, "platforms", []) or []) + except Exception: + platform_accounts = {} + + bot_accounts: Dict[str, str] = {} + qq_account = str(getattr(bot_config, "qq_account", "") or "").strip() + if qq_account: + bot_accounts["qq"] = qq_account + + telegram_account = str(getattr(bot_config, "telegram_account", "") or "").strip() + if telegram_account: + bot_accounts["telegram"] = telegram_account + + for plat, account in platform_accounts.items(): + if account and plat not in bot_accounts: + bot_accounts[plat] = account + + bot_account = bot_accounts.get(platform) + return bool(bot_account and user_id == bot_account) diff --git a/src/bw_learner/message_recorder.py b/src/bw_learner/message_recorder.py new file mode 100644 index 00000000..4d8a5015 --- /dev/null +++ b/src/bw_learner/message_recorder.py @@ -0,0 +1,212 @@ +import time +import asyncio +from typing import List, Any +from src.common.logger import get_logger +from src.config.config import global_config +from src.chat.message_receive.chat_stream import get_chat_manager +from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_with_chat_inclusive +from src.bw_learner.expression_learner import expression_learner_manager +from src.bw_learner.jargon_miner import miner_manager + +logger = get_logger("bw_learner") + + +class MessageRecorder: + """ + 统一的消息记录器,负责管理时间窗口和消息提取,并将消息分发给 expression_learner 和 jargon_miner + """ + + def __init__(self, chat_id: str) -> None: + self.chat_id = chat_id + self.chat_stream = get_chat_manager().get_stream(chat_id) + self.chat_name = get_chat_manager().get_stream_name(chat_id) or chat_id + + # 维护每个chat的上次提取时间 + self.last_extraction_time: float = time.time() + + # 提取锁,防止并发执行 + self._extraction_lock = asyncio.Lock() + + # 获取 expression 和 jargon 的配置参数 + self._init_parameters() + + # 获取 expression_learner 和 jargon_miner 实例 + self.expression_learner = expression_learner_manager.get_expression_learner(chat_id) + self.jargon_miner = miner_manager.get_miner(chat_id) + + def _init_parameters(self) -> None: + """初始化提取参数""" + # 获取 expression 配置 + _, self.enable_expression_learning, self.enable_jargon_learning = ( + global_config.expression.get_expression_config_for_chat(self.chat_id) + ) + self.min_messages_for_extraction = 30 + self.min_extraction_interval = 60 + + logger.debug( + f"MessageRecorder 初始化: chat_id={self.chat_id}, " + f"min_messages={self.min_messages_for_extraction}, " + f"min_interval={self.min_extraction_interval}" + ) + + def should_trigger_extraction(self) -> bool: + """ + 检查是否应该触发消息提取 + + Returns: + bool: 是否应该触发提取 + """ + # 检查时间间隔 + time_diff = time.time() - self.last_extraction_time + if time_diff < self.min_extraction_interval: + return False + + # 检查消息数量 + recent_messages = get_raw_msg_by_timestamp_with_chat_inclusive( + chat_id=self.chat_id, + timestamp_start=self.last_extraction_time, + timestamp_end=time.time(), + ) + + if not recent_messages or len(recent_messages) < self.min_messages_for_extraction: + return False + + return True + + async def extract_and_distribute(self) -> None: + """ + 提取消息并分发给 expression_learner 和 jargon_miner + """ + # 使用异步锁防止并发执行 + async with self._extraction_lock: + # 在锁内检查,避免并发触发 + if not self.should_trigger_extraction(): + return + + # 检查 chat_stream 是否存在 + if not self.chat_stream: + return + + # 记录本次提取的时间窗口,避免重复提取 + extraction_start_time = self.last_extraction_time + extraction_end_time = time.time() + + # 立即更新提取时间,防止并发触发 + self.last_extraction_time = extraction_end_time + + try: + # logger.info(f"在聊天流 {self.chat_name} 开始统一消息提取和分发") + + # 拉取提取窗口内的消息 + messages = get_raw_msg_by_timestamp_with_chat_inclusive( + chat_id=self.chat_id, + timestamp_start=extraction_start_time, + timestamp_end=extraction_end_time, + ) + + if not messages: + logger.debug(f"聊天流 {self.chat_name} 没有新消息,跳过提取") + return + + # 按时间排序,确保顺序一致 + messages = sorted(messages, key=lambda msg: msg.time or 0) + + logger.info( + f"聊天流 {self.chat_name} 提取到 {len(messages)} 条消息," + f"时间窗口: {extraction_start_time:.2f} - {extraction_end_time:.2f}" + ) + + # 分别触发 expression_learner 和 jargon_miner 的处理 + # 传递提取的消息,避免它们重复获取 + # 触发 expression 学习(如果启用) + if self.enable_expression_learning: + asyncio.create_task( + self._trigger_expression_learning(extraction_start_time, extraction_end_time, messages) + ) + + # 触发 jargon 提取(如果启用),传递消息 + # if self.enable_jargon_learning: + # asyncio.create_task( + # self._trigger_jargon_extraction(extraction_start_time, extraction_end_time, messages) + # ) + + except Exception as e: + logger.error(f"为聊天流 {self.chat_name} 提取和分发消息失败: {e}") + import traceback + + traceback.print_exc() + # 即使失败也保持时间戳更新,避免频繁重试 + + async def _trigger_expression_learning( + self, timestamp_start: float, timestamp_end: float, messages: List[Any] + ) -> None: + """ + 触发 expression 学习,使用指定的消息列表 + + Args: + timestamp_start: 开始时间戳 + timestamp_end: 结束时间戳 + messages: 消息列表 + """ + try: + # 传递消息给 ExpressionLearner(必需参数) + learnt_style = await self.expression_learner.learn_and_store(messages=messages) + + if learnt_style: + logger.info(f"聊天流 {self.chat_name} 表达学习完成") + else: + logger.debug(f"聊天流 {self.chat_name} 表达学习未获得有效结果") + except Exception as e: + logger.error(f"为聊天流 {self.chat_name} 触发表达学习失败: {e}") + import traceback + + traceback.print_exc() + + async def _trigger_jargon_extraction( + self, timestamp_start: float, timestamp_end: float, messages: List[Any] + ) -> None: + """ + 触发 jargon 提取,使用指定的消息列表 + + Args: + timestamp_start: 开始时间戳 + timestamp_end: 结束时间戳 + messages: 消息列表 + """ + try: + # 传递消息给 JargonMiner,避免它重复获取 + await self.jargon_miner.run_once(messages=messages) + + except Exception as e: + logger.error(f"为聊天流 {self.chat_name} 触发黑话提取失败: {e}") + import traceback + + traceback.print_exc() + + +class MessageRecorderManager: + """MessageRecorder 管理器""" + + def __init__(self) -> None: + self._recorders: dict[str, MessageRecorder] = {} + + def get_recorder(self, chat_id: str) -> MessageRecorder: + """获取或创建指定 chat_id 的 MessageRecorder""" + if chat_id not in self._recorders: + self._recorders[chat_id] = MessageRecorder(chat_id) + return self._recorders[chat_id] + + +# 全局管理器实例 +recorder_manager = MessageRecorderManager() + + +async def extract_and_distribute_messages(chat_id: str) -> None: + """ + 统一的消息提取和分发入口函数 + + Args: + chat_id: 聊天流ID + """ + recorder = recorder_manager.get_recorder(chat_id) + await recorder.extract_and_distribute() diff --git a/src/bw_learner/reflect_tracker.py b/src/bw_learner/reflect_tracker.py new file mode 100644 index 00000000..c792679d --- /dev/null +++ b/src/bw_learner/reflect_tracker.py @@ -0,0 +1,199 @@ +import time +from typing import Optional, Dict, TYPE_CHECKING +from src.common.logger import get_logger +from src.common.database.database_model import Expression +from src.llm_models.utils_model import LLMRequest +from src.chat.utils.prompt_builder import Prompt, global_prompt_manager +from src.config.config import model_config +from src.chat.message_receive.chat_stream import ChatStream +from src.chat.utils.chat_message_builder import ( + get_raw_msg_by_timestamp_with_chat, + build_readable_messages, +) + +if TYPE_CHECKING: + pass + +logger = get_logger("reflect_tracker") + + +class ReflectTracker: + def __init__(self, chat_stream: ChatStream, expression: Expression, created_time: float): + self.chat_stream = chat_stream + self.expression = expression + self.created_time = created_time + # self.message_count = 0 # Replaced by checking message list length + self.last_check_msg_count = 0 + self.max_message_count = 30 + self.max_duration = 15 * 60 # 15 minutes + + # LLM for judging response + self.judge_model = LLMRequest(model_set=model_config.model_task_config.utils, request_type="reflect.tracker") + + self._init_prompts() + + def _init_prompts(self): + judge_prompt = """ +你是一个表达反思助手。Bot之前询问了表达方式是否合适。 +你需要根据提供的上下文对话,判断是否对该表达方式做出了肯定或否定的评价。 + +**询问内容** +情景: {situation} +风格: {style} + +**上下文对话** +{context_block} + +**判断要求** +1. 判断对话中是否包含对上述询问的回答。 +2. 如果是,判断是肯定(Approve)还是否定(Reject),或者是提供了修改意见。 +3. 如果不是回答,或者是无关内容,请返回 "Ignore"。 +4. 如果是否定并提供了修改意见,请提取修正后的情景和风格。 + +请输出JSON格式: +```json +{{ + "judgment": "Approve" | "Reject" | "Ignore", + "corrected_situation": "...", // 如果有修改意见,提取修正后的情景,否则留空 + "corrected_style": "..." // 如果有修改意见,提取修正后的风格,否则留空 +}} +``` +""" + Prompt(judge_prompt, "reflect_judge_prompt") + + async def trigger_tracker(self) -> bool: + """ + 触发追踪检查 + Returns: True if resolved (should destroy tracker), False otherwise + """ + # Check timeout + if time.time() - self.created_time > self.max_duration: + logger.info(f"ReflectTracker for expr {self.expression.id} timed out (duration).") + return True + + # Fetch messages since creation + msg_list = get_raw_msg_by_timestamp_with_chat( + chat_id=self.chat_stream.stream_id, + timestamp_start=self.created_time, + timestamp_end=time.time(), + ) + + current_msg_count = len(msg_list) + + # Check message limit + if current_msg_count > self.max_message_count: + logger.info(f"ReflectTracker for expr {self.expression.id} timed out (message count).") + return True + + # If no new messages since last check, skip + if current_msg_count <= self.last_check_msg_count: + return False + + self.last_check_msg_count = current_msg_count + + # Build context block + # Use simple readable format + context_block = build_readable_messages( + msg_list, + replace_bot_name=True, + timestamp_mode="relative", + read_mark=0.0, + show_actions=False, + ) + + # LLM Judge + try: + prompt = await global_prompt_manager.format_prompt( + "reflect_judge_prompt", + situation=self.expression.situation, + style=self.expression.style, + context_block=context_block, + ) + + logger.info(f"ReflectTracker LLM Prompt: {prompt}") + + response, _ = await self.judge_model.generate_response_async(prompt, temperature=0.1) + + logger.info(f"ReflectTracker LLM Response: {response}") + + # Parse JSON + import json + import re + from json_repair import repair_json + + json_pattern = r"```json\s*(.*?)\s*```" + matches = re.findall(json_pattern, response, re.DOTALL) + if not matches: + # Try to parse raw response if no code block + matches = [response] + + json_obj = json.loads(repair_json(matches[0])) + + judgment = json_obj.get("judgment") + + if judgment == "Approve": + self.expression.checked = True + self.expression.rejected = False + self.expression.save() + logger.info(f"Expression {self.expression.id} approved by operator.") + return True + + elif judgment == "Reject": + self.expression.checked = True + corrected_situation = json_obj.get("corrected_situation") + corrected_style = json_obj.get("corrected_style") + + # 检查是否有更新 + has_update = bool(corrected_situation or corrected_style) + + if corrected_situation: + self.expression.situation = corrected_situation + if corrected_style: + self.expression.style = corrected_style + + # 如果拒绝但未更新,标记为 rejected=1 + if not has_update: + self.expression.rejected = True + else: + self.expression.rejected = False + + self.expression.save() + + if has_update: + logger.info( + f"Expression {self.expression.id} rejected and updated by operator. New situation: {corrected_situation}, New style: {corrected_style}" + ) + else: + logger.info( + f"Expression {self.expression.id} rejected but no correction provided, marked as rejected=1." + ) + return True + + elif judgment == "Ignore": + logger.info(f"ReflectTracker for expr {self.expression.id} judged as Ignore.") + return False + + except Exception as e: + logger.error(f"Error in ReflectTracker check: {e}") + return False + + return False + + +# Global manager for trackers +class ReflectTrackerManager: + def __init__(self): + self.trackers: Dict[str, ReflectTracker] = {} # chat_id -> tracker + + def add_tracker(self, chat_id: str, tracker: ReflectTracker): + self.trackers[chat_id] = tracker + + def get_tracker(self, chat_id: str) -> Optional[ReflectTracker]: + return self.trackers.get(chat_id) + + def remove_tracker(self, chat_id: str): + if chat_id in self.trackers: + del self.trackers[chat_id] + + +reflect_tracker_manager = ReflectTrackerManager() diff --git a/src/chat/brain_chat/PFC/action_planner.py b/src/chat/brain_chat/PFC/action_planner.py new file mode 100644 index 00000000..4770c6ce --- /dev/null +++ b/src/chat/brain_chat/PFC/action_planner.py @@ -0,0 +1,491 @@ +import time +from typing import Tuple, Optional # 增加了 Optional +from src.common.logger_manager import get_logger +from ..models.utils_model import LLMRequest +from ...config.config import global_config +from .chat_observer import ChatObserver +from .pfc_utils import get_items_from_json +from src.individuality.individuality import Individuality +from .observation_info import ObservationInfo +from .conversation_info import ConversationInfo +from src.plugins.utils.chat_message_builder import build_readable_messages + + +logger = get_logger("pfc_action_planner") + + +# --- 定义 Prompt 模板 --- + +# Prompt(1): 首次回复或非连续回复时的决策 Prompt +PROMPT_INITIAL_REPLY = """{persona_text}。现在你在参与一场QQ私聊,请根据以下【所有信息】审慎且灵活的决策下一步行动,可以回复,可以倾听,可以调取知识,甚至可以屏蔽对方: + +【当前对话目标】 +{goals_str} +{knowledge_info_str} + +【最近行动历史概要】 +{action_history_summary} +【上一次行动的详细情况和结果】 +{last_action_context} +【时间和超时提示】 +{time_since_last_bot_message_info}{timeout_context} +【最近的对话记录】(包括你已成功发送的消息 和 新收到的消息) +{chat_history_text} + +------ +可选行动类型以及解释: +fetch_knowledge: 需要调取知识或记忆,当需要专业知识或特定信息时选择,对方若提到你不太认识的人名或实体也可以尝试选择 +listening: 倾听对方发言,当你认为对方话才说到一半,发言明显未结束时选择 +direct_reply: 直接回复对方 +rethink_goal: 思考一个对话目标,当你觉得目前对话需要目标,或当前目标不再适用,或话题卡住时选择。注意私聊的环境是灵活的,有可能需要经常选择 +end_conversation: 结束对话,对方长时间没回复或者当你觉得对话告一段落时可以选择 +block_and_ignore: 更加极端的结束对话方式,直接结束对话并在一段时间内无视对方所有发言(屏蔽),当对话让你感到十分不适,或你遭到各类骚扰时选择 + +请以JSON格式输出你的决策: +{{ + "action": "选择的行动类型 (必须是上面列表中的一个)", + "reason": "选择该行动的详细原因 (必须有解释你是如何根据“上一次行动结果”、“对话记录”和自身设定人设做出合理判断的)" +}} + +注意:请严格按照JSON格式输出,不要包含任何其他内容。""" + +# Prompt(2): 上一次成功回复后,决定继续发言时的决策 Prompt +PROMPT_FOLLOW_UP = """{persona_text}。现在你在参与一场QQ私聊,刚刚你已经回复了对方,请根据以下【所有信息】审慎且灵活的决策下一步行动,可以继续发送新消息,可以等待,可以倾听,可以调取知识,甚至可以屏蔽对方: + +【当前对话目标】 +{goals_str} +{knowledge_info_str} + +【最近行动历史概要】 +{action_history_summary} +【上一次行动的详细情况和结果】 +{last_action_context} +【时间和超时提示】 +{time_since_last_bot_message_info}{timeout_context} +【最近的对话记录】(包括你已成功发送的消息 和 新收到的消息) +{chat_history_text} + +------ +可选行动类型以及解释: +fetch_knowledge: 需要调取知识,当需要专业知识或特定信息时选择,对方若提到你不太认识的人名或实体也可以尝试选择 +wait: 暂时不说话,留给对方交互空间,等待对方回复(尤其是在你刚发言后、或上次发言因重复、发言过多被拒时、或不确定做什么时,这是不错的选择) +listening: 倾听对方发言(虽然你刚发过言,但如果对方立刻回复且明显话没说完,可以选择这个) +send_new_message: 发送一条新消息继续对话,允许适当的追问、补充、深入话题,或开启相关新话题。**但是避免在因重复被拒后立即使用,也不要在对方没有回复的情况下过多的“消息轰炸”或重复发言** +rethink_goal: 思考一个对话目标,当你觉得目前对话需要目标,或当前目标不再适用,或话题卡住时选择。注意私聊的环境是灵活的,有可能需要经常选择 +end_conversation: 结束对话,对方长时间没回复或者当你觉得对话告一段落时可以选择 +block_and_ignore: 更加极端的结束对话方式,直接结束对话并在一段时间内无视对方所有发言(屏蔽),当对话让你感到十分不适,或你遭到各类骚扰时选择 + +请以JSON格式输出你的决策: +{{ + "action": "选择的行动类型 (必须是上面列表中的一个)", + "reason": "选择该行动的详细原因 (必须有解释你是如何根据“上一次行动结果”、“对话记录”和自身设定人设做出合理判断的。请说明你为什么选择继续发言而不是等待,以及打算发送什么类型的新消息连续发言,必须记录已经发言了几次)" +}} + +注意:请严格按照JSON格式输出,不要包含任何其他内容。""" + +# 新增:Prompt(3): 决定是否在结束对话前发送告别语 +PROMPT_END_DECISION = """{persona_text}。刚刚你决定结束一场 QQ 私聊。 + +【你们之前的聊天记录】 +{chat_history_text} + +你觉得你们的对话已经完整结束了吗?有时候,在对话自然结束后再说点什么可能会有点奇怪,但有时也可能需要一条简短的消息来圆满结束。 +如果觉得确实有必要再发一条简短、自然、符合你人设的告别消息(比如 "好,下次再聊~" 或 "嗯,先这样吧"),就输出 "yes"。 +如果觉得当前状态下直接结束对话更好,没有必要再发消息,就输出 "no"。 + +请以 JSON 格式输出你的选择: +{{ + "say_bye": "yes/no", + "reason": "选择 yes 或 no 的原因和内心想法 (简要说明)" +}} + +注意:请严格按照 JSON 格式输出,不要包含任何其他内容。""" + + +# ActionPlanner 类定义,顶格 +class ActionPlanner: + """行动规划器""" + + def __init__(self, stream_id: str, private_name: str): + self.llm = LLMRequest( + model=global_config.llm_PFC_action_planner, + temperature=global_config.llm_PFC_action_planner["temp"], + max_tokens=1500, + request_type="action_planning", + ) + self.personality_info = Individuality.get_instance().get_prompt(x_person=2, level=3) + self.name = global_config.BOT_NICKNAME + self.private_name = private_name + self.chat_observer = ChatObserver.get_instance(stream_id, private_name) + # self.action_planner_info = ActionPlannerInfo() # 移除未使用的变量 + + # 修改 plan 方法签名,增加 last_successful_reply_action 参数 + async def plan( + self, + observation_info: ObservationInfo, + conversation_info: ConversationInfo, + last_successful_reply_action: Optional[str], + ) -> Tuple[str, str]: + """规划下一步行动 + + Args: + observation_info: 决策信息 + conversation_info: 对话信息 + last_successful_reply_action: 上一次成功的回复动作类型 ('direct_reply' 或 'send_new_message' 或 None) + + Returns: + Tuple[str, str]: (行动类型, 行动原因) + """ + # --- 获取 Bot 上次发言时间信息 --- + # (这部分逻辑不变) + time_since_last_bot_message_info = "" + try: + bot_id = str(global_config.BOT_QQ) + if hasattr(observation_info, "chat_history") and observation_info.chat_history: + for i in range(len(observation_info.chat_history) - 1, -1, -1): + msg = observation_info.chat_history[i] + if not isinstance(msg, dict): + continue + sender_info = msg.get("user_info", {}) + sender_id = str(sender_info.get("user_id")) if isinstance(sender_info, dict) else None + msg_time = msg.get("time") + if sender_id == bot_id and msg_time: + time_diff = time.time() - msg_time + if time_diff < 60.0: + time_since_last_bot_message_info = ( + f"提示:你上一条成功发送的消息是在 {time_diff:.1f} 秒前。\n" + ) + break + else: + logger.debug( + f"[私聊][{self.private_name}]Observation info chat history is empty or not available for bot time check." + ) + except AttributeError: + logger.warning( + f"[私聊][{self.private_name}]ObservationInfo object might not have chat_history attribute yet for bot time check." + ) + except Exception as e: + logger.warning(f"[私聊][{self.private_name}]获取 Bot 上次发言时间时出错: {e}") + + # --- 获取超时提示信息 --- + # (这部分逻辑不变) + timeout_context = "" + try: + if hasattr(conversation_info, "goal_list") and conversation_info.goal_list: + last_goal_dict = conversation_info.goal_list[-1] + if isinstance(last_goal_dict, dict) and "goal" in last_goal_dict: + last_goal_text = last_goal_dict["goal"] + if isinstance(last_goal_text, str) and "分钟,思考接下来要做什么" in last_goal_text: + try: + timeout_minutes_text = last_goal_text.split(",")[0].replace("你等待了", "") + timeout_context = f"重要提示:对方已经长时间({timeout_minutes_text})没有回复你的消息了(这可能代表对方繁忙/不想回复/没注意到你的消息等情况,或在对方看来本次聊天已告一段落),请基于此情况规划下一步。\n" + except Exception: + timeout_context = "重要提示:对方已经长时间没有回复你的消息了(这可能代表对方繁忙/不想回复/没注意到你的消息等情况,或在对方看来本次聊天已告一段落),请基于此情况规划下一步。\n" + else: + logger.debug( + f"[私聊][{self.private_name}]Conversation info goal_list is empty or not available for timeout check." + ) + except AttributeError: + logger.warning( + f"[私聊][{self.private_name}]ConversationInfo object might not have goal_list attribute yet for timeout check." + ) + except Exception as e: + logger.warning(f"[私聊][{self.private_name}]检查超时目标时出错: {e}") + + # --- 构建通用 Prompt 参数 --- + logger.debug( + f"[私聊][{self.private_name}]开始规划行动:当前目标: {getattr(conversation_info, 'goal_list', '不可用')}" + ) + + # 构建对话目标 (goals_str) + goals_str = "" + try: + if hasattr(conversation_info, "goal_list") and conversation_info.goal_list: + for goal_reason in conversation_info.goal_list: + if isinstance(goal_reason, dict): + goal = goal_reason.get("goal", "目标内容缺失") + reasoning = goal_reason.get("reasoning", "没有明确原因") + else: + goal = str(goal_reason) + reasoning = "没有明确原因" + + goal = str(goal) if goal is not None else "目标内容缺失" + reasoning = str(reasoning) if reasoning is not None else "没有明确原因" + goals_str += f"- 目标:{goal}\n 原因:{reasoning}\n" + + if not goals_str: + goals_str = "- 目前没有明确对话目标,请考虑设定一个。\n" + else: + goals_str = "- 目前没有明确对话目标,请考虑设定一个。\n" + except AttributeError: + logger.warning( + f"[私聊][{self.private_name}]ConversationInfo object might not have goal_list attribute yet." + ) + goals_str = "- 获取对话目标时出错。\n" + except Exception as e: + logger.error(f"[私聊][{self.private_name}]构建对话目标字符串时出错: {e}") + goals_str = "- 构建对话目标时出错。\n" + + # --- 知识信息字符串构建开始 --- + knowledge_info_str = "【已获取的相关知识和记忆】\n" + try: + # 检查 conversation_info 是否有 knowledge_list 并且不为空 + if hasattr(conversation_info, "knowledge_list") and conversation_info.knowledge_list: + # 最多只显示最近的 5 条知识,防止 Prompt 过长 + recent_knowledge = conversation_info.knowledge_list[-5:] + for i, knowledge_item in enumerate(recent_knowledge): + if isinstance(knowledge_item, dict): + query = knowledge_item.get("query", "未知查询") + knowledge = knowledge_item.get("knowledge", "无知识内容") + source = knowledge_item.get("source", "未知来源") + # 只取知识内容的前 2000 个字,避免太长 + knowledge_snippet = knowledge[:2000] + "..." if len(knowledge) > 2000 else knowledge + knowledge_info_str += ( + f"{i + 1}. 关于 '{query}' 的知识 (来源: {source}):\n {knowledge_snippet}\n" + ) + else: + # 处理列表里不是字典的异常情况 + knowledge_info_str += f"{i + 1}. 发现一条格式不正确的知识记录。\n" + + if not recent_knowledge: # 如果 knowledge_list 存在但为空 + knowledge_info_str += "- 暂无相关知识和记忆。\n" + + else: + # 如果 conversation_info 没有 knowledge_list 属性,或者列表为空 + knowledge_info_str += "- 暂无相关知识记忆。\n" + except AttributeError: + logger.warning(f"[私聊][{self.private_name}]ConversationInfo 对象可能缺少 knowledge_list 属性。") + knowledge_info_str += "- 获取知识列表时出错。\n" + except Exception as e: + logger.error(f"[私聊][{self.private_name}]构建知识信息字符串时出错: {e}") + knowledge_info_str += "- 处理知识列表时出错。\n" + # --- 知识信息字符串构建结束 --- + + # 获取聊天历史记录 (chat_history_text) + try: + if hasattr(observation_info, "chat_history") and observation_info.chat_history: + chat_history_text = observation_info.chat_history_str + if not chat_history_text: + chat_history_text = "还没有聊天记录。\n" + else: + chat_history_text = "还没有聊天记录。\n" + + if hasattr(observation_info, "new_messages_count") and observation_info.new_messages_count > 0: + if hasattr(observation_info, "unprocessed_messages") and observation_info.unprocessed_messages: + new_messages_list = observation_info.unprocessed_messages + new_messages_str = await build_readable_messages( + new_messages_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + chat_history_text += ( + f"\n--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n{new_messages_str}" + ) + else: + logger.warning( + f"[私聊][{self.private_name}]ObservationInfo has new_messages_count > 0 but unprocessed_messages is empty or missing." + ) + except AttributeError: + logger.warning( + f"[私聊][{self.private_name}]ObservationInfo object might be missing expected attributes for chat history." + ) + chat_history_text = "获取聊天记录时出错。\n" + except Exception as e: + logger.error(f"[私聊][{self.private_name}]处理聊天记录时发生未知错误: {e}") + chat_history_text = "处理聊天记录时出错。\n" + + # 构建 Persona 文本 (persona_text) + persona_text = f"你的名字是{self.name},{self.personality_info}。" + + # 构建行动历史和上一次行动结果 (action_history_summary, last_action_context) + # (这部分逻辑不变) + action_history_summary = "你最近执行的行动历史:\n" + last_action_context = "关于你【上一次尝试】的行动:\n" + action_history_list = [] + try: + if hasattr(conversation_info, "done_action") and conversation_info.done_action: + action_history_list = conversation_info.done_action[-5:] + else: + logger.debug(f"[私聊][{self.private_name}]Conversation info done_action is empty or not available.") + except AttributeError: + logger.warning( + f"[私聊][{self.private_name}]ConversationInfo object might not have done_action attribute yet." + ) + except Exception as e: + logger.error(f"[私聊][{self.private_name}]访问行动历史时出错: {e}") + + if not action_history_list: + action_history_summary += "- 还没有执行过行动。\n" + last_action_context += "- 这是你规划的第一个行动。\n" + else: + for i, action_data in enumerate(action_history_list): + action_type = "未知" + plan_reason = "未知" + status = "未知" + final_reason = "" + action_time = "" + + if isinstance(action_data, dict): + action_type = action_data.get("action", "未知") + plan_reason = action_data.get("plan_reason", "未知规划原因") + status = action_data.get("status", "未知") + final_reason = action_data.get("final_reason", "") + action_time = action_data.get("time", "") + elif isinstance(action_data, tuple): + # 假设旧格式兼容 + if len(action_data) > 0: + action_type = action_data[0] + if len(action_data) > 1: + plan_reason = action_data[1] # 可能是规划原因或最终原因 + if len(action_data) > 2: + status = action_data[2] + if status == "recall" and len(action_data) > 3: + final_reason = action_data[3] + elif status == "done" and action_type in ["direct_reply", "send_new_message"]: + plan_reason = "成功发送" # 简化显示 + + reason_text = f", 失败/取消原因: {final_reason}" if final_reason else "" + summary_line = f"- 时间:{action_time}, 尝试行动:'{action_type}', 状态:{status}{reason_text}" + action_history_summary += summary_line + "\n" + + if i == len(action_history_list) - 1: + last_action_context += f"- 上次【规划】的行动是: '{action_type}'\n" + last_action_context += f"- 当时规划的【原因】是: {plan_reason}\n" + if status == "done": + last_action_context += "- 该行动已【成功执行】。\n" + # 记录这次成功的行动类型,供下次决策 + # self.last_successful_action_type = action_type # 不在这里记录,由 conversation 控制 + elif status == "recall": + last_action_context += "- 但该行动最终【未能执行/被取消】。\n" + if final_reason: + last_action_context += f"- 【重要】失败/取消的具体原因是: “{final_reason}”\n" + else: + last_action_context += "- 【重要】失败/取消原因未明确记录。\n" + # self.last_successful_action_type = None # 行动失败,清除记录 + else: + last_action_context += f"- 该行动当前状态: {status}\n" + # self.last_successful_action_type = None # 非完成状态,清除记录 + + # --- 选择 Prompt --- + if last_successful_reply_action in ["direct_reply", "send_new_message"]: + prompt_template = PROMPT_FOLLOW_UP + logger.debug(f"[私聊][{self.private_name}]使用 PROMPT_FOLLOW_UP (追问决策)") + else: + prompt_template = PROMPT_INITIAL_REPLY + logger.debug(f"[私聊][{self.private_name}]使用 PROMPT_INITIAL_REPLY (首次/非连续回复决策)") + + # --- 格式化最终的 Prompt --- + prompt = prompt_template.format( + persona_text=persona_text, + goals_str=goals_str if goals_str.strip() else "- 目前没有明确对话目标,请考虑设定一个。", + action_history_summary=action_history_summary, + last_action_context=last_action_context, + time_since_last_bot_message_info=time_since_last_bot_message_info, + timeout_context=timeout_context, + chat_history_text=chat_history_text if chat_history_text.strip() else "还没有聊天记录。", + knowledge_info_str=knowledge_info_str, + ) + + logger.debug(f"[私聊][{self.private_name}]发送到LLM的最终提示词:\n------\n{prompt}\n------") + try: + content, _ = await self.llm.generate_response_async(prompt) + logger.debug(f"[私聊][{self.private_name}]LLM (行动规划) 原始返回内容: {content}") + + # --- 初始行动规划解析 --- + success, initial_result = get_items_from_json( + content, + self.private_name, + "action", + "reason", + default_values={"action": "wait", "reason": "LLM返回格式错误或未提供原因,默认等待"}, + ) + + initial_action = initial_result.get("action", "wait") + initial_reason = initial_result.get("reason", "LLM未提供原因,默认等待") + + # 检查是否需要进行结束对话决策 --- + if initial_action == "end_conversation": + logger.info(f"[私聊][{self.private_name}]初步规划结束对话,进入告别决策...") + + # 使用新的 PROMPT_END_DECISION + end_decision_prompt = PROMPT_END_DECISION.format( + persona_text=persona_text, # 复用之前的 persona_text + chat_history_text=chat_history_text, # 复用之前的 chat_history_text + ) + + logger.debug( + f"[私聊][{self.private_name}]发送到LLM的结束决策提示词:\n------\n{end_decision_prompt}\n------" + ) + try: + end_content, _ = await self.llm.generate_response_async(end_decision_prompt) # 再次调用LLM + logger.debug(f"[私聊][{self.private_name}]LLM (结束决策) 原始返回内容: {end_content}") + + # 解析结束决策的JSON + end_success, end_result = get_items_from_json( + end_content, + self.private_name, + "say_bye", + "reason", + default_values={"say_bye": "no", "reason": "结束决策LLM返回格式错误,默认不告别"}, + required_types={"say_bye": str, "reason": str}, # 明确类型 + ) + + say_bye_decision = end_result.get("say_bye", "no").lower() # 转小写方便比较 + end_decision_reason = end_result.get("reason", "未提供原因") + + if end_success and say_bye_decision == "yes": + # 决定要告别,返回新的 'say_goodbye' 动作 + logger.info( + f"[私聊][{self.private_name}]结束决策: yes, 准备生成告别语. 原因: {end_decision_reason}" + ) + # 注意:这里的 reason 可以考虑拼接初始原因和结束决策原因,或者只用结束决策原因 + final_action = "say_goodbye" + final_reason = f"决定发送告别语。决策原因: {end_decision_reason} (原结束理由: {initial_reason})" + return final_action, final_reason + else: + # 决定不告别 (包括解析失败或明确说no) + logger.info( + f"[私聊][{self.private_name}]结束决策: no, 直接结束对话. 原因: {end_decision_reason}" + ) + # 返回原始的 'end_conversation' 动作 + final_action = "end_conversation" + final_reason = initial_reason # 保持原始的结束理由 + return final_action, final_reason + + except Exception as end_e: + logger.error(f"[私聊][{self.private_name}]调用结束决策LLM或处理结果时出错: {str(end_e)}") + # 出错时,默认执行原始的结束对话 + logger.warning(f"[私聊][{self.private_name}]结束决策出错,将按原计划执行 end_conversation") + return "end_conversation", initial_reason # 返回原始动作和原因 + + else: + action = initial_action + reason = initial_reason + + # 验证action类型 (保持不变) + valid_actions = [ + "direct_reply", + "send_new_message", + "fetch_knowledge", + "wait", + "listening", + "rethink_goal", + "end_conversation", # 仍然需要验证,因为可能从上面决策后返回 + "block_and_ignore", + "say_goodbye", # 也要验证这个新动作 + ] + if action not in valid_actions: + logger.warning(f"[私聊][{self.private_name}]LLM返回了未知的行动类型: '{action}',强制改为 wait") + reason = f"(原始行动'{action}'无效,已强制改为wait) {reason}" + action = "wait" + + logger.info(f"[私聊][{self.private_name}]规划的行动: {action}") + logger.info(f"[私聊][{self.private_name}]行动原因: {reason}") + return action, reason + + except Exception as e: + # 外层异常处理保持不变 + logger.error(f"[私聊][{self.private_name}]规划行动时调用 LLM 或处理结果出错: {str(e)}") + return "wait", f"行动规划处理中发生错误,暂时等待: {str(e)}" diff --git a/src/chat/brain_chat/PFC/chat_observer.py b/src/chat/brain_chat/PFC/chat_observer.py new file mode 100644 index 00000000..22cbf27d --- /dev/null +++ b/src/chat/brain_chat/PFC/chat_observer.py @@ -0,0 +1,379 @@ +import time +import asyncio +import traceback +from typing import Optional, Dict, Any, List +from src.common.logger import get_module_logger +from maim_message import UserInfo +from ...config.config import global_config +from .chat_states import NotificationManager, create_new_message_notification, create_cold_chat_notification +from .message_storage import MongoDBMessageStorage +from rich.traceback import install + +install(extra_lines=3) + +logger = get_module_logger("chat_observer") + + +class ChatObserver: + """聊天状态观察器""" + + # 类级别的实例管理 + _instances: Dict[str, "ChatObserver"] = {} + + @classmethod + def get_instance(cls, stream_id: str, private_name: str) -> "ChatObserver": + """获取或创建观察器实例 + + Args: + stream_id: 聊天流ID + private_name: 私聊名称 + + Returns: + ChatObserver: 观察器实例 + """ + if stream_id not in cls._instances: + cls._instances[stream_id] = cls(stream_id, private_name) + return cls._instances[stream_id] + + def __init__(self, stream_id: str, private_name: str): + """初始化观察器 + + Args: + stream_id: 聊天流ID + """ + self.last_check_time = None + self.last_bot_speak_time = None + self.last_user_speak_time = None + if stream_id in self._instances: + raise RuntimeError(f"ChatObserver for {stream_id} already exists. Use get_instance() instead.") + + self.stream_id = stream_id + self.private_name = private_name + self.message_storage = MongoDBMessageStorage() + + # self.last_user_speak_time: Optional[float] = None # 对方上次发言时间 + # self.last_bot_speak_time: Optional[float] = None # 机器人上次发言时间 + # self.last_check_time: float = time.time() # 上次查看聊天记录时间 + self.last_message_read: Optional[Dict[str, Any]] = None # 最后读取的消息ID + self.last_message_time: float = time.time() + + self.waiting_start_time: float = time.time() # 等待开始时间,初始化为当前时间 + + # 运行状态 + self._running: bool = False + self._task: Optional[asyncio.Task] = None + self._update_event = asyncio.Event() # 触发更新的事件 + self._update_complete = asyncio.Event() # 更新完成的事件 + + # 通知管理器 + self.notification_manager = NotificationManager() + + # 冷场检查配置 + self.cold_chat_threshold: float = 60.0 # 60秒无消息判定为冷场 + self.last_cold_chat_check: float = time.time() + self.is_cold_chat_state: bool = False + + self.update_event = asyncio.Event() + self.update_interval = 2 # 更新间隔(秒) + self.message_cache = [] + self.update_running = False + + async def check(self) -> bool: + """检查距离上一次观察之后是否有了新消息 + + Returns: + bool: 是否有新消息 + """ + logger.debug(f"[私聊][{self.private_name}]检查距离上一次观察之后是否有了新消息: {self.last_check_time}") + + new_message_exists = await self.message_storage.has_new_messages(self.stream_id, self.last_check_time) + + if new_message_exists: + logger.debug(f"[私聊][{self.private_name}]发现新消息") + self.last_check_time = time.time() + + return new_message_exists + + async def _add_message_to_history(self, message: Dict[str, Any]): + """添加消息到历史记录并发送通知 + + Args: + message: 消息数据 + """ + try: + # 发送新消息通知 + notification = create_new_message_notification( + sender="chat_observer", target="observation_info", message=message + ) + # print(self.notification_manager) + await self.notification_manager.send_notification(notification) + except Exception as e: + logger.error(f"[私聊][{self.private_name}]添加消息到历史记录时出错: {e}") + print(traceback.format_exc()) + + # 检查并更新冷场状态 + await self._check_cold_chat() + + async def _check_cold_chat(self): + """检查是否处于冷场状态并发送通知""" + current_time = time.time() + + # 每10秒检查一次冷场状态 + if current_time - self.last_cold_chat_check < 10: + return + + self.last_cold_chat_check = current_time + + # 判断是否冷场 + is_cold = ( + True + if self.last_message_time is None + else (current_time - self.last_message_time) > self.cold_chat_threshold + ) + + # 如果冷场状态发生变化,发送通知 + if is_cold != self.is_cold_chat_state: + self.is_cold_chat_state = is_cold + notification = create_cold_chat_notification(sender="chat_observer", target="pfc", is_cold=is_cold) + await self.notification_manager.send_notification(notification) + + def new_message_after(self, time_point: float) -> bool: + """判断是否在指定时间点后有新消息 + + Args: + time_point: 时间戳 + + Returns: + bool: 是否有新消息 + """ + + if self.last_message_time is None: + logger.debug(f"[私聊][{self.private_name}]没有最后消息时间,返回 False") + return False + + has_new = self.last_message_time > time_point + logger.debug( + f"[私聊][{self.private_name}]判断是否在指定时间点后有新消息: {self.last_message_time} > {time_point} = {has_new}" + ) + return has_new + + def get_message_history( + self, + start_time: Optional[float] = None, + end_time: Optional[float] = None, + limit: Optional[int] = None, + user_id: Optional[str] = None, + ) -> List[Dict[str, Any]]: + """获取消息历史 + + Args: + start_time: 开始时间戳 + end_time: 结束时间戳 + limit: 限制返回消息数量 + user_id: 指定用户ID + + Returns: + List[Dict[str, Any]]: 消息列表 + """ + filtered_messages = self.message_history + + if start_time is not None: + filtered_messages = [m for m in filtered_messages if m["time"] >= start_time] + + if end_time is not None: + filtered_messages = [m for m in filtered_messages if m["time"] <= end_time] + + if user_id is not None: + filtered_messages = [ + m for m in filtered_messages if UserInfo.from_dict(m.get("user_info", {})).user_id == user_id + ] + + if limit is not None: + filtered_messages = filtered_messages[-limit:] + + return filtered_messages + + async def _fetch_new_messages(self) -> List[Dict[str, Any]]: + """获取新消息 + + Returns: + List[Dict[str, Any]]: 新消息列表 + """ + new_messages = await self.message_storage.get_messages_after(self.stream_id, self.last_message_time) + + if new_messages: + self.last_message_read = new_messages[-1] + self.last_message_time = new_messages[-1]["time"] + + # print(f"获取数据库中找到的新消息: {new_messages}") + + return new_messages + + async def _fetch_new_messages_before(self, time_point: float) -> List[Dict[str, Any]]: + """获取指定时间点之前的消息 + + Args: + time_point: 时间戳 + + Returns: + List[Dict[str, Any]]: 最多5条消息 + """ + new_messages = await self.message_storage.get_messages_before(self.stream_id, time_point) + + if new_messages: + self.last_message_read = new_messages[-1]["message_id"] + + logger.debug(f"[私聊][{self.private_name}]获取指定时间点111之前的消息: {new_messages}") + + return new_messages + + """主要观察循环""" + + async def _update_loop(self): + """更新循环""" + # try: + # start_time = time.time() + # messages = await self._fetch_new_messages_before(start_time) + # for message in messages: + # await self._add_message_to_history(message) + # logger.debug(f"[私聊][{self.private_name}]缓冲消息: {messages}") + # except Exception as e: + # logger.error(f"[私聊][{self.private_name}]缓冲消息出错: {e}") + + while self._running: + try: + # 等待事件或超时(1秒) + try: + # print("等待事件") + await asyncio.wait_for(self._update_event.wait(), timeout=1) + + except asyncio.TimeoutError: + # print("超时") + pass # 超时后也执行一次检查 + + self._update_event.clear() # 重置触发事件 + self._update_complete.clear() # 重置完成事件 + + # 获取新消息 + new_messages = await self._fetch_new_messages() + + if new_messages: + # 处理新消息 + for message in new_messages: + await self._add_message_to_history(message) + + # 设置完成事件 + self._update_complete.set() + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]更新循环出错: {e}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") + self._update_complete.set() # 即使出错也要设置完成事件 + + def trigger_update(self): + """触发一次立即更新""" + self._update_event.set() + + async def wait_for_update(self, timeout: float = 5.0) -> bool: + """等待更新完成 + + Args: + timeout: 超时时间(秒) + + Returns: + bool: 是否成功完成更新(False表示超时) + """ + try: + await asyncio.wait_for(self._update_complete.wait(), timeout=timeout) + return True + except asyncio.TimeoutError: + logger.warning(f"[私聊][{self.private_name}]等待更新完成超时({timeout}秒)") + return False + + def start(self): + """启动观察器""" + if self._running: + return + + self._running = True + self._task = asyncio.create_task(self._update_loop()) + logger.debug(f"[私聊][{self.private_name}]ChatObserver for {self.stream_id} started") + + def stop(self): + """停止观察器""" + self._running = False + self._update_event.set() # 设置事件以解除等待 + self._update_complete.set() # 设置完成事件以解除等待 + if self._task: + self._task.cancel() + logger.debug(f"[私聊][{self.private_name}]ChatObserver for {self.stream_id} stopped") + + async def process_chat_history(self, messages: list): + """处理聊天历史 + + Args: + messages: 消息列表 + """ + self.update_check_time() + + for msg in messages: + try: + user_info = UserInfo.from_dict(msg.get("user_info", {})) + if user_info.user_id == global_config.BOT_QQ: + self.update_bot_speak_time(msg["time"]) + else: + self.update_user_speak_time(msg["time"]) + except Exception as e: + logger.warning(f"[私聊][{self.private_name}]处理消息时间时出错: {e}") + continue + + def update_check_time(self): + """更新查看时间""" + self.last_check_time = time.time() + + def update_bot_speak_time(self, speak_time: Optional[float] = None): + """更新机器人说话时间""" + self.last_bot_speak_time = speak_time or time.time() + + def update_user_speak_time(self, speak_time: Optional[float] = None): + """更新用户说话时间""" + self.last_user_speak_time = speak_time or time.time() + + def get_time_info(self) -> str: + """获取时间信息文本""" + current_time = time.time() + time_info = "" + + if self.last_bot_speak_time: + bot_speak_ago = current_time - self.last_bot_speak_time + time_info += f"\n距离你上次发言已经过去了{int(bot_speak_ago)}秒" + + if self.last_user_speak_time: + user_speak_ago = current_time - self.last_user_speak_time + time_info += f"\n距离对方上次发言已经过去了{int(user_speak_ago)}秒" + + return time_info + + def get_cached_messages(self, limit: int = 50) -> List[Dict[str, Any]]: + """获取缓存的消息历史 + + Args: + limit: 获取的最大消息数量,默认50 + + Returns: + List[Dict[str, Any]]: 缓存的消息历史列表 + """ + return self.message_cache[-limit:] + + def get_last_message(self) -> Optional[Dict[str, Any]]: + """获取最后一条消息 + + Returns: + Optional[Dict[str, Any]]: 最后一条消息,如果没有则返回None + """ + if not self.message_cache: + return None + return self.message_cache[-1] + + def __str__(self): + return f"ChatObserver for {self.stream_id}" diff --git a/src/chat/brain_chat/PFC/chat_states.py b/src/chat/brain_chat/PFC/chat_states.py new file mode 100644 index 00000000..4b839b7b --- /dev/null +++ b/src/chat/brain_chat/PFC/chat_states.py @@ -0,0 +1,290 @@ +from enum import Enum, auto +from typing import Optional, Dict, Any, List, Set +from dataclasses import dataclass +from datetime import datetime +from abc import ABC, abstractmethod + + +class ChatState(Enum): + """聊天状态枚举""" + + NORMAL = auto() # 正常状态 + NEW_MESSAGE = auto() # 有新消息 + COLD_CHAT = auto() # 冷场状态 + ACTIVE_CHAT = auto() # 活跃状态 + BOT_SPEAKING = auto() # 机器人正在说话 + USER_SPEAKING = auto() # 用户正在说话 + SILENT = auto() # 沉默状态 + ERROR = auto() # 错误状态 + + +class NotificationType(Enum): + """通知类型枚举""" + + NEW_MESSAGE = auto() # 新消息通知 + COLD_CHAT = auto() # 冷场通知 + ACTIVE_CHAT = auto() # 活跃通知 + BOT_SPEAKING = auto() # 机器人说话通知 + USER_SPEAKING = auto() # 用户说话通知 + MESSAGE_DELETED = auto() # 消息删除通知 + USER_JOINED = auto() # 用户加入通知 + USER_LEFT = auto() # 用户离开通知 + ERROR = auto() # 错误通知 + + +@dataclass +class ChatStateInfo: + """聊天状态信息""" + + state: ChatState + last_message_time: Optional[float] = None + last_message_content: Optional[str] = None + last_speaker: Optional[str] = None + message_count: int = 0 + cold_duration: float = 0.0 # 冷场持续时间(秒) + active_duration: float = 0.0 # 活跃持续时间(秒) + + +@dataclass +class Notification: + """通知基类""" + + type: NotificationType + timestamp: float + sender: str # 发送者标识 + target: str # 接收者标识 + data: Dict[str, Any] + + def to_dict(self) -> Dict[str, Any]: + """转换为字典格式""" + return {"type": self.type.name, "timestamp": self.timestamp, "data": self.data} + + +@dataclass +class StateNotification(Notification): + """持续状态通知""" + + is_active: bool = True + + def to_dict(self) -> Dict[str, Any]: + base_dict = super().to_dict() + base_dict["is_active"] = self.is_active + return base_dict + + +class NotificationHandler(ABC): + """通知处理器接口""" + + @abstractmethod + async def handle_notification(self, notification: Notification): + """处理通知""" + pass + + +class NotificationManager: + """通知管理器""" + + def __init__(self): + # 按接收者和通知类型存储处理器 + self._handlers: Dict[str, Dict[NotificationType, List[NotificationHandler]]] = {} + self._active_states: Set[NotificationType] = set() + self._notification_history: List[Notification] = [] + + def register_handler(self, target: str, notification_type: NotificationType, handler: NotificationHandler): + """注册通知处理器 + + Args: + target: 接收者标识(例如:"pfc") + notification_type: 要处理的通知类型 + handler: 处理器实例 + """ + if target not in self._handlers: + self._handlers[target] = {} + if notification_type not in self._handlers[target]: + self._handlers[target][notification_type] = [] + # print(self._handlers[target][notification_type]) + self._handlers[target][notification_type].append(handler) + # print(self._handlers[target][notification_type]) + + def unregister_handler(self, target: str, notification_type: NotificationType, handler: NotificationHandler): + """注销通知处理器 + + Args: + target: 接收者标识 + notification_type: 通知类型 + handler: 要注销的处理器实例 + """ + if target in self._handlers and notification_type in self._handlers[target]: + handlers = self._handlers[target][notification_type] + if handler in handlers: + handlers.remove(handler) + # 如果该类型的处理器列表为空,删除该类型 + if not handlers: + del self._handlers[target][notification_type] + # 如果该目标没有任何处理器,删除该目标 + if not self._handlers[target]: + del self._handlers[target] + + async def send_notification(self, notification: Notification): + """发送通知""" + self._notification_history.append(notification) + + # 如果是状态通知,更新活跃状态 + if isinstance(notification, StateNotification): + if notification.is_active: + self._active_states.add(notification.type) + else: + self._active_states.discard(notification.type) + + # 调用目标接收者的处理器 + target = notification.target + if target in self._handlers: + handlers = self._handlers[target].get(notification.type, []) + # print(handlers) + for handler in handlers: + # print(f"调用处理器: {handler}") + await handler.handle_notification(notification) + + def get_active_states(self) -> Set[NotificationType]: + """获取当前活跃的状态""" + return self._active_states.copy() + + def is_state_active(self, state_type: NotificationType) -> bool: + """检查特定状态是否活跃""" + return state_type in self._active_states + + def get_notification_history( + self, sender: Optional[str] = None, target: Optional[str] = None, limit: Optional[int] = None + ) -> List[Notification]: + """获取通知历史 + + Args: + sender: 过滤特定发送者的通知 + target: 过滤特定接收者的通知 + limit: 限制返回数量 + """ + history = self._notification_history + + if sender: + history = [n for n in history if n.sender == sender] + if target: + history = [n for n in history if n.target == target] + + if limit is not None: + history = history[-limit:] + + return history + + def __str__(self): + str = "" + for target, handlers in self._handlers.items(): + for notification_type, handler_list in handlers.items(): + str += f"NotificationManager for {target} {notification_type} {handler_list}" + return str + + +# 一些常用的通知创建函数 +def create_new_message_notification(sender: str, target: str, message: Dict[str, Any]) -> Notification: + """创建新消息通知""" + return Notification( + type=NotificationType.NEW_MESSAGE, + timestamp=datetime.now().timestamp(), + sender=sender, + target=target, + data={ + "message_id": message.get("message_id"), + "processed_plain_text": message.get("processed_plain_text"), + "detailed_plain_text": message.get("detailed_plain_text"), + "user_info": message.get("user_info"), + "time": message.get("time"), + }, + ) + + +def create_cold_chat_notification(sender: str, target: str, is_cold: bool) -> StateNotification: + """创建冷场状态通知""" + return StateNotification( + type=NotificationType.COLD_CHAT, + timestamp=datetime.now().timestamp(), + sender=sender, + target=target, + data={"is_cold": is_cold}, + is_active=is_cold, + ) + + +def create_active_chat_notification(sender: str, target: str, is_active: bool) -> StateNotification: + """创建活跃状态通知""" + return StateNotification( + type=NotificationType.ACTIVE_CHAT, + timestamp=datetime.now().timestamp(), + sender=sender, + target=target, + data={"is_active": is_active}, + is_active=is_active, + ) + + +class ChatStateManager: + """聊天状态管理器""" + + def __init__(self): + self.current_state = ChatState.NORMAL + self.state_info = ChatStateInfo(state=ChatState.NORMAL) + self.state_history: list[ChatStateInfo] = [] + + def update_state(self, new_state: ChatState, **kwargs): + """更新聊天状态 + + Args: + new_state: 新的状态 + **kwargs: 其他状态信息 + """ + self.current_state = new_state + self.state_info.state = new_state + + # 更新其他状态信息 + for key, value in kwargs.items(): + if hasattr(self.state_info, key): + setattr(self.state_info, key, value) + + # 记录状态历史 + self.state_history.append(self.state_info) + + def get_current_state_info(self) -> ChatStateInfo: + """获取当前状态信息""" + return self.state_info + + def get_state_history(self) -> list[ChatStateInfo]: + """获取状态历史""" + return self.state_history + + def is_cold_chat(self, threshold: float = 60.0) -> bool: + """判断是否处于冷场状态 + + Args: + threshold: 冷场阈值(秒) + + Returns: + bool: 是否冷场 + """ + if not self.state_info.last_message_time: + return True + + current_time = datetime.now().timestamp() + return (current_time - self.state_info.last_message_time) > threshold + + def is_active_chat(self, threshold: float = 5.0) -> bool: + """判断是否处于活跃状态 + + Args: + threshold: 活跃阈值(秒) + + Returns: + bool: 是否活跃 + """ + if not self.state_info.last_message_time: + return False + + current_time = datetime.now().timestamp() + return (current_time - self.state_info.last_message_time) <= threshold diff --git a/src/chat/brain_chat/PFC/conversation.py b/src/chat/brain_chat/PFC/conversation.py new file mode 100644 index 00000000..0bc4cae8 --- /dev/null +++ b/src/chat/brain_chat/PFC/conversation.py @@ -0,0 +1,701 @@ +import time +import asyncio +import datetime + +# from .message_storage import MongoDBMessageStorage +from src.plugins.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat + +# from ...config.config import global_config +from typing import Dict, Any, Optional +from ..chat.message import Message +from .pfc_types import ConversationState +from .pfc import ChatObserver, GoalAnalyzer +from .message_sender import DirectMessageSender +from src.common.logger_manager import get_logger +from .action_planner import ActionPlanner +from .observation_info import ObservationInfo +from .conversation_info import ConversationInfo # 确保导入 ConversationInfo +from .reply_generator import ReplyGenerator +from ..chat.chat_stream import ChatStream +from maim_message import UserInfo +from src.plugins.chat.chat_stream import chat_manager +from .pfc_KnowledgeFetcher import KnowledgeFetcher +from .waiter import Waiter + +import traceback +from rich.traceback import install + +install(extra_lines=3) + +logger = get_logger("pfc") + + +class Conversation: + """对话类,负责管理单个对话的状态和行为""" + + def __init__(self, stream_id: str, private_name: str): + """初始化对话实例 + + Args: + stream_id: 聊天流ID + """ + self.stream_id = stream_id + self.private_name = private_name + self.state = ConversationState.INIT + self.should_continue = False + self.ignore_until_timestamp: Optional[float] = None + + # 回复相关 + self.generated_reply = "" + + async def _initialize(self): + """初始化实例,注册所有组件""" + + try: + self.action_planner = ActionPlanner(self.stream_id, self.private_name) + self.goal_analyzer = GoalAnalyzer(self.stream_id, self.private_name) + self.reply_generator = ReplyGenerator(self.stream_id, self.private_name) + self.knowledge_fetcher = KnowledgeFetcher(self.private_name) + self.waiter = Waiter(self.stream_id, self.private_name) + self.direct_sender = DirectMessageSender(self.private_name) + + # 获取聊天流信息 + self.chat_stream = chat_manager.get_stream(self.stream_id) + + self.stop_action_planner = False + except Exception as e: + logger.error(f"[私聊][{self.private_name}]初始化对话实例:注册运行组件失败: {e}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") + raise + + try: + # 决策所需要的信息,包括自身自信和观察信息两部分 + # 注册观察器和观测信息 + self.chat_observer = ChatObserver.get_instance(self.stream_id, self.private_name) + self.chat_observer.start() + self.observation_info = ObservationInfo(self.private_name) + self.observation_info.bind_to_chat_observer(self.chat_observer) + # print(self.chat_observer.get_cached_messages(limit=) + + self.conversation_info = ConversationInfo() + except Exception as e: + logger.error(f"[私聊][{self.private_name}]初始化对话实例:注册信息组件失败: {e}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") + raise + try: + logger.info(f"[私聊][{self.private_name}]为 {self.stream_id} 加载初始聊天记录...") + initial_messages = get_raw_msg_before_timestamp_with_chat( # + chat_id=self.stream_id, + timestamp=time.time(), + limit=30, # 加载最近30条作为初始上下文,可以调整 + ) + chat_talking_prompt = await build_readable_messages( + initial_messages, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + if initial_messages: + # 将加载的消息填充到 ObservationInfo 的 chat_history + self.observation_info.chat_history = initial_messages + self.observation_info.chat_history_str = chat_talking_prompt + "\n" + self.observation_info.chat_history_count = len(initial_messages) + + # 更新 ObservationInfo 中的时间戳等信息 + last_msg = initial_messages[-1] + self.observation_info.last_message_time = last_msg.get("time") + last_user_info = UserInfo.from_dict(last_msg.get("user_info", {})) + self.observation_info.last_message_sender = last_user_info.user_id + self.observation_info.last_message_content = last_msg.get("processed_plain_text", "") + + logger.info( + f"[私聊][{self.private_name}]成功加载 {len(initial_messages)} 条初始聊天记录。最后一条消息时间: {self.observation_info.last_message_time}" + ) + + # 让 ChatObserver 从加载的最后一条消息之后开始同步 + self.chat_observer.last_message_time = self.observation_info.last_message_time + self.chat_observer.last_message_read = last_msg # 更新 observer 的最后读取记录 + else: + logger.info(f"[私聊][{self.private_name}]没有找到初始聊天记录。") + + except Exception as load_err: + logger.error(f"[私聊][{self.private_name}]加载初始聊天记录时出错: {load_err}") + # 出错也要继续,只是没有历史记录而已 + # 组件准备完成,启动该论对话 + self.should_continue = True + asyncio.create_task(self.start()) + + async def start(self): + """开始对话流程""" + try: + logger.info(f"[私聊][{self.private_name}]对话系统启动中...") + asyncio.create_task(self._plan_and_action_loop()) + except Exception as e: + logger.error(f"[私聊][{self.private_name}]启动对话系统失败: {e}") + raise + + async def _plan_and_action_loop(self): + """思考步,PFC核心循环模块""" + while self.should_continue: + # 忽略逻辑 + if self.ignore_until_timestamp and time.time() < self.ignore_until_timestamp: + await asyncio.sleep(30) + continue + elif self.ignore_until_timestamp and time.time() >= self.ignore_until_timestamp: + logger.info(f"[私聊][{self.private_name}]忽略时间已到 {self.stream_id},准备结束对话。") + self.ignore_until_timestamp = None + self.should_continue = False + continue + try: + # --- 在规划前记录当前新消息数量 --- + initial_new_message_count = 0 + if hasattr(self.observation_info, "new_messages_count"): + initial_new_message_count = self.observation_info.new_messages_count + 1 # 算上麦麦自己发的那一条 + else: + logger.warning( + f"[私聊][{self.private_name}]ObservationInfo missing 'new_messages_count' before planning." + ) + + # --- 调用 Action Planner --- + # 传递 self.conversation_info.last_successful_reply_action + action, reason = await self.action_planner.plan( + self.observation_info, self.conversation_info, self.conversation_info.last_successful_reply_action + ) + + # --- 规划后检查是否有 *更多* 新消息到达 --- + current_new_message_count = 0 + if hasattr(self.observation_info, "new_messages_count"): + current_new_message_count = self.observation_info.new_messages_count + else: + logger.warning( + f"[私聊][{self.private_name}]ObservationInfo missing 'new_messages_count' after planning." + ) + + if current_new_message_count > initial_new_message_count + 2: + logger.info( + f"[私聊][{self.private_name}]规划期间发现新增消息 ({initial_new_message_count} -> {current_new_message_count}),跳过本次行动,重新规划" + ) + # 如果规划期间有新消息,也应该重置上次回复状态,因为现在要响应新消息了 + self.conversation_info.last_successful_reply_action = None + await asyncio.sleep(0.1) + continue + + # 包含 send_new_message + if initial_new_message_count > 0 and action in ["direct_reply", "send_new_message"]: + if hasattr(self.observation_info, "clear_unprocessed_messages"): + logger.debug( + f"[私聊][{self.private_name}]准备执行 {action},清理 {initial_new_message_count} 条规划时已知的新消息。" + ) + await self.observation_info.clear_unprocessed_messages() + if hasattr(self.observation_info, "new_messages_count"): + self.observation_info.new_messages_count = 0 + else: + logger.error( + f"[私聊][{self.private_name}]无法清理未处理消息: ObservationInfo 缺少 clear_unprocessed_messages 方法!" + ) + + await self._handle_action(action, reason, self.observation_info, self.conversation_info) + + # 检查是否需要结束对话 (逻辑不变) + goal_ended = False + if hasattr(self.conversation_info, "goal_list") and self.conversation_info.goal_list: + for goal_item in self.conversation_info.goal_list: + if isinstance(goal_item, dict): + current_goal = goal_item.get("goal") + + if current_goal == "结束对话": + goal_ended = True + break + + if goal_ended: + self.should_continue = False + logger.info(f"[私聊][{self.private_name}]检测到'结束对话'目标,停止循环。") + + except Exception as loop_err: + logger.error(f"[私聊][{self.private_name}]PFC主循环出错: {loop_err}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") + await asyncio.sleep(1) + + if self.should_continue: + await asyncio.sleep(0.1) + + logger.info(f"[私聊][{self.private_name}]PFC 循环结束 for stream_id: {self.stream_id}") + + def _check_new_messages_after_planning(self): + """检查在规划后是否有新消息""" + # 检查 ObservationInfo 是否已初始化并且有 new_messages_count 属性 + if not hasattr(self, "observation_info") or not hasattr(self.observation_info, "new_messages_count"): + logger.warning( + f"[私聊][{self.private_name}]ObservationInfo 未初始化或缺少 'new_messages_count' 属性,无法检查新消息。" + ) + return False # 或者根据需要抛出错误 + + if self.observation_info.new_messages_count > 2: + logger.info( + f"[私聊][{self.private_name}]生成/执行动作期间收到 {self.observation_info.new_messages_count} 条新消息,取消当前动作并重新规划" + ) + # 如果有新消息,也应该重置上次回复状态 + if hasattr(self, "conversation_info"): # 确保 conversation_info 已初始化 + self.conversation_info.last_successful_reply_action = None + else: + logger.warning( + f"[私聊][{self.private_name}]ConversationInfo 未初始化,无法重置 last_successful_reply_action。" + ) + return True + return False + + def _convert_to_message(self, msg_dict: Dict[str, Any]) -> Message: + """将消息字典转换为Message对象""" + try: + # 尝试从 msg_dict 直接获取 chat_stream,如果失败则从全局 chat_manager 获取 + chat_info = msg_dict.get("chat_info") + if chat_info and isinstance(chat_info, dict): + chat_stream = ChatStream.from_dict(chat_info) + elif self.chat_stream: # 使用实例变量中的 chat_stream + chat_stream = self.chat_stream + else: # Fallback: 尝试从 manager 获取 (可能需要 stream_id) + chat_stream = chat_manager.get_stream(self.stream_id) + if not chat_stream: + raise ValueError(f"无法确定 ChatStream for stream_id {self.stream_id}") + + user_info = UserInfo.from_dict(msg_dict.get("user_info", {})) + + return Message( + message_id=msg_dict.get("message_id", f"gen_{time.time()}"), # 提供默认 ID + chat_stream=chat_stream, # 使用确定的 chat_stream + time=msg_dict.get("time", time.time()), # 提供默认时间 + user_info=user_info, + processed_plain_text=msg_dict.get("processed_plain_text", ""), + detailed_plain_text=msg_dict.get("detailed_plain_text", ""), + ) + except Exception as e: + logger.warning(f"[私聊][{self.private_name}]转换消息时出错: {e}") + # 可以选择返回 None 或重新抛出异常,这里选择重新抛出以指示问题 + raise ValueError(f"无法将字典转换为 Message 对象: {e}") from e + + async def _handle_action( + self, action: str, reason: str, observation_info: ObservationInfo, conversation_info: ConversationInfo + ): + """处理规划的行动""" + + logger.debug(f"[私聊][{self.private_name}]执行行动: {action}, 原因: {reason}") + + # 记录action历史 (逻辑不变) + current_action_record = { + "action": action, + "plan_reason": reason, + "status": "start", + "time": datetime.datetime.now().strftime("%H:%M:%S"), + "final_reason": None, + } + # 确保 done_action 列表存在 + if not hasattr(conversation_info, "done_action"): + conversation_info.done_action = [] + conversation_info.done_action.append(current_action_record) + action_index = len(conversation_info.done_action) - 1 + + action_successful = False # 用于标记动作是否成功完成 + + # --- 根据不同的 action 执行 --- + + # send_new_message 失败后执行 wait + if action == "send_new_message": + max_reply_attempts = 3 + reply_attempt_count = 0 + is_suitable = False + need_replan = False + check_reason = "未进行尝试" + final_reply_to_send = "" + + while reply_attempt_count < max_reply_attempts and not is_suitable: + reply_attempt_count += 1 + logger.info( + f"[私聊][{self.private_name}]尝试生成追问回复 (第 {reply_attempt_count}/{max_reply_attempts} 次)..." + ) + self.state = ConversationState.GENERATING + + # 1. 生成回复 (调用 generate 时传入 action_type) + self.generated_reply = await self.reply_generator.generate( + observation_info, conversation_info, action_type="send_new_message" + ) + logger.info( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次生成的追问回复: {self.generated_reply}" + ) + + # 2. 检查回复 (逻辑不变) + self.state = ConversationState.CHECKING + try: + current_goal_str = conversation_info.goal_list[0]["goal"] if conversation_info.goal_list else "" + is_suitable, check_reason, need_replan = await self.reply_generator.check_reply( + reply=self.generated_reply, + goal=current_goal_str, + chat_history=observation_info.chat_history, + chat_history_str=observation_info.chat_history_str, + retry_count=reply_attempt_count - 1, + ) + logger.info( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次追问检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}" + ) + if is_suitable: + final_reply_to_send = self.generated_reply + break + elif need_replan: + logger.warning( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次追问检查建议重新规划,停止尝试。原因: {check_reason}" + ) + break + except Exception as check_err: + logger.error( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次调用 ReplyChecker (追问) 时出错: {check_err}" + ) + check_reason = f"第 {reply_attempt_count} 次检查过程出错: {check_err}" + break + + # 循环结束,处理最终结果 + if is_suitable: + # 检查是否有新消息 + if self._check_new_messages_after_planning(): + logger.info(f"[私聊][{self.private_name}]生成追问回复期间收到新消息,取消发送,重新规划行动") + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"有新消息,取消发送追问: {final_reply_to_send}"} + ) + return # 直接返回,重新规划 + + # 发送合适的回复 + self.generated_reply = final_reply_to_send + # --- 在这里调用 _send_reply --- + await self._send_reply() # <--- 调用恢复后的函数 + + # 更新状态: 标记上次成功是 send_new_message + self.conversation_info.last_successful_reply_action = "send_new_message" + action_successful = True # 标记动作成功 + + elif need_replan: + # 打回动作决策 + logger.warning( + f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试,追问回复决定打回动作决策。打回原因: {check_reason}" + ) + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"追问尝试{reply_attempt_count}次后打回: {check_reason}"} + ) + + else: + # 追问失败 + logger.warning( + f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试,未能生成合适的追问回复。最终原因: {check_reason}" + ) + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"追问尝试{reply_attempt_count}次后失败: {check_reason}"} + ) + # 重置状态: 追问失败,下次用初始 prompt + self.conversation_info.last_successful_reply_action = None + + # 执行 Wait 操作 + logger.info(f"[私聊][{self.private_name}]由于无法生成合适追问回复,执行 'wait' 操作...") + self.state = ConversationState.WAITING + await self.waiter.wait(self.conversation_info) + wait_action_record = { + "action": "wait", + "plan_reason": "因 send_new_message 多次尝试失败而执行的后备等待", + "status": "done", + "time": datetime.datetime.now().strftime("%H:%M:%S"), + "final_reason": None, + } + conversation_info.done_action.append(wait_action_record) + + elif action == "direct_reply": + max_reply_attempts = 3 + reply_attempt_count = 0 + is_suitable = False + need_replan = False + check_reason = "未进行尝试" + final_reply_to_send = "" + + while reply_attempt_count < max_reply_attempts and not is_suitable: + reply_attempt_count += 1 + logger.info( + f"[私聊][{self.private_name}]尝试生成首次回复 (第 {reply_attempt_count}/{max_reply_attempts} 次)..." + ) + self.state = ConversationState.GENERATING + + # 1. 生成回复 + self.generated_reply = await self.reply_generator.generate( + observation_info, conversation_info, action_type="direct_reply" + ) + logger.info( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次生成的首次回复: {self.generated_reply}" + ) + + # 2. 检查回复 + self.state = ConversationState.CHECKING + try: + current_goal_str = conversation_info.goal_list[0]["goal"] if conversation_info.goal_list else "" + is_suitable, check_reason, need_replan = await self.reply_generator.check_reply( + reply=self.generated_reply, + goal=current_goal_str, + chat_history=observation_info.chat_history, + chat_history_str=observation_info.chat_history_str, + retry_count=reply_attempt_count - 1, + ) + logger.info( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次首次回复检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}" + ) + if is_suitable: + final_reply_to_send = self.generated_reply + break + elif need_replan: + logger.warning( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次首次回复检查建议重新规划,停止尝试。原因: {check_reason}" + ) + break + except Exception as check_err: + logger.error( + f"[私聊][{self.private_name}]第 {reply_attempt_count} 次调用 ReplyChecker (首次回复) 时出错: {check_err}" + ) + check_reason = f"第 {reply_attempt_count} 次检查过程出错: {check_err}" + break + + # 循环结束,处理最终结果 + if is_suitable: + # 检查是否有新消息 + if self._check_new_messages_after_planning(): + logger.info(f"[私聊][{self.private_name}]生成首次回复期间收到新消息,取消发送,重新规划行动") + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"有新消息,取消发送首次回复: {final_reply_to_send}"} + ) + return # 直接返回,重新规划 + + # 发送合适的回复 + self.generated_reply = final_reply_to_send + # --- 在这里调用 _send_reply --- + await self._send_reply() # <--- 调用恢复后的函数 + + # 更新状态: 标记上次成功是 direct_reply + self.conversation_info.last_successful_reply_action = "direct_reply" + action_successful = True # 标记动作成功 + + elif need_replan: + # 打回动作决策 + logger.warning( + f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试,首次回复决定打回动作决策。打回原因: {check_reason}" + ) + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"首次回复尝试{reply_attempt_count}次后打回: {check_reason}"} + ) + + else: + # 首次回复失败 + logger.warning( + f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试,未能生成合适的首次回复。最终原因: {check_reason}" + ) + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"首次回复尝试{reply_attempt_count}次后失败: {check_reason}"} + ) + # 重置状态: 首次回复失败,下次还是用初始 prompt + self.conversation_info.last_successful_reply_action = None + + # 执行 Wait 操作 (保持原有逻辑) + logger.info(f"[私聊][{self.private_name}]由于无法生成合适首次回复,执行 'wait' 操作...") + self.state = ConversationState.WAITING + await self.waiter.wait(self.conversation_info) + wait_action_record = { + "action": "wait", + "plan_reason": "因 direct_reply 多次尝试失败而执行的后备等待", + "status": "done", + "time": datetime.datetime.now().strftime("%H:%M:%S"), + "final_reason": None, + } + conversation_info.done_action.append(wait_action_record) + + elif action == "fetch_knowledge": + self.state = ConversationState.FETCHING + knowledge_query = reason + try: + # 检查 knowledge_fetcher 是否存在 + if not hasattr(self, "knowledge_fetcher"): + logger.error(f"[私聊][{self.private_name}]KnowledgeFetcher 未初始化,无法获取知识。") + raise AttributeError("KnowledgeFetcher not initialized") + + knowledge, source = await self.knowledge_fetcher.fetch(knowledge_query, observation_info.chat_history) + logger.info(f"[私聊][{self.private_name}]获取到知识: {knowledge[:100]}..., 来源: {source}") + if knowledge: + # 确保 knowledge_list 存在 + if not hasattr(conversation_info, "knowledge_list"): + conversation_info.knowledge_list = [] + conversation_info.knowledge_list.append( + {"query": knowledge_query, "knowledge": knowledge, "source": source} + ) + action_successful = True + except Exception as fetch_err: + logger.error(f"[私聊][{self.private_name}]获取知识时出错: {str(fetch_err)}") + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"获取知识失败: {str(fetch_err)}"} + ) + self.conversation_info.last_successful_reply_action = None # 重置状态 + + elif action == "rethink_goal": + self.state = ConversationState.RETHINKING + try: + # 检查 goal_analyzer 是否存在 + if not hasattr(self, "goal_analyzer"): + logger.error(f"[私聊][{self.private_name}]GoalAnalyzer 未初始化,无法重新思考目标。") + raise AttributeError("GoalAnalyzer not initialized") + await self.goal_analyzer.analyze_goal(conversation_info, observation_info) + action_successful = True + except Exception as rethink_err: + logger.error(f"[私聊][{self.private_name}]重新思考目标时出错: {rethink_err}") + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"重新思考目标失败: {rethink_err}"} + ) + self.conversation_info.last_successful_reply_action = None # 重置状态 + + elif action == "listening": + self.state = ConversationState.LISTENING + logger.info(f"[私聊][{self.private_name}]倾听对方发言...") + try: + # 检查 waiter 是否存在 + if not hasattr(self, "waiter"): + logger.error(f"[私聊][{self.private_name}]Waiter 未初始化,无法倾听。") + raise AttributeError("Waiter not initialized") + await self.waiter.wait_listening(conversation_info) + action_successful = True # Listening 完成就算成功 + except Exception as listen_err: + logger.error(f"[私聊][{self.private_name}]倾听时出错: {listen_err}") + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"倾听失败: {listen_err}"} + ) + self.conversation_info.last_successful_reply_action = None # 重置状态 + + elif action == "say_goodbye": + self.state = ConversationState.GENERATING # 也可以定义一个新的状态,如 ENDING + logger.info(f"[私聊][{self.private_name}]执行行动: 生成并发送告别语...") + try: + # 1. 生成告别语 (使用 'say_goodbye' action_type) + self.generated_reply = await self.reply_generator.generate( + observation_info, conversation_info, action_type="say_goodbye" + ) + logger.info(f"[私聊][{self.private_name}]生成的告别语: {self.generated_reply}") + + # 2. 直接发送告别语 (不经过检查) + if self.generated_reply: # 确保生成了内容 + await self._send_reply() # 调用发送方法 + # 发送成功后,标记动作成功 + action_successful = True + logger.info(f"[私聊][{self.private_name}]告别语已发送。") + else: + logger.warning(f"[私聊][{self.private_name}]未能生成告别语内容,无法发送。") + action_successful = False # 标记动作失败 + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": "未能生成告别语内容"} + ) + + # 3. 无论是否发送成功,都准备结束对话 + self.should_continue = False + logger.info(f"[私聊][{self.private_name}]发送告别语流程结束,即将停止对话实例。") + + except Exception as goodbye_err: + logger.error(f"[私聊][{self.private_name}]生成或发送告别语时出错: {goodbye_err}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") + # 即使出错,也结束对话 + self.should_continue = False + action_successful = False # 标记动作失败 + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"生成或发送告别语时出错: {goodbye_err}"} + ) + + elif action == "end_conversation": + # 这个分支现在只会在 action_planner 最终决定不告别时被调用 + self.should_continue = False + logger.info(f"[私聊][{self.private_name}]收到最终结束指令,停止对话...") + action_successful = True # 标记这个指令本身是成功的 + + elif action == "block_and_ignore": + logger.info(f"[私聊][{self.private_name}]不想再理你了...") + ignore_duration_seconds = 10 * 60 + self.ignore_until_timestamp = time.time() + ignore_duration_seconds + logger.info( + f"[私聊][{self.private_name}]将忽略此对话直到: {datetime.datetime.fromtimestamp(self.ignore_until_timestamp)}" + ) + self.state = ConversationState.IGNORED + action_successful = True # 标记动作成功 + + else: # 对应 'wait' 动作 + self.state = ConversationState.WAITING + logger.info(f"[私聊][{self.private_name}]等待更多信息...") + try: + # 检查 waiter 是否存在 + if not hasattr(self, "waiter"): + logger.error(f"[私聊][{self.private_name}]Waiter 未初始化,无法等待。") + raise AttributeError("Waiter not initialized") + _timeout_occurred = await self.waiter.wait(self.conversation_info) + action_successful = True # Wait 完成就算成功 + except Exception as wait_err: + logger.error(f"[私聊][{self.private_name}]等待时出错: {wait_err}") + conversation_info.done_action[action_index].update( + {"status": "recall", "final_reason": f"等待失败: {wait_err}"} + ) + self.conversation_info.last_successful_reply_action = None # 重置状态 + + # --- 更新 Action History 状态 --- + # 只有当动作本身成功时,才更新状态为 done + if action_successful: + conversation_info.done_action[action_index].update( + { + "status": "done", + "time": datetime.datetime.now().strftime("%H:%M:%S"), + } + ) + # 重置状态: 对于非回复类动作的成功,清除上次回复状态 + if action not in ["direct_reply", "send_new_message"]: + self.conversation_info.last_successful_reply_action = None + logger.debug(f"[私聊][{self.private_name}]动作 {action} 成功完成,重置 last_successful_reply_action") + # 如果动作是 recall 状态,在各自的处理逻辑中已经更新了 done_action + + async def _send_reply(self): + """发送回复""" + if not self.generated_reply: + logger.warning(f"[私聊][{self.private_name}]没有生成回复内容,无法发送。") + return + + try: + _current_time = time.time() + reply_content = self.generated_reply + + # 发送消息 (确保 direct_sender 和 chat_stream 有效) + if not hasattr(self, "direct_sender") or not self.direct_sender: + logger.error(f"[私聊][{self.private_name}]DirectMessageSender 未初始化,无法发送回复。") + return + if not self.chat_stream: + logger.error(f"[私聊][{self.private_name}]ChatStream 未初始化,无法发送回复。") + return + + await self.direct_sender.send_message(chat_stream=self.chat_stream, content=reply_content) + + # 发送成功后,手动触发 observer 更新可能导致重复处理自己发送的消息 + # 更好的做法是依赖 observer 的自动轮询或数据库触发器(如果支持) + # 暂时注释掉,观察是否影响 ObservationInfo 的更新 + # self.chat_observer.trigger_update() + # if not await self.chat_observer.wait_for_update(): + # logger.warning(f"[私聊][{self.private_name}]等待 ChatObserver 更新完成超时") + + self.state = ConversationState.ANALYZING # 更新状态 + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]发送消息或更新状态时失败: {str(e)}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") + self.state = ConversationState.ANALYZING + + async def _send_timeout_message(self): + """发送超时结束消息""" + try: + messages = self.chat_observer.get_cached_messages(limit=1) + if not messages: + return + + latest_message = self._convert_to_message(messages[0]) + await self.direct_sender.send_message( + chat_stream=self.chat_stream, content="TODO:超时消息", reply_to_message=latest_message + ) + except Exception as e: + logger.error(f"[私聊][{self.private_name}]发送超时消息失败: {str(e)}") diff --git a/src/chat/brain_chat/PFC/conversation_info.py b/src/chat/brain_chat/PFC/conversation_info.py new file mode 100644 index 00000000..04524b69 --- /dev/null +++ b/src/chat/brain_chat/PFC/conversation_info.py @@ -0,0 +1,10 @@ +from typing import Optional + + +class ConversationInfo: + def __init__(self): + self.done_action = [] + self.goal_list = [] + self.knowledge_list = [] + self.memory_list = [] + self.last_successful_reply_action: Optional[str] = None diff --git a/src/chat/brain_chat/PFC/message_sender.py b/src/chat/brain_chat/PFC/message_sender.py new file mode 100644 index 00000000..12c2143e --- /dev/null +++ b/src/chat/brain_chat/PFC/message_sender.py @@ -0,0 +1,81 @@ +import time +from typing import Optional +from src.common.logger import get_module_logger +from ..chat.chat_stream import ChatStream +from ..chat.message import Message +from maim_message import UserInfo, Seg +from src.plugins.chat.message import MessageSending, MessageSet +from src.plugins.chat.message_sender import message_manager +from ..storage.storage import MessageStorage +from ...config.config import global_config +from rich.traceback import install + +install(extra_lines=3) + + +logger = get_module_logger("message_sender") + + +class DirectMessageSender: + """直接消息发送器""" + + def __init__(self, private_name: str): + self.private_name = private_name + self.storage = MessageStorage() + + async def send_message( + self, + chat_stream: ChatStream, + content: str, + reply_to_message: Optional[Message] = None, + ) -> None: + """发送消息到聊天流 + + Args: + chat_stream: 聊天流 + content: 消息内容 + reply_to_message: 要回复的消息(可选) + """ + try: + # 创建消息内容 + segments = Seg(type="seglist", data=[Seg(type="text", data=content)]) + + # 获取麦麦的信息 + bot_user_info = UserInfo( + user_id=global_config.BOT_QQ, + user_nickname=global_config.BOT_NICKNAME, + platform=chat_stream.platform, + ) + + # 用当前时间作为message_id,和之前那套sender一样 + message_id = f"dm{round(time.time(), 2)}" + + # 构建消息对象 + message = MessageSending( + message_id=message_id, + chat_stream=chat_stream, + bot_user_info=bot_user_info, + sender_info=reply_to_message.message_info.user_info if reply_to_message else None, + message_segment=segments, + reply=reply_to_message, + is_head=True, + is_emoji=False, + thinking_start_time=time.time(), + ) + + # 处理消息 + await message.process() + + # 不知道有什么用,先留下来了,和之前那套sender一样 + _message_json = message.to_dict() + + # 发送消息 + message_set = MessageSet(chat_stream, message_id) + message_set.add_message(message) + await message_manager.add_message(message_set) + await self.storage.store_message(message, chat_stream) + logger.info(f"[私聊][{self.private_name}]PFC消息已发送: {content}") + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]PFC消息发送失败: {str(e)}") + raise diff --git a/src/chat/brain_chat/PFC/message_storage.py b/src/chat/brain_chat/PFC/message_storage.py new file mode 100644 index 00000000..cd6a01e3 --- /dev/null +++ b/src/chat/brain_chat/PFC/message_storage.py @@ -0,0 +1,119 @@ +from abc import ABC, abstractmethod +from typing import List, Dict, Any +from src.common.database import db + + +class MessageStorage(ABC): + """消息存储接口""" + + @abstractmethod + async def get_messages_after(self, chat_id: str, message: Dict[str, Any]) -> List[Dict[str, Any]]: + """获取指定消息ID之后的所有消息 + + Args: + chat_id: 聊天ID + message: 消息 + + Returns: + List[Dict[str, Any]]: 消息列表 + """ + pass + + @abstractmethod + async def get_messages_before(self, chat_id: str, time_point: float, limit: int = 5) -> List[Dict[str, Any]]: + """获取指定时间点之前的消息 + + Args: + chat_id: 聊天ID + time_point: 时间戳 + limit: 最大消息数量 + + Returns: + List[Dict[str, Any]]: 消息列表 + """ + pass + + @abstractmethod + async def has_new_messages(self, chat_id: str, after_time: float) -> bool: + """检查是否有新消息 + + Args: + chat_id: 聊天ID + after_time: 时间戳 + + Returns: + bool: 是否有新消息 + """ + pass + + +class MongoDBMessageStorage(MessageStorage): + """MongoDB消息存储实现""" + + async def get_messages_after(self, chat_id: str, message_time: float) -> List[Dict[str, Any]]: + query = {"chat_id": chat_id, "time": {"$gt": message_time}} + # print(f"storage_check_message: {message_time}") + + return list(db.messages.find(query).sort("time", 1)) + + async def get_messages_before(self, chat_id: str, time_point: float, limit: int = 5) -> List[Dict[str, Any]]: + query = {"chat_id": chat_id, "time": {"$lt": time_point}} + + messages = list(db.messages.find(query).sort("time", -1).limit(limit)) + + # 将消息按时间正序排列 + messages.reverse() + return messages + + async def has_new_messages(self, chat_id: str, after_time: float) -> bool: + query = {"chat_id": chat_id, "time": {"$gt": after_time}} + + return db.messages.find_one(query) is not None + + +# # 创建一个内存消息存储实现,用于测试 +# class InMemoryMessageStorage(MessageStorage): +# """内存消息存储实现,主要用于测试""" + +# def __init__(self): +# self.messages: Dict[str, List[Dict[str, Any]]] = {} + +# async def get_messages_after(self, chat_id: str, message_id: Optional[str] = None) -> List[Dict[str, Any]]: +# if chat_id not in self.messages: +# return [] + +# messages = self.messages[chat_id] +# if not message_id: +# return messages + +# # 找到message_id的索引 +# try: +# index = next(i for i, m in enumerate(messages) if m["message_id"] == message_id) +# return messages[index + 1:] +# except StopIteration: +# return [] + +# async def get_messages_before(self, chat_id: str, time_point: float, limit: int = 5) -> List[Dict[str, Any]]: +# if chat_id not in self.messages: +# return [] + +# messages = [ +# m for m in self.messages[chat_id] +# if m["time"] < time_point +# ] + +# return messages[-limit:] + +# async def has_new_messages(self, chat_id: str, after_time: float) -> bool: +# if chat_id not in self.messages: +# return False + +# return any(m["time"] > after_time for m in self.messages[chat_id]) + +# # 测试辅助方法 +# def add_message(self, chat_id: str, message: Dict[str, Any]): +# """添加测试消息""" +# if chat_id not in self.messages: +# self.messages[chat_id] = [] +# self.messages[chat_id].append(message) +# self.messages[chat_id].sort(key=lambda m: m["time"]) diff --git a/src/chat/brain_chat/PFC/observation_info.py b/src/chat/brain_chat/PFC/observation_info.py new file mode 100644 index 00000000..c7572955 --- /dev/null +++ b/src/chat/brain_chat/PFC/observation_info.py @@ -0,0 +1,389 @@ +from typing import List, Optional, Dict, Any, Set +from maim_message import UserInfo +import time +from src.common.logger import get_module_logger +from .chat_observer import ChatObserver +from .chat_states import NotificationHandler, NotificationType, Notification +from src.plugins.utils.chat_message_builder import build_readable_messages +import traceback # 导入 traceback 用于调试 + +logger = get_module_logger("observation_info") + + +class ObservationInfoHandler(NotificationHandler): + """ObservationInfo的通知处理器""" + + def __init__(self, observation_info: "ObservationInfo", private_name: str): + """初始化处理器 + + Args: + observation_info: 要更新的ObservationInfo实例 + private_name: 私聊对象的名称,用于日志记录 + """ + self.observation_info = observation_info + # 将 private_name 存储在 handler 实例中 + self.private_name = private_name + + async def handle_notification(self, notification: Notification): # 添加类型提示 + # 获取通知类型和数据 + notification_type = notification.type + data = notification.data + + try: # 添加错误处理块 + if notification_type == NotificationType.NEW_MESSAGE: + # 处理新消息通知 + # logger.debug(f"[私聊][{self.private_name}]收到新消息通知data: {data}") # 可以在需要时取消注释 + message_id = data.get("message_id") + processed_plain_text = data.get("processed_plain_text") + detailed_plain_text = data.get("detailed_plain_text") + user_info_dict = data.get("user_info") # 先获取字典 + time_value = data.get("time") + + # 确保 user_info 是字典类型再创建 UserInfo 对象 + user_info = None + if isinstance(user_info_dict, dict): + try: + user_info = UserInfo.from_dict(user_info_dict) + except Exception as e: + logger.error( + f"[私聊][{self.private_name}]从字典创建 UserInfo 时出错: {e}, 字典内容: {user_info_dict}" + ) + # 可以选择在这里返回或记录错误,避免后续代码出错 + return + elif user_info_dict is not None: + logger.warning( + f"[私聊][{self.private_name}]收到的 user_info 不是预期的字典类型: {type(user_info_dict)}" + ) + # 根据需要处理非字典情况,这里暂时返回 + return + + message = { + "message_id": message_id, + "processed_plain_text": processed_plain_text, + "detailed_plain_text": detailed_plain_text, + "user_info": user_info_dict, # 存储原始字典或 UserInfo 对象,取决于你的 update_from_message 如何处理 + "time": time_value, + } + # 传递 UserInfo 对象(如果成功创建)或原始字典 + await self.observation_info.update_from_message(message, user_info) # 修改:传递 user_info 对象 + + elif notification_type == NotificationType.COLD_CHAT: + # 处理冷场通知 + is_cold = data.get("is_cold", False) + await self.observation_info.update_cold_chat_status(is_cold, time.time()) # 修改:改为 await 调用 + + elif notification_type == NotificationType.ACTIVE_CHAT: + # 处理活跃通知 (通常由 COLD_CHAT 的反向状态处理) + is_active = data.get("is_active", False) + self.observation_info.is_cold = not is_active + + elif notification_type == NotificationType.BOT_SPEAKING: + # 处理机器人说话通知 (按需实现) + self.observation_info.is_typing = False + self.observation_info.last_bot_speak_time = time.time() + + elif notification_type == NotificationType.USER_SPEAKING: + # 处理用户说话通知 + self.observation_info.is_typing = False + self.observation_info.last_user_speak_time = time.time() + + elif notification_type == NotificationType.MESSAGE_DELETED: + # 处理消息删除通知 + message_id = data.get("message_id") + # 从 unprocessed_messages 中移除被删除的消息 + original_count = len(self.observation_info.unprocessed_messages) + self.observation_info.unprocessed_messages = [ + msg for msg in self.observation_info.unprocessed_messages if msg.get("message_id") != message_id + ] + if len(self.observation_info.unprocessed_messages) < original_count: + logger.info(f"[私聊][{self.private_name}]移除了未处理的消息 (ID: {message_id})") + + elif notification_type == NotificationType.USER_JOINED: + # 处理用户加入通知 (如果适用私聊场景) + user_id = data.get("user_id") + if user_id: + self.observation_info.active_users.add(str(user_id)) # 确保是字符串 + + elif notification_type == NotificationType.USER_LEFT: + # 处理用户离开通知 (如果适用私聊场景) + user_id = data.get("user_id") + if user_id: + self.observation_info.active_users.discard(str(user_id)) # 确保是字符串 + + elif notification_type == NotificationType.ERROR: + # 处理错误通知 + error_msg = data.get("error", "未提供错误信息") + logger.error(f"[私聊][{self.private_name}]收到错误通知: {error_msg}") + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]处理通知时发生错误: {e}") + logger.error(traceback.format_exc()) # 打印详细堆栈信息 + + +# @dataclass <-- 这个,不需要了(递黄瓜) +class ObservationInfo: + """决策信息类,用于收集和管理来自chat_observer的通知信息 (手动实现 __init__)""" + + # 类型提示保留,可用于文档和静态分析 + private_name: str + chat_history: List[Dict[str, Any]] + chat_history_str: str + unprocessed_messages: List[Dict[str, Any]] + active_users: Set[str] + last_bot_speak_time: Optional[float] + last_user_speak_time: Optional[float] + last_message_time: Optional[float] + last_message_id: Optional[str] + last_message_content: str + last_message_sender: Optional[str] + bot_id: Optional[str] + chat_history_count: int + new_messages_count: int + cold_chat_start_time: Optional[float] + cold_chat_duration: float + is_typing: bool + is_cold_chat: bool + changed: bool + chat_observer: Optional[ChatObserver] + handler: Optional[ObservationInfoHandler] + + def __init__(self, private_name: str): + """ + 手动初始化 ObservationInfo 的所有实例变量。 + """ + + # 接收的参数 + self.private_name: str = private_name + + # data_list + self.chat_history: List[Dict[str, Any]] = [] + self.chat_history_str: str = "" + self.unprocessed_messages: List[Dict[str, Any]] = [] + self.active_users: Set[str] = set() + + # data + self.last_bot_speak_time: Optional[float] = None + self.last_user_speak_time: Optional[float] = None + self.last_message_time: Optional[float] = None + self.last_message_id: Optional[str] = None + self.last_message_content: str = "" + self.last_message_sender: Optional[str] = None + self.bot_id: Optional[str] = None + self.chat_history_count: int = 0 + self.new_messages_count: int = 0 + self.cold_chat_start_time: Optional[float] = None + self.cold_chat_duration: float = 0.0 + + # state + self.is_typing: bool = False + self.is_cold_chat: bool = False + self.changed: bool = False + + # 关联对象 + self.chat_observer: Optional[ChatObserver] = None + + self.handler: ObservationInfoHandler = ObservationInfoHandler(self, self.private_name) + + def bind_to_chat_observer(self, chat_observer: ChatObserver): + """绑定到指定的chat_observer + + Args: + chat_observer: 要绑定的 ChatObserver 实例 + """ + if self.chat_observer: + logger.warning(f"[私聊][{self.private_name}]尝试重复绑定 ChatObserver") + return + + self.chat_observer = chat_observer + try: + if not self.handler: # 确保 handler 已经被创建 + logger.error(f"[私聊][{self.private_name}] 尝试绑定时 handler 未初始化!") + self.chat_observer = None # 重置,防止后续错误 + return + + # 注册关心的通知类型 + self.chat_observer.notification_manager.register_handler( + target="observation_info", notification_type=NotificationType.NEW_MESSAGE, handler=self.handler + ) + self.chat_observer.notification_manager.register_handler( + target="observation_info", notification_type=NotificationType.COLD_CHAT, handler=self.handler + ) + # 可以根据需要注册更多通知类型 + # self.chat_observer.notification_manager.register_handler( + # target="observation_info", notification_type=NotificationType.MESSAGE_DELETED, handler=self.handler + # ) + logger.info(f"[私聊][{self.private_name}]成功绑定到 ChatObserver") + except Exception as e: + logger.error(f"[私聊][{self.private_name}]绑定到 ChatObserver 时出错: {e}") + self.chat_observer = None # 绑定失败,重置 + + def unbind_from_chat_observer(self): + """解除与chat_observer的绑定""" + if ( + self.chat_observer and hasattr(self.chat_observer, "notification_manager") and self.handler + ): # 增加 handler 检查 + try: + self.chat_observer.notification_manager.unregister_handler( + target="observation_info", notification_type=NotificationType.NEW_MESSAGE, handler=self.handler + ) + self.chat_observer.notification_manager.unregister_handler( + target="observation_info", notification_type=NotificationType.COLD_CHAT, handler=self.handler + ) + # 如果注册了其他类型,也要在这里注销 + # self.chat_observer.notification_manager.unregister_handler( + # target="observation_info", notification_type=NotificationType.MESSAGE_DELETED, handler=self.handler + # ) + logger.info(f"[私聊][{self.private_name}]成功从 ChatObserver 解绑") + except Exception as e: + logger.error(f"[私聊][{self.private_name}]从 ChatObserver 解绑时出错: {e}") + finally: # 确保 chat_observer 被重置 + self.chat_observer = None + else: + logger.warning(f"[私聊][{self.private_name}]尝试解绑时 ChatObserver 不存在、无效或 handler 未设置") + + # 修改:update_from_message 接收 UserInfo 对象 + async def update_from_message(self, message: Dict[str, Any], user_info: Optional[UserInfo]): + """从消息更新信息 + + Args: + message: 消息数据字典 + user_info: 解析后的 UserInfo 对象 (可能为 None) + """ + message_time = message.get("time") + message_id = message.get("message_id") + processed_text = message.get("processed_plain_text", "") + + # 只有在新消息到达时才更新 last_message 相关信息 + if message_time and message_time > (self.last_message_time or 0): + self.last_message_time = message_time + self.last_message_id = message_id + self.last_message_content = processed_text + # 重置冷场计时器 + self.is_cold_chat = False + self.cold_chat_start_time = None + self.cold_chat_duration = 0.0 + + if user_info: + sender_id = str(user_info.user_id) # 确保是字符串 + self.last_message_sender = sender_id + # 更新发言时间 + if sender_id == self.bot_id: + self.last_bot_speak_time = message_time + else: + self.last_user_speak_time = message_time + self.active_users.add(sender_id) # 用户发言则认为其活跃 + else: + logger.warning( + f"[私聊][{self.private_name}]处理消息更新时缺少有效的 UserInfo 对象, message_id: {message_id}" + ) + self.last_message_sender = None # 发送者未知 + + # 将原始消息字典添加到未处理列表 + self.unprocessed_messages.append(message) + self.new_messages_count = len(self.unprocessed_messages) # 直接用列表长度 + + # logger.debug(f"[私聊][{self.private_name}]消息更新: last_time={self.last_message_time}, new_count={self.new_messages_count}") + self.update_changed() # 标记状态已改变 + else: + # 如果消息时间戳不是最新的,可能不需要处理,或者记录一个警告 + pass + # logger.warning(f"[私聊][{self.private_name}]收到过时或无效时间戳的消息: ID={message_id}, time={message_time}") + + def update_changed(self): + """标记状态已改变,并重置标记""" + # logger.debug(f"[私聊][{self.private_name}]状态标记为已改变 (changed=True)") + self.changed = True + + async def update_cold_chat_status(self, is_cold: bool, current_time: float): + """更新冷场状态 + + Args: + is_cold: 是否处于冷场状态 + current_time: 当前时间戳 + """ + if is_cold != self.is_cold_chat: # 仅在状态变化时更新 + self.is_cold_chat = is_cold + if is_cold: + # 进入冷场状态 + self.cold_chat_start_time = ( + self.last_message_time or current_time + ) # 从最后消息时间开始算,或从当前时间开始 + logger.info(f"[私聊][{self.private_name}]进入冷场状态,开始时间: {self.cold_chat_start_time}") + else: + # 结束冷场状态 + if self.cold_chat_start_time: + self.cold_chat_duration = current_time - self.cold_chat_start_time + logger.info(f"[私聊][{self.private_name}]结束冷场状态,持续时间: {self.cold_chat_duration:.2f} 秒") + self.cold_chat_start_time = None # 重置开始时间 + self.update_changed() # 状态变化,标记改变 + + # 即使状态没变,如果是冷场状态,也更新持续时间 + if self.is_cold_chat and self.cold_chat_start_time: + self.cold_chat_duration = current_time - self.cold_chat_start_time + + def get_active_duration(self) -> float: + """获取当前活跃时长 (距离最后一条消息的时间) + + Returns: + float: 最后一条消息到现在的时长(秒) + """ + if not self.last_message_time: + return 0.0 + return time.time() - self.last_message_time + + def get_user_response_time(self) -> Optional[float]: + """获取用户最后响应时间 (距离用户最后发言的时间) + + Returns: + Optional[float]: 用户最后发言到现在的时长(秒),如果没有用户发言则返回None + """ + if not self.last_user_speak_time: + return None + return time.time() - self.last_user_speak_time + + def get_bot_response_time(self) -> Optional[float]: + """获取机器人最后响应时间 (距离机器人最后发言的时间) + + Returns: + Optional[float]: 机器人最后发言到现在的时长(秒),如果没有机器人发言则返回None + """ + if not self.last_bot_speak_time: + return None + return time.time() - self.last_bot_speak_time + + async def clear_unprocessed_messages(self): + """将未处理消息移入历史记录,并更新相关状态""" + if not self.unprocessed_messages: + return # 没有未处理消息,直接返回 + + # logger.debug(f"[私聊][{self.private_name}]处理 {len(self.unprocessed_messages)} 条未处理消息...") + # 将未处理消息添加到历史记录中 (确保历史记录有长度限制,避免无限增长) + max_history_len = 100 # 示例:最多保留100条历史记录 + self.chat_history.extend(self.unprocessed_messages) + if len(self.chat_history) > max_history_len: + self.chat_history = self.chat_history[-max_history_len:] + + # 更新历史记录字符串 (只使用最近一部分生成,例如20条) + history_slice_for_str = self.chat_history[-20:] + try: + self.chat_history_str = await build_readable_messages( + history_slice_for_str, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, # read_mark 可能需要根据逻辑调整 + ) + except Exception as e: + logger.error(f"[私聊][{self.private_name}]构建聊天记录字符串时出错: {e}") + self.chat_history_str = "[构建聊天记录出错]" # 提供错误提示 + + # 清空未处理消息列表和计数 + # cleared_count = len(self.unprocessed_messages) + self.unprocessed_messages.clear() + self.new_messages_count = 0 + # self.has_unread_messages = False # 这个状态可以通过 new_messages_count 判断 + + self.chat_history_count = len(self.chat_history) # 更新历史记录总数 + # logger.debug(f"[私聊][{self.private_name}]已处理 {cleared_count} 条消息,当前历史记录 {self.chat_history_count} 条。") + + self.update_changed() # 状态改变 diff --git a/src/chat/brain_chat/PFC/pfc.py b/src/chat/brain_chat/PFC/pfc.py new file mode 100644 index 00000000..b17ee21d --- /dev/null +++ b/src/chat/brain_chat/PFC/pfc.py @@ -0,0 +1,345 @@ +from typing import List, Tuple, TYPE_CHECKING +from src.common.logger import get_module_logger +from ..models.utils_model import LLMRequest +from ...config.config import global_config +from .chat_observer import ChatObserver +from .pfc_utils import get_items_from_json +from src.individuality.individuality import Individuality +from .conversation_info import ConversationInfo +from .observation_info import ObservationInfo +from src.plugins.utils.chat_message_builder import build_readable_messages +from rich.traceback import install + +install(extra_lines=3) + +if TYPE_CHECKING: + pass + +logger = get_module_logger("pfc") + + +def _calculate_similarity(goal1: str, goal2: str) -> float: + """简单计算两个目标之间的相似度 + + 这里使用一个简单的实现,实际可以使用更复杂的文本相似度算法 + + Args: + goal1: 第一个目标 + goal2: 第二个目标 + + Returns: + float: 相似度得分 (0-1) + """ + # 简单实现:检查重叠字数比例 + words1 = set(goal1) + words2 = set(goal2) + overlap = len(words1.intersection(words2)) + total = len(words1.union(words2)) + return overlap / total if total > 0 else 0 + + +class GoalAnalyzer: + """对话目标分析器""" + + def __init__(self, stream_id: str, private_name: str): + self.llm = LLMRequest( + model=global_config.llm_normal, temperature=0.7, max_tokens=1000, request_type="conversation_goal" + ) + + self.personality_info = Individuality.get_instance().get_prompt(x_person=2, level=3) + self.name = global_config.BOT_NICKNAME + self.nick_name = global_config.BOT_ALIAS_NAMES + self.private_name = private_name + self.chat_observer = ChatObserver.get_instance(stream_id, private_name) + + # 多目标存储结构 + self.goals = [] # 存储多个目标 + self.max_goals = 3 # 同时保持的最大目标数量 + self.current_goal_and_reason = None + + async def analyze_goal(self, conversation_info: ConversationInfo, observation_info: ObservationInfo): + """分析对话历史并设定目标 + + Args: + conversation_info: 对话信息 + observation_info: 观察信息 + + Returns: + Tuple[str, str, str]: (目标, 方法, 原因) + """ + # 构建对话目标 + goals_str = "" + if conversation_info.goal_list: + for goal_reason in conversation_info.goal_list: + if isinstance(goal_reason, dict): + goal = goal_reason.get("goal", "目标内容缺失") + reasoning = goal_reason.get("reasoning", "没有明确原因") + else: + goal = str(goal_reason) + reasoning = "没有明确原因" + + goal_str = f"目标:{goal},产生该对话目标的原因:{reasoning}\n" + goals_str += goal_str + else: + goal = "目前没有明确对话目标" + reasoning = "目前没有明确对话目标,最好思考一个对话目标" + goals_str = f"目标:{goal},产生该对话目标的原因:{reasoning}\n" + + # 获取聊天历史记录 + chat_history_text = observation_info.chat_history_str + + if observation_info.new_messages_count > 0: + new_messages_list = observation_info.unprocessed_messages + new_messages_str = await build_readable_messages( + new_messages_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + chat_history_text += f"\n--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n{new_messages_str}" + + # await observation_info.clear_unprocessed_messages() + + persona_text = f"你的名字是{self.name},{self.personality_info}。" + # 构建action历史文本 + action_history_list = conversation_info.done_action + action_history_text = "你之前做的事情是:" + for action in action_history_list: + action_history_text += f"{action}\n" + + prompt = f"""{persona_text}。现在你在参与一场QQ聊天,请分析以下聊天记录,并根据你的性格特征确定多个明确的对话目标。 +这些目标应该反映出对话的不同方面和意图。 + +{action_history_text} +当前对话目标: +{goals_str} + +聊天记录: +{chat_history_text} + +请分析当前对话并确定最适合的对话目标。你可以: +1. 保持现有目标不变 +2. 修改现有目标 +3. 添加新目标 +4. 删除不再相关的目标 +5. 如果你想结束对话,请设置一个目标,目标goal为"结束对话",原因reasoning为你希望结束对话 + +请以JSON数组格式输出当前的所有对话目标,每个目标包含以下字段: +1. goal: 对话目标(简短的一句话) +2. reasoning: 对话原因,为什么设定这个目标(简要解释) + +输出格式示例: +[ +{{ + "goal": "回答用户关于Python编程的具体问题", + "reasoning": "用户提出了关于Python的技术问题,需要专业且准确的解答" +}}, +{{ + "goal": "回答用户关于python安装的具体问题", + "reasoning": "用户提出了关于Python的技术问题,需要专业且准确的解答" +}} +]""" + + logger.debug(f"[私聊][{self.private_name}]发送到LLM的提示词: {prompt}") + try: + content, _ = await self.llm.generate_response_async(prompt) + logger.debug(f"[私聊][{self.private_name}]LLM原始返回内容: {content}") + except Exception as e: + logger.error(f"[私聊][{self.private_name}]分析对话目标时出错: {str(e)}") + content = "" + + # 使用改进后的get_items_from_json函数处理JSON数组 + success, result = get_items_from_json( + content, + self.private_name, + "goal", + "reasoning", + required_types={"goal": str, "reasoning": str}, + allow_array=True, + ) + + if success: + # 判断结果是单个字典还是字典列表 + if isinstance(result, list): + # 清空现有目标列表并添加新目标 + conversation_info.goal_list = [] + for item in result: + conversation_info.goal_list.append(item) + + # 返回第一个目标作为当前主要目标(如果有) + if result: + first_goal = result[0] + return first_goal.get("goal", ""), "", first_goal.get("reasoning", "") + else: + # 单个目标的情况 + conversation_info.goal_list.append(result) + return goal, "", reasoning + + # 如果解析失败,返回默认值 + return "", "", "" + + async def _update_goals(self, new_goal: str, method: str, reasoning: str): + """更新目标列表 + + Args: + new_goal: 新的目标 + method: 实现目标的方法 + reasoning: 目标的原因 + """ + # 检查新目标是否与现有目标相似 + for i, (existing_goal, _, _) in enumerate(self.goals): + if _calculate_similarity(new_goal, existing_goal) > 0.7: # 相似度阈值 + # 更新现有目标 + self.goals[i] = (new_goal, method, reasoning) + # 将此目标移到列表前面(最主要的位置) + self.goals.insert(0, self.goals.pop(i)) + return + + # 添加新目标到列表前面 + self.goals.insert(0, (new_goal, method, reasoning)) + + # 限制目标数量 + if len(self.goals) > self.max_goals: + self.goals.pop() # 移除最老的目标 + + async def get_all_goals(self) -> List[Tuple[str, str, str]]: + """获取所有当前目标 + + Returns: + List[Tuple[str, str, str]]: 目标列表,每项为(目标, 方法, 原因) + """ + return self.goals.copy() + + async def get_alternative_goals(self) -> List[Tuple[str, str, str]]: + """获取除了当前主要目标外的其他备选目标 + + Returns: + List[Tuple[str, str, str]]: 备选目标列表 + """ + if len(self.goals) <= 1: + return [] + return self.goals[1:].copy() + + async def analyze_conversation(self, goal, reasoning): + messages = self.chat_observer.get_cached_messages() + chat_history_text = await build_readable_messages( + messages, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + + persona_text = f"你的名字是{self.name},{self.personality_info}。" + # ===> Persona 文本构建结束 <=== + + # --- 修改 Prompt 字符串,使用 persona_text --- + prompt = f"""{persona_text}。现在你在参与一场QQ聊天, + 当前对话目标:{goal} + 产生该对话目标的原因:{reasoning} + + 请分析以下聊天记录,并根据你的性格特征评估该目标是否已经达到,或者你是否希望停止该次对话。 + 聊天记录: + {chat_history_text} + 请以JSON格式输出,包含以下字段: + 1. goal_achieved: 对话目标是否已经达到(true/false) + 2. stop_conversation: 是否希望停止该次对话(true/false) + 3. reason: 为什么希望停止该次对话(简要解释) + +输出格式示例: +{{ + "goal_achieved": true, + "stop_conversation": false, + "reason": "虽然目标已达成,但对话仍然有继续的价值" +}}""" + + try: + content, _ = await self.llm.generate_response_async(prompt) + logger.debug(f"[私聊][{self.private_name}]LLM原始返回内容: {content}") + + # 尝试解析JSON + success, result = get_items_from_json( + content, + self.private_name, + "goal_achieved", + "stop_conversation", + "reason", + required_types={"goal_achieved": bool, "stop_conversation": bool, "reason": str}, + ) + + if not success: + logger.error(f"[私聊][{self.private_name}]无法解析对话分析结果JSON") + return False, False, "解析结果失败" + + goal_achieved = result["goal_achieved"] + stop_conversation = result["stop_conversation"] + reason = result["reason"] + + return goal_achieved, stop_conversation, reason + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]分析对话状态时出错: {str(e)}") + return False, False, f"分析出错: {str(e)}" + + +# 先注释掉,万一以后出问题了还能开回来((( +# class DirectMessageSender: +# """直接发送消息到平台的发送器""" + +# def __init__(self, private_name: str): +# self.logger = get_module_logger("direct_sender") +# self.storage = MessageStorage() +# self.private_name = private_name + +# async def send_via_ws(self, message: MessageSending) -> None: +# try: +# await global_api.send_message(message) +# except Exception as e: +# raise ValueError(f"未找到平台:{message.message_info.platform} 的url配置,请检查配置文件") from e + +# async def send_message( +# self, +# chat_stream: ChatStream, +# content: str, +# reply_to_message: Optional[Message] = None, +# ) -> None: +# """直接发送消息到平台 + +# Args: +# chat_stream: 聊天流 +# content: 消息内容 +# reply_to_message: 要回复的消息 +# """ +# # 构建消息对象 +# message_segment = Seg(type="text", data=content) +# bot_user_info = UserInfo( +# user_id=global_config.BOT_QQ, +# user_nickname=global_config.BOT_NICKNAME, +# platform=chat_stream.platform, +# ) + +# message = MessageSending( +# message_id=f"dm{round(time.time(), 2)}", +# chat_stream=chat_stream, +# bot_user_info=bot_user_info, +# sender_info=reply_to_message.message_info.user_info if reply_to_message else None, +# message_segment=message_segment, +# reply=reply_to_message, +# is_head=True, +# is_emoji=False, +# thinking_start_time=time.time(), +# ) + +# # 处理消息 +# await message.process() + +# _message_json = message.to_dict() + +# # 发送消息 +# try: +# await self.send_via_ws(message) +# await self.storage.store_message(message, chat_stream) +# logger.success(f"[私聊][{self.private_name}]PFC消息已发送: {content}") +# except Exception as e: +# logger.error(f"[私聊][{self.private_name}]PFC消息发送失败: {str(e)}") diff --git a/src/chat/brain_chat/PFC/pfc_KnowledgeFetcher.py b/src/chat/brain_chat/PFC/pfc_KnowledgeFetcher.py new file mode 100644 index 00000000..0989339d --- /dev/null +++ b/src/chat/brain_chat/PFC/pfc_KnowledgeFetcher.py @@ -0,0 +1,85 @@ +from typing import List, Tuple +from src.common.logger import get_module_logger +from src.plugins.memory_system.Hippocampus import HippocampusManager +from ..models.utils_model import LLMRequest +from ...config.config import global_config +from ..chat.message import Message +from ..knowledge.knowledge_lib import qa_manager +from ..utils.chat_message_builder import build_readable_messages + +logger = get_module_logger("knowledge_fetcher") + + +class KnowledgeFetcher: + """知识调取器""" + + def __init__(self, private_name: str): + self.llm = LLMRequest( + model=global_config.llm_normal, + temperature=global_config.llm_normal["temp"], + max_tokens=1000, + request_type="knowledge_fetch", + ) + self.private_name = private_name + + def _lpmm_get_knowledge(self, query: str) -> str: + """获取相关知识 + + Args: + query: 查询内容 + + Returns: + str: 构造好的,带相关度的知识 + """ + + logger.debug(f"[私聊][{self.private_name}]正在从LPMM知识库中获取知识") + try: + knowledge_info = qa_manager.get_knowledge(query) + logger.debug(f"[私聊][{self.private_name}]LPMM知识库查询结果: {knowledge_info:150}") + return knowledge_info + except Exception as e: + logger.error(f"[私聊][{self.private_name}]LPMM知识库搜索工具执行失败: {str(e)}") + return "未找到匹配的知识" + + async def fetch(self, query: str, chat_history: List[Message]) -> Tuple[str, str]: + """获取相关知识 + + Args: + query: 查询内容 + chat_history: 聊天历史 + + Returns: + Tuple[str, str]: (获取的知识, 知识来源) + """ + # 构建查询上下文 + chat_history_text = await build_readable_messages( + chat_history, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + + # 从记忆中获取相关知识 + related_memory = await HippocampusManager.get_instance().get_memory_from_text( + text=f"{query}\n{chat_history_text}", + max_memory_num=3, + max_memory_length=2, + max_depth=3, + fast_retrieval=False, + ) + knowledge_text = "" + sources_text = "无记忆匹配" # 默认值 + if related_memory: + sources = [] + for memory in related_memory: + knowledge_text += memory[1] + "\n" + sources.append(f"记忆片段{memory[0]}") + knowledge_text = knowledge_text.strip() + sources_text = ",".join(sources) + + knowledge_text += "\n现在有以下**知识**可供参考:\n " + knowledge_text += self._lpmm_get_knowledge(query) + knowledge_text += "\n请记住这些**知识**,并根据**知识**回答问题。\n" + + return knowledge_text or "未找到相关知识", sources_text or "无记忆匹配" diff --git a/src/chat/brain_chat/PFC/pfc_manager.py b/src/chat/brain_chat/PFC/pfc_manager.py new file mode 100644 index 00000000..7837606c --- /dev/null +++ b/src/chat/brain_chat/PFC/pfc_manager.py @@ -0,0 +1,115 @@ +import time +from typing import Dict, Optional +from src.common.logger import get_module_logger +from .conversation import Conversation +import traceback + +logger = get_module_logger("pfc_manager") + + +class PFCManager: + """PFC对话管理器,负责管理所有对话实例""" + + # 单例模式 + _instance = None + + # 会话实例管理 + _instances: Dict[str, Conversation] = {} + _initializing: Dict[str, bool] = {} + + @classmethod + def get_instance(cls) -> "PFCManager": + """获取管理器单例 + + Returns: + PFCManager: 管理器实例 + """ + if cls._instance is None: + cls._instance = PFCManager() + return cls._instance + + async def get_or_create_conversation(self, stream_id: str, private_name: str) -> Optional[Conversation]: + """获取或创建对话实例 + + Args: + stream_id: 聊天流ID + private_name: 私聊名称 + + Returns: + Optional[Conversation]: 对话实例,创建失败则返回None + """ + # 检查是否已经有实例 + if stream_id in self._initializing and self._initializing[stream_id]: + logger.debug(f"[私聊][{private_name}]会话实例正在初始化中: {stream_id}") + return None + + if stream_id in self._instances and self._instances[stream_id].should_continue: + logger.debug(f"[私聊][{private_name}]使用现有会话实例: {stream_id}") + return self._instances[stream_id] + if stream_id in self._instances: + instance = self._instances[stream_id] + if ( + hasattr(instance, "ignore_until_timestamp") + and instance.ignore_until_timestamp + and time.time() < instance.ignore_until_timestamp + ): + logger.debug(f"[私聊][{private_name}]会话实例当前处于忽略状态: {stream_id}") + # 返回 None 阻止交互。或者可以返回实例但标记它被忽略了喵? + # 还是返回 None 吧喵。 + return None + + # 检查 should_continue 状态 + if instance.should_continue: + logger.debug(f"[私聊][{private_name}]使用现有会话实例: {stream_id}") + return instance + # else: 实例存在但不应继续 + try: + # 创建新实例 + logger.info(f"[私聊][{private_name}]创建新的对话实例: {stream_id}") + self._initializing[stream_id] = True + # 创建实例 + conversation_instance = Conversation(stream_id, private_name) + self._instances[stream_id] = conversation_instance + + # 启动实例初始化 + await self._initialize_conversation(conversation_instance) + except Exception as e: + logger.error(f"[私聊][{private_name}]创建会话实例失败: {stream_id}, 错误: {e}") + return None + + return conversation_instance + + async def _initialize_conversation(self, conversation: Conversation): + """初始化会话实例 + + Args: + conversation: 要初始化的会话实例 + """ + stream_id = conversation.stream_id + private_name = conversation.private_name + + try: + logger.info(f"[私聊][{private_name}]开始初始化会话实例: {stream_id}") + # 启动初始化流程 + await conversation._initialize() + + # 标记初始化完成 + self._initializing[stream_id] = False + + logger.info(f"[私聊][{private_name}]会话实例 {stream_id} 初始化完成") + + except Exception as e: + logger.error(f"[私聊][{private_name}]管理器初始化会话实例失败: {stream_id}, 错误: {e}") + logger.error(f"[私聊][{private_name}]{traceback.format_exc()}") + # 清理失败的初始化 + + async def get_conversation(self, stream_id: str) -> Optional[Conversation]: + """获取已存在的会话实例 + + Args: + stream_id: 聊天流ID + + Returns: + Optional[Conversation]: 会话实例,不存在则返回None + """ + return self._instances.get(stream_id) diff --git a/src/chat/brain_chat/PFC/pfc_types.py b/src/chat/brain_chat/PFC/pfc_types.py new file mode 100644 index 00000000..0ea5eda6 --- /dev/null +++ b/src/chat/brain_chat/PFC/pfc_types.py @@ -0,0 +1,23 @@ +from enum import Enum +from typing import Literal + + +class ConversationState(Enum): + """对话状态""" + + INIT = "初始化" + RETHINKING = "重新思考" + ANALYZING = "分析历史" + PLANNING = "规划目标" + GENERATING = "生成回复" + CHECKING = "检查回复" + SENDING = "发送消息" + FETCHING = "获取知识" + WAITING = "等待" + LISTENING = "倾听" + ENDED = "结束" + JUDGING = "判断" + IGNORED = "屏蔽" + + +ActionType = Literal["direct_reply", "fetch_knowledge", "wait"] diff --git a/src/chat/brain_chat/PFC/pfc_utils.py b/src/chat/brain_chat/PFC/pfc_utils.py new file mode 100644 index 00000000..2f7bd5e0 --- /dev/null +++ b/src/chat/brain_chat/PFC/pfc_utils.py @@ -0,0 +1,127 @@ +import json +import re +from typing import Dict, Any, Optional, Tuple, List, Union +from src.common.logger import get_module_logger + +logger = get_module_logger("pfc_utils") + + +def get_items_from_json( + content: str, + private_name: str, + *items: str, + default_values: Optional[Dict[str, Any]] = None, + required_types: Optional[Dict[str, type]] = None, + allow_array: bool = True, +) -> Tuple[bool, Union[Dict[str, Any], List[Dict[str, Any]]]]: + """从文本中提取JSON内容并获取指定字段 + + Args: + content: 包含JSON的文本 + private_name: 私聊名称 + *items: 要提取的字段名 + default_values: 字段的默认值,格式为 {字段名: 默认值} + required_types: 字段的必需类型,格式为 {字段名: 类型} + allow_array: 是否允许解析JSON数组 + + Returns: + Tuple[bool, Union[Dict[str, Any], List[Dict[str, Any]]]]: (是否成功, 提取的字段字典或字典列表) + """ + content = content.strip() + result = {} + + # 设置默认值 + if default_values: + result.update(default_values) + + # 首先尝试解析为JSON数组 + if allow_array: + try: + # 尝试找到文本中的JSON数组 + array_pattern = r"\[[\s\S]*\]" + array_match = re.search(array_pattern, content) + if array_match: + array_content = array_match.group() + json_array = json.loads(array_content) + + # 确认是数组类型 + if isinstance(json_array, list): + # 验证数组中的每个项目是否包含所有必需字段 + valid_items = [] + for item in json_array: + if not isinstance(item, dict): + continue + + # 检查是否有所有必需字段 + if all(field in item for field in items): + # 验证字段类型 + if required_types: + type_valid = True + for field, expected_type in required_types.items(): + if field in item and not isinstance(item[field], expected_type): + type_valid = False + break + + if not type_valid: + continue + + # 验证字符串字段不为空 + string_valid = True + for field in items: + if isinstance(item[field], str) and not item[field].strip(): + string_valid = False + break + + if not string_valid: + continue + + valid_items.append(item) + + if valid_items: + return True, valid_items + except json.JSONDecodeError: + logger.debug(f"[私聊][{private_name}]JSON数组解析失败,尝试解析单个JSON对象") + except Exception as e: + logger.debug(f"[私聊][{private_name}]尝试解析JSON数组时出错: {str(e)}") + + # 尝试解析JSON对象 + try: + json_data = json.loads(content) + except json.JSONDecodeError: + # 如果直接解析失败,尝试查找和提取JSON部分 + json_pattern = r"\{[^{}]*\}" + json_match = re.search(json_pattern, content) + if json_match: + try: + json_data = json.loads(json_match.group()) + except json.JSONDecodeError: + logger.error(f"[私聊][{private_name}]提取的JSON内容解析失败") + return False, result + else: + logger.error(f"[私聊][{private_name}]无法在返回内容中找到有效的JSON") + return False, result + + # 提取字段 + for item in items: + if item in json_data: + result[item] = json_data[item] + + # 验证必需字段 + if not all(item in result for item in items): + logger.error(f"[私聊][{private_name}]JSON缺少必要字段,实际内容: {json_data}") + return False, result + + # 验证字段类型 + if required_types: + for field, expected_type in required_types.items(): + if field in result and not isinstance(result[field], expected_type): + logger.error(f"[私聊][{private_name}]{field} 必须是 {expected_type.__name__} 类型") + return False, result + + # 验证字符串字段不为空 + for field in items: + if isinstance(result[field], str) and not result[field].strip(): + logger.error(f"[私聊][{private_name}]{field} 不能为空") + return False, result + + return True, result diff --git a/src/chat/brain_chat/PFC/reply_checker.py b/src/chat/brain_chat/PFC/reply_checker.py new file mode 100644 index 00000000..35e9af50 --- /dev/null +++ b/src/chat/brain_chat/PFC/reply_checker.py @@ -0,0 +1,183 @@ +import json +from typing import Tuple, List, Dict, Any +from src.common.logger import get_module_logger +from ..models.utils_model import LLMRequest +from ...config.config import global_config +from .chat_observer import ChatObserver +from maim_message import UserInfo + +logger = get_module_logger("reply_checker") + + +class ReplyChecker: + """回复检查器""" + + def __init__(self, stream_id: str, private_name: str): + self.llm = LLMRequest( + model=global_config.llm_PFC_reply_checker, temperature=0.50, max_tokens=1000, request_type="reply_check" + ) + self.name = global_config.BOT_NICKNAME + self.private_name = private_name + self.chat_observer = ChatObserver.get_instance(stream_id, private_name) + self.max_retries = 3 # 最大重试次数 + + async def check( + self, reply: str, goal: str, chat_history: List[Dict[str, Any]], chat_history_text: str, retry_count: int = 0 + ) -> Tuple[bool, str, bool]: + """检查生成的回复是否合适 + + Args: + reply: 生成的回复 + goal: 对话目标 + chat_history: 对话历史记录 + chat_history_text: 对话历史记录文本 + retry_count: 当前重试次数 + + Returns: + Tuple[bool, str, bool]: (是否合适, 原因, 是否需要重新规划) + """ + # 不再从 observer 获取,直接使用传入的 chat_history + # messages = self.chat_observer.get_cached_messages(limit=20) + try: + # 筛选出最近由 Bot 自己发送的消息 + bot_messages = [] + for msg in reversed(chat_history): + user_info = UserInfo.from_dict(msg.get("user_info", {})) + if str(user_info.user_id) == str(global_config.BOT_QQ): # 确保比较的是字符串 + bot_messages.append(msg.get("processed_plain_text", "")) + if len(bot_messages) >= 2: # 只和最近的两条比较 + break + # 进行比较 + if bot_messages: + # 可以用简单比较,或者更复杂的相似度库 (如 difflib) + # 简单比较:是否完全相同 + if reply == bot_messages[0]: # 和最近一条完全一样 + logger.warning( + f"[私聊][{self.private_name}]ReplyChecker 检测到回复与上一条 Bot 消息完全相同: '{reply}'" + ) + return ( + False, + "被逻辑检查拒绝:回复内容与你上一条发言完全相同,可以选择深入话题或寻找其它话题或等待", + True, + ) # 不合适,需要返回至决策层 + # 2. 相似度检查 (如果精确匹配未通过) + import difflib # 导入 difflib 库 + + # 计算编辑距离相似度,ratio() 返回 0 到 1 之间的浮点数 + similarity_ratio = difflib.SequenceMatcher(None, reply, bot_messages[0]).ratio() + logger.debug(f"[私聊][{self.private_name}]ReplyChecker - 相似度: {similarity_ratio:.2f}") + + # 设置一个相似度阈值 + similarity_threshold = 0.9 + if similarity_ratio > similarity_threshold: + logger.warning( + f"[私聊][{self.private_name}]ReplyChecker 检测到回复与上一条 Bot 消息高度相似 (相似度 {similarity_ratio:.2f}): '{reply}'" + ) + return ( + False, + f"被逻辑检查拒绝:回复内容与你上一条发言高度相似 (相似度 {similarity_ratio:.2f}),可以选择深入话题或寻找其它话题或等待。", + True, + ) + + except Exception as e: + import traceback + + logger.error(f"[私聊][{self.private_name}]检查回复时出错: 类型={type(e)}, 值={e}") + logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") # 打印详细的回溯信息 + + prompt = f"""你是一个聊天逻辑检查器,请检查以下回复或消息是否合适: + +当前对话目标:{goal} +最新的对话记录: +{chat_history_text} + +待检查的消息: +{reply} + +请结合聊天记录检查以下几点: +1. 这条消息是否依然符合当前对话目标和实现方式 +2. 这条消息是否与最新的对话记录保持一致性 +3. 是否存在重复发言,或重复表达同质内容(尤其是只是换一种方式表达了相同的含义) +4. 这条消息是否包含违规内容(例如血腥暴力,政治敏感等) +5. 这条消息是否以发送者的角度发言(不要让发送者自己回复自己的消息) +6. 这条消息是否通俗易懂 +7. 这条消息是否有些多余,例如在对方没有回复的情况下,依然连续多次“消息轰炸”(尤其是已经连续发送3条信息的情况,这很可能不合理,需要着重判断) +8. 这条消息是否使用了完全没必要的修辞 +9. 这条消息是否逻辑通顺 +10. 这条消息是否太过冗长了(通常私聊的每条消息长度在20字以内,除非特殊情况) +11. 在连续多次发送消息的情况下,这条消息是否衔接自然,会不会显得奇怪(例如连续两条消息中部分内容重叠) + +请以JSON格式输出,包含以下字段: +1. suitable: 是否合适 (true/false) +2. reason: 原因说明 +3. need_replan: 是否需要重新决策 (true/false),当你认为此时已经不适合发消息,需要规划其它行动时,设为true + +输出格式示例: +{{ + "suitable": true, + "reason": "回复符合要求,虽然有可能略微偏离目标,但是整体内容流畅得体", + "need_replan": false +}} + +注意:请严格按照JSON格式输出,不要包含任何其他内容。""" + + try: + content, _ = await self.llm.generate_response_async(prompt) + logger.debug(f"[私聊][{self.private_name}]检查回复的原始返回: {content}") + + # 清理内容,尝试提取JSON部分 + content = content.strip() + try: + # 尝试直接解析 + result = json.loads(content) + except json.JSONDecodeError: + # 如果直接解析失败,尝试查找和提取JSON部分 + import re + + json_pattern = r"\{[^{}]*\}" + json_match = re.search(json_pattern, content) + if json_match: + try: + result = json.loads(json_match.group()) + except json.JSONDecodeError: + # 如果JSON解析失败,尝试从文本中提取结果 + is_suitable = "不合适" not in content.lower() and "违规" not in content.lower() + reason = content[:100] if content else "无法解析响应" + need_replan = "重新规划" in content.lower() or "目标不适合" in content.lower() + return is_suitable, reason, need_replan + else: + # 如果找不到JSON,从文本中判断 + is_suitable = "不合适" not in content.lower() and "违规" not in content.lower() + reason = content[:100] if content else "无法解析响应" + need_replan = "重新规划" in content.lower() or "目标不适合" in content.lower() + return is_suitable, reason, need_replan + + # 验证JSON字段 + suitable = result.get("suitable", None) + reason = result.get("reason", "未提供原因") + need_replan = result.get("need_replan", False) + + # 如果suitable字段是字符串,转换为布尔值 + if isinstance(suitable, str): + suitable = suitable.lower() == "true" + + # 如果suitable字段不存在或不是布尔值,从reason中判断 + if suitable is None: + suitable = "不合适" not in reason.lower() and "违规" not in reason.lower() + + # 如果不合适且未达到最大重试次数,返回需要重试 + if not suitable and retry_count < self.max_retries: + return False, reason, False + + # 如果不合适且已达到最大重试次数,返回需要重新规划 + if not suitable and retry_count >= self.max_retries: + return False, f"多次重试后仍不合适: {reason}", True + + return suitable, reason, need_replan + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]检查回复时出错: {e}") + # 如果出错且已达到最大重试次数,建议重新规划 + if retry_count >= self.max_retries: + return False, "多次检查失败,建议重新规划", True + return False, f"检查过程出错,建议重试: {str(e)}", False diff --git a/src/chat/brain_chat/PFC/reply_generator.py b/src/chat/brain_chat/PFC/reply_generator.py new file mode 100644 index 00000000..890f807c --- /dev/null +++ b/src/chat/brain_chat/PFC/reply_generator.py @@ -0,0 +1,228 @@ +from typing import Tuple, List, Dict, Any +from src.common.logger import get_module_logger +from ..models.utils_model import LLMRequest +from ...config.config import global_config +from .chat_observer import ChatObserver +from .reply_checker import ReplyChecker +from src.individuality.individuality import Individuality +from .observation_info import ObservationInfo +from .conversation_info import ConversationInfo +from src.plugins.utils.chat_message_builder import build_readable_messages + +logger = get_module_logger("reply_generator") + +# --- 定义 Prompt 模板 --- + +# Prompt for direct_reply (首次回复) +PROMPT_DIRECT_REPLY = """{persona_text}。现在你在参与一场QQ私聊,请根据以下信息生成一条回复: + +当前对话目标:{goals_str} + +{knowledge_info_str} + +最近的聊天记录: +{chat_history_text} + + +请根据上述信息,结合聊天记录,回复对方。该回复应该: +1. 符合对话目标,以"你"的角度发言(不要自己与自己对话!) +2. 符合你的性格特征和身份细节 +3. 通俗易懂,自然流畅,像正常聊天一样,简短(通常20字以内,除非特殊情况) +4. 可以适当利用相关知识,但不要生硬引用 +5. 自然、得体,结合聊天记录逻辑合理,且没有重复表达同质内容 + +请注意把握聊天内容,不要回复的太有条理,可以有个性。请分清"你"和对方说的话,不要把"你"说的话当做对方说的话,这是你自己说的话。 +可以回复得自然随意自然一些,就像真人一样,注意把握聊天内容,整体风格可以平和、简短,不要刻意突出自身学科背景,不要说你说过的话,可以简短,多简短都可以,但是避免冗长。 +请你注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。 +不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。 + +请直接输出回复内容,不需要任何额外格式。""" + +# Prompt for send_new_message (追问/补充) +PROMPT_SEND_NEW_MESSAGE = """{persona_text}。现在你在参与一场QQ私聊,**刚刚你已经发送了一条或多条消息**,现在请根据以下信息再发一条新消息: + +当前对话目标:{goals_str} + +{knowledge_info_str} + +最近的聊天记录: +{chat_history_text} + + +请根据上述信息,结合聊天记录,继续发一条新消息(例如对之前消息的补充,深入话题,或追问等等)。该消息应该: +1. 符合对话目标,以"你"的角度发言(不要自己与自己对话!) +2. 符合你的性格特征和身份细节 +3. 通俗易懂,自然流畅,像正常聊天一样,简短(通常20字以内,除非特殊情况) +4. 可以适当利用相关知识,但不要生硬引用 +5. 跟之前你发的消息自然的衔接,逻辑合理,且没有重复表达同质内容或部分重叠内容 + +请注意把握聊天内容,不用太有条理,可以有个性。请分清"你"和对方说的话,不要把"你"说的话当做对方说的话,这是你自己说的话。 +这条消息可以自然随意自然一些,就像真人一样,注意把握聊天内容,整体风格可以平和、简短,不要刻意突出自身学科背景,不要说你说过的话,可以简短,多简短都可以,但是避免冗长。 +请你注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出消息内容。 +不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。 + +请直接输出回复内容,不需要任何额外格式。""" + +# Prompt for say_goodbye (告别语生成) +PROMPT_FAREWELL = """{persona_text}。你在参与一场 QQ 私聊,现在对话似乎已经结束,你决定再发一条最后的消息来圆满结束。 + +最近的聊天记录: +{chat_history_text} + +请根据上述信息,结合聊天记录,构思一条**简短、自然、符合你人设**的最后的消息。 +这条消息应该: +1. 从你自己的角度发言。 +2. 符合你的性格特征和身份细节。 +3. 通俗易懂,自然流畅,通常很简短。 +4. 自然地为这场对话画上句号,避免开启新话题或显得冗长、刻意。 + +请像真人一样随意自然,**简洁是关键**。 +不要输出多余内容(包括前后缀、冒号、引号、括号、表情包、at或@等)。 + +请直接输出最终的告别消息内容,不需要任何额外格式。""" + + +class ReplyGenerator: + """回复生成器""" + + def __init__(self, stream_id: str, private_name: str): + self.llm = LLMRequest( + model=global_config.llm_PFC_chat, + temperature=global_config.llm_PFC_chat["temp"], + max_tokens=300, + request_type="reply_generation", + ) + self.personality_info = Individuality.get_instance().get_prompt(x_person=2, level=3) + self.name = global_config.BOT_NICKNAME + self.private_name = private_name + self.chat_observer = ChatObserver.get_instance(stream_id, private_name) + self.reply_checker = ReplyChecker(stream_id, private_name) + + # 修改 generate 方法签名,增加 action_type 参数 + async def generate( + self, observation_info: ObservationInfo, conversation_info: ConversationInfo, action_type: str + ) -> str: + """生成回复 + + Args: + observation_info: 观察信息 + conversation_info: 对话信息 + action_type: 当前执行的动作类型 ('direct_reply' 或 'send_new_message') + + Returns: + str: 生成的回复 + """ + # 构建提示词 + logger.debug( + f"[私聊][{self.private_name}]开始生成回复 (动作类型: {action_type}):当前目标: {conversation_info.goal_list}" + ) + + # --- 构建通用 Prompt 参数 --- + # (这部分逻辑基本不变) + + # 构建对话目标 (goals_str) + goals_str = "" + if conversation_info.goal_list: + for goal_reason in conversation_info.goal_list: + if isinstance(goal_reason, dict): + goal = goal_reason.get("goal", "目标内容缺失") + reasoning = goal_reason.get("reasoning", "没有明确原因") + else: + goal = str(goal_reason) + reasoning = "没有明确原因" + + goal = str(goal) if goal is not None else "目标内容缺失" + reasoning = str(reasoning) if reasoning is not None else "没有明确原因" + goals_str += f"- 目标:{goal}\n 原因:{reasoning}\n" + else: + goals_str = "- 目前没有明确对话目标\n" # 简化无目标情况 + + # --- 新增:构建知识信息字符串 --- + knowledge_info_str = "【供参考的相关知识和记忆】\n" # 稍微改下标题,表明是供参考 + try: + # 检查 conversation_info 是否有 knowledge_list 并且不为空 + if hasattr(conversation_info, "knowledge_list") and conversation_info.knowledge_list: + # 最多只显示最近的 5 条知识 + recent_knowledge = conversation_info.knowledge_list[-5:] + for i, knowledge_item in enumerate(recent_knowledge): + if isinstance(knowledge_item, dict): + query = knowledge_item.get("query", "未知查询") + knowledge = knowledge_item.get("knowledge", "无知识内容") + source = knowledge_item.get("source", "未知来源") + # 只取知识内容的前 2000 个字 + knowledge_snippet = knowledge[:2000] + "..." if len(knowledge) > 2000 else knowledge + knowledge_info_str += ( + f"{i + 1}. 关于 '{query}' (来源: {source}): {knowledge_snippet}\n" # 格式微调,更简洁 + ) + else: + knowledge_info_str += f"{i + 1}. 发现一条格式不正确的知识记录。\n" + + if not recent_knowledge: + knowledge_info_str += "- 暂无。\n" # 更简洁的提示 + + else: + knowledge_info_str += "- 暂无。\n" + except AttributeError: + logger.warning(f"[私聊][{self.private_name}]ConversationInfo 对象可能缺少 knowledge_list 属性。") + knowledge_info_str += "- 获取知识列表时出错。\n" + except Exception as e: + logger.error(f"[私聊][{self.private_name}]构建知识信息字符串时出错: {e}") + knowledge_info_str += "- 处理知识列表时出错。\n" + + # 获取聊天历史记录 (chat_history_text) + chat_history_text = observation_info.chat_history_str + if observation_info.new_messages_count > 0 and observation_info.unprocessed_messages: + new_messages_list = observation_info.unprocessed_messages + new_messages_str = await build_readable_messages( + new_messages_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + chat_history_text += f"\n--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n{new_messages_str}" + elif not chat_history_text: + chat_history_text = "还没有聊天记录。" + + # 构建 Persona 文本 (persona_text) + persona_text = f"你的名字是{self.name},{self.personality_info}。" + + # --- 选择 Prompt --- + if action_type == "send_new_message": + prompt_template = PROMPT_SEND_NEW_MESSAGE + logger.info(f"[私聊][{self.private_name}]使用 PROMPT_SEND_NEW_MESSAGE (追问生成)") + elif action_type == "say_goodbye": # 处理告别动作 + prompt_template = PROMPT_FAREWELL + logger.info(f"[私聊][{self.private_name}]使用 PROMPT_FAREWELL (告别语生成)") + else: # 默认使用 direct_reply 的 prompt (包括 'direct_reply' 或其他未明确处理的类型) + prompt_template = PROMPT_DIRECT_REPLY + logger.info(f"[私聊][{self.private_name}]使用 PROMPT_DIRECT_REPLY (首次/非连续回复生成)") + + # --- 格式化最终的 Prompt --- + prompt = prompt_template.format( + persona_text=persona_text, + goals_str=goals_str, + chat_history_text=chat_history_text, + knowledge_info_str=knowledge_info_str, + ) + + # --- 调用 LLM 生成 --- + logger.debug(f"[私聊][{self.private_name}]发送到LLM的生成提示词:\n------\n{prompt}\n------") + try: + content, _ = await self.llm.generate_response_async(prompt) + logger.debug(f"[私聊][{self.private_name}]生成的回复: {content}") + # 移除旧的检查新消息逻辑,这应该由 conversation 控制流处理 + return content + + except Exception as e: + logger.error(f"[私聊][{self.private_name}]生成回复时出错: {e}") + return "抱歉,我现在有点混乱,让我重新思考一下..." + + # check_reply 方法保持不变 + async def check_reply( + self, reply: str, goal: str, chat_history: List[Dict[str, Any]], chat_history_str: str, retry_count: int = 0 + ) -> Tuple[bool, str, bool]: + """检查回复是否合适 + (此方法逻辑保持不变) + """ + return await self.reply_checker.check(reply, goal, chat_history, chat_history_str, retry_count) diff --git a/src/chat/brain_chat/PFC/waiter.py b/src/chat/brain_chat/PFC/waiter.py new file mode 100644 index 00000000..0f5881fc --- /dev/null +++ b/src/chat/brain_chat/PFC/waiter.py @@ -0,0 +1,79 @@ +from src.common.logger import get_module_logger +from .chat_observer import ChatObserver +from .conversation_info import ConversationInfo + +# from src.individuality.individuality import Individuality # 不再需要 +from ...config.config import global_config +import time +import asyncio + +logger = get_module_logger("waiter") + +# --- 在这里设定你想要的超时时间(秒) --- +# 例如: 120 秒 = 2 分钟 +DESIRED_TIMEOUT_SECONDS = 300 + + +class Waiter: + """等待处理类""" + + def __init__(self, stream_id: str, private_name: str): + self.chat_observer = ChatObserver.get_instance(stream_id, private_name) + self.name = global_config.BOT_NICKNAME + self.private_name = private_name + # self.wait_accumulated_time = 0 # 不再需要累加计时 + + async def wait(self, conversation_info: ConversationInfo) -> bool: + """等待用户新消息或超时""" + wait_start_time = time.time() + logger.info(f"[私聊][{self.private_name}]进入常规等待状态 (超时: {DESIRED_TIMEOUT_SECONDS} 秒)...") + + while True: + # 检查是否有新消息 + if self.chat_observer.new_message_after(wait_start_time): + logger.info(f"[私聊][{self.private_name}]等待结束,收到新消息") + return False # 返回 False 表示不是超时 + + # 检查是否超时 + elapsed_time = time.time() - wait_start_time + if elapsed_time > DESIRED_TIMEOUT_SECONDS: + logger.info(f"[私聊][{self.private_name}]等待超过 {DESIRED_TIMEOUT_SECONDS} 秒...添加思考目标。") + wait_goal = { + "goal": f"你等待了{elapsed_time / 60:.1f}分钟,注意可能在对方看来聊天已经结束,思考接下来要做什么", + "reasoning": "对方很久没有回复你的消息了", + } + conversation_info.goal_list.append(wait_goal) + logger.info(f"[私聊][{self.private_name}]添加目标: {wait_goal}") + return True # 返回 True 表示超时 + + await asyncio.sleep(5) # 每 5 秒检查一次 + logger.debug( + f"[私聊][{self.private_name}]等待中..." + ) # 可以考虑把这个频繁日志注释掉,只在超时或收到消息时输出 + + async def wait_listening(self, conversation_info: ConversationInfo) -> bool: + """倾听用户发言或超时""" + wait_start_time = time.time() + logger.info(f"[私聊][{self.private_name}]进入倾听等待状态 (超时: {DESIRED_TIMEOUT_SECONDS} 秒)...") + + while True: + # 检查是否有新消息 + if self.chat_observer.new_message_after(wait_start_time): + logger.info(f"[私聊][{self.private_name}]倾听等待结束,收到新消息") + return False # 返回 False 表示不是超时 + + # 检查是否超时 + elapsed_time = time.time() - wait_start_time + if elapsed_time > DESIRED_TIMEOUT_SECONDS: + logger.info(f"[私聊][{self.private_name}]倾听等待超过 {DESIRED_TIMEOUT_SECONDS} 秒...添加思考目标。") + wait_goal = { + # 保持 goal 文本一致 + "goal": f"你等待了{elapsed_time / 60:.1f}分钟,对方似乎话说一半突然消失了,可能忙去了?也可能忘记了回复?要问问吗?还是结束对话?或继续等待?思考接下来要做什么", + "reasoning": "对方话说一半消失了,很久没有回复", + } + conversation_info.goal_list.append(wait_goal) + logger.info(f"[私聊][{self.private_name}]添加目标: {wait_goal}") + return True # 返回 True 表示超时 + + await asyncio.sleep(5) # 每 5 秒检查一次 + logger.debug(f"[私聊][{self.private_name}]倾听等待中...") # 同上,可以考虑注释掉 diff --git a/src/chat/brain_chat/brain_chat.py b/src/chat/brain_chat/brain_chat.py index 3624646f..b555bf0f 100644 --- a/src/chat/brain_chat/brain_chat.py +++ b/src/chat/brain_chat/brain_chat.py @@ -16,7 +16,8 @@ from src.chat.brain_chat.brain_planner import BrainPlanner from src.chat.planner_actions.action_modifier import ActionModifier from src.chat.planner_actions.action_manager import ActionManager from src.chat.heart_flow.hfc_utils import CycleDetail -from src.express.expression_learner import expression_learner_manager +from src.bw_learner.expression_learner import expression_learner_manager +from src.bw_learner.message_recorder import extract_and_distribute_messages from src.person_info.person_info import Person from src.plugin_system.base.component_types import EventType, ActionInfo from src.plugin_system.core import events_manager @@ -96,6 +97,9 @@ class BrainChatting: self.more_plan = False + # 最近一次是否成功进行了 reply,用于选择 BrainPlanner 的 Prompt + self._last_successful_reply: bool = False + async def start(self): """检查是否需要启动主循环,如果未激活则启动。""" @@ -157,6 +161,7 @@ class BrainChatting: ) async def _loopbody(self): # sourcery skip: hoist-if-from-if + # 获取最新消息(用于上下文,但不影响是否调用 observe) recent_messages_list = message_api.get_messages_by_time_in_chat( chat_id=self.stream_id, start_time=self.last_read_time, @@ -164,17 +169,26 @@ class BrainChatting: limit=20, limit_mode="latest", filter_mai=True, - filter_command=True, + filter_command=False, + filter_intercept_message_level=1, ) + # 如果有新消息,更新 last_read_time if len(recent_messages_list) >= 1: self.last_read_time = time.time() - await self._observe(recent_messages_list=recent_messages_list) - else: - # Normal模式:消息数量不足,等待 - await asyncio.sleep(0.2) - return True + # 总是执行一次思考迭代(不管有没有新消息) + # wait 动作会在其内部等待,不需要在这里处理 + should_continue = await self._observe(recent_messages_list=recent_messages_list) + + if not should_continue: + # 选择了 complete_talk,返回 False 表示需要等待新消息 + return False + + # 继续下一次迭代(除非选择了 complete_talk) + # 短暂等待后再继续,避免过于频繁的循环 + await asyncio.sleep(0.1) + return True async def _send_and_store_reply( @@ -235,8 +249,32 @@ class BrainChatting: recent_messages_list = [] _reply_text = "" # 初始化reply_text变量,避免UnboundLocalError + # ------------------------------------------------------------------------- + # ReflectTracker Check + # 在每次回复前检查一次上下文,看是否有反思问题得到了解答 + # ------------------------------------------------------------------------- + from src.bw_learner.reflect_tracker import reflect_tracker_manager + + tracker = reflect_tracker_manager.get_tracker(self.stream_id) + if tracker: + resolved = await tracker.trigger_tracker() + if resolved: + reflect_tracker_manager.remove_tracker(self.stream_id) + logger.info(f"{self.log_prefix} ReflectTracker resolved and removed.") + + # ------------------------------------------------------------------------- + # Expression Reflection Check + # 检查是否需要提问表达反思 + # ------------------------------------------------------------------------- + from src.bw_learner.expression_reflector import expression_reflector_manager + + reflector = expression_reflector_manager.get_or_create_reflector(self.stream_id) + asyncio.create_task(reflector.check_and_ask()) + async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()): - asyncio.create_task(self.expression_learner.trigger_learning_for_chat()) + # 通过 MessageRecorder 统一提取消息并分发给 expression_learner 和 jargon_miner + # 在 replyer 执行时触发,统一管理时间窗口,避免重复获取消息 + asyncio.create_task(extract_and_distribute_messages(self.stream_id)) cycle_timers, thinking_id = self.start_cycle() logger.info(f"{self.log_prefix} 开始第{self._cycle_counter}次思考") @@ -249,13 +287,16 @@ class BrainChatting: except Exception as e: logger.error(f"{self.log_prefix} 动作修改失败: {e}") - # 执行planner + # 获取必要信息 is_group_chat, chat_target_info, _ = self.action_planner.get_necessary_info() + # 一次思考迭代:Think - Act - Observe + # 获取聊天上下文 message_list_before_now = get_raw_msg_before_timestamp_with_chat( chat_id=self.stream_id, timestamp=time.time(), limit=int(global_config.chat.max_context_size * 0.6), + filter_intercept_message_level=1, ) chat_content_block, message_id_list = build_readable_messages_with_id( messages=message_list_before_now, @@ -266,12 +307,11 @@ class BrainChatting: ) prompt_info = await self.action_planner.build_planner_prompt( - is_group_chat=is_group_chat, chat_target_info=chat_target_info, current_available_actions=available_actions, chat_content_block=chat_content_block, message_id_list=message_id_list, - interest=global_config.personality.interest, + prompt_key="brain_planner_prompt_react", ) continue_flag, modified_message = await events_manager.handle_mai_events( EventType.ON_PLAN, None, prompt_info[0], None, self.chat_stream.stream_id @@ -287,7 +327,10 @@ class BrainChatting: available_actions=available_actions, ) - # 3. 并行执行所有动作 + # 检查是否有 complete_talk 动作(会停止后续迭代) + has_complete_talk = any(action.action_type == "complete_talk" for action in action_to_use_info) + + # 并行执行所有动作 action_tasks = [ asyncio.create_task( self._execute_action(action, action_to_use_info, thinking_id, available_actions, cycle_timers) @@ -319,7 +362,14 @@ class BrainChatting: else: logger.warning(f"{self.log_prefix} 回复动作执行失败") - # 构建最终的循环信息 + # 更新观察时间标记 + self.action_planner.last_obs_time_mark = time.time() + + # 如果选择了 complete_talk,标记为完成,不再继续迭代 + if has_complete_talk: + logger.info(f"{self.log_prefix} 检测到 complete_talk 动作,本次思考完成") + + # 构建循环信息 if reply_loop_info: # 如果有回复信息,使用回复的loop_info作为基础 loop_info = reply_loop_info @@ -345,10 +395,16 @@ class BrainChatting: } _reply_text = action_reply_text + # 如果选择了 complete_talk,返回 False 以停止 _loopbody 的循环 + # 否则返回 True,让 _loopbody 继续下一次迭代 + should_continue = not has_complete_talk + self.end_cycle(loop_info, cycle_timers) self.print_cycle_info(cycle_timers) - return True + # 如果选择了 complete_talk,返回 False 停止循环 + # 否则返回 True,继续下一次思考迭代 + return should_continue async def _main_chat_loop(self): """主循环,持续进行计划并可能回复消息,直到被外部取消。""" @@ -356,9 +412,13 @@ class BrainChatting: while self.running: # 主循环 success = await self._loopbody() - await asyncio.sleep(0.1) if not success: - break + # 选择了 complete,等待新消息 + logger.info(f"{self.log_prefix} 选择了 complete,等待新消息...") + await self._wait_for_new_message() + # 有新消息后继续循环 + continue + await asyncio.sleep(0.1) except asyncio.CancelledError: # 设置了关闭标志位后被取消是正常流程 logger.info(f"{self.log_prefix} 麦麦已关闭聊天") @@ -369,6 +429,33 @@ class BrainChatting: self._loop_task = asyncio.create_task(self._main_chat_loop()) logger.error(f"{self.log_prefix} 结束了当前聊天循环") + async def _wait_for_new_message(self): + """等待新消息到达""" + last_check_time = self.last_read_time + check_interval = 1.0 # 每秒检查一次 + + while self.running: + # 检查是否有新消息 + recent_messages_list = message_api.get_messages_by_time_in_chat( + chat_id=self.stream_id, + start_time=last_check_time, + end_time=time.time(), + limit=20, + limit_mode="latest", + filter_mai=True, + filter_command=False, + filter_intercept_message_level=1, + ) + + # 如果有新消息,更新 last_read_time 并返回 + if len(recent_messages_list) >= 1: + self.last_read_time = time.time() + logger.info(f"{self.log_prefix} 检测到新消息,恢复循环") + return + + # 等待一段时间后再次检查 + await asyncio.sleep(check_interval) + async def _handle_action( self, action: str, @@ -482,12 +569,12 @@ class BrainChatting: """执行单个动作的通用函数""" try: with Timer(f"动作{action_planner_info.action_type}", cycle_timers): - if action_planner_info.action_type == "no_reply": - # 直接处理no_reply逻辑,不再通过动作系统 - reason = action_planner_info.reasoning or "选择不回复" - # logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}") + if action_planner_info.action_type == "complete_talk": + # 直接处理complete_talk逻辑,不再通过动作系统 + reason = action_planner_info.reasoning or "选择完成对话" + logger.info(f"{self.log_prefix} 选择完成对话,原因: {reason}") - # 存储no_reply信息到数据库 + # 存储complete_talk信息到数据库 await database_api.store_action_info( chat_stream=self.chat_stream, action_build_into_prompt=False, @@ -495,18 +582,33 @@ class BrainChatting: action_done=True, thinking_id=thinking_id, action_data={"reason": reason}, - action_name="no_reply", + action_name="complete_talk", ) - return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""} + return {"action_type": "complete_talk", "success": True, "reply_text": "", "command": ""} elif action_planner_info.action_type == "reply": try: + # 从 Planner 的 action_data 中提取未知词语列表(仅在 reply 时使用) + unknown_words = None + if isinstance(action_planner_info.action_data, dict): + uw = action_planner_info.action_data.get("unknown_words") + if isinstance(uw, list): + cleaned_uw: List[str] = [] + for item in uw: + if isinstance(item, str): + s = item.strip() + if s: + cleaned_uw.append(s) + if cleaned_uw: + unknown_words = cleaned_uw + success, llm_response = await generator_api.generate_reply( chat_stream=self.chat_stream, reply_message=action_planner_info.action_message, available_actions=available_actions, chosen_actions=chosen_action_plan_infos, reply_reason=action_planner_info.reasoning or "", + unknown_words=unknown_words, enable_tool=global_config.tool.enable_tool, request_type="replyer", from_plugin=False, @@ -519,11 +621,17 @@ class BrainChatting: ) else: logger.info("回复生成失败") - return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None} + return { + "action_type": "reply", + "success": False, + "reply_text": "", + "loop_info": None, + } except asyncio.CancelledError: logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消") return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None} + response_set = llm_response.reply_set selected_expressions = llm_response.selected_expressions loop_info, reply_text, _ = await self._send_and_store_reply( @@ -534,6 +642,8 @@ class BrainChatting: actions=chosen_action_plan_infos, selected_expressions=selected_expressions, ) + # 标记这次循环已经成功进行了回复 + self._last_successful_reply = True return { "action_type": "reply", "success": True, @@ -543,7 +653,88 @@ class BrainChatting: # 其他动作 else: - # 执行普通动作 + # 内建 wait / listening:不通过插件系统,直接在这里处理 + if action_planner_info.action_type in ["wait", "listening"]: + reason = action_planner_info.reasoning or "" + action_data = action_planner_info.action_data or {} + + if action_planner_info.action_type == "wait": + # 获取等待时间(必填) + wait_seconds = action_data.get("wait_seconds") + if wait_seconds is None: + logger.warning(f"{self.log_prefix} wait 动作缺少 wait_seconds 参数,使用默认值 5 秒") + wait_seconds = 5 + else: + try: + wait_seconds = float(wait_seconds) + if wait_seconds < 0: + logger.warning(f"{self.log_prefix} wait_seconds 不能为负数,使用默认值 5 秒") + wait_seconds = 5 + except (ValueError, TypeError): + logger.warning(f"{self.log_prefix} wait_seconds 参数格式错误,使用默认值 5 秒") + wait_seconds = 5 + + logger.info(f"{self.log_prefix} 执行 wait 动作,等待 {wait_seconds} 秒") + + # 记录动作信息 + await database_api.store_action_info( + chat_stream=self.chat_stream, + action_build_into_prompt=False, + action_prompt_display=reason or f"等待 {wait_seconds} 秒", + action_done=True, + thinking_id=thinking_id, + action_data={"reason": reason, "wait_seconds": wait_seconds}, + action_name="wait", + ) + + # 等待指定时间 + await asyncio.sleep(wait_seconds) + + logger.info(f"{self.log_prefix} wait 动作完成,继续下一次思考") + + # 这些动作本身不产生文本回复 + self._last_successful_reply = False + return { + "action_type": "wait", + "success": True, + "reply_text": "", + "command": "", + } + + # listening 已合并到 wait,如果遇到则转换为 wait(向后兼容) + elif action_planner_info.action_type == "listening": + logger.debug(f"{self.log_prefix} 检测到 listening 动作,已合并到 wait,自动转换") + # 使用默认等待时间 + wait_seconds = 3 + + logger.info(f"{self.log_prefix} 执行 listening(转换为 wait)动作,等待 {wait_seconds} 秒") + + # 记录动作信息 + await database_api.store_action_info( + chat_stream=self.chat_stream, + action_build_into_prompt=False, + action_prompt_display=reason or f"倾听并等待 {wait_seconds} 秒", + action_done=True, + thinking_id=thinking_id, + action_data={"reason": reason, "wait_seconds": wait_seconds}, + action_name="listening", + ) + + # 等待指定时间 + await asyncio.sleep(wait_seconds) + + logger.info(f"{self.log_prefix} listening 动作完成,继续下一次思考") + + # 这些动作本身不产生文本回复 + self._last_successful_reply = False + return { + "action_type": "listening", + "success": True, + "reply_text": "", + "command": "", + } + + # 其余动作:走原有插件 Action 体系 with Timer("动作执行", cycle_timers): success, reply_text, command = await self._handle_action( action_planner_info.action_type, @@ -553,6 +744,10 @@ class BrainChatting: thinking_id, action_planner_info.action_message, ) + # 非 reply 类动作执行成功时,清空最近成功回复标记,让下一轮回到 initial Prompt + if success and action_planner_info.action_type != "reply": + self._last_successful_reply = False + return { "action_type": action_planner_info.action_type, "success": success, diff --git a/src/chat/brain_chat/brain_planner.py b/src/chat/brain_chat/brain_planner.py index 55a8771b..14d28575 100644 --- a/src/chat/brain_chat/brain_planner.py +++ b/src/chat/brain_chat/brain_planner.py @@ -35,12 +35,13 @@ install(extra_lines=3) def init_prompt(): + # ReAct 形式的 Planner Prompt Prompt( """ {time_block} {name_block} -你的兴趣是:{interest} {chat_context_description},以下是具体的聊天内容 + **聊天内容** {chat_content_block} @@ -57,11 +58,35 @@ reply "reason":"回复的原因" }} -no_reply +wait 动作描述: -等待,保持沉默,等待对方发言 +暂时不再发言,等待指定时间。适用于以下情况: +- 你已经表达清楚一轮,想给对方留出空间 +- 你感觉对方的话还没说完,或者自己刚刚发了好几条连续消息 +- 你想要等待一定时间来让对方把话说完,或者等待对方反应 +- 你想保持安静,专注"听"而不是马上回复 +请你根据上下文来判断要等待多久,请你灵活判断: +- 如果你们交流间隔时间很短,聊的很频繁,不宜等待太久 +- 如果你们交流间隔时间很长,聊的很少,可以等待较长时间 {{ - "action": "no_reply", + "action": "wait", + "target_message_id":"想要作为这次等待依据的消息id(通常是对方的最新消息)", + "wait_seconds": 等待的秒数(必填,例如:5 表示等待5秒), + "reason":"选择等待的原因" +}} + +complete_talk +动作描述: +当前聊天暂时结束了,对方离开,没有更多话题了 +你可以使用该动作来暂时休息,等待对方有新发言再继续: +- 多次wait之后,对方迟迟不回复消息才用 +- 如果对方只是短暂不回复,应该使用wait而不是complete_talk +- 聊天内容显示当前聊天已经结束或者没有新内容时候,选择complete_talk +选择此动作后,将不再继续循环思考,直到收到对方的新消息 +{{ + "action": "complete_talk", + "target_message_id":"触发完成对话的消息id(通常是对方的最新消息)", + "reason":"选择完成对话的原因" }} {action_options_text} @@ -92,7 +117,7 @@ no_reply ``` """, - "brain_planner_prompt", + "brain_planner_prompt_react", ) Prompt( @@ -123,6 +148,9 @@ class BrainPlanner: self.last_obs_time_mark = 0.0 + # 计划日志记录 + self.plan_log: List[Tuple[str, float, List[ActionPlannerInfo]]] = [] + def find_message_by_id( self, message_id: str, message_id_list: List[Tuple[str, "DatabaseMessages"]] ) -> Optional["DatabaseMessages"]: @@ -152,10 +180,11 @@ class BrainPlanner: action_planner_infos = [] try: - action = action_json.get("action", "no_reply") + action = action_json.get("action", "complete_talk") + logger.debug(f"{self.log_prefix}解析动作JSON: action={action}, json={action_json}") reasoning = action_json.get("reason", "未提供原因") action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]} - # 非no_reply动作需要target_message_id + # 非complete_talk动作需要target_message_id target_message = None if target_message_id := action_json.get("target_message_id"): @@ -171,16 +200,28 @@ class BrainPlanner: # 验证action是否可用 available_action_names = [action_name for action_name, _ in current_available_actions] - internal_action_names = ["no_reply", "reply", "wait_time"] + # 内部保留动作(不依赖插件系统) + # 注意:listening 已合并到 wait 中,如果遇到 listening 则转换为 wait + internal_action_names = ["complete_talk", "reply", "wait_time", "wait", "listening"] + + logger.debug( + f"{self.log_prefix}动作验证: action={action}, internal={internal_action_names}, available={available_action_names}" + ) + + # 将 listening 转换为 wait(向后兼容) + if action == "listening": + logger.debug(f"{self.log_prefix}检测到 listening 动作,已合并到 wait,自动转换") + action = "wait" if action not in internal_action_names and action not in available_action_names: logger.warning( - f"{self.log_prefix}LLM 返回了当前不可用或无效的动作: '{action}' (可用: {available_action_names}),将强制使用 'no_reply'" + f"{self.log_prefix}LLM 返回了当前不可用或无效的动作: '{action}' (内部动作: {internal_action_names}, 可用插件动作: {available_action_names}),将强制使用 'complete_talk'" ) reasoning = ( f"LLM 返回了当前不可用的动作 '{action}' (可用: {available_action_names})。原始理由: {reasoning}" ) - action = "no_reply" + action = "complete_talk" + logger.warning(f"{self.log_prefix}动作已转换为 complete_talk") # 创建ActionPlannerInfo对象 # 将列表转换为字典格式 @@ -201,7 +242,7 @@ class BrainPlanner: available_actions_dict = dict(current_available_actions) action_planner_infos.append( ActionPlannerInfo( - action_type="no_reply", + action_type="complete_talk", reasoning=f"解析单个action时出错: {e}", action_data={}, action_message=None, @@ -218,7 +259,7 @@ class BrainPlanner: ) -> List[ActionPlannerInfo]: # sourcery skip: use-named-expression """ - 规划器 (Planner): 使用LLM根据上下文决定做出什么动作。 + 规划器 (Planner): 使用LLM根据上下文决定做出什么动作(ReAct模式)。 """ # 获取聊天上下文 @@ -226,6 +267,7 @@ class BrainPlanner: chat_id=self.chat_id, timestamp=time.time(), limit=int(global_config.chat.max_context_size * 0.6), + filter_intercept_message_level=1, ) message_id_list: list[Tuple[str, "DatabaseMessages"]] = [] chat_content_block, message_id_list = build_readable_messages_with_id( @@ -256,18 +298,19 @@ class BrainPlanner: logger.debug(f"{self.log_prefix}过滤后有{len(filtered_actions)}个可用动作") - # 构建包含所有动作的提示词 + # 构建包含所有动作的提示词:使用统一的 ReAct Prompt + prompt_key = "brain_planner_prompt_react" + # 这里不记录日志,避免重复打印,由调用方按需控制 log_prompt prompt, message_id_list = await self.build_planner_prompt( - is_group_chat=is_group_chat, chat_target_info=chat_target_info, current_available_actions=filtered_actions, chat_content_block=chat_content_block, message_id_list=message_id_list, - interest=global_config.personality.interest, + prompt_key=prompt_key, ) # 调用LLM获取决策 - actions = await self._execute_main_planner( + reasoning, actions = await self._execute_main_planner( prompt=prompt, message_id_list=message_id_list, filtered_actions=filtered_actions, @@ -275,16 +318,22 @@ class BrainPlanner: loop_start_time=loop_start_time, ) + # 记录和展示计划日志 + logger.info( + f"{self.log_prefix}Planner: {reasoning}。选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}" + ) + self.add_plan_log(reasoning, actions) + return actions async def build_planner_prompt( self, - is_group_chat: bool, chat_target_info: Optional["TargetPersonInfo"], current_available_actions: Dict[str, ActionInfo], message_id_list: List[Tuple[str, "DatabaseMessages"]], chat_content_block: str = "", interest: str = "", + prompt_key: str = "brain_planner_prompt_react", ) -> tuple[str, List[Tuple[str, "DatabaseMessages"]]]: """构建 Planner LLM 的提示词 (获取模板并填充数据)""" try: @@ -320,7 +369,7 @@ class BrainPlanner: name_block = f"你的名字是{bot_name}{bot_nickname},请注意哪些是你自己的发言。" # 获取主规划器模板并填充 - planner_prompt_template = await global_prompt_manager.get_prompt_async("brain_planner_prompt") + planner_prompt_template = await global_prompt_manager.get_prompt_async(prompt_key) prompt = planner_prompt_template.format( time_block=time_block, chat_context_description=chat_context_description, @@ -430,17 +479,18 @@ class BrainPlanner: filtered_actions: Dict[str, ActionInfo], available_actions: Dict[str, ActionInfo], loop_start_time: float, - ) -> List[ActionPlannerInfo]: + ) -> Tuple[str, List[ActionPlannerInfo]]: """执行主规划器""" llm_content = None actions: List[ActionPlannerInfo] = [] + extracted_reasoning = "" try: # 调用LLM llm_content, (reasoning_content, _, _) = await self.planner_llm.generate_response_async(prompt=prompt) - # logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") - # logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}") + logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") + logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}") if global_config.debug.show_planner_prompt: logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") @@ -455,10 +505,11 @@ class BrainPlanner: except Exception as req_e: logger.error(f"{self.log_prefix}LLM 请求执行失败: {req_e}") - return [ + extracted_reasoning = f"LLM 请求失败,模型出现问题: {req_e}" + return extracted_reasoning, [ ActionPlannerInfo( - action_type="no_reply", - reasoning=f"LLM 请求失败,模型出现问题: {req_e}", + action_type="complete_talk", + reasoning=extracted_reasoning, action_data={}, action_message=None, available_actions=available_actions, @@ -468,24 +519,32 @@ class BrainPlanner: # 解析LLM响应 if llm_content: try: - if json_objects := self._extract_json_from_markdown(llm_content): - logger.debug(f"{self.log_prefix}从响应中提取到{len(json_objects)}个JSON对象") + json_objects, extracted_reasoning = self._extract_json_from_markdown(llm_content) + if json_objects: + logger.info(f"{self.log_prefix}从响应中提取到{len(json_objects)}个JSON对象") + for i, json_obj in enumerate(json_objects): + logger.info(f"{self.log_prefix}解析第{i + 1}个JSON对象: {json_obj}") filtered_actions_list = list(filtered_actions.items()) for json_obj in json_objects: - actions.extend(self._parse_single_action(json_obj, message_id_list, filtered_actions_list)) + parsed_actions = self._parse_single_action(json_obj, message_id_list, filtered_actions_list) + logger.info(f"{self.log_prefix}解析后的动作: {[a.action_type for a in parsed_actions]}") + actions.extend(parsed_actions) else: # 尝试解析为直接的JSON logger.warning(f"{self.log_prefix}LLM没有返回可用动作: {llm_content}") - actions = self._create_no_reply("LLM没有返回可用动作", available_actions) + extracted_reasoning = extracted_reasoning or "LLM没有返回可用动作" + actions = self._create_complete_talk(extracted_reasoning, available_actions) except Exception as json_e: logger.warning(f"{self.log_prefix}解析LLM响应JSON失败 {json_e}. LLM原始输出: '{llm_content}'") - actions = self._create_no_reply(f"解析LLM响应JSON失败: {json_e}", available_actions) + extracted_reasoning = f"解析LLM响应JSON失败: {json_e}" + actions = self._create_complete_talk(extracted_reasoning, available_actions) traceback.print_exc() else: - actions = self._create_no_reply("规划器没有获得LLM响应", available_actions) + extracted_reasoning = "规划器没有获得LLM响应" + actions = self._create_complete_talk(extracted_reasoning, available_actions) - # 添加循环开始时间到所有非no_reply动作 + # 添加循环开始时间到所有动作 for action in actions: action.action_data = action.action_data or {} action.action_data["loop_start_time"] = loop_start_time @@ -494,13 +553,15 @@ class BrainPlanner: f"{self.log_prefix}规划器决定执行{len(actions)}个动作: {' '.join([a.action_type for a in actions])}" ) - return actions + return extracted_reasoning, actions - def _create_no_reply(self, reasoning: str, available_actions: Dict[str, ActionInfo]) -> List[ActionPlannerInfo]: - """创建no_reply""" + def _create_complete_talk( + self, reasoning: str, available_actions: Dict[str, ActionInfo] + ) -> List[ActionPlannerInfo]: + """创建complete_talk""" return [ ActionPlannerInfo( - action_type="no_reply", + action_type="complete_talk", reasoning=reasoning, action_data={}, action_message=None, @@ -508,33 +569,122 @@ class BrainPlanner: ) ] - def _extract_json_from_markdown(self, content: str) -> List[dict]: + def add_plan_log(self, reasoning: str, actions: List[ActionPlannerInfo]): + """添加计划日志""" + self.plan_log.append((reasoning, time.time(), actions)) + if len(self.plan_log) > 20: + self.plan_log.pop(0) + + def _extract_json_from_markdown(self, content: str) -> Tuple[List[dict], str]: # sourcery skip: for-append-to-extend - """从Markdown格式的内容中提取JSON对象""" + """从Markdown格式的内容中提取JSON对象和推理内容""" json_objects = [] + reasoning_content = "" # 使用正则表达式查找```json包裹的JSON内容 json_pattern = r"```json\s*(.*?)\s*```" - matches = re.findall(json_pattern, content, re.DOTALL) + markdown_matches = re.findall(json_pattern, content, re.DOTALL) - for match in matches: + # 提取JSON之前的内容作为推理文本 + first_json_pos = len(content) + if markdown_matches: + # 找到第一个```json的位置 + first_json_pos = content.find("```json") + if first_json_pos > 0: + reasoning_content = content[:first_json_pos].strip() + # 清理推理内容中的注释标记 + reasoning_content = re.sub(r"^//\s*", "", reasoning_content, flags=re.MULTILINE) + reasoning_content = reasoning_content.strip() + + # 处理```json包裹的JSON + for match in markdown_matches: try: # 清理可能的注释和格式问题 json_str = re.sub(r"//.*?\n", "\n", match) # 移除单行注释 json_str = re.sub(r"/\*.*?\*/", "", json_str, flags=re.DOTALL) # 移除多行注释 if json_str := json_str.strip(): - json_obj = json.loads(repair_json(json_str)) - if isinstance(json_obj, dict): - json_objects.append(json_obj) - elif isinstance(json_obj, list): - for item in json_obj: - if isinstance(item, dict): - json_objects.append(item) + # 先尝试将整个块作为一个JSON对象或数组(适用于多行JSON) + try: + json_obj = json.loads(repair_json(json_str)) + if isinstance(json_obj, dict): + json_objects.append(json_obj) + elif isinstance(json_obj, list): + for item in json_obj: + if isinstance(item, dict): + json_objects.append(item) + except json.JSONDecodeError: + # 如果整个块解析失败,尝试按行分割(适用于多个单行JSON对象) + lines = [line.strip() for line in json_str.split("\n") if line.strip()] + for line in lines: + try: + # 尝试解析每一行作为独立的JSON对象 + json_obj = json.loads(repair_json(line)) + if isinstance(json_obj, dict): + json_objects.append(json_obj) + elif isinstance(json_obj, list): + for item in json_obj: + if isinstance(item, dict): + json_objects.append(item) + except json.JSONDecodeError: + # 单行解析失败,继续下一行 + continue except Exception as e: - logger.warning(f"解析JSON块失败: {e}, 块内容: {match[:100]}...") + logger.warning(f"{self.log_prefix}解析JSON块失败: {e}, 块内容: {match[:100]}...") continue - return json_objects + # 如果没有找到完整的```json```块,尝试查找不完整的代码块(缺少结尾```) + if not json_objects: + json_start_pos = content.find("```json") + if json_start_pos != -1: + # 找到```json之后的内容 + json_content_start = json_start_pos + 7 # ```json的长度 + # 提取从```json之后到内容结尾的所有内容 + incomplete_json_str = content[json_content_start:].strip() + + # 提取JSON之前的内容作为推理文本 + if json_start_pos > 0: + reasoning_content = content[:json_start_pos].strip() + reasoning_content = re.sub(r"^//\s*", "", reasoning_content, flags=re.MULTILINE) + reasoning_content = reasoning_content.strip() + + if incomplete_json_str: + try: + # 清理可能的注释和格式问题 + json_str = re.sub(r"//.*?\n", "\n", incomplete_json_str) + json_str = re.sub(r"/\*.*?\*/", "", json_str, flags=re.DOTALL) + json_str = json_str.strip() + + if json_str: + # 尝试按行分割,每行可能是一个JSON对象 + lines = [line.strip() for line in json_str.split("\n") if line.strip()] + for line in lines: + try: + json_obj = json.loads(repair_json(line)) + if isinstance(json_obj, dict): + json_objects.append(json_obj) + elif isinstance(json_obj, list): + for item in json_obj: + if isinstance(item, dict): + json_objects.append(item) + except json.JSONDecodeError: + pass + + # 如果按行解析没有成功,尝试将整个块作为一个JSON对象或数组 + if not json_objects: + try: + json_obj = json.loads(repair_json(json_str)) + if isinstance(json_obj, dict): + json_objects.append(json_obj) + elif isinstance(json_obj, list): + for item in json_obj: + if isinstance(item, dict): + json_objects.append(item) + except Exception as e: + logger.debug(f"尝试解析不完整的JSON代码块失败: {e}") + except Exception as e: + logger.debug(f"处理不完整的JSON代码块时出错: {e}") + + return json_objects, reasoning_content init_prompt() diff --git a/src/chat/emoji_system/emoji_manager.py b/src/chat/emoji_system/emoji_manager.py index 1a562fcc..af12bb1a 100644 --- a/src/chat/emoji_system/emoji_manager.py +++ b/src/chat/emoji_system/emoji_manager.py @@ -13,7 +13,7 @@ from typing import Optional, Tuple, List, Any from PIL import Image from rich.traceback import install -from src.common.database.database_model import Emoji +from src.common.database.database_model import Emoji, EmojiDescriptionCache from src.common.database.database import db as peewee_db from src.common.logger import get_logger from src.config.config import global_config, model_config @@ -271,7 +271,7 @@ def _to_emoji_objects(data: Any) -> Tuple[List["MaiEmoji"], int]: emoji.description = emoji_data.description # Deserialize emotion string from DB to list - emoji.emotion = emoji_data.emotion.split(",") if emoji_data.emotion else [] + emoji.emotion = emoji_data.emotion.replace(",", ",").split(",") if emoji_data.emotion else [] emoji.usage_count = emoji_data.usage_count db_last_used_time = emoji_data.last_used_time @@ -356,7 +356,7 @@ async def clean_unused_emojis(emoji_dir: str, emoji_objects: List["MaiEmoji"], r if cleaned_count > 0: logger.info(f"[清理] 在目录 {emoji_dir} 中清理了 {cleaned_count} 个破损表情包。") else: - logger.info(f"[清理] 目录 {emoji_dir} 中没有需要清理的。") + logger.debug(f"[清理] 目录 {emoji_dir} 中没有需要清理的。") except Exception as e: logger.error(f"[错误] 清理未使用表情包文件时出错 ({emoji_dir}): {str(e)}") @@ -398,6 +398,7 @@ class EmojiManager: raise RuntimeError("数据库连接失败") _ensure_emoji_dir() Emoji.create_table(safe=True) # Ensures table exists + EmojiDescriptionCache.create_table(safe=True) self._initialized = True def _ensure_db(self) -> None: @@ -731,7 +732,7 @@ class EmojiManager: emoji_record = Emoji.get_or_none(Emoji.emoji_hash == emoji_hash) if emoji_record and emoji_record.emotion: logger.info(f"[缓存命中] 从数据库获取表情包情感标签: {emoji_record.emotion[:50]}...") - return emoji_record.emotion.split(",") + return emoji_record.emotion.replace(",", ",").split(",") except Exception as e: logger.error(f"从数据库查询表情包情感标签时出错: {e}") @@ -918,17 +919,15 @@ class EmojiManager: image_hash = hashlib.md5(image_bytes).hexdigest() image_format = Image.open(io.BytesIO(image_bytes)).format.lower() # type: ignore - # 尝试从Images表获取已有的详细描述(可能在收到表情包时已生成) + # 尝试从 EmojiDescriptionCache 表获取已有的详细描述 existing_description = None try: - from src.common.database.database_model import Images - - existing_image = Images.get_or_none((Images.emoji_hash == image_hash) & (Images.type == "emoji")) - if existing_image and existing_image.description: - existing_description = existing_image.description - logger.info(f"[复用描述] 找到已有详细描述: {existing_description[:50]}...") + cache_record = EmojiDescriptionCache.get_or_none(EmojiDescriptionCache.emoji_hash == image_hash) + if cache_record and cache_record.description: + existing_description = cache_record.description + logger.info(f"[复用描述] 表情描述缓存命中: {existing_description[:50]}...") except Exception as e: - logger.debug(f"查询已有描述时出错: {e}") + logger.debug(f"查询表情描述缓存时出错: {e}") # 第一步:VLM视觉分析(如果没有已有描述才调用) if existing_description: @@ -950,6 +949,21 @@ class EmojiManager: prompt, image_base64, image_format, temperature=0.5 ) + # 若是新生成的描述,写入缓存表(此时还没有情感标签,稍后会更新) + if not existing_description: + try: + cache_record, created = EmojiDescriptionCache.get_or_create( + emoji_hash=image_hash, + defaults={"description": description, "timestamp": time.time()}, + ) + if not created: + # 更新描述,但保留已有的情感标签(如果有) + cache_record.description = description + cache_record.timestamp = time.time() + cache_record.save() + except Exception as cache_error: + logger.debug(f"写入表情描述缓存失败: {cache_error}") + # 审核表情包 if global_config.emoji.content_filtration: prompt = f''' @@ -979,7 +993,7 @@ class EmojiManager: ) # 处理情感列表 - emotions = [e.strip() for e in emotions_text.split(",") if e.strip()] + emotions = [e.strip() for e in emotions_text.replace(",", ",").split(",") if e.strip()] # 根据情感标签数量随机选择 - 超过5个选3个,超过2个选2个 if len(emotions) > 5: @@ -989,6 +1003,30 @@ class EmojiManager: logger.info(f"[注册分析] 详细描述: {description[:50]}... -> 情感标签: {emotions}") + # 将情感标签列表转换为逗号分隔的字符串 + emotion_tags_str = ",".join(emotions) + + # 更新EmojiDescriptionCache,保存情感标签 + try: + cache_record = EmojiDescriptionCache.get_or_none(EmojiDescriptionCache.emoji_hash == image_hash) + if cache_record: + # 更新已有记录的情感标签 + cache_record.emotion_tags = emotion_tags_str + cache_record.timestamp = time.time() + cache_record.save() + logger.info(f"[缓存更新] 表情包情感标签已更新到EmojiDescriptionCache: {image_hash[:8]}...") + else: + # 如果缓存不存在,创建新记录(包含描述和情感标签) + EmojiDescriptionCache.create( + emoji_hash=image_hash, + description=description, + emotion_tags=emotion_tags_str, + timestamp=time.time(), + ) + logger.info(f"[缓存创建] 表情包描述和情感标签已保存到EmojiDescriptionCache: {image_hash[:8]}...") + except Exception as cache_error: + logger.debug(f"更新表情包情感标签缓存失败: {cache_error}") + return f"[表情包:{description}]", emotions except Exception as e: diff --git a/src/chat/frequency_control/frequency_control.py b/src/chat/frequency_control/frequency_control.py deleted file mode 100644 index 78041ae7..00000000 --- a/src/chat/frequency_control/frequency_control.py +++ /dev/null @@ -1,150 +0,0 @@ -from datetime import datetime -import time -from typing import Dict - -from src.chat.utils.chat_message_builder import ( - get_raw_msg_by_timestamp_with_chat, - build_readable_messages, -) -from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.config.config import global_config, model_config -from src.llm_models.utils_model import LLMRequest -from src.common.logger import get_logger -from src.plugin_system.apis import frequency_api - - -def init_prompt(): - Prompt( - """{name_block} -{time_block} -你现在正在聊天,请根据下面的聊天记录判断是否有用户觉得你的发言过于频繁或者发言过少 -{message_str} - -如果用户觉得你的发言过于频繁,请输出"过于频繁",否则输出"正常" -如果用户觉得你的发言过少,请输出"过少",否则输出"正常" -**你只能输出以下三个词之一,不要输出任何其他文字、解释或标点:** -- 正常 -- 过于频繁 -- 过少 -""", - "frequency_adjust_prompt", - ) - - -logger = get_logger("frequency_control") - - -class FrequencyControl: - """简化的频率控制类,仅管理不同chat_id的频率值""" - - def __init__(self, chat_id: str): - self.chat_id = chat_id - # 发言频率调整值 - self.talk_frequency_adjust: float = 1.0 - - self.last_frequency_adjust_time: float = 0.0 - self.frequency_model = LLMRequest( - model_set=model_config.model_task_config.utils_small, request_type="frequency.adjust" - ) - - def get_talk_frequency_adjust(self) -> float: - """获取发言频率调整值""" - return self.talk_frequency_adjust - - def set_talk_frequency_adjust(self, value: float) -> None: - """设置发言频率调整值""" - self.talk_frequency_adjust = max(0.1, min(5.0, value)) - - async def trigger_frequency_adjust(self) -> None: - msg_list = get_raw_msg_by_timestamp_with_chat( - chat_id=self.chat_id, - timestamp_start=self.last_frequency_adjust_time, - timestamp_end=time.time(), - ) - - if time.time() - self.last_frequency_adjust_time < 160 or len(msg_list) <= 20: - return - else: - new_msg_list = get_raw_msg_by_timestamp_with_chat( - chat_id=self.chat_id, - timestamp_start=self.last_frequency_adjust_time, - timestamp_end=time.time(), - limit=20, - limit_mode="latest", - ) - - message_str = build_readable_messages( - new_msg_list, - replace_bot_name=True, - timestamp_mode="relative", - read_mark=0.0, - show_actions=False, - ) - time_block = f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" - bot_name = global_config.bot.nickname - bot_nickname = ( - f",也有人叫你{','.join(global_config.bot.alias_names)}" if global_config.bot.alias_names else "" - ) - name_block = f"你的名字是{bot_name}{bot_nickname},请注意哪些是你自己的发言。" - - prompt = await global_prompt_manager.format_prompt( - "frequency_adjust_prompt", - name_block=name_block, - time_block=time_block, - message_str=message_str, - ) - response, (reasoning_content, _, _) = await self.frequency_model.generate_response_async( - prompt, - ) - - # logger.info(f"频率调整 prompt: {prompt}") - # logger.info(f"频率调整 response: {response}") - - if global_config.debug.show_prompt: - logger.info(f"频率调整 prompt: {prompt}") - logger.info(f"频率调整 response: {response}") - logger.info(f"频率调整 reasoning_content: {reasoning_content}") - - final_value_by_api = frequency_api.get_current_talk_value(self.chat_id) - - # LLM依然输出过多内容时取消本次调整。合法最多4个字,但有的模型可能会输出一些markdown换行符等,需要长度宽限 - if len(response) < 20: - if "过于频繁" in response: - logger.info(f"频率调整: 过于频繁,调整值到{final_value_by_api}") - self.talk_frequency_adjust = max(0.1, min(1.5, self.talk_frequency_adjust * 0.8)) - elif "过少" in response: - logger.info(f"频率调整: 过少,调整值到{final_value_by_api}") - self.talk_frequency_adjust = max(0.1, min(1.5, self.talk_frequency_adjust * 1.2)) - self.last_frequency_adjust_time = time.time() - else: - logger.info("频率调整:response不符合要求,取消本次调整") - - -class FrequencyControlManager: - """频率控制管理器,管理多个聊天流的频率控制实例""" - - def __init__(self): - self.frequency_control_dict: Dict[str, FrequencyControl] = {} - - def get_or_create_frequency_control(self, chat_id: str) -> FrequencyControl: - """获取或创建指定聊天流的频率控制实例""" - if chat_id not in self.frequency_control_dict: - self.frequency_control_dict[chat_id] = FrequencyControl(chat_id) - return self.frequency_control_dict[chat_id] - - def remove_frequency_control(self, chat_id: str) -> bool: - """移除指定聊天流的频率控制实例""" - if chat_id in self.frequency_control_dict: - del self.frequency_control_dict[chat_id] - return True - return False - - def get_all_chat_ids(self) -> list[str]: - """获取所有有频率控制的聊天ID""" - return list(self.frequency_control_dict.keys()) - - -init_prompt() - -# 创建全局实例 -frequency_control_manager = FrequencyControlManager() diff --git a/src/chat/heart_flow/frequency_control.py b/src/chat/heart_flow/frequency_control.py new file mode 100644 index 00000000..d3be7801 --- /dev/null +++ b/src/chat/heart_flow/frequency_control.py @@ -0,0 +1,50 @@ +from typing import Dict + +from src.common.logger import get_logger + +logger = get_logger("frequency_control") + + +class FrequencyControl: + """简化的频率控制类,仅管理不同chat_id的频率值""" + + def __init__(self, chat_id: str): + self.chat_id = chat_id + # 发言频率调整值 + self.talk_frequency_adjust: float = 1.0 + + def get_talk_frequency_adjust(self) -> float: + """获取发言频率调整值""" + return self.talk_frequency_adjust + + def set_talk_frequency_adjust(self, value: float) -> None: + """设置发言频率调整值""" + self.talk_frequency_adjust = max(0.1, min(5.0, value)) + + +class FrequencyControlManager: + """频率控制管理器,管理多个聊天流的频率控制实例""" + + def __init__(self): + self.frequency_control_dict: Dict[str, FrequencyControl] = {} + + def get_or_create_frequency_control(self, chat_id: str) -> FrequencyControl: + """获取或创建指定聊天流的频率控制实例""" + if chat_id not in self.frequency_control_dict: + self.frequency_control_dict[chat_id] = FrequencyControl(chat_id) + return self.frequency_control_dict[chat_id] + + def remove_frequency_control(self, chat_id: str) -> bool: + """移除指定聊天流的频率控制实例""" + if chat_id in self.frequency_control_dict: + del self.frequency_control_dict[chat_id] + return True + return False + + def get_all_chat_ids(self) -> list[str]: + """获取所有有频率控制的聊天ID""" + return list(self.frequency_control_dict.keys()) + + +# 创建全局实例 +frequency_control_manager = FrequencyControlManager() diff --git a/src/chat/heart_flow/heartFC_chat.py b/src/chat/heart_flow/heartFC_chat.py index bb37e29e..13db1783 100644 --- a/src/chat/heart_flow/heartFC_chat.py +++ b/src/chat/heart_flow/heartFC_chat.py @@ -16,9 +16,11 @@ from src.chat.planner_actions.planner import ActionPlanner from src.chat.planner_actions.action_modifier import ActionModifier from src.chat.planner_actions.action_manager import ActionManager from src.chat.heart_flow.hfc_utils import CycleDetail -from src.express.expression_learner import expression_learner_manager -from src.chat.frequency_control.frequency_control import frequency_control_manager -from src.jargon import extract_and_store_jargon +from src.bw_learner.expression_learner import expression_learner_manager +from src.chat.heart_flow.frequency_control import frequency_control_manager +from src.bw_learner.reflect_tracker import reflect_tracker_manager +from src.bw_learner.expression_reflector import expression_reflector_manager +from src.bw_learner.message_recorder import extract_and_distribute_messages from src.person_info.person_info import Person from src.plugin_system.base.component_types import EventType, ActionInfo from src.plugin_system.core import events_manager @@ -27,7 +29,8 @@ from src.chat.utils.chat_message_builder import ( build_readable_messages_with_id, get_raw_msg_before_timestamp_with_chat, ) -from src.chat.utils.chat_history_summarizer import ChatHistorySummarizer +from src.chat.utils.utils import record_replyer_action_temp +from src.hippo_memorizer.chat_history_summarizer import ChatHistorySummarizer if TYPE_CHECKING: from src.common.data_models.database_data_model import DatabaseMessages @@ -97,7 +100,6 @@ class HeartFChatting: self._current_cycle_detail: CycleDetail = None # type: ignore self.last_read_time = time.time() - 2 - self.no_reply_until_call = False self.is_mute = False @@ -187,7 +189,8 @@ class HeartFChatting: limit=20, limit_mode="latest", filter_mai=True, - filter_command=True, + filter_command=False, + filter_intercept_message_level=0, ) # 根据连续 no_reply 次数动态调整阈值 @@ -204,23 +207,6 @@ class HeartFChatting: if len(recent_messages_list) >= threshold: # for message in recent_messages_list: # print(message.processed_plain_text) - # !处理no_reply_until_call逻辑 - if self.no_reply_until_call: - for message in recent_messages_list: - if ( - message.is_mentioned - or message.is_at - or len(recent_messages_list) >= 8 - or time.time() - self.last_read_time > 600 - ): - self.no_reply_until_call = False - self.last_read_time = time.time() - break - # 没有提到,继续保持沉默 - if self.no_reply_until_call: - # logger.info(f"{self.log_prefix} 没有提到,继续保持沉默") - await asyncio.sleep(1) - return True self.last_read_time = time.time() @@ -300,90 +286,6 @@ class HeartFChatting: return loop_info, reply_text, cycle_timers - async def _run_planner_without_reply( - self, - available_actions: Dict[str, ActionInfo], - cycle_timers: Dict[str, float], - ) -> List[ActionPlannerInfo]: - """执行planner,但不包含reply动作(用于并行执行场景,提及时使用简化版提示词)""" - try: - with Timer("规划器", cycle_timers): - action_to_use_info = await self.action_planner.plan( - loop_start_time=self.last_read_time, - available_actions=available_actions, - is_mentioned=True, # 标记为提及时,使用简化版提示词 - ) - # 过滤掉reply动作(虽然提及时不应该有reply,但为了安全还是过滤一下) - return [action for action in action_to_use_info if action.action_type != "reply"] - except Exception as e: - logger.error(f"{self.log_prefix} Planner执行失败: {e}") - traceback.print_exc() - return [] - - async def _generate_mentioned_reply( - self, - force_reply_message: "DatabaseMessages", - thinking_id: str, - cycle_timers: Dict[str, float], - available_actions: Dict[str, ActionInfo], - ) -> Dict[str, Any]: - """当被提及时,独立生成回复的任务""" - try: - self.questioned = False - # 重置连续 no_reply 计数 - self.consecutive_no_reply_count = 0 - reason = "" - - await database_api.store_action_info( - chat_stream=self.chat_stream, - action_build_into_prompt=False, - action_prompt_display=reason, - action_done=True, - thinking_id=thinking_id, - action_data={}, - action_name="reply", - action_reasoning=reason, - ) - - with Timer("提及回复生成", cycle_timers): - success, llm_response = await generator_api.generate_reply( - chat_stream=self.chat_stream, - reply_message=force_reply_message, - available_actions=available_actions, - chosen_actions=[], # 独立回复,不依赖planner的动作 - reply_reason=reason, - enable_tool=global_config.tool.enable_tool, - request_type="replyer", - from_plugin=False, - reply_time_point=self.last_read_time, - ) - - if not success or not llm_response or not llm_response.reply_set: - logger.warning(f"{self.log_prefix} 提及回复生成失败") - return {"action_type": "reply", "success": False, "result": "提及回复生成失败", "loop_info": None} - - response_set = llm_response.reply_set - selected_expressions = llm_response.selected_expressions - loop_info, reply_text, _ = await self._send_and_store_reply( - response_set=response_set, - action_message=force_reply_message, - cycle_timers=cycle_timers, - thinking_id=thinking_id, - actions=[], # 独立回复,不依赖planner的动作 - selected_expressions=selected_expressions, - ) - self.last_active_time = time.time() - return { - "action_type": "reply", - "success": True, - "result": f"你回复内容{reply_text}", - "loop_info": loop_info, - } - except Exception as e: - logger.error(f"{self.log_prefix} 提及回复生成异常: {e}") - traceback.print_exc() - return {"action_type": "reply", "success": False, "result": f"提及回复生成异常: {e}", "loop_info": None} - async def _observe( self, # interest_value: float = 0.0, recent_messages_list: Optional[List["DatabaseMessages"]] = None, @@ -393,24 +295,36 @@ class HeartFChatting: recent_messages_list = [] _reply_text = "" # 初始化reply_text变量,避免UnboundLocalError - start_time = time.time() + # ------------------------------------------------------------------------- + # ReflectTracker Check + # 在每次回复前检查一次上下文,看是否有反思问题得到了解答 + # ------------------------------------------------------------------------- + reflector = expression_reflector_manager.get_or_create_reflector(self.stream_id) + await reflector.check_and_ask() + tracker = reflect_tracker_manager.get_tracker(self.stream_id) + if tracker: + resolved = await tracker.trigger_tracker() + if resolved: + reflect_tracker_manager.remove_tracker(self.stream_id) + logger.info(f"{self.log_prefix} ReflectTracker resolved and removed.") + + start_time = time.time() async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()): - asyncio.create_task(self.expression_learner.trigger_learning_for_chat()) - asyncio.create_task( - frequency_control_manager.get_or_create_frequency_control(self.stream_id).trigger_frequency_adjust() - ) + # 通过 MessageRecorder 统一提取消息并分发给 expression_learner 和 jargon_miner + # 在 replyer 执行时触发,统一管理时间窗口,避免重复获取消息 + asyncio.create_task(extract_and_distribute_messages(self.stream_id)) # 添加curious检测任务 - 检测聊天记录中的矛盾、冲突或需要提问的内容 # asyncio.create_task(check_and_make_question(self.stream_id)) - # 添加jargon提取任务 - 提取聊天中的黑话/俚语并入库(内部自行取消息并带冷却) - asyncio.create_task(extract_and_store_jargon(self.stream_id)) # 添加聊天内容概括任务 - 累积、打包和压缩聊天记录 # 注意:后台循环已在start()中启动,这里作为额外触发点,在有思考时立即处理 # asyncio.create_task(self.chat_history_summarizer.process()) cycle_timers, thinking_id = self.start_cycle() - logger.info(f"{self.log_prefix} 开始第{self._cycle_counter}次思考(频率: {global_config.chat.get_talk_value(self.stream_id)})") + logger.info( + f"{self.log_prefix} 开始第{self._cycle_counter}次思考(频率: {global_config.chat.get_talk_value(self.stream_id)})" + ) # 第一步:动作检查 available_actions: Dict[str, ActionInfo] = {} @@ -420,94 +334,50 @@ class HeartFChatting: except Exception as e: logger.error(f"{self.log_prefix} 动作修改失败: {e}") - # 如果被提及,让回复生成和planner并行执行 - if force_reply_message: - logger.info(f"{self.log_prefix} 检测到提及,回复生成与planner并行执行") + # 执行planner + is_group_chat, chat_target_info, _ = self.action_planner.get_necessary_info() - # 并行执行planner和回复生成 - planner_task = asyncio.create_task( - self._run_planner_without_reply( - available_actions=available_actions, - cycle_timers=cycle_timers, - ) + message_list_before_now = get_raw_msg_before_timestamp_with_chat( + chat_id=self.stream_id, + timestamp=time.time(), + limit=int(global_config.chat.max_context_size * 0.6), + filter_intercept_message_level=1, + ) + chat_content_block, message_id_list = build_readable_messages_with_id( + messages=message_list_before_now, + timestamp_mode="normal_no_YMD", + read_mark=self.action_planner.last_obs_time_mark, + truncate=True, + show_actions=True, + ) + + prompt_info = await self.action_planner.build_planner_prompt( + is_group_chat=is_group_chat, + chat_target_info=chat_target_info, + current_available_actions=available_actions, + chat_content_block=chat_content_block, + message_id_list=message_id_list, + ) + continue_flag, modified_message = await events_manager.handle_mai_events( + EventType.ON_PLAN, None, prompt_info[0], None, self.chat_stream.stream_id + ) + if not continue_flag: + return False + if modified_message and modified_message._modify_flags.modify_llm_prompt: + prompt_info = (modified_message.llm_prompt, prompt_info[1]) + + with Timer("规划器", cycle_timers): + action_to_use_info = await self.action_planner.plan( + loop_start_time=self.last_read_time, + available_actions=available_actions, + force_reply_message=force_reply_message, ) - reply_task = asyncio.create_task( - self._generate_mentioned_reply( - force_reply_message=force_reply_message, - thinking_id=thinking_id, - cycle_timers=cycle_timers, - available_actions=available_actions, - ) - ) - - # 等待两个任务完成 - planner_result, reply_result = await asyncio.gather(planner_task, reply_task, return_exceptions=True) - - # 处理planner结果 - if isinstance(planner_result, BaseException): - logger.error(f"{self.log_prefix} Planner执行异常: {planner_result}") - action_to_use_info = [] - else: - action_to_use_info = planner_result - - # 处理回复结果 - if isinstance(reply_result, BaseException): - logger.error(f"{self.log_prefix} 回复生成异常: {reply_result}") - reply_result = { - "action_type": "reply", - "success": False, - "result": "回复生成异常", - "loop_info": None, - } - else: - # 正常流程:只执行planner - is_group_chat, chat_target_info, _ = self.action_planner.get_necessary_info() - - message_list_before_now = get_raw_msg_before_timestamp_with_chat( - chat_id=self.stream_id, - timestamp=time.time(), - limit=int(global_config.chat.max_context_size * 0.6), - ) - chat_content_block, message_id_list = build_readable_messages_with_id( - messages=message_list_before_now, - timestamp_mode="normal_no_YMD", - read_mark=self.action_planner.last_obs_time_mark, - truncate=True, - show_actions=True, - ) - - prompt_info = await self.action_planner.build_planner_prompt( - is_group_chat=is_group_chat, - chat_target_info=chat_target_info, - current_available_actions=available_actions, - chat_content_block=chat_content_block, - message_id_list=message_id_list, - interest=global_config.personality.interest, - ) - continue_flag, modified_message = await events_manager.handle_mai_events( - EventType.ON_PLAN, None, prompt_info[0], None, self.chat_stream.stream_id - ) - if not continue_flag: - return False - if modified_message and modified_message._modify_flags.modify_llm_prompt: - prompt_info = (modified_message.llm_prompt, prompt_info[1]) - - with Timer("规划器", cycle_timers): - action_to_use_info = await self.action_planner.plan( - loop_start_time=self.last_read_time, - available_actions=available_actions, - ) - reply_result = None - - # 只在提及情况下过滤掉planner返回的reply动作(提及时已有独立回复生成) - if force_reply_message: - action_to_use_info = [action for action in action_to_use_info if action.action_type != "reply"] logger.info( f"{self.log_prefix} 决定执行{len(action_to_use_info)}个动作: {' '.join([a.action_type for a in action_to_use_info])}" ) - # 3. 并行执行所有动作(不包括reply,reply已经独立执行) + # 3. 并行执行所有动作 action_tasks = [ asyncio.create_task( self._execute_action(action, action_to_use_info, thinking_id, available_actions, cycle_timers) @@ -518,10 +388,6 @@ class HeartFChatting: # 并行执行所有任务 results = await asyncio.gather(*action_tasks, return_exceptions=True) - # 如果有独立的回复结果,添加到结果列表中 - if reply_result: - results = list(results) + [reply_result] - # 处理执行结果 reply_loop_info = None reply_text_from_reply = "" @@ -732,31 +598,6 @@ class HeartFChatting: return {"action_type": "no_reply", "success": True, "result": "选择不回复", "command": ""} - elif action_planner_info.action_type == "no_reply_until_call": - # 直接当场执行no_reply_until_call逻辑 - logger.info(f"{self.log_prefix} 保持沉默,直到有人直接叫的名字") - reason = action_planner_info.reasoning or "选择不回复" - - # 增加连续 no_reply 计数 - self.consecutive_no_reply_count += 1 - self.no_reply_until_call = True - await database_api.store_action_info( - chat_stream=self.chat_stream, - action_build_into_prompt=False, - action_prompt_display=reason, - action_done=True, - thinking_id=thinking_id, - action_data={}, - action_name="no_reply_until_call", - action_reasoning=reason, - ) - return { - "action_type": "no_reply_until_call", - "success": True, - "result": "保持沉默,直到有人直接叫的名字", - "command": "", - } - elif action_planner_info.action_type == "reply": # 直接当场执行reply逻辑 self.questioned = False @@ -765,8 +606,27 @@ class HeartFChatting: self.consecutive_no_reply_count = 0 reason = action_planner_info.reasoning or "" + # 根据 think_mode 配置决定 think_level 的值 + think_mode = global_config.chat.think_mode + if think_mode == "default": + think_level = 0 + elif think_mode == "deep": + think_level = 1 + elif think_mode == "dynamic": + # dynamic 模式:从 planner 返回的 action_data 中获取 + think_level = action_planner_info.action_data.get("think_level", 1) + else: + # 默认使用 default 模式 + think_level = 0 # 使用 action_reasoning(planner 的整体思考理由)作为 reply_reason planner_reasoning = action_planner_info.action_reasoning or reason + + record_replyer_action_temp( + chat_id=self.stream_id, + reason=reason, + think_level=think_level, + ) + await database_api.store_action_info( chat_stream=self.chat_stream, action_build_into_prompt=False, @@ -778,16 +638,32 @@ class HeartFChatting: action_reasoning=reason, ) + # 从 Planner 的 action_data 中提取未知词语列表(仅在 reply 时使用) + unknown_words = None + if isinstance(action_planner_info.action_data, dict): + uw = action_planner_info.action_data.get("unknown_words") + if isinstance(uw, list): + cleaned_uw: List[str] = [] + for item in uw: + if isinstance(item, str): + s = item.strip() + if s: + cleaned_uw.append(s) + if cleaned_uw: + unknown_words = cleaned_uw + success, llm_response = await generator_api.generate_reply( chat_stream=self.chat_stream, reply_message=action_planner_info.action_message, available_actions=available_actions, chosen_actions=chosen_action_plan_infos, reply_reason=planner_reasoning, + unknown_words=unknown_words, enable_tool=global_config.tool.enable_tool, request_type="replyer", from_plugin=False, reply_time_point=action_planner_info.action_data.get("loop_start_time", time.time()), + think_level=think_level, ) if not success or not llm_response or not llm_response.reply_set: @@ -814,6 +690,7 @@ class HeartFChatting: "result": f"你回复内容{reply_text}", "loop_info": loop_info, } + else: # 执行普通动作 with Timer("动作执行", cycle_timers): diff --git a/src/chat/heart_flow/heartflow_message_processor.py b/src/chat/heart_flow/heartflow_message_processor.py index d0e1f9c9..09a3a94d 100644 --- a/src/chat/heart_flow/heartflow_message_processor.py +++ b/src/chat/heart_flow/heartflow_message_processor.py @@ -39,6 +39,11 @@ class HeartFCMessageReceiver: message_data: 原始消息字符串 """ try: + # 通知消息不处理 + if message.is_notify: + logger.debug("通知消息,跳过处理") + return + # 1. 消息解析与初始化 userinfo = message.message_info.user_info chat = message.chat_stream diff --git a/src/chat/knowledge/__init__.py b/src/chat/knowledge/__init__.py index a570277c..57e94472 100644 --- a/src/chat/knowledge/__init__.py +++ b/src/chat/knowledge/__init__.py @@ -42,7 +42,10 @@ def lpmm_start_up(): # sourcery skip: extract-duplicate-method logger.info("创建LLM客户端") # 初始化Embedding库 - embed_manager = EmbeddingManager() + embed_manager = EmbeddingManager( + max_workers=global_config.lpmm_knowledge.max_embedding_workers, + chunk_size=global_config.lpmm_knowledge.embedding_chunk_size, + ) logger.info("正在从文件加载Embedding库") try: embed_manager.load_from_file() diff --git a/src/chat/knowledge/embedding_store.py b/src/chat/knowledge/embedding_store.py index 768373cf..9c460a0d 100644 --- a/src/chat/knowledge/embedding_store.py +++ b/src/chat/knowledge/embedding_store.py @@ -104,7 +104,9 @@ class EmbeddingStore: self.dir = dir_path self.embedding_file_path = f"{dir_path}/{namespace}.parquet" self.index_file_path = f"{dir_path}/{namespace}.index" - self.idx2hash_file_path = dir_path + "/" + namespace + "_i2h.json" + self.idx2hash_file_path = f"{dir_path}/{namespace}_i2h.json" + + self.dirty = False # 标记是否有新增数据需要重建索引 # 多线程配置参数验证和设置 self.max_workers = max(MIN_WORKERS, min(MAX_WORKERS, max_workers)) @@ -125,6 +127,11 @@ class EmbeddingStore: self.faiss_index = None self.idx2hash = None + @staticmethod + def hash_texts(namespace: str, texts: List[str]) -> List[str]: + """将原文计算为带前缀的键""" + return [f"{namespace}-{get_sha256(t)}" for t in texts] + def _get_embedding(self, s: str) -> List[float]: """获取字符串的嵌入向量,使用完全同步的方式避免事件循环问题""" # 创建新的事件循环并在完成后立即关闭 @@ -412,6 +419,7 @@ class EmbeddingStore: item_hash = self.namespace + "-" + get_sha256(s) if embedding: # 只有成功获取到嵌入才存入 self.store[item_hash] = EmbeddingStoreItem(item_hash, embedding, s) + self.dirty = True else: logger.warning(f"跳过存储失败的嵌入: {s[:50]}...") @@ -488,9 +496,17 @@ class EmbeddingStore: self.build_faiss_index() logger.info(f"{self.namespace}嵌入库的FaissIndex重建成功") self.save_to_file() + self.dirty = False def build_faiss_index(self) -> None: """重新构建Faiss索引,以余弦相似度为度量""" + # 空库直接跳过,清空索引映射 + if not self.store: + self.idx2hash = {} + self.faiss_index = None + self.dirty = False + return + # 获取所有的embedding array = [] self.idx2hash = dict() @@ -498,11 +514,44 @@ class EmbeddingStore: array.append(self.store[key].embedding) self.idx2hash[str(len(array) - 1)] = key embeddings = np.array(array, dtype=np.float32) + if embeddings.size == 0: + self.idx2hash = {} + self.faiss_index = None + self.dirty = False + return # L2归一化 faiss.normalize_L2(embeddings) # 构建索引 self.faiss_index = faiss.IndexFlatIP(global_config.lpmm_knowledge.embedding_dimension) self.faiss_index.add(embeddings) + self.dirty = False + + def delete_items(self, hashes: List[str]) -> Tuple[int, int]: + """删除指定键的嵌入并重建 idx2hash(不直接重建 faiss) + + Args: + hashes: 需要删除的完整键列表(如 paragraph-xxx) + + Returns: + (deleted, skipped) + """ + deleted = 0 + skipped = 0 + for h in hashes: + if h in self.store: + self.store.pop(h) + deleted += 1 + else: + skipped += 1 + + # 重新构建 idx2hash 映射 + self.idx2hash = {} + for idx, key in enumerate(self.store.keys()): + self.idx2hash[str(idx)] = key + + # 删除后标记 dirty,faiss 重建由上层统一调用 + self.dirty = True + return deleted, skipped def search_top_k(self, query: List[float], k: int) -> List[Tuple[str, float]]: """搜索最相似的k个项,以余弦相似度为度量 @@ -536,7 +585,7 @@ class EmbeddingStore: class EmbeddingManager: - def __init__(self, max_workers: int = DEFAULT_MAX_WORKERS, chunk_size: int = DEFAULT_CHUNK_SIZE): + def __init__(self, max_workers: int | None = None, chunk_size: int | None = None): """ 初始化EmbeddingManager @@ -544,6 +593,8 @@ class EmbeddingManager: max_workers: 最大线程数 chunk_size: 每个线程处理的数据块大小 """ + max_workers = max_workers if max_workers is not None else global_config.lpmm_knowledge.max_embedding_workers + chunk_size = chunk_size if chunk_size is not None else global_config.lpmm_knowledge.embedding_chunk_size self.paragraphs_embedding_store = EmbeddingStore( "paragraph", # type: ignore EMBEDDING_DATA_DIR_STR, @@ -617,7 +668,19 @@ class EmbeddingManager: self.relation_embedding_store.save_to_file() def rebuild_faiss_index(self): - """重建Faiss索引(请在添加新数据后调用)""" - self.paragraphs_embedding_store.build_faiss_index() - self.entities_embedding_store.build_faiss_index() - self.relation_embedding_store.build_faiss_index() + """重建Faiss索引,新增数据后调用,带跳过逻辑""" + + def _rebuild_if_needed(store: EmbeddingStore): + if ( + not store.dirty + and store.faiss_index is not None + and store.idx2hash is not None + and getattr(store.faiss_index, "ntotal", 0) == len(store.idx2hash) == len(store.store) + ): + logger.info(f"{store.namespace} FaissIndex 已是最新,跳过重建") + return + store.build_faiss_index() + + _rebuild_if_needed(self.paragraphs_embedding_store) + _rebuild_if_needed(self.entities_embedding_store) + _rebuild_if_needed(self.relation_embedding_store) diff --git a/src/chat/knowledge/kg_manager.py b/src/chat/knowledge/kg_manager.py index ac86fa20..8108c296 100644 --- a/src/chat/knowledge/kg_manager.py +++ b/src/chat/knowledge/kg_manager.py @@ -1,7 +1,8 @@ import json import os import time -from typing import Dict, List, Tuple +from typing import Dict, List, Tuple, Set +import xml.etree.ElementTree as ET import numpy as np import pandas as pd @@ -98,6 +99,28 @@ class KGManager: # 加载KG self.graph = di_graph.load_from_file(self.graph_data_path) + def _rebuild_metadata_from_graph(self) -> None: + """根据当前图重建 stored_paragraph_hashes 与 ent_appear_cnt""" + nodes = self.graph.get_node_list() + edges = self.graph.get_edge_list() + + # 段落 hash:paragraph-{hash} + self.stored_paragraph_hashes = set() + for node_id in nodes: + if node_id.startswith("paragraph-"): + self.stored_paragraph_hashes.add(node_id.split("paragraph-", 1)[1]) + + # 实体出现次数:基于 entity -> paragraph 的边权 + ent_appear_cnt: Dict[str, float] = {} + for edge_tuple in edges: + src, tgt = edge_tuple[0], edge_tuple[1] + if src.startswith("entity") and tgt.startswith("paragraph"): + edge_data = self.graph[src, tgt] + weight = edge_data["weight"] if "weight" in edge_data else 1.0 + ent_appear_cnt[src] = ent_appear_cnt.get(src, 0.0) + float(weight) + + self.ent_appear_cnt = ent_appear_cnt + def _build_edges_between_ent( self, node_to_node: Dict[Tuple[str, str], float], @@ -149,6 +172,13 @@ class KGManager: ent_hash_list.add("entity" + "-" + get_sha256(triple[0])) ent_hash_list.add("entity" + "-" + get_sha256(triple[2])) ent_hash_list = list(ent_hash_list) + # 性能保护:限制同义连接的实体数量 + max_synonym_entities = global_config.lpmm_knowledge.max_synonym_entities + if max_synonym_entities and len(ent_hash_list) > max_synonym_entities: + logger.warning( + f"同义连接实体数 {len(ent_hash_list)} 超过阈值 {max_synonym_entities},跳过同义边构建以保护性能" + ) + return 0 synonym_hash_set = set() synonym_result = {} @@ -328,6 +358,10 @@ class KGManager: paragraph_search_result: ParagraphEmbedding的搜索结果(paragraph_hash, similarity) embed_manager: EmbeddingManager对象 """ + # 性能保护:关闭时直接返回向量检索结果 + if not global_config.lpmm_knowledge.enable_ppr: + logger.info("PPR 已禁用,使用纯向量检索结果") + return paragraph_search_result, None # 图中存在的节点总集 existed_nodes = self.graph.get_node_list() @@ -357,7 +391,15 @@ class KGManager: ent_mean_scores = {} # 记录实体的平均相似度 for ent_hash, scores in ent_sim_scores.items(): # 先对相似度进行累加,然后与实体计数相除获取最终权重 - ent_weights[ent_hash] = float(np.sum(scores)) / self.ent_appear_cnt[ent_hash] + # 保护:有些实体在当前图中可能只有实体-实体关系,不会出现在 ent_appear_cnt 中 + appear_cnt = self.ent_appear_cnt.get(ent_hash) + if not appear_cnt or appear_cnt <= 0: + logger.debug( + f"实体 {ent_hash} 在 ent_appear_cnt 中不存在或计数为 0," + f"将使用 1.0 作为默认出现次数参与权重计算" + ) + appear_cnt = 1.0 + ent_weights[ent_hash] = float(np.sum(scores)) / float(appear_cnt) # 记录实体的平均相似度,用于后续的top_k筛选 ent_mean_scores[ent_hash] = float(np.mean(scores)) del ent_sim_scores @@ -434,3 +476,115 @@ class KGManager: passage_node_res = sorted(passage_node_res, key=lambda item: item[1], reverse=True) return passage_node_res, ppr_node_weights + + def delete_paragraphs( + self, + pg_hashes: List[str], + ent_hashes: List[str] | None = None, + remove_orphan_entities: bool = False, + ) -> Dict[str, int]: + """删除段落/实体节点及相关边(基于 GraphML),可选清理孤立实体,并重建元数据""" + # 要删除的节点 ID + nodes_to_delete: Set[str] = {f"paragraph-{h}" for h in pg_hashes} + if ent_hashes: + nodes_to_delete.update({f"entity-{h}" for h in ent_hashes}) + + if not os.path.exists(self.graph_data_path): + raise FileNotFoundError(f"KG图文件{self.graph_data_path}不存在") + + tree = ET.parse(self.graph_data_path) + root = tree.getroot() + + # GraphML 可能带命名空间,用尾缀判断 + def is_node(elem: ET.Element) -> bool: + return elem.tag.endswith("node") + + def is_edge(elem: ET.Element) -> bool: + return elem.tag.endswith("edge") + + graph_elem = None + for child in root: + if child.tag.endswith("graph"): + graph_elem = child + break + if graph_elem is None: + raise RuntimeError("GraphML 中未找到 节点") + + # 统计现有节点 + existing_nodes: Set[str] = set() + for elem in graph_elem: + if is_node(elem): + node_id = elem.get("id") + if node_id: + existing_nodes.add(node_id) + + deleted_nodes = len(nodes_to_delete & existing_nodes) + skipped_nodes = len(nodes_to_delete - existing_nodes) + + # 先删除指定节点及相关边 + # 删除节点 + for elem in list(graph_elem): + if is_node(elem): + node_id = elem.get("id") + if node_id and node_id in nodes_to_delete: + graph_elem.remove(elem) + + # 删除 incident edges + for elem in list(graph_elem): + if is_edge(elem): + src = elem.get("source") + tgt = elem.get("target") + if src in nodes_to_delete or tgt in nodes_to_delete: + graph_elem.remove(elem) + + orphan_removed = 0 + if remove_orphan_entities: + # 计算仍然参与边的节点 + used_nodes: Set[str] = set() + for elem in graph_elem: + if is_edge(elem): + src = elem.get("source") + tgt = elem.get("target") + if src: + used_nodes.add(src) + if tgt: + used_nodes.add(tgt) + + # 找出没有任何边的实体节点 + orphan_entities: Set[str] = set() + for elem in graph_elem: + if is_node(elem): + node_id = elem.get("id") + if node_id and node_id.startswith("entity") and node_id not in used_nodes: + orphan_entities.add(node_id) + + orphan_removed = len(orphan_entities) + + if orphan_entities: + # 删除孤立实体节点 + for elem in list(graph_elem): + if is_node(elem): + node_id = elem.get("id") + if node_id in orphan_entities: + graph_elem.remove(elem) + + # 删除与孤立实体相关的边(理论上已无,但做一次防御性清理) + for elem in list(graph_elem): + if is_edge(elem): + src = elem.get("source") + tgt = elem.get("target") + if src in orphan_entities or tgt in orphan_entities: + graph_elem.remove(elem) + + # 写回 GraphML + tree.write(self.graph_data_path, encoding="utf-8", xml_declaration=True) + + # 重新加载图并重建元数据 + self.graph = di_graph.load_from_file(self.graph_data_path) + self._rebuild_metadata_from_graph() + + return { + "deleted": deleted_nodes, + "skipped": skipped_nodes, + "orphan_removed": orphan_removed, + } diff --git a/src/chat/message_receive/bot.py b/src/chat/message_receive/bot.py index 070f78bd..c45ec105 100644 --- a/src/chat/message_receive/bot.py +++ b/src/chat/message_receive/bot.py @@ -7,7 +7,6 @@ from maim_message import UserInfo, Seg, GroupInfo from src.common.logger import get_logger from src.config.config import global_config -from src.mood.mood_manager import mood_manager # 导入情绪管理器 from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.message import MessageRecv from src.chat.message_receive.storage import MessageStorage @@ -73,7 +72,6 @@ class ChatBot: def __init__(self): self.bot = None # bot 实例引用 self._started = False - self.mood_manager = mood_manager # 获取情绪管理器单例 self.heartflow_message_receiver = HeartFCMessageReceiver() # 新增 async def _ensure_started(self): @@ -83,7 +81,7 @@ class ChatBot: self._started = True - async def _process_commands_with_new_system(self, message: MessageRecv): + async def _process_commands(self, message: MessageRecv): # sourcery skip: use-named-expression """使用新插件系统处理命令""" try: @@ -115,16 +113,21 @@ class ChatBot: try: # 执行命令 - success, response, intercept_message = await command_instance.execute() + success, response, intercept_message_level = await command_instance.execute() + message.intercept_message_level = intercept_message_level # 记录命令执行结果 if success: - logger.info(f"命令执行成功: {command_class.__name__} (拦截: {intercept_message})") + logger.info(f"命令执行成功: {command_class.__name__} (拦截等级: {intercept_message_level})") else: logger.warning(f"命令执行失败: {command_class.__name__} - {response}") # 根据命令的拦截设置决定是否继续处理消息 - return True, response, not intercept_message # 找到命令,根据intercept_message决定是否继续 + return ( + True, + response, + not bool(intercept_message_level), + ) # 找到命令,根据intercept_message决定是否继续 except Exception as e: logger.error(f"执行命令时出错: {command_class.__name__} - {e}") @@ -294,7 +297,7 @@ class ChatBot: # return # 命令处理 - 使用新插件系统检查并处理命令 - is_command, cmd_result, continue_process = await self._process_commands_with_new_system(message) + is_command, cmd_result, continue_process = await self._process_commands(message) # 如果是命令且不需要继续处理,则直接返回 if is_command and not continue_process: diff --git a/src/chat/message_receive/message.py b/src/chat/message_receive/message.py index 6c1ec1a7..d093e07e 100644 --- a/src/chat/message_receive/message.py +++ b/src/chat/message_receive/message.py @@ -122,6 +122,7 @@ class MessageRecv(Message): self.is_notify = False self.is_command = False + self.intercept_message_level = 0 self.priority_mode = "interest" self.priority_info = None @@ -212,6 +213,68 @@ class MessageRecv(Message): } """ return "" + elif segment.type == "video_card": + # 处理视频卡片消息 + self.is_picid = False + self.is_emoji = False + self.is_voice = False + if isinstance(segment.data, dict): + file_name = segment.data.get("file", "未知视频") + file_size = segment.data.get("file_size", "") + url = segment.data.get("url", "") + text = f"[视频: {file_name}" + if file_size: + text += f", 大小: {file_size}字节" + text += "]" + if url: + text += f" 链接: {url}" + return text + return "[视频]" + elif segment.type == "music_card": + # 处理音乐卡片消息 + self.is_picid = False + self.is_emoji = False + self.is_voice = False + if isinstance(segment.data, dict): + title = segment.data.get("title", "未知歌曲") + singer = segment.data.get("singer", "") + tag = segment.data.get("tag", "") # 音乐来源,如"网易云音乐" + jump_url = segment.data.get("jump_url", "") + music_url = segment.data.get("music_url", "") + text = f"[音乐: {title}" + if singer: + text += f" - {singer}" + if tag: + text += f" ({tag})" + text += "]" + if jump_url: + text += f" 跳转链接: {jump_url}" + if music_url: + text += f" 音乐链接: {music_url}" + return text + return "[音乐]" + elif segment.type == "miniapp_card": + # 处理小程序分享卡片(如B站视频分享) + self.is_picid = False + self.is_emoji = False + self.is_voice = False + if isinstance(segment.data, dict): + title = segment.data.get("title", "") # 小程序名称 + desc = segment.data.get("desc", "") # 内容描述 + source_url = segment.data.get("source_url", "") # 原始链接 + url = segment.data.get("url", "") # 小程序链接 + text = "[小程序分享" + if title: + text += f" - {title}" + text += "]" + if desc: + text += f" {desc}" + if source_url: + text += f" 链接: {source_url}" + elif url: + text += f" 链接: {url}" + return text + return "[小程序分享]" else: return "" except Exception as e: diff --git a/src/chat/message_receive/storage.py b/src/chat/message_receive/storage.py index 2abf4ce2..b73b04a3 100644 --- a/src/chat/message_receive/storage.py +++ b/src/chat/message_receive/storage.py @@ -33,6 +33,11 @@ class MessageStorage: async def store_message(message: Union[MessageSending, MessageRecv], chat_stream: ChatStream) -> None: """存储消息到数据库""" try: + # 通知消息不存储 + if isinstance(message, MessageRecv) and message.is_notify: + logger.debug("通知消息,跳过存储") + return + pattern = r".*?|.*?|.*?" # print(message) @@ -67,6 +72,7 @@ class MessageStorage: key_words = "" key_words_lite = "" selected_expressions = message.selected_expressions + intercept_message_level = 0 else: filtered_display_message = "" interest_value = message.interest_value @@ -80,6 +86,7 @@ class MessageStorage: is_picid = message.is_picid is_notify = message.is_notify is_command = message.is_command + intercept_message_level = getattr(message, "intercept_message_level", 0) # 序列化关键词列表为JSON字符串 key_words = MessageStorage._serialize_keywords(message.key_words) key_words_lite = MessageStorage._serialize_keywords(message.key_words_lite) @@ -131,6 +138,7 @@ class MessageStorage: is_picid=is_picid, is_notify=is_notify, is_command=is_command, + intercept_message_level=intercept_message_level, key_words=key_words, key_words_lite=key_words_lite, selected_expressions=selected_expressions, diff --git a/src/chat/message_receive/uni_message_sender.py b/src/chat/message_receive/uni_message_sender.py index 5a8ae022..b0a328e1 100644 --- a/src/chat/message_receive/uni_message_sender.py +++ b/src/chat/message_receive/uni_message_sender.py @@ -15,17 +15,237 @@ install(extra_lines=3) logger = get_logger("sender") +# WebUI 聊天室的消息广播器(延迟导入避免循环依赖) +_webui_chat_broadcaster = None + +# 虚拟群 ID 前缀(与 chat_routes.py 保持一致) +VIRTUAL_GROUP_ID_PREFIX = "webui_virtual_group_" + + +def get_webui_chat_broadcaster(): + """获取 WebUI 聊天室广播器""" + global _webui_chat_broadcaster + if _webui_chat_broadcaster is None: + try: + from src.webui.chat_routes import chat_manager, WEBUI_CHAT_PLATFORM + + _webui_chat_broadcaster = (chat_manager, WEBUI_CHAT_PLATFORM) + except ImportError: + _webui_chat_broadcaster = (None, None) + return _webui_chat_broadcaster + + +def is_webui_virtual_group(group_id: str) -> bool: + """检查是否是 WebUI 虚拟群""" + return group_id and group_id.startswith(VIRTUAL_GROUP_ID_PREFIX) + + +def parse_message_segments(segment) -> list: + """解析消息段,转换为 WebUI 可用的格式 + + 参考 NapCat 适配器的消息解析逻辑 + + Args: + segment: Seg 消息段对象 + + Returns: + list: 消息段列表,每个元素为 {"type": "...", "data": ...} + """ + + result = [] + + if segment is None: + return result + + if segment.type == "seglist": + # 处理消息段列表 + if segment.data: + for seg in segment.data: + result.extend(parse_message_segments(seg)) + elif segment.type == "text": + # 文本消息 + if segment.data: + result.append({"type": "text", "data": segment.data}) + elif segment.type == "image": + # 图片消息(base64) + if segment.data: + result.append({"type": "image", "data": f"data:image/png;base64,{segment.data}"}) + elif segment.type == "emoji": + # 表情包消息(base64) + if segment.data: + result.append({"type": "emoji", "data": f"data:image/gif;base64,{segment.data}"}) + elif segment.type == "imageurl": + # 图片链接消息 + if segment.data: + result.append({"type": "image", "data": segment.data}) + elif segment.type == "face": + # 原生表情 + result.append({"type": "face", "data": segment.data}) + elif segment.type == "voice": + # 语音消息(base64) + if segment.data: + result.append({"type": "voice", "data": f"data:audio/wav;base64,{segment.data}"}) + elif segment.type == "voiceurl": + # 语音链接 + if segment.data: + result.append({"type": "voice", "data": segment.data}) + elif segment.type == "video": + # 视频消息(base64) + if segment.data: + result.append({"type": "video", "data": f"data:video/mp4;base64,{segment.data}"}) + elif segment.type == "videourl": + # 视频链接 + if segment.data: + result.append({"type": "video", "data": segment.data}) + elif segment.type == "music": + # 音乐消息 + result.append({"type": "music", "data": segment.data}) + elif segment.type == "file": + # 文件消息 + result.append({"type": "file", "data": segment.data}) + elif segment.type == "reply": + # 回复消息 + result.append({"type": "reply", "data": segment.data}) + elif segment.type == "forward": + # 转发消息 + forward_items = [] + if segment.data: + for item in segment.data: + forward_items.append( + { + "content": parse_message_segments(item.get("message_segment", {})) + if isinstance(item, dict) + else [] + } + ) + result.append({"type": "forward", "data": forward_items}) + else: + # 未知类型,尝试作为文本处理 + if segment.data: + result.append({"type": "unknown", "original_type": segment.type, "data": str(segment.data)}) + + return result + async def _send_message(message: MessageSending, show_log=True) -> bool: """合并后的消息发送函数,包含WS发送和日志记录""" message_preview = truncate_message(message.processed_plain_text, max_length=200) + platform = message.message_info.platform + group_id = message.message_info.group_info.group_id if message.message_info.group_info else None try: - # 直接调用API发送消息 - await get_global_api().send_message(message) - if show_log: - logger.info(f"已将消息 '{message_preview}' 发往平台'{message.message_info.platform}'") - return True + # 检查是否是 WebUI 平台的消息,或者是 WebUI 虚拟群的消息 + chat_manager, webui_platform = get_webui_chat_broadcaster() + is_webui_message = (platform == webui_platform) or is_webui_virtual_group(group_id) + + if is_webui_message and chat_manager is not None: + # WebUI 聊天室消息(包括虚拟身份模式),通过 WebSocket 广播 + import time + from src.config.config import global_config + + # 解析消息段,获取富文本内容 + message_segments = parse_message_segments(message.message_segment) + + # 判断消息类型 + # 如果只有一个文本段,使用简单的 text 类型 + # 否则使用 rich 类型,包含完整的消息段 + if len(message_segments) == 1 and message_segments[0].get("type") == "text": + message_type = "text" + segments = None + else: + message_type = "rich" + segments = message_segments + + await chat_manager.broadcast( + { + "type": "bot_message", + "content": message.processed_plain_text, + "message_type": message_type, + "segments": segments, # 富文本消息段 + "timestamp": time.time(), + "group_id": group_id, # 包含群 ID 以便前端区分不同的聊天标签 + "sender": { + "name": global_config.bot.nickname, + "avatar": None, + "is_bot": True, + }, + } + ) + + # 注意:机器人消息会由 MessageStorage.store_message 自动保存到数据库 + # 无需手动保存 + + if show_log: + if is_webui_virtual_group(group_id): + logger.info(f"已将消息 '{message_preview}' 发往 WebUI 虚拟群 (平台: {platform})") + else: + logger.info(f"已将消息 '{message_preview}' 发往 WebUI 聊天室") + return True + + # Fallback 逻辑: 尝试通过 API Server 发送 + async def send_with_new_api(legacy_exception=None): + try: + from src.config.config import global_config + + # 如果未开启 API Server,直接跳过 Fallback + if not global_config.maim_message.enable_api_server: + if legacy_exception: + raise legacy_exception + return False + + global_api = get_global_api() + extra_server = getattr(global_api, "extra_server", None) + + if extra_server and extra_server.is_running(): + # Fallback: 使用极其简单的 Platform -> API Key 映射 + # 只有收到过该平台的消息,我们才知道该平台的 API Key,才能回传消息 + platform_map = getattr(global_api, "platform_map", {}) + target_api_key = platform_map.get(platform) + + if target_api_key: + # 构造 APIMessageBase + from maim_message.message import APIMessageBase, MessageDim + + msg_dim = MessageDim(api_key=target_api_key, platform=platform) + + api_message = APIMessageBase( + message_info=message.message_info, + message_segment=message.message_segment, + message_dim=msg_dim, + ) + + # 直接调用 Server 的 send_message 接口,它会自动处理路由 + results = await extra_server.send_message(api_message) + + # 检查是否有任何连接发送成功 + if any(results.values()): + if show_log: + logger.info( + f"已通过API Server Fallback将消息 '{message_preview}' 发往平台'{platform}' (key: {target_api_key})" + ) + return True + except Exception: + pass + + # 如果 Fallback 失败,且存在 legacy 异常,则抛出 legacy 异常 + if legacy_exception: + raise legacy_exception + return False + + try: + send_result = await get_global_api().send_message(message) + # if send_result: + if show_log: + logger.info(f"已将消息 '{message_preview}' 发往平台'{message.message_info.platform}'") + return True + + # Legacy API 返回 False (发送失败但未报错),尝试 Fallback + # return await send_with_new_api() + + except Exception as legacy_e: + # Legacy API 抛出异常,尝试 Fallback + # 如果 Fallback 也失败,将重新抛出 legacy_e + return await send_with_new_api(legacy_exception=legacy_e) except Exception as e: logger.error(f"发送消息 '{message_preview}' 发往平台'{message.message_info.platform}' 失败: {str(e)}") diff --git a/src/chat/planner_actions/action_modifier.py b/src/chat/planner_actions/action_modifier.py index def8322a..baf1e1c5 100644 --- a/src/chat/planner_actions/action_modifier.py +++ b/src/chat/planner_actions/action_modifier.py @@ -69,6 +69,7 @@ class ActionModifier: chat_id=self.chat_stream.stream_id, timestamp=time.time(), limit=min(int(global_config.chat.max_context_size * 0.33), 10), + filter_intercept_message_level=1, ) chat_content = build_readable_messages( diff --git a/src/chat/planner_actions/planner.py b/src/chat/planner_actions/planner.py index 5771feed..645ee003 100644 --- a/src/chat/planner_actions/planner.py +++ b/src/chat/planner_actions/planner.py @@ -15,12 +15,15 @@ from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.chat_message_builder import ( build_readable_messages_with_id, get_raw_msg_before_timestamp_with_chat, + replace_user_references, ) from src.chat.utils.utils import get_chat_type_and_target_info from src.chat.planner_actions.action_manager import ActionManager from src.chat.message_receive.chat_stream import get_chat_manager from src.plugin_system.base.component_types import ActionInfo, ComponentType, ActionActivationType from src.plugin_system.core.component_registry import component_registry +from src.plugin_system.apis.message_api import translate_pid_to_description +from src.person_info.person_info import Person if TYPE_CHECKING: from src.common.data_models.info_data_model import TargetPersonInfo @@ -36,7 +39,6 @@ def init_prompt(): """ {time_block} {name_block} -你的兴趣是:{interest} {chat_context_description},以下是具体的聊天内容 **聊天内容** {chat_content_block} @@ -46,9 +48,12 @@ reply 动作描述: 1.你可以选择呼叫了你的名字,但是你没有做出回应的消息进行回复 2.你可以自然的顺着正在进行的聊天内容进行回复或自然的提出一个问题 -3.不要回复你自己发送的消息 -4.不要单独对表情包进行回复 -{{"action":"reply", "target_message_id":"消息id(m+数字)", "reason":"原因"}} +3.最好一次对一个话题进行回复,免得啰嗦或者回复内容太乱。 +4.不要选择回复你自己发送的消息 +5.不要单独对表情包进行回复 +6.将上下文中所有含义不明的,疑似黑话的,缩写词均写入unknown_words中 +7.用一句简单的话来描述当前回复场景,不超过10个字 +{reply_action_example} no_reply 动作描述: @@ -56,75 +61,37 @@ no_reply 控制聊天频率,不要太过频繁的发言 {{"action":"no_reply"}} -{no_reply_until_call_block} - {action_options_text} - **你之前的action执行和思考记录** {actions_before_now_block} 请选择**可选的**且符合使用条件的action,并说明触发action的消息id(消息id格式:m+数字) -不要回复你自己发送的消息 先输出你的简短的选择思考理由,再输出你选择的action,理由不要分点,精简。 **动作选择要求** 请你根据聊天内容,用户的最新消息和以下标准选择合适的动作: {plan_style} {moderation_prompt} -请选择所有符合使用要求的action,动作用json格式输出,用```json包裹,如果输出多个json,每个json都要单独一行放在同一个```json代码块内,你可以重复使用同一个动作或不同动作: +target_message_id为必填,表示触发消息的id +请选择所有符合使用要求的action,每个动作最多选择一次,但是可以选择多个动作; +动作用json格式输出,用```json包裹,如果输出多个json,每个json都要单独一行放在同一个```json代码块内: **示例** // 理由文本(简短) ```json -{{"action":"动作名", "target_message_id":"m123", "reason":"原因"}} -{{"action":"动作名", "target_message_id":"m456", "reason":"原因"}} +{{"action":"动作名", "target_message_id":"m123", .....}} +{{"action":"动作名", "target_message_id":"m456", .....}} ```""", "planner_prompt", ) - Prompt( - """{time_block} -{name_block} -{chat_context_description},以下是具体的聊天内容 -**聊天内容** -{chat_content_block} - -**可选的action** -no_reply -动作描述: -没有合适的可以使用的动作,不使用action -{{"action":"no_reply"}} - -{action_options_text} - -**你之前的action执行和思考记录** -{actions_before_now_block} - -请选择**可选的**且符合使用条件的action,并说明触发action的消息id(消息id格式:m+数字) -先输出你的简短的选择思考理由,再输出你选择的action,理由不要分点,精简。 -**动作选择要求** -请你根据聊天内容,用户的最新消息和以下标准选择合适的动作: -1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 -2.如果相同的内容已经被执行,请不要重复执行 -{moderation_prompt} - -请选择所有符合使用要求的action,动作用json格式输出,用```json包裹,如果输出多个json,每个json都要单独一行放在同一个```json代码块内,你可以重复使用同一个动作或不同动作: -**示例** -// 理由文本(简短) -```json -{{"action":"动作名", "target_message_id":"m123", "reason":"原因"}} -{{"action":"动作名", "target_message_id":"m456", "reason":"原因"}} -```""", - "planner_prompt_mentioned", - ) - Prompt( """ {action_name} 动作描述:{action_description} 使用条件{parallel_text}: {action_require} -{{"action":"{action_name}",{action_parameters}, "target_message_id":"消息id(m+数字)", "reason":"原因"}} +{{"action":"{action_name}",{action_parameters}, "target_message_id":"消息id(m+数字)"}} """, "action_prompt", ) @@ -181,8 +148,12 @@ class ActionPlanner: found_ids = set(matches) missing_ids = found_ids - available_ids if missing_ids: - logger.info(f"{self.log_prefix}planner理由中引用的消息ID不在当前上下文中: {missing_ids}, 可用ID: {list(available_ids)[:10]}...") - logger.info(f"{self.log_prefix}planner理由替换: 找到{len(matches)}个消息ID引用,其中{len(found_ids & available_ids)}个在上下文中") + logger.info( + f"{self.log_prefix}planner理由中引用的消息ID不在当前上下文中: {missing_ids}, 可用ID: {list(available_ids)[:10]}..." + ) + logger.info( + f"{self.log_prefix}planner理由替换: 找到{len(matches)}个消息ID引用,其中{len(found_ids & available_ids)}个在上下文中" + ) def _replace(match: re.Match[str]) -> str: msg_id = match.group(0) @@ -191,11 +162,41 @@ class ActionPlanner: logger.warning(f"{self.log_prefix}planner理由引用 {msg_id} 未找到对应消息,保持原样") return msg_id - msg_text = (message.processed_plain_text or message.display_message or "").strip() + msg_text = (message.processed_plain_text or "").strip() if not msg_text: logger.warning(f"{self.log_prefix}planner理由引用 {msg_id} 的消息内容为空,保持原样") return msg_id + # 替换 [picid:xxx] 为 [图片:描述] + pic_pattern = r"\[picid:([^\]]+)\]" + def replace_pic_id(pic_match: re.Match) -> str: + pic_id = pic_match.group(1) + description = translate_pid_to_description(pic_id) + return f"[图片:{description}]" + msg_text = re.sub(pic_pattern, replace_pic_id, msg_text) + + # 替换用户引用格式:回复 和 @ + platform = getattr(message, "user_info", None) and message.user_info.platform or getattr(message, "chat_info", None) and message.chat_info.platform or "qq" + msg_text = replace_user_references(msg_text, platform, replace_bot_name=True) + + # 替换单独的 <用户名:用户ID> 格式(replace_user_references 已处理回复<和@<格式) + # 匹配所有 格式,由于 replace_user_references 已经替换了回复<和@<格式, + # 这里匹配到的应该都是单独的格式 + user_ref_pattern = r"<([^:<>]+):([^:<>]+)>" + def replace_user_ref(user_match: re.Match) -> str: + user_name = user_match.group(1) + user_id = user_match.group(2) + try: + # 检查是否是机器人自己 + if user_id == global_config.bot.qq_account: + return f"{global_config.bot.nickname}(你)" + person = Person(platform=platform, user_id=user_id) + return person.person_name or user_name + except Exception: + # 如果解析失败,使用原始昵称 + return user_name + msg_text = re.sub(user_ref_pattern, replace_user_ref, msg_text) + preview = msg_text if len(msg_text) <= 100 else f"{msg_text[:97]}..." logger.info(f"{self.log_prefix}planner理由引用 {msg_id} -> 消息({preview})") return f"消息({msg_text})" @@ -214,15 +215,19 @@ class ActionPlanner: try: action = action_json.get("action", "no_reply") - original_reasoning = action_json.get("reason", "未提供原因") - reasoning = self._replace_message_ids_with_text(original_reasoning, message_id_list) - if reasoning is None: - reasoning = original_reasoning - action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]} + # 使用 extracted_reasoning(整体推理文本)作为 reasoning + if extracted_reasoning: + reasoning = self._replace_message_ids_with_text(extracted_reasoning, message_id_list) + if reasoning is None: + reasoning = extracted_reasoning + else: + reasoning = "未提供原因" + action_data = {key: value for key, value in action_json.items() if key not in ["action"]} # 非no_reply动作需要target_message_id target_message = None - if target_message_id := action_json.get("target_message_id"): + target_message_id = action_json.get("target_message_id") + if target_message_id: # 根据target_message_id查找原始消息 target_message = self.find_message_by_id(target_message_id, message_id_list) if target_message is None: @@ -233,9 +238,17 @@ class ActionPlanner: target_message = message_id_list[-1][1] logger.debug(f"{self.log_prefix}动作'{action}'缺少target_message_id,使用最新消息作为target_message") + if action != "no_reply" and target_message is not None and self._is_message_from_self(target_message): + logger.info( + f"{self.log_prefix}Planner选择了自己的消息 {target_message_id or target_message.message_id} 作为目标,强制使用 no_reply" + ) + reasoning = f"目标消息 {target_message_id or target_message.message_id} 来自机器人自身,违反不回复自身消息规则。原始理由: {reasoning}" + action = "no_reply" + target_message = None + # 验证action是否可用 available_action_names = [action_name for action_name, _ in current_available_actions] - internal_action_names = ["no_reply", "reply", "wait_time", "no_reply_until_call"] + internal_action_names = ["no_reply", "reply", "wait_time"] if action not in internal_action_names and action not in available_action_names: logger.warning( @@ -277,11 +290,21 @@ class ActionPlanner: return action_planner_infos + def _is_message_from_self(self, message: "DatabaseMessages") -> bool: + """判断消息是否由机器人自身发送""" + try: + return str(message.user_info.user_id) == str(global_config.bot.qq_account) and ( + message.user_info.platform or "" + ) == (global_config.bot.platform or "") + except AttributeError: + logger.warning(f"{self.log_prefix}检测消息发送者失败,缺少必要字段") + return False + async def plan( self, available_actions: Dict[str, ActionInfo], loop_start_time: float = 0.0, - is_mentioned: bool = False, + force_reply_message: Optional["DatabaseMessages"] = None, ) -> List[ActionPlannerInfo]: # sourcery skip: use-named-expression """ @@ -293,6 +316,7 @@ class ActionPlanner: chat_id=self.chat_id, timestamp=time.time(), limit=int(global_config.chat.max_context_size * 0.6), + filter_intercept_message_level=1, ) message_id_list: list[Tuple[str, "DatabaseMessages"]] = [] chat_content_block, message_id_list = build_readable_messages_with_id( @@ -321,11 +345,6 @@ class ActionPlanner: logger.debug(f"{self.log_prefix}过滤后有{len(filtered_actions)}个可用动作") - # 如果是提及时且没有可用动作,直接返回空列表,不调用LLM以节省token - if is_mentioned and not filtered_actions: - logger.info(f"{self.log_prefix}提及时没有可用动作,跳过plan调用") - return [] - # 构建包含所有动作的提示词 prompt, message_id_list = await self.build_planner_prompt( is_group_chat=is_group_chat, @@ -333,8 +352,6 @@ class ActionPlanner: current_available_actions=filtered_actions, chat_content_block=chat_content_block, message_id_list=message_id_list, - interest=global_config.personality.interest, - is_mentioned=is_mentioned, ) # 调用LLM获取决策 @@ -346,6 +363,34 @@ class ActionPlanner: loop_start_time=loop_start_time, ) + # 如果有强制回复消息,确保回复该消息 + if force_reply_message: + # 检查是否已经有回复该消息的 action + has_reply_to_force_message = False + for action in actions: + if action.action_type == "reply" and action.action_message and action.action_message.message_id == force_reply_message.message_id: + has_reply_to_force_message = True + break + + # 如果没有回复该消息,强制添加回复 action + if not has_reply_to_force_message: + # 移除所有 no_reply action(如果有) + actions = [a for a in actions if a.action_type != "no_reply"] + + # 创建强制回复 action + available_actions_dict = dict(current_available_actions) + force_reply_action = ActionPlannerInfo( + action_type="reply", + reasoning="用户提及了我,必须回复该消息", + action_data={"loop_start_time": loop_start_time}, + action_message=force_reply_message, + available_actions=available_actions_dict, + action_reasoning=None, + ) + # 将强制回复 action 放在最前面 + actions.insert(0, force_reply_action) + logger.info(f"{self.log_prefix} 检测到强制回复消息,已添加回复动作") + logger.info( f"{self.log_prefix}Planner:{reasoning}。选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}" ) @@ -406,32 +451,6 @@ class ActionPlanner: return plan_log_str - def _has_consecutive_no_reply(self, min_count: int = 3) -> bool: - """ - 检查是否有连续min_count次以上的no_reply - - Args: - min_count: 需要连续的最少次数,默认3 - - Returns: - 如果有连续min_count次以上no_reply返回True,否则返回False - """ - consecutive_count = 0 - - # 从后往前遍历plan_log,检查最新的连续记录 - for _reasoning, _timestamp, content in reversed(self.plan_log): - if isinstance(content, list) and all(isinstance(action, ActionPlannerInfo) for action in content): - # 检查所有action是否都是no_reply - if all(action.action_type == "no_reply" for action in content): - consecutive_count += 1 - if consecutive_count >= min_count: - return True - else: - # 如果遇到非no_reply的action,重置计数 - break - - return False - async def build_planner_prompt( self, is_group_chat: bool, @@ -440,7 +459,6 @@ class ActionPlanner: message_id_list: List[Tuple[str, "DatabaseMessages"]], chat_content_block: str = "", interest: str = "", - is_mentioned: bool = False, ) -> tuple[str, List[Tuple[str, "DatabaseMessages"]]]: """构建 Planner LLM 的提示词 (获取模板并填充数据)""" try: @@ -461,48 +479,35 @@ class ActionPlanner: ) name_block = f"你的名字是{bot_name}{bot_nickname},请注意哪些是你自己的发言。" - # 根据是否是提及时选择不同的模板 - if is_mentioned: - # 提及时使用简化版提示词,不需要reply、no_reply、no_reply_until_call - planner_prompt_template = await global_prompt_manager.get_prompt_async("planner_prompt_mentioned") - prompt = planner_prompt_template.format( - time_block=time_block, - chat_context_description=chat_context_description, - chat_content_block=chat_content_block, - actions_before_now_block=actions_before_now_block, - action_options_text=action_options_block, - moderation_prompt=moderation_prompt_block, - name_block=name_block, - interest=interest, - plan_style=global_config.personality.plan_style, + # 根据 think_mode 配置决定 reply action 的示例 JSON + # 在 JSON 中直接作为 action 参数携带 unknown_words + if global_config.chat.think_mode == "classic": + reply_action_example = ( + '{{"action":"reply", "target_message_id":"消息id(m+数字)", ' + '"unknown_words":["词语1","词语2"]}}' ) else: - # 正常流程使用完整版提示词 - # 检查是否有连续3次以上no_reply,如果有则添加no_reply_until_call选项 - no_reply_until_call_block = "" - if self._has_consecutive_no_reply(min_count=3): - no_reply_until_call_block = """no_reply_until_call -动作描述: -保持沉默,直到有人直接叫你的名字 -当前话题不感兴趣时使用,或有人不喜欢你的发言时使用 -当你频繁选择no_reply时使用,表示话题暂时与你无关 -{{"action":"no_reply_until_call"}} -""" - - planner_prompt_template = await global_prompt_manager.get_prompt_async("planner_prompt") - prompt = planner_prompt_template.format( - time_block=time_block, - chat_context_description=chat_context_description, - chat_content_block=chat_content_block, - actions_before_now_block=actions_before_now_block, - action_options_text=action_options_block, - no_reply_until_call_block=no_reply_until_call_block, - moderation_prompt=moderation_prompt_block, - name_block=name_block, - interest=interest, - plan_style=global_config.personality.plan_style, + reply_action_example = ( + "5.think_level表示思考深度,0表示该回复不需要思考和回忆,1表示该回复需要进行回忆和思考\n" + + '{{"action":"reply", "think_level":数值等级(0或1), ' + '"target_message_id":"消息id(m+数字)", ' + '"unknown_words":["词语1","词语2"]}}' ) + planner_prompt_template = await global_prompt_manager.get_prompt_async("planner_prompt") + prompt = planner_prompt_template.format( + time_block=time_block, + chat_context_description=chat_context_description, + chat_content_block=chat_content_block, + actions_before_now_block=actions_before_now_block, + action_options_text=action_options_block, + moderation_prompt=moderation_prompt_block, + name_block=name_block, + interest=interest, + plan_style=global_config.personality.plan_style, + reply_action_example=reply_action_example, + ) + return prompt, message_id_list except Exception as e: logger.error(f"构建 Planner 提示词时出错: {e}") @@ -672,6 +677,12 @@ class ActionPlanner: action.action_data = action.action_data or {} action.action_data["loop_start_time"] = loop_start_time + # 去重:如果同一个动作被选择了多次,随机选择其中一个 + if actions: + shuffled = actions.copy() + random.shuffle(shuffled) + actions = list({a.action_type: a for a in shuffled}.values()) + logger.debug(f"{self.log_prefix}规划器选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}") return extracted_reasoning, actions @@ -723,28 +734,88 @@ class ActionPlanner: # 尝试解析每一行作为独立的JSON对象 json_obj = json.loads(repair_json(line)) if isinstance(json_obj, dict): - json_objects.append(json_obj) + # 过滤掉空字典,避免单个 { 字符被错误修复为 {} 的情况 + if json_obj: + json_objects.append(json_obj) elif isinstance(json_obj, list): for item in json_obj: - if isinstance(item, dict): + if isinstance(item, dict) and item: json_objects.append(item) except json.JSONDecodeError: # 如果单行解析失败,尝试将整个块作为一个JSON对象或数组 pass - # 如果按行解析没有成功,尝试将整个块作为一个JSON对象或数组 + # 如果按行解析没有成功(或只得到空字典),尝试将整个块作为一个JSON对象或数组 if not json_objects: json_obj = json.loads(repair_json(json_str)) if isinstance(json_obj, dict): - json_objects.append(json_obj) + # 过滤掉空字典 + if json_obj: + json_objects.append(json_obj) elif isinstance(json_obj, list): for item in json_obj: - if isinstance(item, dict): + if isinstance(item, dict) and item: json_objects.append(item) except Exception as e: logger.warning(f"解析JSON块失败: {e}, 块内容: {match[:100]}...") continue + # 如果没有找到完整的```json```块,尝试查找不完整的代码块(缺少结尾```) + if not json_objects: + json_start_pos = content.find("```json") + if json_start_pos != -1: + # 找到```json之后的内容 + json_content_start = json_start_pos + 7 # ```json的长度 + # 提取从```json之后到内容结尾的所有内容 + incomplete_json_str = content[json_content_start:].strip() + + # 提取JSON之前的内容作为推理文本 + if json_start_pos > 0: + reasoning_content = content[:json_start_pos].strip() + reasoning_content = re.sub(r"^//\s*", "", reasoning_content, flags=re.MULTILINE) + reasoning_content = reasoning_content.strip() + + if incomplete_json_str: + try: + # 清理可能的注释和格式问题 + json_str = re.sub(r"//.*?\n", "\n", incomplete_json_str) + json_str = re.sub(r"/\*.*?\*/", "", json_str, flags=re.DOTALL) + json_str = json_str.strip() + + if json_str: + # 尝试按行分割,每行可能是一个JSON对象 + lines = [line.strip() for line in json_str.split("\n") if line.strip()] + for line in lines: + try: + json_obj = json.loads(repair_json(line)) + if isinstance(json_obj, dict): + # 过滤掉空字典,避免单个 { 字符被错误修复为 {} 的情况 + if json_obj: + json_objects.append(json_obj) + elif isinstance(json_obj, list): + for item in json_obj: + if isinstance(item, dict) and item: + json_objects.append(item) + except json.JSONDecodeError: + pass + + # 如果按行解析没有成功(或只得到空字典),尝试将整个块作为一个JSON对象或数组 + if not json_objects: + try: + json_obj = json.loads(repair_json(json_str)) + if isinstance(json_obj, dict): + # 过滤掉空字典 + if json_obj: + json_objects.append(json_obj) + elif isinstance(json_obj, list): + for item in json_obj: + if isinstance(item, dict) and item: + json_objects.append(item) + except Exception as e: + logger.debug(f"尝试解析不完整的JSON代码块失败: {e}") + except Exception as e: + logger.debug(f"处理不完整的JSON代码块时出错: {e}") + return json_objects, reasoning_content diff --git a/src/chat/replyer/group_generator.py b/src/chat/replyer/group_generator.py index cc948db1..1ec04556 100644 --- a/src/chat/replyer/group_generator.py +++ b/src/chat/replyer/group_generator.py @@ -18,13 +18,12 @@ from src.chat.message_receive.uni_message_sender import UniversalMessageSender from src.chat.utils.timer_calculator import Timer # <--- Import Timer from src.chat.utils.utils import get_chat_type_and_target_info from src.chat.utils.prompt_builder import global_prompt_manager -from src.mood.mood_manager import mood_manager from src.chat.utils.chat_message_builder import ( build_readable_messages, get_raw_msg_before_timestamp_with_chat, replace_user_references, ) -from src.express.expression_selector import expression_selector +from src.bw_learner.expression_selector import expression_selector from src.plugin_system.apis.message_api import translate_pid_to_description # from src.memory_system.memory_activator import MemoryActivator @@ -36,6 +35,7 @@ from src.chat.replyer.prompt.lpmm_prompt import init_lpmm_prompt from src.chat.replyer.prompt.replyer_prompt import init_replyer_prompt from src.chat.replyer.prompt.rewrite_prompt import init_rewrite_prompt from src.memory_system.memory_retrieval import init_memory_retrieval_prompt, build_memory_retrieval_prompt +from src.bw_learner.jargon_explainer import explain_jargon_in_context, retrieve_concepts_with_jargon init_lpmm_prompt() init_replyer_prompt() @@ -72,6 +72,8 @@ class DefaultReplyer: stream_id: Optional[str] = None, reply_message: Optional[DatabaseMessages] = None, reply_time_point: Optional[float] = time.time(), + think_level: int = 1, + unknown_words: Optional[List[str]] = None, ) -> Tuple[bool, LLMGenerationDataModel]: # sourcery skip: merge-nested-ifs """ @@ -97,8 +99,10 @@ class DefaultReplyer: available_actions = {} try: # 3. 构建 Prompt + timing_logs = [] + almost_zero_str = "" with Timer("构建Prompt", {}): # 内部计时器,可选保留 - prompt, selected_expressions = await self.build_prompt_reply_context( + prompt, selected_expressions, timing_logs, almost_zero_str = await self.build_prompt_reply_context( extra_info=extra_info, available_actions=available_actions, chosen_actions=chosen_actions, @@ -106,6 +110,8 @@ class DefaultReplyer: reply_message=reply_message, reply_reason=reply_reason, reply_time_point=reply_time_point, + think_level=think_level, + unknown_words=unknown_words, ) llm_response.prompt = prompt llm_response.selected_expressions = selected_expressions @@ -134,10 +140,22 @@ class DefaultReplyer: content, reasoning_content, model_name, tool_call = await self.llm_generate_content(prompt) # logger.debug(f"replyer生成内容: {content}") - logger.info(f"replyer生成内容: {content}") - if global_config.debug.show_replyer_reasoning: - logger.info(f"replyer生成推理:\n{reasoning_content}") - logger.info(f"replyer生成模型: {model_name}") + # 统一输出所有日志信息,使用try-except确保即使某个步骤出错也能输出 + try: + # 1. 输出回复准备日志 + timing_log_str = f"回复准备: {'; '.join(timing_logs)}; {almost_zero_str} <0.1s" if timing_logs or almost_zero_str else "回复准备: 无计时信息" + logger.info(timing_log_str) + # 2. 输出Prompt日志 + if global_config.debug.show_replyer_prompt: + logger.info(f"\n{prompt}\n") + else: + logger.debug(f"\nreplyer_Prompt:{prompt}\n") + # 3. 输出模型生成内容和推理日志 + logger.info(f"模型: [{model_name}][思考等级:{think_level}]生成内容: {content}") + if global_config.debug.show_replyer_reasoning and reasoning_content: + logger.info(f"模型: [{model_name}][思考等级:{think_level}]生成推理:\n{reasoning_content}") + except Exception as e: + logger.warning(f"输出日志时出错: {e}") llm_response.content = content llm_response.reasoning = reasoning_content @@ -161,6 +179,21 @@ class DefaultReplyer: except Exception as llm_e: # 精简报错信息 logger.error(f"LLM 生成失败: {llm_e}") + # 即使LLM生成失败,也尝试输出已收集的日志信息 + try: + # 1. 输出回复准备日志 + timing_log_str = f"回复准备: {'; '.join(timing_logs)}; {almost_zero_str} <0.1s" if timing_logs or almost_zero_str else "回复准备: 无计时信息" + logger.info(timing_log_str) + # 2. 输出Prompt日志 + if global_config.debug.show_replyer_prompt: + logger.info(f"\n{prompt}\n") + else: + logger.debug(f"\nreplyer_Prompt:{prompt}\n") + # 3. 输出模型生成失败信息 + logger.info("模型生成失败,无法输出生成内容和推理") + except Exception as log_e: + logger.warning(f"输出日志时出错: {log_e}") + return False, llm_response # LLM 调用失败则无法生成回复 return True, llm_response @@ -227,7 +260,7 @@ class DefaultReplyer: return False, llm_response async def build_expression_habits( - self, chat_history: str, target: str, reply_reason: str = "" + self, chat_history: str, target: str, reply_reason: str = "", think_level: int = 1 ) -> Tuple[str, List[int]]: # sourcery skip: for-append-to-extend """构建表达习惯块 @@ -236,6 +269,7 @@ class DefaultReplyer: chat_history: 聊天历史记录 target: 目标消息内容 reply_reason: planner给出的回复理由 + think_level: 思考级别,0/1/2 Returns: str: 表达习惯信息字符串 @@ -248,14 +282,19 @@ class DefaultReplyer: # 使用从处理器传来的选中表达方式 # 使用模型预测选择表达方式 selected_expressions, selected_ids = await expression_selector.select_suitable_expressions( - self.chat_stream.stream_id, chat_history, max_num=8, target_message=target, reply_reason=reply_reason + self.chat_stream.stream_id, + chat_history, + max_num=8, + target_message=target, + reply_reason=reply_reason, + think_level=think_level, ) if selected_expressions: logger.debug(f"使用处理器选中的{len(selected_expressions)}个表达方式") for expr in selected_expressions: if isinstance(expr, dict) and "situation" in expr and "style" in expr: - style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}") + style_habits.append(f"当{expr['situation']}时:{expr['style']}") else: logger.debug("没有从处理器获得表达方式,将使用空的表达方式") # 不再在replyer中进行随机选择,全部交给处理器处理 @@ -271,13 +310,6 @@ class DefaultReplyer: return f"{expression_habits_title}\n{expression_habits_block}", selected_ids - async def build_mood_state_prompt(self) -> str: - """构建情绪状态提示""" - if not global_config.mood.enable_mood: - return "" - mood_state = await mood_manager.get_mood_by_chat_id(self.chat_stream.stream_id).get_mood() - return f"你现在的心情是:{mood_state}" - async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str: """构建工具信息块 @@ -458,6 +490,57 @@ class DefaultReplyer: duration = end_time - start_time return name, result, duration + async def _build_disabled_jargon_explanation(self) -> str: + """当关闭黑话解释时使用的占位协程,避免额外的LLM调用""" + return "" + + async def _build_unknown_words_jargon(self, unknown_words: Optional[List[str]], chat_id: str) -> str: + """针对 Planner 提供的未知词语列表执行黑话检索""" + if not unknown_words: + return "" + # 清洗未知词语列表,只保留非空字符串 + concepts: List[str] = [] + for item in unknown_words: + if isinstance(item, str): + s = item.strip() + if s: + concepts.append(s) + if not concepts: + return "" + try: + return await retrieve_concepts_with_jargon(concepts, chat_id) + except Exception as e: + logger.error(f"未知词语黑话检索失败: {e}") + return "" + + async def _build_jargon_explanation( + self, + chat_id: str, + messages_short: List[DatabaseMessages], + chat_talking_prompt_short: str, + unknown_words: Optional[List[str]], + ) -> str: + """ + 统一的黑话解释构建函数: + - 根据 enable_jargon_explanation / jargon_mode 决定具体策略 + """ + enable_jargon_explanation = getattr(global_config.expression, "enable_jargon_explanation", True) + if not enable_jargon_explanation: + return "" + + jargon_mode = getattr(global_config.expression, "jargon_mode", "context") + + # planner 模式:仅使用 Planner 的 unknown_words + if jargon_mode == "planner": + return await self._build_unknown_words_jargon(unknown_words, chat_id) + + # 默认 / context 模式:使用上下文自动匹配黑话 + try: + return await explain_jargon_in_context(chat_id, messages_short, chat_talking_prompt_short) + except Exception as e: + logger.error(f"上下文黑话解释失败: {e}") + return "" + def build_chat_history_prompts( self, message_list_before_now: List[DatabaseMessages], target_user_id: str, sender: str ) -> Tuple[str, str]: @@ -605,7 +688,7 @@ class DefaultReplyer: # 获取基础personality prompt_personality = global_config.personality.personality - # 检查是否需要随机替换为状态 + # 检查是否需要随机替换为状态(personality 本体) if ( global_config.personality.states and global_config.personality.state_probability > 0 @@ -642,16 +725,10 @@ class DefaultReplyer: # 判断是否为群聊 is_group = stream_type == "group" - # 使用与 ChatStream.get_stream_id 相同的逻辑生成 chat_id - import hashlib - - if is_group: - components = [platform, str(id_str)] - else: - components = [platform, str(id_str), "private"] - key = "_".join(components) - chat_id = hashlib.md5(key.encode()).hexdigest() + # 使用 ChatManager 提供的接口生成 chat_id,避免在此重复实现逻辑 + from src.chat.message_receive.chat_stream import get_chat_manager + chat_id = get_chat_manager().get_stream_id(platform, str(id_str), is_group=is_group) return chat_id, prompt_content except (ValueError, IndexError): @@ -704,7 +781,9 @@ class DefaultReplyer: chosen_actions: Optional[List[ActionPlannerInfo]] = None, enable_tool: bool = True, reply_time_point: Optional[float] = time.time(), - ) -> Tuple[str, List[int]]: + think_level: int = 1, + unknown_words: Optional[List[str]] = None, + ) -> Tuple[str, List[int], List[str], str]: """ 构建回复器上下文 @@ -750,12 +829,14 @@ class DefaultReplyer: chat_id=chat_id, timestamp=reply_time_point, limit=global_config.chat.max_context_size * 1, + filter_intercept_message_level=1, ) message_list_before_short = get_raw_msg_before_timestamp_with_chat( chat_id=chat_id, timestamp=reply_time_point, limit=int(global_config.chat.max_context_size * 0.33), + filter_intercept_message_level=1, ) person_list_short: List[Person] = [] @@ -786,10 +867,16 @@ class DefaultReplyer: show_actions=True, ) - # 并行执行七个构建任务 + # 统一黑话解释构建:根据配置选择上下文或 Planner 模式 + jargon_coroutine = self._build_jargon_explanation( + chat_id, message_list_before_short, chat_talking_prompt_short, unknown_words + ) + + # 并行执行构建任务(包括黑话解释,可配置关闭) task_results = await asyncio.gather( self._time_and_run_task( - self.build_expression_habits(chat_talking_prompt_short, target, reply_reason), "expression_habits" + self.build_expression_habits(chat_talking_prompt_short, target, reply_reason, think_level=think_level), + "expression_habits", ), self._time_and_run_task( self.build_tool_info(chat_talking_prompt_short, sender, target, enable_tool=enable_tool), "tool_info" @@ -797,13 +884,13 @@ class DefaultReplyer: self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"), self._time_and_run_task(self.build_actions_prompt(available_actions, chosen_actions), "actions_info"), self._time_and_run_task(self.build_personality_prompt(), "personality_prompt"), - self._time_and_run_task(self.build_mood_state_prompt(), "mood_state_prompt"), self._time_and_run_task( build_memory_retrieval_prompt( - chat_talking_prompt_short, sender, target, self.chat_stream, self.tool_executor + chat_talking_prompt_short, sender, target, self.chat_stream, think_level=think_level ), "memory_retrieval", ), + self._time_and_run_task(jargon_coroutine, "jargon_explanation"), ) # 任务名称中英文映射 @@ -814,8 +901,8 @@ class DefaultReplyer: "prompt_info": "获取知识", "actions_info": "动作信息", "personality_prompt": "人格信息", - "mood_state_prompt": "情绪状态", "memory_retrieval": "记忆检索", + "jargon_explanation": "黑话解释", } # 处理结果 @@ -831,9 +918,8 @@ class DefaultReplyer: continue timing_logs.append(f"{chinese_name}: {duration:.1f}s") - if duration > 12: - logger.warning(f"回复生成前信息获取耗时过长: {chinese_name} 耗时: {duration:.1f}s,请使用更快的模型") - logger.info(f"回复准备: {'; '.join(timing_logs)}; {almost_zero_str} <0.1s") + # 不再在这里输出日志,而是返回给调用者统一输出 + # logger.info(f"回复准备: {'; '.join(timing_logs)}; {almost_zero_str} <0.1s") expression_habits_block, selected_expressions = results_dict["expression_habits"] expression_habits_block: str @@ -845,13 +931,8 @@ class DefaultReplyer: personality_prompt: str = results_dict["personality_prompt"] memory_retrieval: str = results_dict["memory_retrieval"] keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target) - mood_state_prompt: str = results_dict["mood_state_prompt"] - - # 从 chosen_actions 中提取 planner 的整体思考理由 - planner_reasoning = "" - if global_config.chat.include_planner_reasoning and reply_reason: - # 如果没有 chosen_actions,使用 reply_reason 作为备选 - planner_reasoning = f"你的想法是:{reply_reason}" + jargon_explanation: str = results_dict.get("jargon_explanation") or "" + planner_reasoning = f"你的想法是:{reply_reason}" if extra_info: extra_info_block = f"以下是你在回复时需要参考的信息,现在请你阅读以下内容,进行决策\n{extra_info}\n以上是你在回复时需要参考的信息,现在请你阅读以下内容,进行决策" @@ -886,29 +967,47 @@ class DefaultReplyer: chat_prompt_content = self.get_chat_prompt_for_chat(chat_id) chat_prompt_block = f"{chat_prompt_content}\n" if chat_prompt_content else "" - # 固定使用群聊回复模板 + # 根据think_level选择不同的回复模板 + # think_level=0: 轻量回复(简短平淡) + # think_level=1: 中等回复(日常口语化) + if think_level == 0: + prompt_name = "replyer_prompt_0" + else: # think_level == 1 或默认 + prompt_name = "replyer_prompt" + + # 根据配置构建最终的 reply_style:支持 multiple_reply_style 按概率随机替换 + reply_style = global_config.personality.reply_style + multi_styles = getattr(global_config.personality, "multiple_reply_style", None) or [] + multi_prob = getattr(global_config.personality, "multiple_probability", 0.0) or 0.0 + if multi_styles and multi_prob > 0 and random.random() < multi_prob: + try: + reply_style = random.choice(list(multi_styles)) + except Exception: + # 兜底:即使 multiple_reply_style 配置异常也不影响正常回复 + reply_style = global_config.personality.reply_style + return await global_prompt_manager.format_prompt( - "replyer_prompt", + prompt_name, expression_habits_block=expression_habits_block, tool_info_block=tool_info, bot_name=global_config.bot.nickname, knowledge_prompt=prompt_info, - mood_state=mood_state_prompt, # relation_info_block=relation_info, extra_info_block=extra_info_block, + jargon_explanation=jargon_explanation, identity=personality_prompt, action_descriptions=actions_info, sender_name=sender, dialogue_prompt=dialogue_prompt, time_block=time_block, reply_target_block=reply_target_block, - reply_style=global_config.personality.reply_style, + reply_style=reply_style, keywords_reaction_prompt=keywords_reaction_prompt, moderation_prompt=moderation_prompt_block, memory_retrieval=memory_retrieval, chat_prompt=chat_prompt_block, planner_reasoning=planner_reasoning, - ), selected_expressions + ), selected_expressions, timing_logs, almost_zero_str async def build_prompt_rewrite_context( self, @@ -918,8 +1017,6 @@ class DefaultReplyer: ) -> str: # sourcery skip: merge-else-if-into-elif, remove-redundant-if chat_stream = self.chat_stream chat_id = chat_stream.stream_id - is_group_chat = bool(chat_stream.group_info) - sender, target = self._parse_reply_target(reply_to) target = replace_user_references(target, chat_stream.platform, replace_bot_name=True) @@ -933,6 +1030,7 @@ class DefaultReplyer: chat_id=chat_id, timestamp=time.time(), limit=min(int(global_config.chat.max_context_size * 0.33), 15), + filter_intercept_message_level=1, ) chat_talking_prompt_half = build_readable_messages( message_list_before_now_half, @@ -958,61 +1056,42 @@ class DefaultReplyer: if sender and target: # 使用预先分析的内容类型结果 - if is_group_chat: - if sender: - if has_only_pics and not has_text: - # 只包含图片 - reply_target_block = ( - f"现在{sender}发送的图片:{pic_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" - ) - elif has_text and pic_part: - # 既有图片又有文字 - reply_target_block = f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" - else: - # 只包含文字 - reply_target_block = ( - f"现在{sender}说的:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" - ) - elif target: - reply_target_block = f"现在{target}引起了你的注意,你想要在群里发言或者回复这条消息。" + if sender: + if has_only_pics and not has_text: + # 只包含图片 + reply_target_block = ( + f"现在{sender}发送的图片:{pic_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" + ) + elif has_text and pic_part: + # 既有图片又有文字 + reply_target_block = f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" else: - reply_target_block = "现在,你想要在群里发言或者回复消息。" - else: # private chat - if sender: - if has_only_pics and not has_text: - # 只包含图片 - reply_target_block = f"现在{sender}发送的图片:{pic_part}。引起了你的注意,针对这条消息回复。" - elif has_text and pic_part: - # 既有图片又有文字 - reply_target_block = ( - f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,针对这条消息回复。" - ) - else: - # 只包含文字 - reply_target_block = f"现在{sender}说的:{text_part}。引起了你的注意,针对这条消息回复。" - elif target: - reply_target_block = f"现在{target}引起了你的注意,针对这条消息回复。" - else: - reply_target_block = "现在,你想要回复。" + # 只包含文字 + reply_target_block = ( + f"现在{sender}说的:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" + ) + elif target: + reply_target_block = f"现在{target}引起了你的注意,你想要在群里发言或者回复这条消息。" + else: + reply_target_block = "现在,你想要在群里发言或者回复消息。" else: reply_target_block = "" - if is_group_chat: - chat_target_1 = await global_prompt_manager.get_prompt_async("chat_target_group1") - chat_target_2 = await global_prompt_manager.get_prompt_async("chat_target_group2") - else: - chat_target_name = "对方" - if self.chat_target_info: - chat_target_name = self.chat_target_info.person_name or self.chat_target_info.user_nickname or "对方" - chat_target_1 = await global_prompt_manager.format_prompt( - "chat_target_private1", sender_name=chat_target_name - ) - chat_target_2 = await global_prompt_manager.format_prompt( - "chat_target_private2", sender_name=chat_target_name - ) + chat_target_1 = await global_prompt_manager.get_prompt_async("chat_target_group1") + chat_target_2 = await global_prompt_manager.get_prompt_async("chat_target_group2") template_name = "default_expressor_prompt" + # 根据配置构建最终的 reply_style:支持 multiple_reply_style 按概率随机替换 + reply_style = global_config.personality.reply_style + multi_styles = getattr(global_config.personality, "multiple_reply_style", None) or [] + multi_prob = getattr(global_config.personality, "multiple_probability", 0.0) or 0.0 + if multi_styles and multi_prob > 0 and random.random() < multi_prob: + try: + reply_style = random.choice(list(multi_styles)) + except Exception: + reply_style = global_config.personality.reply_style + return await global_prompt_manager.format_prompt( template_name, expression_habits_block=expression_habits_block, @@ -1025,7 +1104,7 @@ class DefaultReplyer: reply_target_block=reply_target_block, raw_reply=raw_reply, reason=reason, - reply_style=global_config.personality.reply_style, + reply_style=reply_style, keywords_reaction_prompt=keywords_reaction_prompt, moderation_prompt=moderation_prompt_block, ) @@ -1069,10 +1148,11 @@ class DefaultReplyer: # 直接使用已初始化的模型实例 # logger.info(f"\n{prompt}\n") - if global_config.debug.show_replyer_prompt: - logger.info(f"\n{prompt}\n") - else: - logger.debug(f"\nreplyer_Prompt:{prompt}\n") + # 不再在这里输出日志,而是返回给调用者统一输出 + # if global_config.debug.show_replyer_prompt: + # logger.info(f"\n{prompt}\n") + # else: + # logger.debug(f"\nreplyer_Prompt:{prompt}\n") content, (reasoning_content, model_name, tool_calls) = await self.express_model.generate_response_async( prompt @@ -1081,7 +1161,7 @@ class DefaultReplyer: # 移除 content 前后的换行符和空格 content = content.strip() - logger.info(f"使用 {model_name} 生成回复内容: {content}") + # logger.info(f"使用 {model_name} 生成回复内容: {content}") return content, reasoning_content, model_name, tool_calls async def get_prompt_info(self, message: str, sender: str, target: str): diff --git a/src/chat/replyer/private_generator.py b/src/chat/replyer/private_generator.py index 74b04f6e..5e107b41 100644 --- a/src/chat/replyer/private_generator.py +++ b/src/chat/replyer/private_generator.py @@ -23,9 +23,8 @@ from src.chat.utils.chat_message_builder import ( get_raw_msg_before_timestamp_with_chat, replace_user_references, ) -from src.express.expression_selector import expression_selector +from src.bw_learner.expression_selector import expression_selector from src.plugin_system.apis.message_api import translate_pid_to_description -from src.mood.mood_manager import mood_manager # from src.memory_system.memory_activator import MemoryActivator @@ -34,12 +33,13 @@ from src.plugin_system.base.component_types import ActionInfo, EventType from src.plugin_system.apis import llm_api from src.chat.replyer.prompt.lpmm_prompt import init_lpmm_prompt -from src.chat.replyer.prompt.replyer_prompt import init_replyer_prompt +from src.chat.replyer.prompt.replyer_private_prompt import init_replyer_private_prompt from src.chat.replyer.prompt.rewrite_prompt import init_rewrite_prompt from src.memory_system.memory_retrieval import init_memory_retrieval_prompt, build_memory_retrieval_prompt +from src.bw_learner.jargon_explainer import explain_jargon_in_context init_lpmm_prompt() -init_replyer_prompt() +init_replyer_private_prompt() init_rewrite_prompt() init_memory_retrieval_prompt() @@ -71,9 +71,11 @@ class PrivateReplyer: chosen_actions: Optional[List[ActionPlannerInfo]] = None, enable_tool: bool = True, from_plugin: bool = True, + think_level: int = 1, stream_id: Optional[str] = None, reply_message: Optional[DatabaseMessages] = None, reply_time_point: Optional[float] = time.time(), + unknown_words: Optional[List[str]] = None, ) -> Tuple[bool, LLMGenerationDataModel]: # sourcery skip: merge-nested-ifs """ @@ -270,7 +272,7 @@ class PrivateReplyer: logger.debug(f"使用处理器选中的{len(selected_expressions)}个表达方式") for expr in selected_expressions: if isinstance(expr, dict) and "situation" in expr and "style" in expr: - style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}") + style_habits.append(f"当{expr['situation']}时:{expr['style']}") else: logger.debug("没有从处理器获得表达方式,将使用空的表达方式") # 不再在replyer中进行随机选择,全部交给处理器处理 @@ -286,13 +288,6 @@ class PrivateReplyer: return f"{expression_habits_title}\n{expression_habits_block}", selected_ids - async def build_mood_state_prompt(self) -> str: - """构建情绪状态提示""" - if not global_config.mood.enable_mood: - return "" - mood_state = await mood_manager.get_mood_by_chat_id(self.chat_stream.stream_id).get_mood() - return f"你现在的心情是:{mood_state}" - async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str: """构建工具信息块 @@ -473,6 +468,10 @@ class PrivateReplyer: duration = end_time - start_time return name, result, duration + async def _build_disabled_jargon_explanation(self) -> str: + """当关闭黑话解释时使用的占位协程,避免额外的LLM调用""" + return "" + async def build_actions_prompt( self, available_actions: Dict[str, ActionInfo], chosen_actions_info: Optional[List[ActionPlannerInfo]] = None ) -> str: @@ -556,16 +555,10 @@ class PrivateReplyer: # 判断是否为群聊 is_group = stream_type == "group" - # 使用与 ChatStream.get_stream_id 相同的逻辑生成 chat_id - import hashlib - - if is_group: - components = [platform, str(id_str)] - else: - components = [platform, str(id_str), "private"] - key = "_".join(components) - chat_id = hashlib.md5(key.encode()).hexdigest() + # 使用 ChatManager 提供的接口生成 chat_id,避免在此重复实现逻辑 + from src.chat.message_receive.chat_stream import get_chat_manager + chat_id = get_chat_manager().get_stream_id(platform, str(id_str), is_group=is_group) return chat_id, prompt_content except (ValueError, IndexError): @@ -662,6 +655,7 @@ class PrivateReplyer: chat_id=chat_id, timestamp=time.time(), limit=global_config.chat.max_context_size, + filter_intercept_message_level=1, ) dialogue_prompt = build_readable_messages( @@ -676,6 +670,7 @@ class PrivateReplyer: chat_id=chat_id, timestamp=time.time(), limit=int(global_config.chat.max_context_size * 0.33), + filter_intercept_message_level=1, ) person_list_short: List[Person] = [] @@ -706,7 +701,14 @@ class PrivateReplyer: show_actions=True, ) - # 并行执行八个构建任务 + # 根据配置决定是否启用黑话解释 + enable_jargon_explanation = getattr(global_config.expression, "enable_jargon_explanation", True) + if enable_jargon_explanation: + jargon_coroutine = explain_jargon_in_context(chat_id, message_list_before_short, chat_talking_prompt_short) + else: + jargon_coroutine = self._build_disabled_jargon_explanation() + + # 并行执行九个构建任务(包括黑话解释,可配置关闭) task_results = await asyncio.gather( self._time_and_run_task( self.build_expression_habits(chat_talking_prompt_short, target, reply_reason), "expression_habits" @@ -718,13 +720,13 @@ class PrivateReplyer: self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"), self._time_and_run_task(self.build_actions_prompt(available_actions, chosen_actions), "actions_info"), self._time_and_run_task(self.build_personality_prompt(), "personality_prompt"), - self._time_and_run_task(self.build_mood_state_prompt(), "mood_state_prompt"), self._time_and_run_task( build_memory_retrieval_prompt( chat_talking_prompt_short, sender, target, self.chat_stream, self.tool_executor ), "memory_retrieval", ), + self._time_and_run_task(jargon_coroutine, "jargon_explanation"), ) # 任务名称中英文映射 @@ -735,8 +737,8 @@ class PrivateReplyer: "prompt_info": "获取知识", "actions_info": "动作信息", "personality_prompt": "人格信息", - "mood_state_prompt": "情绪状态", "memory_retrieval": "记忆检索", + "jargon_explanation": "黑话解释", } # 处理结果 @@ -752,8 +754,6 @@ class PrivateReplyer: continue timing_logs.append(f"{chinese_name}: {duration:.1f}s") - if duration > 12: - logger.warning(f"回复生成前信息获取耗时过长: {chinese_name} 耗时: {duration:.1f}s,请使用更快的模型") logger.info(f"回复准备: {'; '.join(timing_logs)}; {almost_zero_str} <0.1s") expression_habits_block, selected_expressions = results_dict["expression_habits"] @@ -764,15 +764,10 @@ class PrivateReplyer: prompt_info: str = results_dict["prompt_info"] # 直接使用格式化后的结果 actions_info: str = results_dict["actions_info"] personality_prompt: str = results_dict["personality_prompt"] - mood_state_prompt: str = results_dict["mood_state_prompt"] memory_retrieval: str = results_dict["memory_retrieval"] keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target) - - # 从 chosen_actions 中提取 planner 的整体思考理由 - planner_reasoning = "" - if global_config.chat.include_planner_reasoning and reply_reason: - # 如果没有 chosen_actions,使用 reply_reason 作为备选 - planner_reasoning = f"你的想法是:{reply_reason}" + jargon_explanation: str = results_dict.get("jargon_explanation") or "" + planner_reasoning = f"你的想法是:{reply_reason}" if extra_info: extra_info_block = f"以下是你在回复时需要参考的信息,现在请你阅读以下内容,进行决策\n{extra_info}\n以上是你在回复时需要参考的信息,现在请你阅读以下内容,进行决策" @@ -807,12 +802,12 @@ class PrivateReplyer: expression_habits_block=expression_habits_block, tool_info_block=tool_info, knowledge_prompt=prompt_info, - mood_state=mood_state_prompt, relation_info_block=relation_info, extra_info_block=extra_info_block, identity=personality_prompt, action_descriptions=actions_info, dialogue_prompt=dialogue_prompt, + jargon_explanation=jargon_explanation, time_block=time_block, target=target, reason=reply_reason, @@ -829,12 +824,12 @@ class PrivateReplyer: expression_habits_block=expression_habits_block, tool_info_block=tool_info, knowledge_prompt=prompt_info, - mood_state=mood_state_prompt, relation_info_block=relation_info, extra_info_block=extra_info_block, identity=personality_prompt, action_descriptions=actions_info, dialogue_prompt=dialogue_prompt, + jargon_explanation=jargon_explanation, time_block=time_block, reply_target_block=reply_target_block, reply_style=global_config.personality.reply_style, @@ -869,6 +864,7 @@ class PrivateReplyer: chat_id=chat_id, timestamp=time.time(), limit=min(int(global_config.chat.max_context_size * 0.33), 15), + filter_intercept_message_level=1, ) chat_talking_prompt_half = build_readable_messages( message_list_before_now_half, @@ -894,59 +890,30 @@ class PrivateReplyer: ) if sender and target: - # 使用预先分析的内容类型结果 - if is_group_chat: - if sender: - if has_only_pics and not has_text: - # 只包含图片 - reply_target_block = ( - f"现在{sender}发送的图片:{pic_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" - ) - elif has_text and pic_part: - # 既有图片又有文字 - reply_target_block = f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" - else: - # 只包含文字 - reply_target_block = ( - f"现在{sender}说的:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。" - ) - elif target: - reply_target_block = f"现在{target}引起了你的注意,你想要在群里发言或者回复这条消息。" + if sender: + if has_only_pics and not has_text: + # 只包含图片 + reply_target_block = f"现在{sender}发送的图片:{pic_part}。引起了你的注意,针对这条消息回复。" + elif has_text and pic_part: + # 既有图片又有文字 + reply_target_block = ( + f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,针对这条消息回复。" + ) else: - reply_target_block = "现在,你想要在群里发言或者回复消息。" - else: # private chat - if sender: - if has_only_pics and not has_text: - # 只包含图片 - reply_target_block = f"现在{sender}发送的图片:{pic_part}。引起了你的注意,针对这条消息回复。" - elif has_text and pic_part: - # 既有图片又有文字 - reply_target_block = ( - f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,针对这条消息回复。" - ) - else: - # 只包含文字 - reply_target_block = f"现在{sender}说的:{text_part}。引起了你的注意,针对这条消息回复。" - elif target: - reply_target_block = f"现在{target}引起了你的注意,针对这条消息回复。" - else: - reply_target_block = "现在,你想要回复。" + # 只包含文字 + reply_target_block = f"现在{sender}说的:{text_part}。引起了你的注意,针对这条消息回复。" + elif target: + reply_target_block = f"现在{target}引起了你的注意,针对这条消息回复。" + else: + reply_target_block = "现在,你想要回复。" else: reply_target_block = "" - if is_group_chat: - chat_target_1 = await global_prompt_manager.get_prompt_async("chat_target_group1") - chat_target_2 = await global_prompt_manager.get_prompt_async("chat_target_group2") - else: - chat_target_name = "对方" - if self.chat_target_info: - chat_target_name = self.chat_target_info.person_name or self.chat_target_info.user_nickname or "对方" - chat_target_1 = await global_prompt_manager.format_prompt( - "chat_target_private1", sender_name=chat_target_name - ) - chat_target_2 = await global_prompt_manager.format_prompt( - "chat_target_private2", sender_name=chat_target_name - ) + chat_target_name = "对方" + if self.chat_target_info: + chat_target_name = self.chat_target_info.person_name or self.chat_target_info.user_nickname or "对方" + chat_target_1 = await global_prompt_manager.format_prompt("chat_target_private1", sender_name=chat_target_name) + chat_target_2 = await global_prompt_manager.format_prompt("chat_target_private2", sender_name=chat_target_name) template_name = "default_expressor_prompt" diff --git a/src/chat/replyer/prompt/replyer_private_prompt.py b/src/chat/replyer/prompt/replyer_private_prompt.py new file mode 100644 index 00000000..7dfd54e7 --- /dev/null +++ b/src/chat/replyer/prompt/replyer_private_prompt.py @@ -0,0 +1,41 @@ +from src.chat.utils.prompt_builder import Prompt + + +def init_replyer_private_prompt(): + Prompt( + """{knowledge_prompt}{tool_info_block}{extra_info_block} + {expression_habits_block}{memory_retrieval}{jargon_explanation} + + 你正在和{sender_name}聊天,这是你们之前聊的内容: + {time_block} + {dialogue_prompt} + + {reply_target_block}。 + {planner_reasoning} + {identity} + {chat_prompt}你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些, + 尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。 + {reply_style} + 请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。 + {moderation_prompt}不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""", + "private_replyer_prompt", + ) + + Prompt( + """{knowledge_prompt}{tool_info_block}{extra_info_block} +{expression_habits_block}{memory_retrieval}{jargon_explanation} + +你正在和{sender_name}聊天,这是你们之前聊的内容: +{time_block} +{dialogue_prompt} + +你现在想补充说明你刚刚自己的发言内容:{target},原因是{reason} +请你根据聊天内容,组织一条新回复。注意,{target} 是刚刚你自己的发言,你要在这基础上进一步发言,请按照你自己的角度来继续进行回复。注意保持上下文的连贯性。 +{identity} +{chat_prompt}尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。 +{reply_style} +请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。 +{moderation_prompt}不要输出多余内容(包括冒号和引号,括号,表情包,at或 @等 )。 +""", + "private_replyer_self_prompt", + ) diff --git a/src/chat/replyer/prompt/replyer_prompt.py b/src/chat/replyer/prompt/replyer_prompt.py index 7c7a91e3..6b92a3a9 100644 --- a/src/chat/replyer/prompt/replyer_prompt.py +++ b/src/chat/replyer/prompt/replyer_prompt.py @@ -3,12 +3,9 @@ from src.chat.utils.prompt_builder import Prompt def init_replyer_prompt(): - Prompt("正在群里聊天", "chat_target_group2") - Prompt("和{sender_name}聊天", "chat_target_private2") - Prompt( """{knowledge_prompt}{tool_info_block}{extra_info_block} -{expression_habits_block}{memory_retrieval} +{expression_habits_block}{memory_retrieval}{jargon_explanation} 你正在qq群里聊天,下面是群里正在聊的内容,其中包含聊天记录和聊天中的图片 其中标注 {bot_name}(你) 的发言是你自己的发言,请注意区分: @@ -18,49 +15,34 @@ def init_replyer_prompt(): {reply_target_block}。 {planner_reasoning} {identity} -{chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state} -尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。 +{chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复, +尽量简短一些。{keywords_reaction_prompt} +请注意把握聊天内容,不要回复的太有条理。 {reply_style} -请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出一句回复内容就好。 -不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。 +请注意不要输出多余内容(包括不必要的前后缀,冒号,括号,表情包,at或 @等 ),只输出发言内容就好。 +最好一次对一个话题进行回复,免得啰嗦或者回复内容太乱。 现在,你说:""", - "replyer_prompt", + "replyer_prompt_0", ) Prompt( """{knowledge_prompt}{tool_info_block}{extra_info_block} -{expression_habits_block}{memory_retrieval} +{expression_habits_block}{memory_retrieval}{jargon_explanation} -你正在和{sender_name}聊天,这是你们之前聊的内容: +你正在qq群里聊天,下面是群里正在聊的内容,其中包含聊天记录和聊天中的图片 +其中标注 {bot_name}(你) 的发言是你自己的发言,请注意区分: {time_block} {dialogue_prompt} {reply_target_block}。 {planner_reasoning} {identity} -{chat_prompt}你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state} -尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。 +{chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,把握当前的话题,然后给出日常且简短的回复。 +最好一次对一个话题进行回复,免得啰嗦或者回复内容太乱。 +{keywords_reaction_prompt} +请注意把握聊天内容。 {reply_style} -请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。 -{moderation_prompt}不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""", - "private_replyer_prompt", - ) - - Prompt( - """{knowledge_prompt}{tool_info_block}{extra_info_block} -{expression_habits_block}{memory_retrieval} - -你正在和{sender_name}聊天,这是你们之前聊的内容: -{time_block} -{dialogue_prompt} - -你现在想补充说明你刚刚自己的发言内容:{target},原因是{reason} -请你根据聊天内容,组织一条新回复。注意,{target} 是刚刚你自己的发言,你要在这基础上进一步发言,请按照你自己的角度来继续进行回复。注意保持上下文的连贯性。{mood_state} -{identity} -{chat_prompt}尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。 -{reply_style} -请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。 -{moderation_prompt}不要输出多余内容(包括冒号和引号,括号,表情包,at或 @等 )。 -""", - "private_replyer_self_prompt", +请注意不要输出多余内容(包括不必要的前后缀,冒号,括号,at或 @等 ),只输出发言内容就好。 +现在,你说:""", + "replyer_prompt", ) diff --git a/src/chat/utils/chat_history_summarizer.py b/src/chat/utils/chat_history_summarizer.py deleted file mode 100644 index 7fa55834..00000000 --- a/src/chat/utils/chat_history_summarizer.py +++ /dev/null @@ -1,493 +0,0 @@ -""" -聊天内容概括器 -用于累积、打包和压缩聊天记录 -""" - -import asyncio -import json -import time -from typing import List, Optional, Set -from dataclasses import dataclass - -from src.common.logger import get_logger -from src.common.data_models.database_data_model import DatabaseMessages -from src.config.config import global_config, model_config -from src.llm_models.utils_model import LLMRequest -from src.plugin_system.apis import message_api -from src.chat.utils.chat_message_builder import build_readable_messages -from src.person_info.person_info import Person -from src.chat.message_receive.chat_stream import get_chat_manager - -logger = get_logger("chat_history_summarizer") - - -@dataclass -class MessageBatch: - """消息批次""" - - messages: List[DatabaseMessages] - start_time: float - end_time: float - is_preparing: bool = False # 是否处于准备结束模式 - - -class ChatHistorySummarizer: - """聊天内容概括器""" - - def __init__(self, chat_id: str, check_interval: int = 60): - """ - 初始化聊天内容概括器 - - Args: - chat_id: 聊天ID - check_interval: 定期检查间隔(秒),默认60秒 - """ - self.chat_id = chat_id - self._chat_display_name = self._get_chat_display_name() - self.log_prefix = f"[{self._chat_display_name}]" - - # 记录时间点,用于计算新消息 - self.last_check_time = time.time() - - # 当前累积的消息批次 - self.current_batch: Optional[MessageBatch] = None - - # LLM请求器,用于压缩聊天内容 - self.summarizer_llm = LLMRequest( - model_set=model_config.model_task_config.utils, request_type="chat_history_summarizer" - ) - - # 后台循环相关 - self.check_interval = check_interval # 检查间隔(秒) - self._periodic_task: Optional[asyncio.Task] = None - self._running = False - - def _get_chat_display_name(self) -> str: - """获取聊天显示名称""" - try: - chat_name = get_chat_manager().get_stream_name(self.chat_id) - if chat_name: - return chat_name - # 如果获取失败,使用简化的chat_id显示 - if len(self.chat_id) > 20: - return f"{self.chat_id[:8]}..." - return self.chat_id - except Exception: - # 如果获取失败,使用简化的chat_id显示 - if len(self.chat_id) > 20: - return f"{self.chat_id[:8]}..." - return self.chat_id - - async def process(self, current_time: Optional[float] = None): - """ - 处理聊天内容概括 - - Args: - current_time: 当前时间戳,如果为None则使用time.time() - """ - if current_time is None: - current_time = time.time() - - try: - # 获取从上次检查时间到当前时间的新消息 - new_messages = message_api.get_messages_by_time_in_chat( - chat_id=self.chat_id, - start_time=self.last_check_time, - end_time=current_time, - limit=0, - limit_mode="latest", - filter_mai=False, # 不过滤bot消息,因为需要检查bot是否发言 - filter_command=False, - ) - - if not new_messages: - # 没有新消息,检查是否需要打包 - if self.current_batch and self.current_batch.messages: - await self._check_and_package(current_time) - self.last_check_time = current_time - return - - logger.debug( - f"{self.log_prefix} 开始处理聊天概括,时间窗口: {self.last_check_time:.2f} -> {current_time:.2f}" - ) - - # 有新消息,更新最后检查时间 - self.last_check_time = current_time - - # 如果有当前批次,添加新消息 - if self.current_batch: - before_count = len(self.current_batch.messages) - self.current_batch.messages.extend(new_messages) - self.current_batch.end_time = current_time - logger.info(f"{self.log_prefix} 更新聊天话题: {before_count} -> {len(self.current_batch.messages)} 条消息") - else: - # 创建新批次 - self.current_batch = MessageBatch( - messages=new_messages, - start_time=new_messages[0].time if new_messages else current_time, - end_time=current_time, - ) - logger.info(f"{self.log_prefix} 新建聊天话题: {len(new_messages)} 条消息") - - # 检查是否需要打包 - await self._check_and_package(current_time) - - except Exception as e: - logger.error(f"{self.log_prefix} 处理聊天内容概括时出错: {e}") - import traceback - - traceback.print_exc() - - async def _check_and_package(self, current_time: float): - """检查是否需要打包""" - if not self.current_batch or not self.current_batch.messages: - return - - messages = self.current_batch.messages - message_count = len(messages) - last_message_time = messages[-1].time if messages else current_time - time_since_last_message = current_time - last_message_time - - # 格式化时间差显示 - if time_since_last_message < 60: - time_str = f"{time_since_last_message:.1f}秒" - elif time_since_last_message < 3600: - time_str = f"{time_since_last_message / 60:.1f}分钟" - else: - time_str = f"{time_since_last_message / 3600:.1f}小时" - - preparing_status = "是" if self.current_batch.is_preparing else "否" - - logger.info( - f"{self.log_prefix} 批次状态检查 | 消息数: {message_count} | 距最后消息: {time_str} | 准备结束模式: {preparing_status}" - ) - - # 检查打包条件 - should_package = False - - # 条件1: 消息长度超过120,直接打包 - if message_count >= 120: - should_package = True - logger.info(f"{self.log_prefix} 触发打包条件: 消息数量达到 {message_count} 条(阈值: 120条)") - - # 条件2: 最后一条消息的时间和当前时间差>600秒,直接打包 - elif time_since_last_message > 600: - should_package = True - logger.info(f"{self.log_prefix} 触发打包条件: 距最后消息 {time_str}(阈值: 10分钟)") - - # 条件3: 消息长度超过100,进入准备结束模式 - elif message_count > 100: - if not self.current_batch.is_preparing: - self.current_batch.is_preparing = True - logger.info(f"{self.log_prefix} 消息数量 {message_count} 条超过阈值(100条),进入准备结束模式") - - # 在准备结束模式下,如果最后一条消息的时间和当前时间差>10秒,就打包 - if time_since_last_message > 10: - should_package = True - logger.info(f"{self.log_prefix} 触发打包条件: 准备结束模式下,距最后消息 {time_str}(阈值: 10秒)") - - if should_package: - await self._package_and_store() - - async def _package_and_store(self): - """打包并存储聊天记录""" - if not self.current_batch or not self.current_batch.messages: - return - - messages = self.current_batch.messages - start_time = self.current_batch.start_time - end_time = self.current_batch.end_time - - logger.info( - f"{self.log_prefix} 开始打包批次 | 消息数: {len(messages)} | 时间范围: {start_time:.2f} - {end_time:.2f}" - ) - - # 检查是否有bot发言 - # 第一条消息前推600s到最后一条消息的时间内 - check_start_time = max(start_time - 600, 0) - check_end_time = end_time - - # 使用包含边界的时间范围查询 - bot_messages = message_api.get_messages_by_time_in_chat_inclusive( - chat_id=self.chat_id, - start_time=check_start_time, - end_time=check_end_time, - limit=0, - limit_mode="latest", - filter_mai=False, - filter_command=False, - ) - - # 检查是否有bot的发言 - has_bot_message = False - bot_user_id = str(global_config.bot.qq_account) - for msg in bot_messages: - if msg.user_info.user_id == bot_user_id: - has_bot_message = True - break - - if not has_bot_message: - logger.info( - f"{self.log_prefix} 批次内无Bot发言,丢弃批次 | 检查时间范围: {check_start_time:.2f} - {check_end_time:.2f}" - ) - self.current_batch = None - return - - # 有bot发言,进行压缩和存储 - try: - # 构建对话原文 - original_text = build_readable_messages( - messages=messages, - replace_bot_name=True, - timestamp_mode="normal_no_YMD", - read_mark=0.0, - truncate=False, - show_actions=False, - ) - - # 获取参与的所有人的昵称 - participants_set: Set[str] = set() - for msg in messages: - # 使用 msg.user_platform(扁平化字段)或 msg.user_info.platform - platform = ( - getattr(msg, "user_platform", None) - or (msg.user_info.platform if msg.user_info else None) - or msg.chat_info.platform - ) - person = Person(platform=platform, user_id=msg.user_info.user_id) - person_name = person.person_name - if person_name: - participants_set.add(person_name) - participants = list(participants_set) - logger.info(f"{self.log_prefix} 批次参与者: {', '.join(participants) if participants else '未知'}") - - # 使用LLM压缩聊天内容 - success, theme, keywords, summary = await self._compress_with_llm(original_text) - - if not success: - logger.warning(f"{self.log_prefix} LLM压缩失败,不存储到数据库 | 消息数: {len(messages)}") - # 清空当前批次,避免重复处理 - self.current_batch = None - return - - logger.info( - f"{self.log_prefix} LLM压缩完成 | 主题: {theme} | 关键词数: {len(keywords)} | 概括长度: {len(summary)} 字" - ) - - # 存储到数据库 - await self._store_to_database( - start_time=start_time, - end_time=end_time, - original_text=original_text, - participants=participants, - theme=theme, - keywords=keywords, - summary=summary, - ) - - logger.info(f"{self.log_prefix} 成功打包并存储聊天记录 | 消息数: {len(messages)} | 主题: {theme}") - - # 清空当前批次 - self.current_batch = None - - except Exception as e: - logger.error(f"{self.log_prefix} 打包和存储聊天记录时出错: {e}") - import traceback - - traceback.print_exc() - # 出错时也清空批次,避免重复处理 - self.current_batch = None - - async def _compress_with_llm(self, original_text: str) -> tuple[bool, str, List[str], str]: - """ - 使用LLM压缩聊天内容 - - Returns: - tuple[bool, str, List[str], str]: (是否成功, 主题, 关键词列表, 概括) - """ - prompt = f"""请对以下聊天记录进行概括,提取以下信息: - -1. 主题:这段对话的主要内容,一个简短的标题(不超过20字) -2. 关键词:这段对话的关键词,用列表形式返回(3-10个关键词) -3. 概括:对这段话的平文本概括(50-200字) - -请以JSON格式返回,格式如下: -{{ - "theme": "主题", - "keywords": ["关键词1", "关键词2", ...], - "summary": "概括内容" -}} - -聊天记录: -{original_text} - -请直接返回JSON,不要包含其他内容。""" - - try: - response, _ = await self.summarizer_llm.generate_response_async( - prompt=prompt, - temperature=0.3, - max_tokens=500, - ) - - # 解析JSON响应 - import re - - # 移除可能的markdown代码块标记 - json_str = response.strip() - json_str = re.sub(r"^```json\s*", "", json_str, flags=re.MULTILINE) - json_str = re.sub(r"^```\s*", "", json_str, flags=re.MULTILINE) - json_str = json_str.strip() - - # 尝试找到JSON对象的开始和结束位置 - # 查找第一个 { 和最后一个匹配的 } - start_idx = json_str.find("{") - if start_idx == -1: - raise ValueError("未找到JSON对象开始标记") - - # 从后往前查找最后一个 } - end_idx = json_str.rfind("}") - if end_idx == -1 or end_idx <= start_idx: - raise ValueError("未找到JSON对象结束标记") - - # 提取JSON字符串 - json_str = json_str[start_idx : end_idx + 1] - - # 尝试解析JSON - try: - result = json.loads(json_str) - except json.JSONDecodeError: - # 如果解析失败,尝试修复字符串值中的中文引号 - # 简单方法:将字符串值中的中文引号替换为转义的英文引号 - # 使用状态机方法:遍历字符串,在字符串值内部替换中文引号 - fixed_chars = [] - in_string = False - escape_next = False - i = 0 - while i < len(json_str): - char = json_str[i] - if escape_next: - fixed_chars.append(char) - escape_next = False - elif char == "\\": - fixed_chars.append(char) - escape_next = True - elif char == '"' and not escape_next: - fixed_chars.append(char) - in_string = not in_string - elif in_string and (char == '"' or char == '"'): - # 在字符串值内部,将中文引号替换为转义的英文引号 - fixed_chars.append('\\"') - else: - fixed_chars.append(char) - i += 1 - - json_str = "".join(fixed_chars) - # 再次尝试解析 - result = json.loads(json_str) - - theme = result.get("theme", "未命名对话") - keywords = result.get("keywords", []) - summary = result.get("summary", "无概括") - - # 确保keywords是列表 - if isinstance(keywords, str): - keywords = [keywords] - - return True, theme, keywords, summary - - except Exception as e: - logger.error(f"{self.log_prefix} LLM压缩聊天内容时出错: {e}") - logger.error(f"{self.log_prefix} LLM响应: {response if 'response' in locals() else 'N/A'}") - # 返回失败标志和默认值 - return False, "未命名对话", [], "压缩失败,无法生成概括" - - async def _store_to_database( - self, - start_time: float, - end_time: float, - original_text: str, - participants: List[str], - theme: str, - keywords: List[str], - summary: str, - ): - """存储到数据库""" - try: - from src.common.database.database_model import ChatHistory - from src.plugin_system.apis import database_api - - # 准备数据 - data = { - "chat_id": self.chat_id, - "start_time": start_time, - "end_time": end_time, - "original_text": original_text, - "participants": json.dumps(participants, ensure_ascii=False), - "theme": theme, - "keywords": json.dumps(keywords, ensure_ascii=False), - "summary": summary, - "count": 0, - } - - # 使用db_save存储(使用start_time和chat_id作为唯一标识) - # 由于可能有多条记录,我们使用组合键,但peewee不支持,所以使用start_time作为唯一标识 - # 但为了避免冲突,我们使用组合键:chat_id + start_time - # 由于peewee不支持组合键,我们直接创建新记录(不提供key_field和key_value) - saved_record = await database_api.db_save( - ChatHistory, - data=data, - ) - - if saved_record: - logger.debug(f"{self.log_prefix} 成功存储聊天历史记录到数据库") - else: - logger.warning(f"{self.log_prefix} 存储聊天历史记录到数据库失败") - - except Exception as e: - logger.error(f"{self.log_prefix} 存储到数据库时出错: {e}") - import traceback - - traceback.print_exc() - raise - - async def start(self): - """启动后台定期检查循环""" - if self._running: - logger.warning(f"{self.log_prefix} 后台循环已在运行,无需重复启动") - return - - self._running = True - self._periodic_task = asyncio.create_task(self._periodic_check_loop()) - logger.info(f"{self.log_prefix} 已启动后台定期检查循环 | 检查间隔: {self.check_interval}秒") - - async def stop(self): - """停止后台定期检查循环""" - self._running = False - if self._periodic_task: - self._periodic_task.cancel() - try: - await self._periodic_task - except asyncio.CancelledError: - pass - self._periodic_task = None - logger.info(f"{self.log_prefix} 已停止后台定期检查循环") - - async def _periodic_check_loop(self): - """后台定期检查循环""" - try: - while self._running: - # 执行一次检查 - await self.process() - - # 等待指定间隔后再次检查 - await asyncio.sleep(self.check_interval) - except asyncio.CancelledError: - logger.info(f"{self.log_prefix} 后台检查循环被取消") - raise - except Exception as e: - logger.error(f"{self.log_prefix} 后台检查循环出错: {e}") - import traceback - - traceback.print_exc() - self._running = False diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index 4bd7850f..156322ae 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -120,6 +120,7 @@ def get_raw_msg_by_timestamp_with_chat( limit_mode: str = "latest", filter_bot=False, filter_command=False, + filter_intercept_message_level: Optional[int] = None, ) -> List[DatabaseMessages]: """获取在特定聊天从指定时间戳到指定时间戳的消息,按时间升序排序,返回消息列表 limit: 限制返回的消息数量,0为不限制 @@ -137,6 +138,7 @@ def get_raw_msg_by_timestamp_with_chat( limit_mode=limit_mode, filter_bot=filter_bot, filter_command=filter_command, + filter_intercept_message_level=filter_intercept_message_level, ) @@ -147,6 +149,8 @@ def get_raw_msg_by_timestamp_with_chat_inclusive( limit: int = 0, limit_mode: str = "latest", filter_bot=False, + filter_command=False, + filter_intercept_message_level: Optional[int] = None, ) -> List[DatabaseMessages]: """获取在特定聊天从指定时间戳到指定时间戳的消息(包含边界),按时间升序排序,返回消息列表 limit: 限制返回的消息数量,0为不限制 @@ -157,7 +161,13 @@ def get_raw_msg_by_timestamp_with_chat_inclusive( sort_order = [("time", 1)] if limit == 0 else None # 直接将 limit_mode 传递给 find_messages return find_messages( - message_filter=filter_query, sort=sort_order, limit=limit, limit_mode=limit_mode, filter_bot=filter_bot + message_filter=filter_query, + sort=sort_order, + limit=limit, + limit_mode=limit_mode, + filter_bot=filter_bot, + filter_command=filter_command, + filter_intercept_message_level=filter_intercept_message_level, ) @@ -292,13 +302,20 @@ def get_raw_msg_before_timestamp(timestamp: float, limit: int = 0) -> List[Datab return find_messages(message_filter=filter_query, sort=sort_order, limit=limit) -def get_raw_msg_before_timestamp_with_chat(chat_id: str, timestamp: float, limit: int = 0) -> List[DatabaseMessages]: +def get_raw_msg_before_timestamp_with_chat( + chat_id: str, timestamp: float, limit: int = 0, filter_intercept_message_level: Optional[int] = None +) -> List[DatabaseMessages]: """获取指定时间戳之前的消息,按时间升序排序,返回消息列表 limit: 限制返回的消息数量,0为不限制 """ filter_query = {"chat_id": chat_id, "time": {"$lt": timestamp}} sort_order = [("time", 1)] - return find_messages(message_filter=filter_query, sort=sort_order, limit=limit) + return find_messages( + message_filter=filter_query, + sort=sort_order, + limit=limit, + filter_intercept_message_level=filter_intercept_message_level, + ) def get_raw_msg_before_timestamp_with_users( @@ -352,6 +369,7 @@ def _build_readable_messages_internal( pic_counter: int = 1, show_pic: bool = True, message_id_list: Optional[List[Tuple[str, DatabaseMessages]]] = None, + pic_single: bool = False, ) -> Tuple[str, List[Tuple[float, str, str]], Dict[str, str], int]: # sourcery skip: use-getitem-for-re-match-groups """ @@ -378,6 +396,7 @@ def _build_readable_messages_internal( if pic_id_mapping is None: pic_id_mapping = {} current_pic_counter = pic_counter + pic_description_cache: Dict[str, str] = {} # 创建时间戳到消息ID的映射,用于在消息前添加[id]标识符 timestamp_to_id_mapping: Dict[float, str] = {} @@ -400,6 +419,17 @@ def _build_readable_messages_internal( nonlocal current_pic_counter nonlocal pic_counter pic_id = match.group(1) + if pic_single: + if pic_id not in pic_description_cache: + description = "内容正在阅读,请稍等" + try: + image = Images.get_or_none(Images.image_id == pic_id) + if image and image.description: + description = image.description + except Exception: + pass + pic_description_cache[pic_id] = description + return f"[图片:{pic_description_cache[pic_id]}]" if pic_id not in pic_id_mapping: pic_id_mapping[pic_id] = f"图片{current_pic_counter}" current_pic_counter += 1 @@ -445,6 +475,8 @@ def _build_readable_messages_internal( # 使用独立函数处理用户引用格式 if content := replace_user_references(content, platform, replace_bot_name=replace_bot_name): + if getattr(message, "is_command", False): + content = f"[is_command=True] {content}" detailed_messages_raw.append((timestamp, person_name, content, False)) if not detailed_messages_raw: @@ -603,6 +635,7 @@ async def build_readable_messages_with_list( replace_bot_name: bool = True, timestamp_mode: str = "relative", truncate: bool = False, + pic_single: bool = False, ) -> Tuple[str, List[Tuple[float, str, str]]]: """ 将消息列表转换为可读的文本格式,并返回原始(时间戳, 昵称, 内容)列表。 @@ -613,10 +646,16 @@ async def build_readable_messages_with_list( replace_bot_name, timestamp_mode, truncate, + pic_id_mapping=None, + pic_counter=1, + show_pic=True, + message_id_list=None, + pic_single=pic_single, ) - if pic_mapping_info := build_pic_mapping_info(pic_id_mapping): - formatted_string = f"{pic_mapping_info}\n\n{formatted_string}" + if not pic_single: + if pic_mapping_info := build_pic_mapping_info(pic_id_mapping): + formatted_string = f"{pic_mapping_info}\n\n{formatted_string}" return formatted_string, details_list @@ -630,6 +669,7 @@ def build_readable_messages_with_id( show_actions: bool = False, show_pic: bool = True, remove_emoji_stickers: bool = False, + pic_single: bool = False, ) -> Tuple[str, List[Tuple[str, DatabaseMessages]]]: """ 将消息列表转换为可读的文本格式,并返回原始(时间戳, 昵称, 内容)列表。 @@ -647,6 +687,7 @@ def build_readable_messages_with_id( read_mark=read_mark, message_id_list=message_id_list, remove_emoji_stickers=remove_emoji_stickers, + pic_single=pic_single, ) return formatted_string, message_id_list @@ -662,6 +703,7 @@ def build_readable_messages( show_pic: bool = True, message_id_list: Optional[List[Tuple[str, DatabaseMessages]]] = None, remove_emoji_stickers: bool = False, + pic_single: bool = False, ) -> str: # sourcery skip: extract-method """ 将消息列表转换为可读的文本格式。 @@ -769,14 +811,14 @@ def build_readable_messages( truncate, show_pic=show_pic, message_id_list=message_id_list, + pic_single=pic_single, ) - # 生成图片映射信息并添加到最前面 - pic_mapping_info = build_pic_mapping_info(pic_id_mapping) - if pic_mapping_info: - return f"{pic_mapping_info}\n\n{formatted_string}" - else: - return formatted_string + if not pic_single: + pic_mapping_info = build_pic_mapping_info(pic_id_mapping) + if pic_mapping_info: + return f"{pic_mapping_info}\n\n{formatted_string}" + return formatted_string else: # 按 read_mark 分割消息 messages_before_mark = [msg for msg in copy_messages if (msg.time or 0) <= read_mark] @@ -796,6 +838,7 @@ def build_readable_messages( pic_counter, show_pic=show_pic, message_id_list=message_id_list, + pic_single=pic_single, ) formatted_after, _, pic_id_mapping, _ = _build_readable_messages_internal( messages_after_mark, @@ -806,15 +849,19 @@ def build_readable_messages( pic_counter, show_pic=show_pic, message_id_list=message_id_list, + pic_single=pic_single, ) read_mark_line = "\n--- 以上消息是你已经看过,请关注以下未读的新消息---\n" # 生成图片映射信息 - if pic_id_mapping: - pic_mapping_info = f"图片信息:\n{build_pic_mapping_info(pic_id_mapping)}\n聊天记录信息:\n" + if not pic_single: + if pic_id_mapping: + pic_mapping_info = f"图片信息:\n{build_pic_mapping_info(pic_id_mapping)}\n聊天记录信息:\n" + else: + pic_mapping_info = "聊天记录信息:\n" else: - pic_mapping_info = "聊天记录信息:\n" + pic_mapping_info = "" # 组合结果 result_parts = [] @@ -832,7 +879,7 @@ def build_readable_messages( return "".join(result_parts) -async def build_anonymous_messages(messages: List[DatabaseMessages]) -> str: +async def build_anonymous_messages(messages: List[DatabaseMessages], show_ids: bool = False) -> str: """ 构建匿名可读消息,将不同人的名称转为唯一占位符(A、B、C...),bot自己用SELF。 处理 回复 和 @ 字段,将bbb映射为匿名占位符。 @@ -889,7 +936,7 @@ async def build_anonymous_messages(messages: List[DatabaseMessages]) -> str: current_char += 1 return person_map[person_id] - for msg in messages: + for i, msg in enumerate(messages): try: platform = msg.chat_info.platform user_id = msg.user_info.user_id @@ -910,7 +957,12 @@ async def build_anonymous_messages(messages: List[DatabaseMessages]) -> str: content = replace_user_references(content, platform, anon_name_resolver, replace_bot_name=False) - header = f"{anon_name}说 " + # 构建消息头,如果启用show_ids则添加序号 + if show_ids: + header = f"[{i + 1}] {anon_name}说 " + else: + header = f"{anon_name}说 " + output_lines.append(header) stripped_line = content.strip() if stripped_line: diff --git a/src/chat/utils/statistic.py b/src/chat/utils/statistic.py index 9b5497e9..20c0843b 100644 --- a/src/chat/utils/statistic.py +++ b/src/chat/utils/statistic.py @@ -8,7 +8,7 @@ from typing import Any, Dict, Tuple, List from src.common.logger import get_logger from src.common.database.database import db -from src.common.database.database_model import OnlineTime, LLMUsage, Messages +from src.common.database.database_model import OnlineTime, LLMUsage, Messages, ActionRecords from src.manager.async_task_manager import AsyncTask from src.manager.local_store_manager import local_storage from src.config.config import global_config @@ -227,6 +227,8 @@ class StatisticOutputTask(AsyncTask): "", self._format_model_classified_stat(stats["last_hour"]), "", + self._format_module_classified_stat(stats["last_hour"]), + "", self._format_chat_stat(stats["last_hour"]), self.SEP_LINE, "", @@ -503,13 +505,6 @@ class StatisticOutputTask(AsyncTask): for period_key, _ in collect_period } - # 获取bot的QQ账号 - bot_qq_account = ( - str(global_config.bot.qq_account) - if hasattr(global_config, "bot") and hasattr(global_config.bot, "qq_account") - else "" - ) - query_start_timestamp = collect_period[-1][1].timestamp() # Messages.time is a DoubleField (timestamp) for message in Messages.select().where(Messages.time >= query_start_timestamp): # type: ignore message_time_ts = message.time # This is a float timestamp @@ -535,7 +530,7 @@ class StatisticOutputTask(AsyncTask): if not chat_id: # Should not happen if above logic is correct continue - # Update name_mapping + # Update name_mapping(仅用于展示聊天名称) try: if chat_id in self.name_mapping: if chat_name != self.name_mapping[chat_id][0] and message_time_ts > self.name_mapping[chat_id][1]: @@ -547,19 +542,30 @@ class StatisticOutputTask(AsyncTask): # 重置为正确的格式 self.name_mapping[chat_id] = (chat_name, message_time_ts) - # 检查是否是bot发送的消息(回复) - is_bot_reply = False - if bot_qq_account and message.user_id == bot_qq_account: - is_bot_reply = True - for idx, (_, period_start_dt) in enumerate(collect_period): if message_time_ts >= period_start_dt.timestamp(): for period_key, _ in collect_period[idx:]: stats[period_key][TOTAL_MSG_CNT] += 1 stats[period_key][MSG_CNT_BY_CHAT][chat_id] += 1 - if is_bot_reply: - stats[period_key][TOTAL_REPLY_CNT] += 1 break + + # 使用 ActionRecords 中的 reply 动作次数作为回复数基准 + try: + action_query_start_timestamp = collect_period[-1][1].timestamp() + for action in ActionRecords.select().where(ActionRecords.time >= action_query_start_timestamp): # type: ignore + # 仅统计已完成的 reply 动作 + if action.action_name != "reply" or not action.action_done: + continue + + action_time_ts = action.time + for idx, (_, period_start_dt) in enumerate(collect_period): + if action_time_ts >= period_start_dt.timestamp(): + for period_key, _ in collect_period[idx:]: + stats[period_key][TOTAL_REPLY_CNT] += 1 + break + except Exception as e: + logger.warning(f"统计 reply 动作次数失败,将回复数视为 0,错误信息:{e}") + return stats def _collect_all_statistics(self, now: datetime) -> Dict[str, Dict[str, Any]]: @@ -737,11 +743,13 @@ class StatisticOutputTask(AsyncTask): """ if stats[TOTAL_REQ_CNT] <= 0: return "" - data_fmt = "{:<32} {:>10} {:>12} {:>12} {:>12} {:>9.2f}¥ {:>10.1f} {:>10.1f}" + data_fmt = "{:<32} {:>10} {:>12} {:>12} {:>12} {:>9.2f}¥ {:>10.1f} {:>10.1f} {:>12} {:>12}" + + total_replies = stats.get(TOTAL_REPLY_CNT, 0) output = [ "按模型分类统计:", - " 模型名称 调用次数 输入Token 输出Token Token总量 累计花费 平均耗时(秒) 标准差(秒)", + " 模型名称 调用次数 输入Token 输出Token Token总量 累计花费 平均耗时(秒) 标准差(秒) 每次回复平均调用次数 每次回复平均Token数", ] for model_name, count in sorted(stats[REQ_CNT_BY_MODEL].items()): name = f"{model_name[:29]}..." if len(model_name) > 32 else model_name @@ -751,11 +759,19 @@ class StatisticOutputTask(AsyncTask): cost = stats[COST_BY_MODEL][model_name] avg_time_cost = stats[AVG_TIME_COST_BY_MODEL][model_name] std_time_cost = stats[STD_TIME_COST_BY_MODEL][model_name] + + # 计算每次回复平均值 + avg_count_per_reply = count / total_replies if total_replies > 0 else 0.0 + avg_tokens_per_reply = tokens / total_replies if total_replies > 0 else 0.0 + # 格式化大数字 formatted_count = _format_large_number(count) formatted_in_tokens = _format_large_number(in_tokens) formatted_out_tokens = _format_large_number(out_tokens) formatted_tokens = _format_large_number(tokens) + formatted_avg_count = _format_large_number(avg_count_per_reply) if total_replies > 0 else "N/A" + formatted_avg_tokens = _format_large_number(avg_tokens_per_reply) if total_replies > 0 else "N/A" + output.append( data_fmt.format( name, @@ -766,6 +782,62 @@ class StatisticOutputTask(AsyncTask): cost, avg_time_cost, std_time_cost, + formatted_avg_count, + formatted_avg_tokens, + ) + ) + + output.append("") + return "\n".join(output) + + @staticmethod + def _format_module_classified_stat(stats: Dict[str, Any]) -> str: + """ + 格式化按模块分类的统计数据 + """ + if stats[TOTAL_REQ_CNT] <= 0: + return "" + data_fmt = "{:<32} {:>10} {:>12} {:>12} {:>12} {:>9.2f}¥ {:>10.1f} {:>10.1f} {:>12} {:>12}" + + total_replies = stats.get(TOTAL_REPLY_CNT, 0) + + output = [ + "按模块分类统计:", + " 模块名称 调用次数 输入Token 输出Token Token总量 累计花费 平均耗时(秒) 标准差(秒) 每次回复平均调用次数 每次回复平均Token数", + ] + for module_name, count in sorted(stats[REQ_CNT_BY_MODULE].items()): + name = f"{module_name[:29]}..." if len(module_name) > 32 else module_name + in_tokens = stats[IN_TOK_BY_MODULE][module_name] + out_tokens = stats[OUT_TOK_BY_MODULE][module_name] + tokens = stats[TOTAL_TOK_BY_MODULE][module_name] + cost = stats[COST_BY_MODULE][module_name] + avg_time_cost = stats[AVG_TIME_COST_BY_MODULE][module_name] + std_time_cost = stats[STD_TIME_COST_BY_MODULE][module_name] + + # 计算每次回复平均值 + avg_count_per_reply = count / total_replies if total_replies > 0 else 0.0 + avg_tokens_per_reply = tokens / total_replies if total_replies > 0 else 0.0 + + # 格式化大数字 + formatted_count = _format_large_number(count) + formatted_in_tokens = _format_large_number(in_tokens) + formatted_out_tokens = _format_large_number(out_tokens) + formatted_tokens = _format_large_number(tokens) + formatted_avg_count = _format_large_number(avg_count_per_reply) if total_replies > 0 else "N/A" + formatted_avg_tokens = _format_large_number(avg_tokens_per_reply) if total_replies > 0 else "N/A" + + output.append( + data_fmt.format( + name, + formatted_count, + formatted_in_tokens, + formatted_out_tokens, + formatted_tokens, + cost, + avg_time_cost, + std_time_cost, + formatted_avg_count, + formatted_avg_tokens, ) ) @@ -849,6 +921,7 @@ class StatisticOutputTask(AsyncTask): # format总在线时间 # 按模型分类统计 + total_replies = stat_data.get(TOTAL_REPLY_CNT, 0) model_rows = "\n".join( [ f"" @@ -860,11 +933,13 @@ class StatisticOutputTask(AsyncTask): f"{stat_data[COST_BY_MODEL][model_name]:.2f} ¥" f"{stat_data[AVG_TIME_COST_BY_MODEL][model_name]:.1f} 秒" f"{stat_data[STD_TIME_COST_BY_MODEL][model_name]:.1f} 秒" + f"{_format_large_number(count / total_replies, html=True) if total_replies > 0 else 'N/A'}" + f"{_format_large_number(stat_data[TOTAL_TOK_BY_MODEL][model_name] / total_replies, html=True) if total_replies > 0 else 'N/A'}" f"" for model_name, count in sorted(stat_data[REQ_CNT_BY_MODEL].items()) ] if stat_data[REQ_CNT_BY_MODEL] - else ["暂无数据"] + else ["暂无数据"] ) # 按请求类型分类统计 type_rows = "\n".join( @@ -878,11 +953,13 @@ class StatisticOutputTask(AsyncTask): f"{stat_data[COST_BY_TYPE][req_type]:.2f} ¥" f"{stat_data[AVG_TIME_COST_BY_TYPE][req_type]:.1f} 秒" f"{stat_data[STD_TIME_COST_BY_TYPE][req_type]:.1f} 秒" + f"{_format_large_number(count / total_replies, html=True) if total_replies > 0 else 'N/A'}" + f"{_format_large_number(stat_data[TOTAL_TOK_BY_TYPE][req_type] / total_replies, html=True) if total_replies > 0 else 'N/A'}" f"" for req_type, count in sorted(stat_data[REQ_CNT_BY_TYPE].items()) ] if stat_data[REQ_CNT_BY_TYPE] - else ["暂无数据"] + else ["暂无数据"] ) # 按模块分类统计 module_rows = "\n".join( @@ -896,11 +973,13 @@ class StatisticOutputTask(AsyncTask): f"{stat_data[COST_BY_MODULE][module_name]:.2f} ¥" f"{stat_data[AVG_TIME_COST_BY_MODULE][module_name]:.1f} 秒" f"{stat_data[STD_TIME_COST_BY_MODULE][module_name]:.1f} 秒" + f"{_format_large_number(count / total_replies, html=True) if total_replies > 0 else 'N/A'}" + f"{_format_large_number(stat_data[TOTAL_TOK_BY_MODULE][module_name] / total_replies, html=True) if total_replies > 0 else 'N/A'}" f"" for module_name, count in sorted(stat_data[REQ_CNT_BY_MODULE].items()) ] if stat_data[REQ_CNT_BY_MODULE] - else ["暂无数据"] + else ["暂无数据"] ) # 聊天消息统计 @@ -975,7 +1054,7 @@ class StatisticOutputTask(AsyncTask):

按模型分类统计

- + {model_rows} @@ -986,7 +1065,7 @@ class StatisticOutputTask(AsyncTask):
模型名称调用次数输入Token输出TokenToken总量累计花费平均耗时(秒)标准差(秒)
模型名称调用次数输入Token输出TokenToken总量累计花费平均耗时(秒)标准差(秒)每次回复平均调用次数每次回复平均Token数
- + {module_rows} @@ -998,7 +1077,7 @@ class StatisticOutputTask(AsyncTask):
模块名称调用次数输入Token输出TokenToken总量累计花费平均耗时(秒)标准差(秒)
模块名称调用次数输入Token输出TokenToken总量累计花费平均耗时(秒)标准差(秒)每次回复平均调用次数每次回复平均Token数
- + {type_rows} diff --git a/src/chat/utils/utils.py b/src/chat/utils/utils.py index 0464b734..b525f03d 100644 --- a/src/chat/utils/utils.py +++ b/src/chat/utils/utils.py @@ -4,6 +4,8 @@ import time import jieba import json import ast +import os +from datetime import datetime from typing import Optional, Tuple, List, TYPE_CHECKING @@ -196,21 +198,54 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]: List[str]: 分割和合并后的句子列表 """ # 预处理:处理多余的换行符 - # 1. 将连续的换行符替换为单个换行符 + # 1. 将连续的换行符替换为单个换行符(保留换行符用于分割) text = re.sub(r"\n\s*\n+", "\n", text) - # 2. 处理换行符和其他分隔符的组合 - text = re.sub(r"\n\s*([,,。;\s])", r"\1", text) - text = re.sub(r"([,,。;\s])\s*\n", r"\1", text) + # 2. 处理换行符和其他分隔符的组合(保留换行符,删除其他分隔符) + text = re.sub(r"\n\s*([,,。;\s])", r"\n\1", text) + text = re.sub(r"([,,。;\s])\s*\n", r"\1\n", text) - # 处理两个汉字中间的换行符 - text = re.sub(r"([\u4e00-\u9fff])\n([\u4e00-\u9fff])", r"\1。\2", text) + # 处理两个汉字中间的换行符(保留换行符,不替换为句号,让换行符强制分割) + # text = re.sub(r"([\u4e00-\u9fff])\n([\u4e00-\u9fff])", r"\1。\2", text) # 注释掉,保留换行符用于分割 len_text = len(text) if len_text < 3: return list(text) if random.random() < 0.01 else [text] - # 定义分隔符 - separators = {",", ",", " ", "。", ";"} + # 先标记哪些位置位于成对引号内部,避免在引号内部进行句子分割 + # 支持的引号包括:中英文单/双引号和常见中文书名号/引号 + quote_chars = { + '"', + "'", + "“", + "”", + "‘", + "’", + "「", + "」", + "『", + "』", + } + inside_quote = [False] * len_text + in_quote = False + current_quote_char = "" + for idx, ch in enumerate(text): + if ch in quote_chars: + # 遇到引号时切换状态(英文引号本身开闭相同,用同一个字符表示) + if not in_quote: + in_quote = True + current_quote_char = ch + inside_quote[idx] = False + else: + # 只有遇到同一类引号才视为关闭 + if ch == current_quote_char or ch in {'"', "'"} and current_quote_char in {'"', "'"}: + in_quote = False + current_quote_char = "" + inside_quote[idx] = False + else: + inside_quote[idx] = in_quote + + # 定义分隔符(包含换行符) + separators = {",", ",", " ", "。", ";", "\n"} segments = [] current_segment = "" @@ -219,24 +254,42 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]: while i < len(text): char = text[i] if char in separators: - # 检查分割条件:如果空格左右都是英文字母、数字,或数字和英文之间,则不分割(仅对空格应用此规则) - can_split = True - if 0 < i < len(text) - 1: - prev_char = text[i - 1] - next_char = text[i + 1] - # 只对空格应用"不分割数字和数字、数字和英文、英文和数字、英文和英文之间的空格"规则 - if char == " ": - prev_is_alnum = prev_char.isdigit() or is_english_letter(prev_char) - next_is_alnum = next_char.isdigit() or is_english_letter(next_char) - if prev_is_alnum and next_is_alnum: - can_split = False + # 引号内部一律不作为分割点(包括换行) + if inside_quote[i]: + can_split = False + else: + # 换行符在不在引号内时都强制分割 + if char == "\n": + can_split = True + else: + # 检查分割条件 + can_split = True + # 检查分隔符左右是否有冒号(中英文),如果有则不分割 + if i > 0: + prev_char = text[i - 1] + if prev_char in {":", ":"}: + can_split = False + if i < len(text) - 1: + next_char = text[i + 1] + if next_char in {":", ":"}: + can_split = False + + # 如果左右没有冒号,再检查空格的特殊情况 + if can_split and char == " " and i > 0 and i < len(text) - 1: + prev_char = text[i - 1] + next_char = text[i + 1] + # 不分割数字和数字、数字和英文、英文和数字、英文和英文之间的空格 + prev_is_alnum = prev_char.isdigit() or is_english_letter(prev_char) + next_is_alnum = next_char.isdigit() or is_english_letter(next_char) + if prev_is_alnum and next_is_alnum: + can_split = False if can_split: # 只有当当前段不为空时才添加 if current_segment: segments.append((current_segment, char)) - # 如果当前段为空,但分隔符是空格,则也添加一个空段(保留空格) - elif char == " ": + # 如果当前段为空,但分隔符是空格或换行符,则也添加一个空段(保留分隔符) + elif char in {" ", "\n"}: segments.append(("", char)) current_segment = "" else: @@ -641,6 +694,42 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional["TargetP return is_group_chat, chat_target_info +def record_replyer_action_temp(chat_id: str, reason: str, think_level: int) -> None: + """ + 临时记录replyer动作被选择的信息(仅群聊) + + Args: + chat_id: 聊天ID + reason: 选择理由 + think_level: 思考深度等级 + """ + try: + # 确保data/temp目录存在 + temp_dir = "data/temp" + os.makedirs(temp_dir, exist_ok=True) + + # 创建记录数据 + record_data = { + "chat_id": chat_id, + "reason": reason, + "think_level": think_level, + "timestamp": datetime.now().isoformat(), + } + + # 生成文件名(使用时间戳避免冲突) + timestamp_str = datetime.now().strftime("%Y%m%d_%H%M%S_%f") + filename = f"replyer_action_{timestamp_str}.json" + filepath = os.path.join(temp_dir, filename) + + # 写入文件 + with open(filepath, "w", encoding="utf-8") as f: + json.dump(record_data, f, ensure_ascii=False, indent=2) + + logger.debug(f"已记录replyer动作选择: chat_id={chat_id}, think_level={think_level}") + except Exception as e: + logger.warning(f"记录replyer动作选择失败: {e}") + + def assign_message_ids(messages: List[DatabaseMessages]) -> List[Tuple[str, DatabaseMessages]]: """ 为消息列表中的每个消息分配唯一的简短随机ID diff --git a/src/chat/utils/utils_image.py b/src/chat/utils/utils_image.py index f6012f09..1145cc83 100644 --- a/src/chat/utils/utils_image.py +++ b/src/chat/utils/utils_image.py @@ -12,7 +12,7 @@ from rich.traceback import install from src.common.logger import get_logger from src.common.database.database import db -from src.common.database.database_model import Images, ImageDescriptions +from src.common.database.database_model import Images, ImageDescriptions, EmojiDescriptionCache from src.config.config import global_config, model_config from src.llm_models.utils_model import LLMRequest @@ -40,7 +40,7 @@ class ImageManager: try: db.connect(reuse_if_open=True) - db.create_tables([Images, ImageDescriptions], safe=True) + db.create_tables([Images, ImageDescriptions, EmojiDescriptionCache], safe=True) except Exception as e: logger.error(f"数据库连接或表创建失败: {e}") @@ -49,6 +49,11 @@ class ImageManager: except Exception as e: logger.warning(f"数据库清理失败: {e}") + try: + self._cleanup_emoji_from_image_descriptions() + except Exception as e: + logger.warning(f"清理ImageDescriptions中的emoji记录失败: {e}") + self._initialized = True def _ensure_image_dir(self): @@ -119,6 +124,29 @@ class ImageManager: else: logger.info("[清理完成] 未发现无效描述记录") + @staticmethod + def _cleanup_emoji_from_image_descriptions(): + """清理Images和ImageDescriptions表中type为emoji的记录(已迁移到EmojiDescriptionCache)""" + try: + # 清理Images表中type为emoji的记录 + deleted_images = Images.delete().where(Images.type == "emoji").execute() + + # 清理ImageDescriptions表中type为emoji的记录 + deleted_descriptions = ImageDescriptions.delete().where(ImageDescriptions.type == "emoji").execute() + + total_deleted = deleted_images + deleted_descriptions + if total_deleted > 0: + logger.info( + f"[清理完成] 从Images表中删除 {deleted_images} 条emoji类型记录, " + f"从ImageDescriptions表中删除 {deleted_descriptions} 条emoji类型记录, " + f"共删除 {total_deleted} 条记录" + ) + else: + logger.info("[清理完成] Images和ImageDescriptions表中未发现emoji类型记录") + except Exception as e: + logger.error(f"清理Images和ImageDescriptions中的emoji记录时出错: {str(e)}") + raise + async def get_emoji_tag(self, image_base64: str) -> str: from src.chat.emoji_system.emoji_manager import get_emoji_manager @@ -134,8 +162,49 @@ class ImageManager: tag_str = ",".join(emotion_list) return f"[表情包:{tag_str}]" + async def _save_emoji_file_if_needed(self, image_base64: str, image_hash: str, image_format: str) -> None: + """如果启用了steal_emoji且表情包未注册,保存文件到data/emoji目录 + + Args: + image_base64: 图片的base64编码 + image_hash: 图片的MD5哈希值 + image_format: 图片格式 + """ + if not global_config.emoji.steal_emoji: + return + + try: + from src.chat.emoji_system.emoji_manager import EMOJI_DIR + from src.chat.emoji_system.emoji_manager import get_emoji_manager + + # 确保目录存在 + os.makedirs(EMOJI_DIR, exist_ok=True) + + # 检查是否已存在该表情包(通过哈希值) + emoji_manager = get_emoji_manager() + existing_emoji = await emoji_manager.get_emoji_from_manager(image_hash) + if existing_emoji: + logger.debug(f"[自动保存] 表情包已注册,跳过保存: {image_hash[:8]}...") + return + + # 生成文件名:使用哈希值前8位 + 格式 + filename = f"{image_hash[:8]}.{image_format}" + file_path = os.path.join(EMOJI_DIR, filename) + + # 检查文件是否已存在(可能之前保存过但未注册) + if not os.path.exists(file_path): + # 保存文件 + if base64_to_image(image_base64, file_path): + logger.info(f"[自动保存] 表情包已保存到 {file_path} (Hash: {image_hash[:8]}...)") + else: + logger.warning(f"[自动保存] 保存表情包文件失败: {file_path}") + else: + logger.debug(f"[自动保存] 表情包文件已存在,跳过: {file_path}") + except Exception as save_error: + logger.warning(f"[自动保存] 保存表情包文件时出错: {save_error}") + async def get_emoji_description(self, image_base64: str) -> str: - """获取表情包描述,优先使用Emoji表中的缓存数据""" + """获取表情包描述,优先使用EmojiDescriptionCache表中的缓存数据""" try: # 计算图片哈希 # 确保base64字符串只包含ASCII字符 @@ -158,10 +227,29 @@ class ImageManager: except Exception as e: logger.debug(f"查询EmojiManager时出错: {e}") - # 查询ImageDescriptions表的缓存描述 - if cached_description := self._get_description_from_db(image_hash, "emoji"): - logger.info(f"[缓存命中] 使用ImageDescriptions表中的描述: {cached_description[:50]}...") - return f"[表情包:{cached_description}]" + # 查询EmojiDescriptionCache表的缓存(包含描述和情感标签) + try: + cache_record = EmojiDescriptionCache.get_or_none(EmojiDescriptionCache.emoji_hash == image_hash) + if cache_record: + # 优先使用情感标签,如果没有则使用详细描述 + result_text = "" + if cache_record.emotion_tags: + logger.info( + f"[缓存命中] 使用EmojiDescriptionCache表中的情感标签: {cache_record.emotion_tags[:50]}..." + ) + result_text = f"[表情包:{cache_record.emotion_tags}]" + elif cache_record.description: + logger.info( + f"[缓存命中] 使用EmojiDescriptionCache表中的描述: {cache_record.description[:50]}..." + ) + result_text = f"[表情包:{cache_record.description}]" + + # 即使缓存命中,如果启用了steal_emoji,也检查是否需要保存文件 + if result_text: + await self._save_emoji_file_if_needed(image_base64, image_hash, image_format) + return result_text + except Exception as e: + logger.debug(f"查询EmojiDescriptionCache时出错: {e}") # === 二步走识别流程 === @@ -221,45 +309,38 @@ class ImageManager: logger.debug(f"[emoji识别] 详细描述: {detailed_description[:50]}... -> 情感标签: {final_emotion}") - if cached_description := self._get_description_from_db(image_hash, "emoji"): - logger.warning(f"虽然生成了描述,但是找到缓存表情包描述: {cached_description}") - return f"[表情包:{cached_description}]" - - # 保存表情包文件和元数据(用于可能的后续分析) - logger.debug(f"保存表情包: {image_hash}") - current_timestamp = time.time() - filename = f"{int(current_timestamp)}_{image_hash[:8]}.{image_format}" - emoji_dir = os.path.join(self.IMAGE_DIR, "emoji") - os.makedirs(emoji_dir, exist_ok=True) - file_path = os.path.join(emoji_dir, filename) - + # 再次检查缓存(防止并发情况下其他线程已经保存) try: - # 保存文件 - with open(file_path, "wb") as f: - f.write(image_bytes) - - # 保存到数据库 (Images表) - 包含详细描述用于可能的注册流程 - try: - img_obj = Images.get((Images.emoji_hash == image_hash) & (Images.type == "emoji")) - img_obj.path = file_path - img_obj.description = detailed_description # 保存详细描述 - img_obj.timestamp = current_timestamp - img_obj.save() - except Images.DoesNotExist: # type: ignore - Images.create( - image_id=str(uuid.uuid4()), - emoji_hash=image_hash, - path=file_path, - type="emoji", - description=detailed_description, # 保存详细描述 - timestamp=current_timestamp, - vlm_processed=True, - ) + cache_record = EmojiDescriptionCache.get_or_none(EmojiDescriptionCache.emoji_hash == image_hash) + if cache_record and cache_record.emotion_tags: + logger.warning(f"虽然生成了描述,但是找到缓存表情包情感标签: {cache_record.emotion_tags}") + return f"[表情包:{cache_record.emotion_tags}]" except Exception as e: - logger.error(f"保存表情包文件或元数据失败: {str(e)}") + logger.debug(f"再次查询EmojiDescriptionCache时出错: {e}") - # 保存最终的情感标签到缓存 (ImageDescriptions表) - self._save_description_to_db(image_hash, final_emotion, "emoji") + # 保存识别出的详细描述和情感标签到 emoji_description_cache + try: + current_timestamp = time.time() + cache_record, created = EmojiDescriptionCache.get_or_create( + emoji_hash=image_hash, + defaults={ + "description": detailed_description, + "emotion_tags": final_emotion, + "timestamp": current_timestamp, + }, + ) + if not created: + # 更新已有记录 + cache_record.description = detailed_description + cache_record.emotion_tags = final_emotion + cache_record.timestamp = current_timestamp + cache_record.save() + logger.info(f"[缓存保存] 表情包描述和情感标签已保存到EmojiDescriptionCache: {image_hash[:8]}...") + except Exception as e: + logger.error(f"保存表情包描述和情感标签缓存失败: {str(e)}") + + # 如果启用了steal_emoji,自动保存表情包文件到data/emoji目录 + await self._save_emoji_file_if_needed(image_base64, image_hash, image_format) return f"[表情包:{final_emotion}]" diff --git a/src/common/data_models/database_data_model.py b/src/common/data_models/database_data_model.py index b981bd33..5bd35873 100644 --- a/src/common/data_models/database_data_model.py +++ b/src/common/data_models/database_data_model.py @@ -77,6 +77,7 @@ class DatabaseMessages(BaseDataModel): is_emoji: bool = False, is_picid: bool = False, is_command: bool = False, + intercept_message_level: int = 0, is_notify: bool = False, selected_expressions: Optional[str] = None, user_id: str = "", @@ -119,6 +120,7 @@ class DatabaseMessages(BaseDataModel): self.is_emoji = is_emoji self.is_picid = is_picid self.is_command = is_command + self.intercept_message_level = intercept_message_level self.is_notify = is_notify self.selected_expressions = selected_expressions @@ -186,6 +188,7 @@ class DatabaseMessages(BaseDataModel): "is_emoji": self.is_emoji, "is_picid": self.is_picid, "is_command": self.is_command, + "intercept_message_level": self.intercept_message_level, "is_notify": self.is_notify, "selected_expressions": self.selected_expressions, "user_id": self.user_info.user_id, diff --git a/src/common/data_models/message_data_model.py b/src/common/data_models/message_data_model.py index a3d5751f..dc4ad951 100644 --- a/src/common/data_models/message_data_model.py +++ b/src/common/data_models/message_data_model.py @@ -21,6 +21,8 @@ class MessageAndActionModel(BaseDataModel): chat_info_platform: str = field(default_factory=str) is_action_record: bool = field(default=False) action_name: Optional[str] = None + is_command: bool = field(default=False) + intercept_message_level: int = field(default=0) @classmethod def from_DatabaseMessages(cls, message: "DatabaseMessages"): @@ -34,6 +36,8 @@ class MessageAndActionModel(BaseDataModel): processed_plain_text=message.processed_plain_text, display_message=message.display_message, chat_info_platform=message.chat_info.platform, + is_command=message.is_command, + intercept_message_level=getattr(message, "intercept_message_level", 0), ) diff --git a/src/common/database/database_model.py b/src/common/database/database_model.py index c97c0b72..a59f68e2 100644 --- a/src/common/database/database_model.py +++ b/src/common/database/database_model.py @@ -170,6 +170,7 @@ class Messages(BaseModel): is_emoji = BooleanField(default=False) is_picid = BooleanField(default=False) is_command = BooleanField(default=False) + intercept_message_level = IntegerField(default=0) is_notify = BooleanField(default=False) selected_expressions = TextField(null=True) @@ -239,6 +240,20 @@ class ImageDescriptions(BaseModel): table_name = "image_descriptions" +class EmojiDescriptionCache(BaseModel): + """ + 存储表情包的详细描述和情感标签缓存 + """ + + emoji_hash = TextField(unique=True, index=True) + description = TextField() # 详细描述 + emotion_tags = TextField(null=True) # 情感标签,逗号分隔 + timestamp = FloatField() + + class Meta: + table_name = "emoji_description_cache" + + class OnlineTime(BaseModel): """ 用于存储在线时长记录的模型。 @@ -309,13 +324,15 @@ class Expression(BaseModel): # new mode fields context = TextField(null=True) - up_content = TextField(null=True) content_list = TextField(null=True) + style_list = TextField(null=True) # 存储相似的 style,格式与 content_list 相同(JSON 数组) count = IntegerField(default=1) last_active_time = FloatField() chat_id = TextField(index=True) create_date = FloatField(null=True) # 创建日期,允许为空以兼容老数据 + checked = BooleanField(default=False) # 是否已检查 + rejected = BooleanField(default=False) # 是否被拒绝但未更新 class Meta: table_name = "expression" @@ -328,8 +345,6 @@ class Jargon(BaseModel): content = TextField() raw_content = TextField(null=True) - type = TextField(null=True) - translation = TextField(null=True) meaning = TextField(null=True) chat_id = TextField(index=True) is_global = BooleanField(default=False) @@ -357,6 +372,7 @@ class ChatHistory(BaseModel): theme = TextField() # 主题:这段对话的主要内容,一个简短的标题 keywords = TextField() # 关键词:这段对话的关键词,JSON格式存储 summary = TextField() # 概括:对这段话的平文本概括 + key_point = TextField(null=True) # 关键信息:话题中的关键信息点,JSON格式存储 count = IntegerField(default=0) # 被检索次数 forget_times = IntegerField(default=0) # 被遗忘检查的次数 @@ -389,6 +405,7 @@ MODELS = [ Messages, Images, ImageDescriptions, + EmojiDescriptionCache, OnlineTime, PersonInfo, Expression, @@ -576,22 +593,41 @@ def _fix_table_constraints(table_name, model, constraints_to_fix): db.execute_sql(f"CREATE TABLE {backup_table} AS SELECT * FROM {table_name}") logger.info(f"已创建备份表 '{backup_table}'") - # 2. 删除原表 + # 2. 获取原始行数(在删除表之前) + original_count = db.execute_sql(f"SELECT COUNT(*) FROM {backup_table}").fetchone()[0] + logger.info(f"备份表 '{backup_table}' 包含 {original_count} 行数据") + + # 3. 删除原表 db.execute_sql(f"DROP TABLE {table_name}") logger.info(f"已删除原表 '{table_name}'") - # 3. 重新创建表(使用当前模型定义) + # 4. 重新创建表(使用当前模型定义) db.create_tables([model]) logger.info(f"已重新创建表 '{table_name}' 使用新的约束") - # 4. 从备份表恢复数据 - # 获取字段列表 + # 5. 从备份表恢复数据 + # 获取字段列表,排除主键字段(让数据库自动生成新的主键) fields = list(model._meta.fields.keys()) - fields_str = ", ".join(fields) + # Peewee 默认使用 'id' 作为主键字段名 + # 尝试获取主键字段名,如果获取失败则默认使用 'id' + primary_key_name = "id" # 默认值 + try: + if hasattr(model._meta, "primary_key") and model._meta.primary_key: + if hasattr(model._meta.primary_key, "name"): + primary_key_name = model._meta.primary_key.name + elif isinstance(model._meta.primary_key, str): + primary_key_name = model._meta.primary_key + except Exception: + pass # 如果获取失败,使用默认值 'id' - # 对于需要从 NOT NULL 改为 NULL 的字段,直接复制数据 - # 对于需要从 NULL 改为 NOT NULL 的字段,需要处理 NULL 值 - insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {fields_str} FROM {backup_table}" + # 如果字段列表包含主键,则排除它 + if primary_key_name in fields: + fields_without_pk = [f for f in fields if f != primary_key_name] + logger.info(f"排除主键字段 '{primary_key_name}',让数据库自动生成新的主键") + else: + fields_without_pk = fields + + fields_str = ", ".join(fields_without_pk) # 检查是否有字段需要从 NULL 改为 NOT NULL null_to_notnull_fields = [ @@ -604,7 +640,7 @@ def _fix_table_constraints(table_name, model, constraints_to_fix): # 构建更复杂的 SELECT 语句来处理 NULL 值 select_fields = [] - for field_name in fields: + for field_name in fields_without_pk: if field_name in null_to_notnull_fields: field_obj = model._meta.fields[field_name] # 根据字段类型设置默认值 @@ -625,12 +661,13 @@ def _fix_table_constraints(table_name, model, constraints_to_fix): select_str = ", ".join(select_fields) insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {select_str} FROM {backup_table}" + else: + # 没有需要处理 NULL 的字段,直接复制数据(排除主键) + insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {fields_str} FROM {backup_table}" db.execute_sql(insert_sql) logger.info(f"已从备份表恢复数据到 '{table_name}'") - # 5. 验证数据完整性 - original_count = db.execute_sql(f"SELECT COUNT(*) FROM {backup_table}").fetchone()[0] new_count = db.execute_sql(f"SELECT COUNT(*) FROM {table_name}").fetchone()[0] if original_count == new_count: diff --git a/src/common/logger.py b/src/common/logger.py index 4cf40398..b57c9dd3 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -20,6 +20,9 @@ PROJECT_ROOT = logger_file.parent.parent.parent.resolve() _file_handler = None _console_handler = None _ws_handler = None +# 全局标志,防止重复初始化 +_logging_initialized = False +_cleanup_task_started = False def get_file_handler(): @@ -869,29 +872,41 @@ def get_logger(name: Optional[str]) -> structlog.stdlib.BoundLogger: return logger -def initialize_logging(): +def initialize_logging(verbose: bool = True): """手动初始化日志系统,确保所有logger都使用正确的配置 在应用程序的早期调用此函数,确保所有模块都使用统一的日志配置 + + Args: + verbose: 是否输出详细的初始化信息。默认为 True。 + 在 Runner 进程中可以设置为 False 以避免重复的初始化日志。 """ - global LOG_CONFIG + global LOG_CONFIG, _logging_initialized + + # 防止重复初始化(在同一进程内) + if _logging_initialized: + return + + _logging_initialized = True + LOG_CONFIG = load_log_config() # print(LOG_CONFIG) configure_third_party_loggers() reconfigure_existing_loggers() # 启动日志清理任务 - start_log_cleanup_task() + start_log_cleanup_task(verbose=verbose) - # 输出初始化信息 - logger = get_logger("logger") - console_level = LOG_CONFIG.get("console_log_level", LOG_CONFIG.get("log_level", "INFO")) - file_level = LOG_CONFIG.get("file_log_level", LOG_CONFIG.get("log_level", "INFO")) + # 只在 verbose=True 时输出详细的初始化信息 + if verbose: + logger = get_logger("logger") + console_level = LOG_CONFIG.get("console_log_level", LOG_CONFIG.get("log_level", "INFO")) + file_level = LOG_CONFIG.get("file_log_level", LOG_CONFIG.get("log_level", "INFO")) - logger.info("日志系统已初始化:") - logger.info(f" - 控制台级别: {console_level}") - logger.info(f" - 文件级别: {file_level}") - logger.info(" - 轮转份数: 30个文件|自动清理: 30天前的日志") + logger.info("日志系统已初始化:") + logger.info(f" - 控制台级别: {console_level}") + logger.info(f" - 文件级别: {file_level}") + logger.info(" - 轮转份数: 30个文件|自动清理: 30天前的日志") def cleanup_old_logs(): @@ -924,8 +939,19 @@ def cleanup_old_logs(): logger.error(f"清理旧日志文件时出错: {e}") -def start_log_cleanup_task(): - """启动日志清理任务""" +def start_log_cleanup_task(verbose: bool = True): + """启动日志清理任务 + + Args: + verbose: 是否输出启动信息。默认为 True。 + """ + global _cleanup_task_started + + # 防止重复启动清理任务 + if _cleanup_task_started: + return + + _cleanup_task_started = True def cleanup_task(): while True: @@ -935,8 +961,9 @@ def start_log_cleanup_task(): cleanup_thread = threading.Thread(target=cleanup_task, daemon=True) cleanup_thread.start() - logger = get_logger("logger") - logger.info("已启动日志清理任务,将自动清理30天前的日志文件(轮转份数限制: 30个文件)") + if verbose: + logger = get_logger("logger") + logger.info("已启动日志清理任务,将自动清理30天前的日志文件(轮转份数限制: 30个文件)") def shutdown_logging(): diff --git a/src/common/message/api.py b/src/common/message/api.py index eed85c0a..f9f6c8f5 100644 --- a/src/common/message/api.py +++ b/src/common/message/api.py @@ -15,14 +15,18 @@ def get_global_api() -> MessageServer: # sourcery skip: extract-method # 检查maim_message版本 try: maim_message_version = importlib.metadata.version("maim_message") - version_compatible = [int(x) for x in maim_message_version.split(".")] >= [0, 3, 3] + version_int = [int(x) for x in maim_message_version.split(".")] + version_compatible = version_int >= [0, 3, 3] + # Check for API Server feature (>= 0.6.0) + has_api_server_feature = version_int >= [0, 6, 0] except (importlib.metadata.PackageNotFoundError, ValueError): version_compatible = False + has_api_server_feature = False # 读取配置项 maim_message_config = global_config.maim_message - # 设置基本参数 + # 设置基本参数 (Legacy Server Mode) kwargs = { "host": os.environ["HOST"], "port": int(os.environ["PORT"]), @@ -39,21 +43,129 @@ def get_global_api() -> MessageServer: # sourcery skip: extract-method if maim_message_config.auth_token and len(maim_message_config.auth_token) > 0: kwargs["enable_token"] = True - if maim_message_config.use_custom: - # 添加WSS模式支持 - del kwargs["app"] - kwargs["host"] = maim_message_config.host - kwargs["port"] = maim_message_config.port - kwargs["mode"] = maim_message_config.mode - if maim_message_config.use_wss: - if maim_message_config.cert_file: - kwargs["ssl_certfile"] = maim_message_config.cert_file - if maim_message_config.key_file: - kwargs["ssl_keyfile"] = maim_message_config.key_file - kwargs["enable_custom_uvicorn_logger"] = False + # Removed legacy custom config block (use_custom) as requested. + kwargs["enable_custom_uvicorn_logger"] = False global_api = MessageServer(**kwargs) if version_compatible and maim_message_config.auth_token: for token in maim_message_config.auth_token: global_api.add_valid_token(token) + + # --------------------------------------------------------------------- + # Additional API Server Configuration (maim_message >= 6.0) + # --------------------------------------------------------------------- + enable_api_server = maim_message_config.enable_api_server + + # 如果版本支持且启用了API Server,则初始化额外服务器 + if has_api_server_feature and enable_api_server: + try: + from maim_message.server import WebSocketServer, ServerConfig + from maim_message.message import APIMessageBase + + api_logger = get_logger("maim_message_api_server") + + # 1. Prepare Config + api_server_host = maim_message_config.api_server_host + api_server_port = maim_message_config.api_server_port + use_wss = maim_message_config.api_server_use_wss + + server_config = ServerConfig( + host=api_server_host, + port=api_server_port, + ssl_enabled=use_wss, + ssl_certfile=maim_message_config.api_server_cert_file if use_wss else None, + ssl_keyfile=maim_message_config.api_server_key_file if use_wss else None, + ) + + # 2. Setup Auth Handler + async def auth_handler(metadata: dict) -> bool: + allowed_keys = maim_message_config.api_server_allowed_api_keys + # If list is empty/None, allow all (default behavior of returning True) + if not allowed_keys: + return True + + api_key = metadata.get("api_key") + if api_key in allowed_keys: + return True + + api_logger.warning(f"Rejected connection with invalid API Key: {api_key}") + return False + + server_config.on_auth = auth_handler + + # 3. Setup Message Bridge + # Initialize refined route map if not exists + if not hasattr(global_api, "platform_map"): + global_api.platform_map = {} + + async def bridge_message_handler(message: APIMessageBase, metadata: dict): + # Bridge message to the main bot logic + # We convert APIMessageBase to dict to be compatible with legacy handlers + # that MainBot (ChatManager) expects. + msg_dict = message.to_dict() + + # Compatibility Layer: Flatten sender_info to top-level user_info/group_info + # Legacy MessageBase expects message_info to have user_info and group_info directly. + if "message_info" in msg_dict: + msg_info = msg_dict["message_info"] + sender_info = msg_info.get("sender_info") + if sender_info: + # If direct user_info/group_info are missing, populate them from sender_info + if "user_info" not in msg_info and (ui := sender_info.get("user_info")): + msg_info["user_info"] = ui + + if "group_info" not in msg_info and (gi := sender_info.get("group_info")): + msg_info["group_info"] = gi + + # Route Caching Logic: Simply map platform to API Key + # This allows us to send messages back to the correct API client for this platform + try: + api_key = metadata.get("api_key") + if api_key: + platform = msg_info.get("platform") + if platform: + global_api.platform_map[platform] = api_key + except Exception as e: + api_logger.warning(f"Failed to update platform map: {e}") + + # Compatibility Layer: Ensure raw_message exists (even if None) as it's part of MessageBase + if "raw_message" not in msg_dict: + msg_dict["raw_message"] = None + + await global_api.process_message(msg_dict) + + server_config.on_message = bridge_message_handler + + # 4. Initialize Server + extra_server = WebSocketServer(config=server_config) + + # 5. Patch global_api lifecycle methods to manage both servers + original_run = global_api.run + original_stop = global_api.stop + + async def patched_run(): + api_logger.info(f"Starting Additional API Server on {api_server_host}:{api_server_port} (WSS: {use_wss})") + # Start the extra server (non-blocking start) + await extra_server.start() + # Run the original legacy server (this usually keeps running) + await original_run() + + async def patched_stop(): + api_logger.info("Stopping Additional API Server...") + await extra_server.stop() + await original_stop() + + global_api.run = patched_run + global_api.stop = patched_stop + + # Attach for reference + global_api.extra_server = extra_server + + except ImportError: + get_logger("maim_message").error("Cannot import maim_message.server components. Is maim_message >= 0.6.0 installed?") + except Exception as e: + get_logger("maim_message").error(f"Failed to initialize Additional API Server: {e}") + import traceback + get_logger("maim_message").debug(traceback.format_exc()) + return global_api diff --git a/src/common/message_repository.py b/src/common/message_repository.py index fb9120ac..fa0126d4 100644 --- a/src/common/message_repository.py +++ b/src/common/message_repository.py @@ -25,6 +25,7 @@ def find_messages( limit_mode: str = "latest", filter_bot=False, filter_command=False, + filter_intercept_message_level: Optional[int] = None, ) -> List[DatabaseMessages]: """ 根据提供的过滤器、排序和限制条件查找消息。 @@ -84,6 +85,10 @@ def find_messages( # 使用按位取反构造 Peewee 的 NOT 条件,避免直接与 False 比较 query = query.where(~Messages.is_command) + if filter_intercept_message_level is not None: + # 过滤掉所有 intercept_message_level > filter_intercept_message_level 的消息 + query = query.where(Messages.intercept_message_level <= filter_intercept_message_level) + if limit > 0: if limit_mode == "earliest": # 获取时间最早的 limit 条记录,已经是正序 diff --git a/src/common/toml_utils.py b/src/common/toml_utils.py new file mode 100644 index 00000000..6a7b8bb9 --- /dev/null +++ b/src/common/toml_utils.py @@ -0,0 +1,125 @@ +""" +TOML 工具函数 + +提供 TOML 文件的格式化保存功能,确保数组等元素以美观的多行格式输出。 +""" + +import re +from typing import Any +import tomlkit +from tomlkit.items import AoT, Table, Array + + +def _format_toml_value(obj: Any, threshold: int, depth: int = 0) -> Any: + """递归格式化 TOML 值,将数组转换为多行格式""" + # 处理 AoT (Array of Tables) - 保持原样,递归处理内部 + if isinstance(obj, AoT): + for item in obj: + _format_toml_value(item, threshold, depth) + return obj + + # 处理字典类型 (dict 或 Table) + if isinstance(obj, (dict, Table)): + for k, v in obj.items(): + obj[k] = _format_toml_value(v, threshold, depth) + return obj + + # 处理列表类型 (list 或 Array) + if isinstance(obj, (list, Array)): + # 如果是纯 list (非 tomlkit Array) 且包含字典/表,视为 AoT 的列表形式 + # 保持结构递归处理,避免转换为 Inline Table Array (因为 Inline Table 必须单行,复杂对象不友好) + if isinstance(obj, list) and not isinstance(obj, Array) and obj and isinstance(obj[0], (dict, Table)): + for i, item in enumerate(obj): + obj[i] = _format_toml_value(item, threshold, depth) + return obj + + # 决定是否多行:仅在顶层且长度超过阈值时 + should_multiline = depth == 0 and len(obj) > threshold + + # 如果已经是 tomlkit Array,原地修改以保留注释 + if isinstance(obj, Array): + obj.multiline(should_multiline) + for i, item in enumerate(obj): + obj[i] = _format_toml_value(item, threshold, depth + 1) + return obj + + # 普通 list:转换为 tomlkit 数组 + arr = tomlkit.array() + arr.multiline(should_multiline) + + for item in obj: + arr.append(_format_toml_value(item, threshold, depth + 1)) + return arr + + # 其他基本类型直接返回 + return obj + + +def _update_toml_doc(target: Any, source: Any) -> None: + """ + 递归合并字典,将 source 的值更新到 target 中,保留 target 的注释和格式。 + - 已存在的键:更新值(递归处理嵌套字典) + - 新增的键:添加到 target + - 跳过 version 字段 + """ + if isinstance(source, list) or not isinstance(source, dict) or not isinstance(target, dict): + return + + for key, value in source.items(): + if key == "version": + continue + if key in target: + # 已存在的键:递归更新或直接赋值 + target_value = target[key] + if isinstance(value, dict) and isinstance(target_value, dict): + _update_toml_doc(target_value, value) + else: + try: + target[key] = tomlkit.item(value) + except (TypeError, ValueError): + target[key] = value + else: + # 新增的键:添加到 target + try: + target[key] = tomlkit.item(value) + except (TypeError, ValueError): + target[key] = value + + +def save_toml_with_format( + data: Any, file_path: str, multiline_threshold: int = 1, preserve_comments: bool = True +) -> None: + """ + 格式化 TOML 数据并保存到文件。 + + Args: + data: 要保存的数据(dict 或 tomlkit 文档) + file_path: 保存路径 + multiline_threshold: 数组多行格式化阈值,-1 表示不格式化 + preserve_comments: 是否保留原文件的注释和格式(默认 True) + 若为 True 且文件已存在且 data 不是 tomlkit 文档,会先读取原文件,再将 data 合并进去 + """ + import os + from tomlkit import TOMLDocument + + # 如果需要保留注释、文件存在、且 data 不是已有的 tomlkit 文档,先读取原文件再合并 + if preserve_comments and os.path.exists(file_path) and not isinstance(data, TOMLDocument): + with open(file_path, "r", encoding="utf-8") as f: + doc = tomlkit.load(f) + _update_toml_doc(doc, data) + data = doc + + formatted = _format_toml_value(data, multiline_threshold) if multiline_threshold >= 0 else data + output = tomlkit.dumps(formatted) + # 规范化:将 3+ 连续空行压缩为 1 个空行,防止空行累积 + output = re.sub(r"\n{3,}", "\n\n", output) + with open(file_path, "w", encoding="utf-8") as f: + f.write(output) + + +def format_toml_string(data: Any, multiline_threshold: int = 1) -> str: + """格式化 TOML 数据并返回字符串""" + formatted = _format_toml_value(data, multiline_threshold) if multiline_threshold >= 0 else data + output = tomlkit.dumps(formatted) + # 规范化:将 3+ 连续空行压缩为 1 个空行,防止空行累积 + return re.sub(r"\n{3,}", "\n\n", output) diff --git a/src/config/api_ada_configs.py b/src/config/api_ada_configs.py index 3fc9c878..a5d5f059 100644 --- a/src/config/api_ada_configs.py +++ b/src/config/api_ada_configs.py @@ -60,6 +60,12 @@ class ModelInfo(ConfigBase): price_out: float = field(default=0.0) """每M token输出价格""" + temperature: float | None = field(default=None) + """模型级别温度(可选),会覆盖任务配置中的温度""" + + max_tokens: int | None = field(default=None) + """模型级别最大token数(可选),会覆盖任务配置中的max_tokens""" + force_stream_mode: bool = field(default=False) """是否强制使用流式输出模式""" @@ -88,6 +94,9 @@ class TaskConfig(ConfigBase): temperature: float = 0.3 """模型温度""" + slow_threshold: float = 15.0 + """慢请求阈值(秒),超过此值会输出警告日志""" + @dataclass class ModelTaskConfig(ConfigBase): diff --git a/src/config/config.py b/src/config/config.py index 01b9f6ca..4001d4ff 100644 --- a/src/config/config.py +++ b/src/config/config.py @@ -11,6 +11,7 @@ from rich.traceback import install from typing import List, Optional from src.common.logger import get_logger +from src.common.toml_utils import format_toml_string from src.config.config_base import ConfigBase from src.config.official_configs import ( BotConfig, @@ -30,10 +31,10 @@ from src.config.official_configs import ( RelationshipConfig, ToolConfig, VoiceConfig, - MoodConfig, MemoryConfig, DebugConfig, - JargonConfig, + DreamConfig, + WebUIConfig, ) from .api_ada_configs import ( @@ -56,7 +57,7 @@ TEMPLATE_DIR = os.path.join(PROJECT_ROOT, "template") # 考虑到,实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码 # 对该字段的更新,请严格参照语义化版本规范:https://semver.org/lang/zh-CN/ -MMC_VERSION = "0.11.5" +MMC_VERSION = "0.12.0" def get_key_comment(toml_table, key): @@ -252,7 +253,7 @@ def _update_config_generic(config_name: str, template_name: str): # 如果配置有更新,立即保存到文件 if config_updated: with open(old_config_path, "w", encoding="utf-8") as f: - f.write(tomlkit.dumps(old_config)) + f.write(format_toml_string(old_config)) logger.info(f"已保存更新后的{config_name}配置文件") else: logger.info(f"未检测到{config_name}模板默认值变动") @@ -313,9 +314,9 @@ def _update_config_generic(config_name: str, template_name: str): logger.info(f"开始合并{config_name}新旧配置...") _update_dict(new_config, old_config) - # 保存更新后的配置(保留注释和格式) + # 保存更新后的配置(保留注释和格式,数组多行格式化) with open(new_config_path, "w", encoding="utf-8") as f: - f.write(tomlkit.dumps(new_config)) + f.write(format_toml_string(new_config)) logger.info(f"{config_name}配置文件更新完成,建议检查新配置文件中的内容,以免丢失重要信息") @@ -347,15 +348,15 @@ class Config(ConfigBase): response_post_process: ResponsePostProcessConfig response_splitter: ResponseSplitterConfig telemetry: TelemetryConfig + webui: WebUIConfig experimental: ExperimentalConfig maim_message: MaimMessageConfig lpmm_knowledge: LPMMKnowledgeConfig tool: ToolConfig memory: MemoryConfig debug: DebugConfig - mood: MoodConfig voice: VoiceConfig - jargon: JargonConfig + dream: DreamConfig @dataclass diff --git a/src/config/official_configs.py b/src/config/official_configs.py index fc084ecb..38665e6d 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -43,10 +43,13 @@ class PersonalityConfig(ConfigBase): """人格""" reply_style: str = "" - """表达风格""" + """默认表达风格""" - interest: str = "" - """兴趣""" + multiple_reply_style: list[str] = field(default_factory=lambda: []) + """可选的多种表达风格列表,当配置不为空时可按概率随机替换 reply_style""" + + multiple_probability: float = 0.0 + """每次构建回复时,从 multiple_reply_style 中随机替换 reply_style 的概率(0.0-1.0)""" plan_style: str = "" """说话规则,行为风格""" @@ -79,12 +82,6 @@ class ChatConfig(ConfigBase): max_context_size: int = 18 """上下文长度""" - interest_rate_mode: Literal["fast", "accurate"] = "fast" - """兴趣值计算模式,fast为快速计算,accurate为精确计算""" - - planner_size: float = 1.5 - """副规划器大小,越小,麦麦的动作执行能力越精细,但是消耗更多token,调大可以缓解429类错误""" - mentioned_bot_reply: bool = True """是否启用提及必回复""" @@ -117,8 +114,13 @@ class ChatConfig(ConfigBase): 时间区间支持跨夜,例如 "23:00-02:00"。 """ - include_planner_reasoning: bool = False - """是否将planner推理加入replyer,默认关闭(不加入)""" + think_mode: Literal["classic", "deep", "dynamic"] = "classic" + """ + 思考模式配置 + - classic: 默认think_level为0(轻量回复,不需要思考和回忆) + - deep: 默认think_level为1(深度回复,需要进行回忆和思考) + - dynamic: think_level由planner动态给出(根据planner返回的think_level决定) + """ def _parse_stream_config_to_chat_id(self, stream_config_str: str) -> Optional[str]: """与 ChatStream.get_stream_id 一致地从 "platform:id:type" 生成 chat_id。""" @@ -133,14 +135,9 @@ class ChatConfig(ConfigBase): is_group = stream_type == "group" - import hashlib + from src.chat.message_receive.chat_stream import get_chat_manager - if is_group: - components = [platform, str(id_str)] - else: - components = [platform, str(id_str), "private"] - key = "_".join(components) - return hashlib.md5(key.encode()).hexdigest() + return get_chat_manager().get_stream_id(platform, str(id_str), is_group=is_group) except (ValueError, IndexError): return None @@ -173,7 +170,11 @@ class ChatConfig(ConfigBase): def get_talk_value(self, chat_id: Optional[str]) -> float: """根据规则返回当前 chat 的动态 talk_value,未匹配则回退到基础值。""" if not self.enable_talk_value_rules or not self.talk_value_rules: - return self.talk_value + result = self.talk_value + # 防止返回0值,自动转换为0.0001 + if result == 0: + return 0.0000001 + return result now_min = self._now_minutes() @@ -199,7 +200,11 @@ class ChatConfig(ConfigBase): start_min, end_min = parsed if self._in_range(now_min, start_min, end_min): try: - return float(value) + result = float(value) + # 防止返回0值,自动转换为0.0001 + if result == 0: + return 0.0000001 + return result except Exception: continue @@ -218,12 +223,20 @@ class ChatConfig(ConfigBase): start_min, end_min = parsed if self._in_range(now_min, start_min, end_min): try: - return float(value) + result = float(value) + # 防止返回0值,自动转换为0.0001 + if result == 0: + return 0.0000001 + return result except Exception: continue # 3) 未命中规则返回基础值 - return self.talk_value + result = self.talk_value + # 防止返回0值,自动转换为0.0001 + if result == 0: + return 0.0000001 + return result @dataclass @@ -244,10 +257,21 @@ class MemoryConfig(ConfigBase): max_agent_iterations: int = 5 """Agent最多迭代轮数(最低为1)""" + agent_timeout_seconds: float = 120.0 + """Agent超时时间(秒)""" + + enable_jargon_detection: bool = True + """记忆检索过程中是否启用黑话识别""" + + global_memory: bool = False + """是否允许记忆检索在聊天记录中进行全局查询(忽略当前chat_id,仅对 search_chat_history 等工具生效)""" + def __post_init__(self): """验证配置值""" if self.max_agent_iterations < 1: raise ValueError(f"max_agent_iterations 必须至少为1,当前值: {self.max_agent_iterations}") + if self.agent_timeout_seconds <= 0: + raise ValueError(f"agent_timeout_seconds 必须大于0,当前值: {self.agent_timeout_seconds}") @dataclass @@ -257,20 +281,20 @@ class ExpressionConfig(ConfigBase): learning_list: list[list] = field(default_factory=lambda: []) """ 表达学习配置列表,支持按聊天流配置 - 格式: [["chat_stream_id", "use_expression", "enable_learning", learning_intensity], ...] + 格式: [["chat_stream_id", "use_expression", "enable_learning", "enable_jargon_learning"], ...] 示例: [ - ["", "enable", "enable", 1.0], # 全局配置:使用表达,启用学习,学习强度1.0 - ["qq:1919810:private", "enable", "enable", 1.5], # 特定私聊配置:使用表达,启用学习,学习强度1.5 - ["qq:114514:private", "enable", "disable", 0.5], # 特定私聊配置:使用表达,禁用学习,学习强度0.5 + ["", "enable", "enable", "enable"], # 全局配置:使用表达,启用学习,启用jargon学习 + ["qq:1919810:private", "enable", "enable", "enable"], # 特定私聊配置:使用表达,启用学习,启用jargon学习 + ["qq:114514:private", "enable", "disable", "disable"], # 特定私聊配置:使用表达,禁用学习,禁用jargon学习 ] 说明: - 第一位: chat_stream_id,空字符串表示全局配置 - 第二位: 是否使用学到的表达 ("enable"/"disable") - 第三位: 是否学习表达 ("enable"/"disable") - - 第四位: 学习强度(浮点数),影响学习频率,最短学习时间间隔 = 300/学习强度(秒) + - 第四位: 是否启用jargon学习 ("enable"/"disable") """ expression_groups: list[list[str]] = field(default_factory=list) @@ -279,6 +303,33 @@ class ExpressionConfig(ConfigBase): 格式: [["qq:12345:group", "qq:67890:private"]] """ + reflect: bool = False + """是否启用表达反思""" + + reflect_operator_id: str = "" + """表达反思操作员ID""" + + allow_reflect: list[str] = field(default_factory=list) + """ + 允许进行表达反思的聊天流ID列表 + 格式: ["qq:123456:private", "qq:654321:group", ...] + 只有在此列表中的聊天流才会提出问题并跟踪 + 如果列表为空,则所有聊天流都可以进行表达反思(前提是 reflect = true) + """ + + all_global_jargon: bool = False + """是否将所有新增的jargon项目默认为全局(is_global=True),chat_id记录第一次存储时的id。注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除""" + + enable_jargon_explanation: bool = True + """是否在回复前尝试对上下文中的黑话进行解释(关闭可减少一次LLM调用,仅影响回复前的黑话匹配与解释,不影响黑话学习)""" + + jargon_mode: Literal["context", "planner"] = "context" + """ + 黑话解释来源模式: + - "context": 使用上下文自动匹配黑话并解释(原有模式) + - "planner": 仅使用 Planner 在 reply 动作中给出的 unknown_words 列表进行黑话检索 + """ + def _parse_stream_config_to_chat_id(self, stream_config_str: str) -> Optional[str]: """ 解析流配置字符串并生成对应的 chat_id @@ -301,20 +352,15 @@ class ExpressionConfig(ConfigBase): # 判断是否为群聊 is_group = stream_type == "group" - # 使用与 ChatStream.get_stream_id 相同的逻辑生成 chat_id - import hashlib + # 使用 ChatManager 提供的接口生成 chat_id,避免在此重复实现逻辑 + from src.chat.message_receive.chat_stream import get_chat_manager - if is_group: - components = [platform, str(id_str)] - else: - components = [platform, str(id_str), "private"] - key = "_".join(components) - return hashlib.md5(key.encode()).hexdigest() + return get_chat_manager().get_stream_id(platform, str(id_str), is_group=is_group) except (ValueError, IndexError): return None - def get_expression_config_for_chat(self, chat_stream_id: Optional[str] = None) -> tuple[bool, bool, int]: + def get_expression_config_for_chat(self, chat_stream_id: Optional[str] = None) -> tuple[bool, bool, bool]: """ 根据聊天流ID获取表达配置 @@ -322,11 +368,11 @@ class ExpressionConfig(ConfigBase): chat_stream_id: 聊天流ID,格式为哈希值 Returns: - tuple: (是否使用表达, 是否学习表达, 学习间隔) + tuple: (是否使用表达, 是否学习表达, 是否启用jargon学习) """ if not self.learning_list: - # 如果没有配置,使用默认值:启用表达,启用学习,300秒间隔 - return True, True, 300 + # 如果没有配置,使用默认值:启用表达,启用学习,启用jargon学习 + return True, True, True # 优先检查聊天流特定的配置 if chat_stream_id: @@ -339,10 +385,10 @@ class ExpressionConfig(ConfigBase): if global_expression_config is not None: return global_expression_config - # 如果都没有匹配,返回默认值 - return True, True, 300 + # 如果都没有匹配,返回默认值:启用表达,启用学习,启用jargon学习 + return True, True, True - def _get_stream_specific_config(self, chat_stream_id: str) -> Optional[tuple[bool, bool, int]]: + def _get_stream_specific_config(self, chat_stream_id: str) -> Optional[tuple[bool, bool, bool]]: """ 获取特定聊天流的表达配置 @@ -350,7 +396,7 @@ class ExpressionConfig(ConfigBase): chat_stream_id: 聊天流ID(哈希值) Returns: - tuple: (是否使用表达, 是否学习表达, 学习间隔),如果没有配置则返回 None + tuple: (是否使用表达, 是否学习表达, 是否启用jargon学习),如果没有配置则返回 None """ for config_item in self.learning_list: if not config_item or len(config_item) < 4: @@ -375,19 +421,19 @@ class ExpressionConfig(ConfigBase): try: use_expression: bool = config_item[1].lower() == "enable" enable_learning: bool = config_item[2].lower() == "enable" - learning_intensity: float = float(config_item[3]) - return use_expression, enable_learning, learning_intensity # type: ignore + enable_jargon_learning: bool = config_item[3].lower() == "enable" + return use_expression, enable_learning, enable_jargon_learning # type: ignore except (ValueError, IndexError): continue return None - def _get_global_config(self) -> Optional[tuple[bool, bool, int]]: + def _get_global_config(self) -> Optional[tuple[bool, bool, bool]]: """ 获取全局表达配置 Returns: - tuple: (是否使用表达, 是否学习表达, 学习间隔),如果没有配置则返回 None + tuple: (是否使用表达, 是否学习表达, 是否启用jargon学习),如果没有配置则返回 None """ for config_item in self.learning_list: if not config_item or len(config_item) < 4: @@ -398,8 +444,8 @@ class ExpressionConfig(ConfigBase): try: use_expression: bool = config_item[1].lower() == "enable" enable_learning: bool = config_item[2].lower() == "enable" - learning_intensity = float(config_item[3]) - return use_expression, enable_learning, learning_intensity # type: ignore + enable_jargon_learning: bool = config_item[3].lower() == "enable" + return use_expression, enable_learning, enable_jargon_learning # type: ignore except (ValueError, IndexError): continue @@ -414,20 +460,6 @@ class ToolConfig(ConfigBase): """是否在聊天中启用工具""" -@dataclass -class MoodConfig(ConfigBase): - """情绪配置类""" - - enable_mood: bool = True - """是否启用情绪系统""" - - mood_update_threshold: float = 1 - """情绪更新阈值,越高,更新越慢""" - - emotion_style: str = "情绪较为稳定,但遭遇特定事件的时候起伏较大" - """情感特征,影响情绪的变化情况""" - - @dataclass class VoiceConfig(ConfigBase): """语音识别配置类""" @@ -565,6 +597,35 @@ class TelemetryConfig(ConfigBase): """是否启用遥测""" +@dataclass +class WebUIConfig(ConfigBase): + """WebUI配置类 + + 注意: host 和 port 配置已移至环境变量 WEBUI_HOST 和 WEBUI_PORT + """ + + enabled: bool = True + """是否启用WebUI""" + + mode: Literal["development", "production"] = "production" + """运行模式:development(开发) 或 production(生产)""" + + anti_crawler_mode: Literal["false", "strict", "loose", "basic"] = "basic" + """防爬虫模式:false(禁用) / strict(严格) / loose(宽松) / basic(基础-只记录不阻止)""" + + allowed_ips: str = "127.0.0.1" + """IP白名单(逗号分隔,支持精确IP、CIDR格式和通配符)""" + + trusted_proxies: str = "" + """信任的代理IP列表(逗号分隔),只有来自这些IP的X-Forwarded-For才被信任""" + + trust_xff: bool = False + """是否启用X-Forwarded-For代理解析(默认false)""" + + secure_cookie: bool = False + """是否启用安全Cookie(仅通过HTTPS传输,默认false)""" + + @dataclass class DebugConfig(ConfigBase): """调试配置类""" @@ -622,29 +683,29 @@ class ExperimentalConfig(ConfigBase): class MaimMessageConfig(ConfigBase): """maim_message配置类""" - use_custom: bool = False - """是否使用自定义的maim_message配置""" - - host: str = "127.0.0.1" - """主机地址""" - - port: int = 8090 - """"端口号""" - - mode: Literal["ws", "tcp"] = "ws" - """连接模式,支持ws和tcp""" - - use_wss: bool = False - """是否使用WSS安全连接""" - - cert_file: str = "" - """SSL证书文件路径,仅在use_wss=True时有效""" - - key_file: str = "" - """SSL密钥文件路径,仅在use_wss=True时有效""" - auth_token: list[str] = field(default_factory=lambda: []) - """认证令牌,用于API验证,为空则不启用验证""" + """认证令牌,用于旧版API验证,为空则不启用验证""" + + enable_api_server: bool = False + """是否启用额外的新版API Server""" + + api_server_host: str = "0.0.0.0" + """新版API Server主机地址""" + + api_server_port: int = 8090 + """新版API Server端口号""" + + api_server_use_wss: bool = False + """新版API Server是否启用WSS""" + + api_server_cert_file: str = "" + """新版API Server SSL证书文件路径""" + + api_server_key_file: str = "" + """新版API Server SSL密钥文件路径""" + + api_server_allowed_api_keys: list[str] = field(default_factory=lambda: []) + """新版API Server允许的API Key列表,为空则允许所有连接""" @dataclass @@ -690,10 +751,107 @@ class LPMMKnowledgeConfig(ConfigBase): embedding_dimension: int = 1024 """嵌入向量维度,应该与模型的输出维度一致""" + max_embedding_workers: int = 3 + """嵌入/抽取并发线程数""" + + embedding_chunk_size: int = 4 + """每批嵌入的条数""" + + max_synonym_entities: int = 2000 + """同义边参与的实体数上限,超限则跳过""" + + enable_ppr: bool = True + """是否启用PPR,低配机器可关闭""" + @dataclass -class JargonConfig(ConfigBase): - """Jargon配置类""" +class DreamConfig(ConfigBase): + """Dream配置类""" - all_global: bool = False - """是否将所有新增的jargon项目默认为全局(is_global=True),chat_id记录第一次存储时的id""" + interval_minutes: int = 30 + """做梦时间间隔(分钟),默认30分钟""" + + max_iterations: int = 20 + """做梦最大轮次,默认20轮""" + + first_delay_seconds: int = 60 + """程序启动后首次做梦前的延迟时间(秒),默认60秒""" + + dream_send: str = "" + """ + 做梦结果推送目标,格式为 "platform:user_id" + 例如: "qq:123456" 表示在做梦结束后,将梦境文本额外发送给该QQ私聊用户。 + 为空字符串时不推送。 + """ + + dream_time_ranges: list[str] = field(default_factory=lambda: []) + """ + 做梦时间段配置列表,格式:["HH:MM-HH:MM", ...] + 如果列表为空,则表示全天允许做梦。 + 如果配置了时间段,则只有在这些时间段内才会实际执行做梦流程。 + 时间段外,调度器仍会按间隔检查,但不会进入做梦流程。 + + 示例: + [ + "09:00-22:00", # 白天允许做梦 + "23:00-02:00", # 跨夜时间段(23:00到次日02:00) + ] + + 支持跨夜区间,例如 "23:00-02:00" 表示从23:00到次日02:00。 + """ + + def _now_minutes(self) -> int: + """返回本地时间的分钟数(0-1439)。""" + lt = time.localtime() + return lt.tm_hour * 60 + lt.tm_min + + def _parse_range(self, range_str: str) -> Optional[tuple[int, int]]: + """解析 "HH:MM-HH:MM" 到 (start_min, end_min)。""" + try: + start_str, end_str = [s.strip() for s in range_str.split("-")] + sh, sm = [int(x) for x in start_str.split(":")] + eh, em = [int(x) for x in end_str.split(":")] + return sh * 60 + sm, eh * 60 + em + except Exception: + return None + + def _in_range(self, now_min: int, start_min: int, end_min: int) -> bool: + """ + 判断 now_min 是否在 [start_min, end_min] 区间内。 + 支持跨夜:如果 start > end,则表示跨越午夜。 + """ + if start_min <= end_min: + return start_min <= now_min <= end_min + # 跨夜:例如 23:00-02:00 + return now_min >= start_min or now_min <= end_min + + def is_in_dream_time(self) -> bool: + """ + 检查当前时间是否在允许做梦的时间段内。 + 如果 dream_time_ranges 为空,则返回 True(全天允许)。 + """ + if not self.dream_time_ranges: + return True + + now_min = self._now_minutes() + + for time_range in self.dream_time_ranges: + if not isinstance(time_range, str): + continue + parsed = self._parse_range(time_range) + if not parsed: + continue + start_min, end_min = parsed + if self._in_range(now_min, start_min, end_min): + return True + + return False + + def __post_init__(self): + """验证配置值""" + if self.interval_minutes < 1: + raise ValueError(f"interval_minutes 必须至少为1,当前值: {self.interval_minutes}") + if self.max_iterations < 1: + raise ValueError(f"max_iterations 必须至少为1,当前值: {self.max_iterations}") + if self.first_delay_seconds < 0: + raise ValueError(f"first_delay_seconds 不能为负数,当前值: {self.first_delay_seconds}") diff --git a/src/dream/dream_agent.py b/src/dream/dream_agent.py new file mode 100644 index 00000000..b516a88e --- /dev/null +++ b/src/dream/dream_agent.py @@ -0,0 +1,580 @@ +import asyncio +import random +import time +from typing import Any, Dict, List, Optional, Tuple + +from peewee import fn + +from src.common.logger import get_logger +from src.config.config import global_config, model_config +from src.common.database.database_model import ChatHistory +from src.chat.utils.prompt_builder import Prompt, global_prompt_manager +from src.llm_models.payload_content.message import MessageBuilder, RoleType, Message +from src.plugin_system.apis import llm_api +from src.dream.dream_generator import generate_dream_summary + +# dream 工具工厂函数 +from src.dream.tools.search_chat_history_tool import make_search_chat_history +from src.dream.tools.get_chat_history_detail_tool import make_get_chat_history_detail +from src.dream.tools.delete_chat_history_tool import make_delete_chat_history +from src.dream.tools.create_chat_history_tool import make_create_chat_history +from src.dream.tools.update_chat_history_tool import make_update_chat_history +from src.dream.tools.finish_maintenance_tool import make_finish_maintenance +from src.dream.tools.search_jargon_tool import make_search_jargon +from src.dream.tools.delete_jargon_tool import make_delete_jargon +from src.dream.tools.update_jargon_tool import make_update_jargon + +logger = get_logger("dream_agent") + + +def init_dream_prompts() -> None: + """初始化 dream agent 的提示词""" + Prompt( + """ +你的名字是{bot_name},你现在处于"梦境维护模式(dream agent)"。 +你可以自由地在 ChatHistory 库中探索、整理、创建和删改记录,以帮助自己在未来更好地回忆和理解对话历史。 + +本轮要维护的聊天ID:{chat_id} +本轮随机选中的起始记忆 ID:{start_memory_id} +请优先以这条起始记忆为切入点,先理解它的内容与上下文,再决定如何在其附近进行创建新概括、重写或删除等整理操作;如果起始记忆为空,则由你自行选择合适的切入点。 + +你可以使用的工具包括: +**ChatHistory 维护工具:** +- search_chat_history:根据关键词或参与人搜索该 chat_id 下的历史记忆概括列表 +- get_chat_history_detail:查看某条概括的详细内容 +- create_chat_history:根据整理后的理解创建一条新的 ChatHistory 概括记录(主题、概括、关键词、关键信息等) +- update_chat_history:在不改变事实的前提下重写或精炼主题、概括、关键词、关键信息 +- delete_chat_history:删除明显冗余、噪声、错误或无意义的记录,或者非常有时效性的信息,或者无太多有用信息的日常互动。 +你也可以先用 create_chat_history 创建一条新的综合概括,再对旧的冗余记录执行多次 delete_chat_history 来完成“合并”效果。 + +**Jargon(黑话)维护工具(只读,禁止修改):** +- search_jargon:根据一个或多个关键词搜索Jargon 记录,通常是含义不明确的词条或者特殊的缩写 + +**通用工具:** +- finish_maintenance:当你认为当前维护工作已经完成,没有更多需要整理的内容时,调用此工具来结束本次运行 + +**工作目标**: +- 发现冗余、重复或高度相似的记录,并进行合并或删除; +- 发现主题/概括过于含糊、啰嗦或缺少关键信息的记录,进行重写和精简; +- summary要尽可能保持有用的信息; +- 尽量保持信息的真实与可用性,不要凭空捏造事实。 + +**合并准则** +- 你可以新建一个记录,然后删除旧记录来实现合并。 +- 如果两个或多个记录的主题相似,内容是对主题不同方面的信息或讨论,且信息量较少,则可以合并为一条记录。 +- 如果两个记录冲突,可以根据逻辑保留一个或者进行整合,也可以采取更新的记录,删除旧的记录 + +**轮次信息**: +- 本次维护最多执行 {max_iterations} 轮 +- 每轮开始时,系统会告知你当前是第几轮,还剩多少轮 +- 如果提前完成维护工作,可以调用 finish_maintenance 工具主动结束 + +**每一轮的执行方式(必须遵守):** +- 第一步:先用一小段中文自然语言,写出你的「思考」和本轮计划(例如要查什么、准备怎么合并/修改); +- 第二步:在这段思考之后,再通过工具调用来执行你的计划(可以调用 0~N 个工具); +- 第三步:收到工具结果后,在下一轮继续先写出新的思考,再视情况继续调用工具。 + +请不要在没有先写出思考的情况下直接调用工具。 +只输出你的思考内容或工具调用结果,由系统负责真正执行工具调用。 +""", + name="dream_react_head_prompt", + ) + + +class DreamTool: + """dream 模块内部使用的简易工具封装""" + + def __init__(self, name: str, description: str, parameters: List[Tuple], execute_func): + self.name = name + self.description = description + self.parameters = parameters + self.execute_func = execute_func + + def get_tool_definition(self) -> Dict[str, Any]: + return { + "name": self.name, + "description": self.description, + "parameters": self.parameters, + } + + async def execute(self, **kwargs) -> str: + return await self.execute_func(**kwargs) + + +class DreamToolRegistry: + def __init__(self) -> None: + self.tools: Dict[str, DreamTool] = {} + + def register_tool(self, tool: DreamTool) -> None: + """ + 注册或更新 dream 工具。 + 注意:dream agent 每个 chat_id 会重新初始化工具,这里允许覆盖已有同名工具。 + """ + self.tools[tool.name] = tool + logger.info(f"注册/更新 dream 工具: {tool.name}") + + def get_tool(self, name: str) -> Optional[DreamTool]: + return self.tools.get(name) + + def get_tool_definitions(self) -> List[Dict[str, Any]]: + return [tool.get_tool_definition() for tool in self.tools.values()] + + +_dream_tool_registry = DreamToolRegistry() + + +def get_dream_tool_registry() -> DreamToolRegistry: + return _dream_tool_registry + + +def init_dream_tools(chat_id: str) -> None: + """注册 dream agent 可用的 ChatHistory / Jargon 相关工具(限定在当前 chat_id 作用域内)""" + from src.llm_models.payload_content.tool_option import ToolParamType + + # 通过工厂函数生成绑定当前 chat_id 的工具实现 + search_chat_history = make_search_chat_history(chat_id) + get_chat_history_detail = make_get_chat_history_detail(chat_id) + delete_chat_history = make_delete_chat_history(chat_id) + create_chat_history = make_create_chat_history(chat_id) + update_chat_history = make_update_chat_history(chat_id) + finish_maintenance = make_finish_maintenance(chat_id) + + search_jargon = make_search_jargon(chat_id) + delete_jargon = make_delete_jargon(chat_id) + update_jargon = make_update_jargon(chat_id) + + _dream_tool_registry.register_tool( + DreamTool( + "search_chat_history", + "根据关键词或参与人查询当前 chat_id 下的 ChatHistory 概览,便于快速定位相关记忆。", + [ + ( + "keyword", + ToolParamType.STRING, + "关键词(可选,支持多个关键词,可用空格、逗号等分隔)。", + False, + None, + ), + ("participant", ToolParamType.STRING, "参与人昵称(可选)。", False, None), + ], + search_chat_history, + ) + ) + + _dream_tool_registry.register_tool( + DreamTool( + "get_chat_history_detail", + "根据 memory_id 获取单条 ChatHistory 的详细内容,包含主题、概括、关键词、关键信息等字段(不包含原文)。", + [ + ("memory_id", ToolParamType.INTEGER, "ChatHistory 主键 ID。", True, None), + ], + get_chat_history_detail, + ) + ) + + _dream_tool_registry.register_tool( + DreamTool( + "delete_chat_history", + "根据 memory_id 删除一条 ChatHistory 记录(请谨慎使用)。", + [ + ("memory_id", ToolParamType.INTEGER, "需要删除的 ChatHistory 主键 ID。", True, None), + ], + delete_chat_history, + ) + ) + + _dream_tool_registry.register_tool( + DreamTool( + "update_chat_history", + "按字段更新 ChatHistory 记录,可用于清理、重写或补充信息。", + [ + ("memory_id", ToolParamType.INTEGER, "需要更新的 ChatHistory 主键 ID。", True, None), + ("theme", ToolParamType.STRING, "新的主题标题,如果不需要修改可不填。", False, None), + ("summary", ToolParamType.STRING, "新的概括内容,如果不需要修改可不填。", False, None), + ("keywords", ToolParamType.STRING, "新的关键词 JSON 字符串,如 ['关键词1','关键词2']。", False, None), + ("key_point", ToolParamType.STRING, "新的关键信息 JSON 字符串,如 ['要点1','要点2']。", False, None), + ], + update_chat_history, + ) + ) + + _dream_tool_registry.register_tool( + DreamTool( + "create_chat_history", + "根据整理后的理解创建一条新的 ChatHistory 概括记录(主题、概括、关键词、关键信息等)。", + [ + ("theme", ToolParamType.STRING, "新的主题标题(必填)。", True, None), + ("summary", ToolParamType.STRING, "新的概括内容(必填)。", True, None), + ( + "keywords", + ToolParamType.STRING, + "新的关键词 JSON 字符串,如 ['关键词1','关键词2'](必填)。", + True, + None, + ), + ( + "key_point", + ToolParamType.STRING, + "新的关键信息 JSON 字符串,如 ['要点1','要点2'](必填)。", + True, + None, + ), + ("start_time", ToolParamType.STRING, "起始时间戳(秒,Unix 时间,必填)。", True, None), + ("end_time", ToolParamType.STRING, "结束时间戳(秒,Unix 时间,必填)。", True, None), + ], + create_chat_history, + ) + ) + + _dream_tool_registry.register_tool( + DreamTool( + "finish_maintenance", + "结束本次 dream 维护任务。当你认为当前 chat_id 下的维护工作已经完成,没有更多需要整理、合并或修改的内容时,调用此工具来主动结束本次运行。", + [ + ( + "reason", + ToolParamType.STRING, + "结束维护的原因说明(可选),例如 '已完成所有记录的整理' 或 '当前记录质量良好,无需进一步维护'。", + False, + None, + ), + ], + finish_maintenance, + ) + ) + + # ==================== Jargon 维护工具 ==================== + # 注册 Jargon 工具 + _dream_tool_registry.register_tool( + DreamTool( + "search_jargon", + "根据一个或多个关键词搜索当前 chat_id 相关的 Jargon 记录概览(只包含 is_jargon=True,含全局 Jargon),便于快速理解黑话库。", + [ + ("keyword", ToolParamType.STRING, "按一个或多个关键词搜索内容/含义/推断结果(必填)。", True, None), + ], + search_jargon, + ) + ) + + +async def run_dream_agent_once( + chat_id: str, + max_iterations: Optional[int] = None, + start_memory_id: Optional[int] = None, +) -> None: + """ + 运行一次 dream agent,对指定 chat_id 的 ChatHistory 进行最多 max_iterations 轮的整理。 + 如果 max_iterations 为 None,则使用配置文件中的默认值。 + """ + if max_iterations is None: + max_iterations = global_config.dream.max_iterations + + start_ts = time.time() + logger.info(f"[dream] 开始对 chat_id={chat_id} 进行 dream 维护,最多迭代 {max_iterations} 轮") + + # 初始化工具(作用域限定在当前 chat_id) + init_dream_tools(chat_id) + + tool_registry = get_dream_tool_registry() + tool_defs = tool_registry.get_tool_definitions() + + bot_name = global_config.bot.nickname + time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + + head_prompt = await global_prompt_manager.format_prompt( + "dream_react_head_prompt", + bot_name=bot_name, + time_now=time_now, + chat_id=chat_id, + start_memory_id=start_memory_id if start_memory_id is not None else "无(本轮由你自由选择切入点)", + max_iterations=max_iterations, + ) + + conversation_messages: List[Message] = [] + + # 如果提供了起始记忆 ID,则在对话正式开始前,先把这条记忆的详细信息放入上下文, + # 避免 LLM 还需要额外调用一次 get_chat_history_detail 才能看到起始记忆内容。 + if start_memory_id is not None: + try: + record = ChatHistory.get_or_none(ChatHistory.id == start_memory_id) + if record: + start_time_str = ( + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.start_time)) + if record.start_time + else "未知" + ) + end_time_str = ( + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.end_time)) if record.end_time else "未知" + ) + detail_text = ( + f"ID={record.id}\n" + f"chat_id={record.chat_id}\n" + f"时间范围={start_time_str} 至 {end_time_str}\n" + f"主题={record.theme or '无'}\n" + f"关键词={record.keywords or '无'}\n" + f"参与者={record.participants or '无'}\n" + f"概括={record.summary or '无'}\n" + f"关键信息={record.key_point or '无'}" + ) + + logger.debug( + f"[dream] 预加载起始记忆详情 memory_id={start_memory_id}," + f"预览: {detail_text[:200].replace(chr(10), ' ')}" + ) + + start_detail_builder = MessageBuilder() + start_detail_builder.set_role(RoleType.User) + start_detail_builder.add_text_content( + "【起始记忆详情】以下是本轮随机/指定的起始记忆的详细信息,供你在整理时优先参考:\n\n" + detail_text + ) + conversation_messages.append(start_detail_builder.build()) + else: + logger.warning( + f"[dream] 提供的 start_memory_id={start_memory_id} 未找到对应 ChatHistory 记录," + "将不预加载起始记忆详情。" + ) + except Exception as e: + logger.error(f"[dream] 预加载起始记忆详情失败 start_memory_id={start_memory_id}: {e}") + + # 注意:message_factory 必须是同步函数,返回消息列表(不能是 async/coroutine) + def message_factory( + _client, + *, + _head_prompt: str = head_prompt, + _conversation_messages: List[Message] = conversation_messages, + ) -> List[Message]: + messages: List[Message] = [] + system_builder = MessageBuilder() + system_builder.set_role(RoleType.System) + system_builder.add_text_content(_head_prompt) + messages.append(system_builder.build()) + messages.extend(_conversation_messages) + return messages + + for iteration in range(1, max_iterations + 1): + # 在每轮开始时,添加轮次信息到对话中 + remaining_rounds = max_iterations - iteration + 1 + round_info_builder = MessageBuilder() + round_info_builder.set_role(RoleType.User) + round_info_builder.add_text_content( + f"【轮次信息】当前是第 {iteration}/{max_iterations} 轮,还剩 {remaining_rounds} 轮。" + ) + conversation_messages.append(round_info_builder.build()) + + # 调用 LLM 让其决定是否要使用工具 + ( + success, + response, + reasoning_content, + model_name, + tool_calls, + ) = await llm_api.generate_with_model_with_tools_by_message_factory( + message_factory, + model_config=model_config.model_task_config.tool_use, + tool_options=tool_defs, + request_type="dream.react", + ) + + if not success: + logger.error(f"[dream] 第 {iteration} 轮 LLM 调用失败: {response}") + break + + # 先输出「思考」内容,再输出工具调用信息(思考文本较长,仅在 debug 下输出) + thought_log = reasoning_content or (response[:300] if response else "") + if thought_log: + logger.debug(f"[dream] 第 {iteration} 轮思考内容: {thought_log}") + + logger.info( + f"[dream] 第 {iteration} 轮响应,模型={model_name},工具调用数={len(tool_calls) if tool_calls else 0}" + ) + + assistant_msg: Optional[Message] = None + if tool_calls: + builder = MessageBuilder() + builder.set_role(RoleType.Assistant) + if response and response.strip(): + builder.add_text_content(response) + builder.set_tool_calls(tool_calls) + assistant_msg = builder.build() + elif response and response.strip(): + builder = MessageBuilder() + builder.set_role(RoleType.Assistant) + builder.add_text_content(response) + assistant_msg = builder.build() + + if assistant_msg: + conversation_messages.append(assistant_msg) + + # 如果本轮没有工具调用,仅作为思考记录,继续下一轮 + if not tool_calls: + logger.debug(f"[dream] 第 {iteration} 轮未调用任何工具,仅记录思考。") + continue + + # 执行所有工具调用 + tasks = [] + finish_maintenance_called = False + for tc in tool_calls: + tool = tool_registry.get_tool(tc.func_name) + if not tool: + logger.warning(f"[dream] 未知工具:{tc.func_name}") + continue + + # 检测是否调用了 finish_maintenance 工具 + if tc.func_name == "finish_maintenance": + finish_maintenance_called = True + + params = tc.args or {} + + async def _run_single(t: DreamTool, p: Dict[str, Any], call_id: str, it: int): + try: + result = await t.execute(**p) + logger.debug(f"[dream] 第 {it} 轮 工具 {t.name} 执行完成") + return call_id, result + except Exception as e: + logger.error(f"[dream] 工具 {t.name} 执行失败: {e}") + return call_id, f"工具 {t.name} 执行失败: {e}" + + tasks.append(_run_single(tool, params, tc.call_id, iteration)) + + if not tasks: + continue + + tool_results = await asyncio.gather(*tasks, return_exceptions=False) + + # 将工具结果作为 Tool 消息追加 + for call_id, obs in tool_results: + tool_builder = MessageBuilder() + tool_builder.set_role(RoleType.Tool) + tool_builder.add_text_content(str(obs)) + tool_builder.add_tool_call(call_id) + conversation_messages.append(tool_builder.build()) + + # 如果调用了 finish_maintenance 工具,提前结束本次运行 + if finish_maintenance_called: + logger.info(f"[dream] 第 {iteration} 轮检测到 finish_maintenance 工具调用,提前结束本次维护。") + break + + cost = time.time() - start_ts + logger.info(f"[dream] 对 chat_id={chat_id} 的 dream 维护结束,共迭代 {iteration} 轮,耗时 {cost:.1f} 秒") + + # 生成梦境总结 + await generate_dream_summary(chat_id, conversation_messages, iteration, cost) + + +def _pick_random_chat_id() -> Optional[str]: + """从 ChatHistory 中随机选择一个 chat_id,用于 dream agent 本次维护 + + 规则: + - 只在 chat_id 所属的 ChatHistory 记录数 >= 10 时才会参与随机选择; + - 记录数不足 10 的 chat_id 将被跳过,不会触发做梦 react。 + """ + try: + # 统计每个 chat_id 的记录数,只保留记录数 >= 10 的 chat_id + rows = ( + ChatHistory.select(ChatHistory.chat_id, fn.COUNT(ChatHistory.id).alias("cnt")) + .group_by(ChatHistory.chat_id) + .having(fn.COUNT(ChatHistory.id) >= 10) + .order_by(ChatHistory.chat_id) + .limit(200) + ) + eligible_ids = [r.chat_id for r in rows] + if not eligible_ids: + logger.warning("[dream] ChatHistory 中暂无满足条件(记录数 >= 10)的 chat_id,本轮 dream 任务跳过。") + return None + chosen = random.choice(eligible_ids) + logger.info(f"[dream] 从 {len(eligible_ids)} 个满足条件的 chat_id 中随机选择:{chosen}") + return chosen + except Exception as e: + logger.error(f"[dream] 随机选择 chat_id 失败: {e}") + return None + + +def _pick_random_memory_for_chat(chat_id: str) -> Optional[int]: + """ + 在给定 chat_id 下随机选择一条 ChatHistory 记录,作为本轮整理的起始记忆。 + """ + try: + rows = ( + ChatHistory.select(ChatHistory.id) + .where(ChatHistory.chat_id == chat_id) + .order_by(ChatHistory.start_time.asc()) + .limit(200) + ) + ids = [r.id for r in rows] + if not ids: + logger.warning(f"[dream] chat_id={chat_id} 下暂无 ChatHistory 记录,无法选择起始记忆。") + return None + return random.choice(ids) + except Exception as e: + logger.error(f"[dream] 在 chat_id={chat_id} 下随机选择起始记忆失败: {e}") + return None + + +async def run_dream_cycle_once() -> None: + """ + 单次 dream 周期: + - 随机选择一个 chat_id + - 在该 chat_id 下随机选择一条 ChatHistory 作为起始记忆 + - 以这条起始记忆为切入点,对该 chat_id 运行一次 dream agent(最多 15 轮) + """ + chat_id = _pick_random_chat_id() + if not chat_id: + return + + start_memory_id = _pick_random_memory_for_chat(chat_id) + await run_dream_agent_once( + chat_id=chat_id, + max_iterations=None, # 使用配置文件中的默认值 + start_memory_id=start_memory_id, + ) + + +async def start_dream_scheduler( + first_delay_seconds: Optional[int] = None, + interval_seconds: Optional[int] = None, + stop_event: Optional[asyncio.Event] = None, +) -> None: + """ + dream 调度器: + - 程序启动后先等待 first_delay_seconds(如果为 None,则使用配置文件中的值,默认 60s) + - 然后每隔 interval_seconds(如果为 None,则使用配置文件中的值,默认 30 分钟)运行一次 dream agent 周期 + - 如果提供 stop_event,则在 stop_event 被 set() 后优雅退出循环 + """ + if first_delay_seconds is None: + first_delay_seconds = global_config.dream.first_delay_seconds + + if interval_seconds is None: + interval_seconds = global_config.dream.interval_minutes * 60 + + logger.info( + f"[dream] dream 调度器启动:首次延迟 {first_delay_seconds}s,之后每隔 {interval_seconds}s ({interval_seconds // 60} 分钟) 运行一次 dream agent" + ) + + try: + await asyncio.sleep(first_delay_seconds) + while True: + if stop_event is not None and stop_event.is_set(): + logger.info("[dream] 收到停止事件,结束 dream 调度器循环。") + break + + start_ts = time.time() + # 检查当前时间是否在允许做梦的时间段内 + if not global_config.dream.is_in_dream_time(): + logger.debug("[dream] 当前时间不在允许做梦的时间段内,跳过本次执行") + else: + try: + await run_dream_cycle_once() + except Exception as e: + logger.error(f"[dream] 单次 dream 周期执行异常: {e}") + + elapsed = time.time() - start_ts + # 保证两次执行之间至少间隔 interval_seconds + to_sleep = max(0.0, interval_seconds - elapsed) + await asyncio.sleep(to_sleep) + except asyncio.CancelledError: + logger.info("[dream] dream 调度器任务被取消,准备退出。") + raise + + +# 初始化提示词 +init_dream_prompts() diff --git a/src/dream/dream_generator.py b/src/dream/dream_generator.py new file mode 100644 index 00000000..8c4b5bc3 --- /dev/null +++ b/src/dream/dream_generator.py @@ -0,0 +1,251 @@ +import random +from typing import List, Optional + +from src.common.logger import get_logger +from src.config.config import global_config, model_config +from src.chat.utils.prompt_builder import Prompt +from src.llm_models.payload_content.message import RoleType, Message +from src.llm_models.utils_model import LLMRequest +from src.chat.message_receive.chat_stream import get_chat_manager +from src.plugin_system.apis import send_api + +logger = get_logger("dream_generator") + +# 初始化 utils 模型用于生成梦境总结 +_dream_summary_model: Optional[LLMRequest] = None + +# 梦境风格列表(21种) +DREAM_STYLES = [ + "保持诗意和想象力,自由编写", + "诗意朦胧,如薄雾笼罩的清晨", + "奇幻冒险,充满未知与探索", + "温暖怀旧,带着时光的痕迹", + "神秘悬疑,暗藏深意", + "浪漫唯美,如诗如画", + "科幻未来,科技与想象交织", + "自然清新,如山林间的微风", + "深沉哲思,引人深思", + "轻松幽默,充满趣味", + "悲伤忧郁,带着淡淡哀愁", + "激昂热烈,充满活力", + "宁静平和,如湖面般平静", + "荒诞离奇,打破常规", + "细腻温柔,如春风拂面", + "壮阔宏大,气势磅礴", + "简约纯粹,返璞归真", + "复杂多变,层次丰富", + "梦幻迷离,虚实难辨", + "现实写意,贴近生活", + "抽象概念,超越具象", +] + + +def get_random_dream_styles(count: int = 2) -> List[str]: + """从梦境风格列表中随机选择指定数量的风格""" + return random.sample(DREAM_STYLES, min(count, len(DREAM_STYLES))) + + +def get_dream_summary_model() -> LLMRequest: + """获取用于生成梦境总结的 utils 模型实例""" + global _dream_summary_model + if _dream_summary_model is None: + _dream_summary_model = LLMRequest( + model_set=model_config.model_task_config.utils, + request_type="dream.summary", + ) + return _dream_summary_model + + +def init_dream_summary_prompt() -> None: + """初始化梦境总结的提示词""" + Prompt( + """ +你刚刚完成了一次对聊天记录的记忆整理工作。以下是整理过程的摘要: +整理过程: +{conversation_text} + +请将这次整理涉及的相关信息改写为一个富有诗意和想象力的"梦境",请你仅使用具体的记忆的内容,而不是整理过程编写。 +要求: +1. 使用第一人称视角 +2. 叙述直白,不要复杂修辞,口语化 +3. 长度控制在200-800字 +4. 用中文输出 +梦境风格: +{dream_styles} +请直接输出梦境内容,不要添加其他说明: +""", + name="dream_summary_prompt", + ) + + +async def generate_dream_summary( + chat_id: str, + conversation_messages: List[Message], + total_iterations: int, + time_cost: float, +) -> None: + """生成梦境总结,输出到日志,并根据配置可选地推送给指定用户""" + try: + import json + from src.chat.utils.prompt_builder import global_prompt_manager + + # 第一步:建立工具调用结果映射 (call_id -> result) + tool_results_map: dict[str, str] = {} + for msg in conversation_messages: + if msg.role == RoleType.Tool and msg.tool_call_id: + content = "" + if msg.content: + if isinstance(msg.content, list) and msg.content: + content = msg.content[0].text if hasattr(msg.content[0], "text") else str(msg.content[0]) + else: + content = str(msg.content) + tool_results_map[msg.tool_call_id] = content + + # 第二步:详细记录所有工具调用操作和结果到日志 + tool_call_count = 0 + logger.info(f"[dream][工具调用详情] 开始记录 chat_id={chat_id} 的所有工具调用操作:") + + for msg in conversation_messages: + if msg.role == RoleType.Assistant and msg.tool_calls: + tool_call_count += 1 + # 提取思考内容 + thought_content = "" + if msg.content: + if isinstance(msg.content, list) and msg.content: + thought_content = ( + msg.content[0].text if hasattr(msg.content[0], "text") else str(msg.content[0]) + ) + else: + thought_content = str(msg.content) + + logger.info(f"[dream][工具调用详情] === 第 {tool_call_count} 组工具调用 ===") + if thought_content: + logger.info( + f"[dream][工具调用详情] 思考内容:{thought_content[:500]}{'...' if len(thought_content) > 500 else ''}" + ) + + # 记录每个工具调用的详细信息 + for idx, tool_call in enumerate(msg.tool_calls, 1): + tool_name = tool_call.func_name + tool_args = tool_call.args or {} + tool_call_id = tool_call.call_id + tool_result = tool_results_map.get(tool_call_id, "未找到执行结果") + + # 格式化参数 + try: + args_str = json.dumps(tool_args, ensure_ascii=False, indent=2) if tool_args else "无参数" + except Exception: + args_str = str(tool_args) + + logger.info(f"[dream][工具调用详情] --- 工具 {idx}: {tool_name} ---") + logger.info(f"[dream][工具调用详情] 调用参数:\n{args_str}") + logger.info(f"[dream][工具调用详情] 执行结果:\n{tool_result}") + logger.info(f"[dream][工具调用详情] {'-' * 60}") + + logger.info(f"[dream][工具调用详情] 共记录了 {tool_call_count} 组工具调用操作") + + # 第三步:构建对话历史摘要(用于生成梦境) + conversation_summary = [] + for msg in conversation_messages: + role = msg.role.value if hasattr(msg.role, "value") else str(msg.role) + content = "" + if msg.content: + content = msg.content[0].text if isinstance(msg.content, list) and msg.content else str(msg.content) + + if role == "user" and "轮次信息" in content: + # 跳过轮次信息消息 + continue + + if role == "assistant": + # 只保留思考内容,简化工具调用信息 + if content: + # 截取前500字符,避免过长 + content_preview = content[:500] + ("..." if len(content) > 500 else "") + conversation_summary.append(f"[{role}] {content_preview}") + elif role == "tool": + # 工具结果,只保留关键信息 + if content: + # 截取前300字符 + content_preview = content[:300] + ("..." if len(content) > 300 else "") + conversation_summary.append(f"[工具执行] {content_preview}") + + conversation_text = "\n".join(conversation_summary[-20:]) # 只保留最后20条消息 + + # 随机选择2个梦境风格 + selected_styles = get_random_dream_styles(2) + dream_styles_text = "\n".join([f"{i + 1}. {style}" for i, style in enumerate(selected_styles)]) + + # 使用 Prompt 管理器格式化梦境生成 prompt + dream_prompt = await global_prompt_manager.format_prompt( + "dream_summary_prompt", + chat_id=chat_id, + total_iterations=total_iterations, + time_cost=time_cost, + conversation_text=conversation_text, + dream_styles=dream_styles_text, + ) + + # 调用 utils 模型生成梦境 + summary_model = get_dream_summary_model() + dream_content, (reasoning, model_name, _) = await summary_model.generate_response_async( + dream_prompt, + max_tokens=512, + temperature=0.8, + ) + + if dream_content: + logger.info(f"[dream][梦境总结] 对 chat_id={chat_id} 的整理过程梦境:\n{dream_content}") + + # 第五步:根据配置决定是否将梦境发送给指定用户 + try: + dream_send_raw = getattr(global_config.dream, "dream_send", "") or "" + dream_send = dream_send_raw.strip() + if dream_send: + parts = dream_send.split(":") + if len(parts) != 2: + logger.warning( + f"[dream][梦境总结] dream_send 配置格式不正确,应为 'platform:user_id',当前值: {dream_send_raw!r}" + ) + else: + platform, user_id = parts[0].strip(), parts[1].strip() + if not platform or not user_id: + logger.warning( + f"[dream][梦境总结] dream_send 平台或用户ID为空,当前值: {dream_send_raw!r}" + ) + else: + # 默认为私聊会话 + stream_id = get_chat_manager().get_stream_id( + platform=platform, + id=str(user_id), + is_group=False, + ) + if not stream_id: + logger.error( + f"[dream][梦境总结] 无法根据 dream_send 找到有效的聊天流," + f"platform={platform!r}, user_id={user_id!r}" + ) + else: + ok = await send_api.text_to_stream( + dream_content, + stream_id=stream_id, + typing=False, + storage_message=True, + ) + if ok: + logger.info( + f"[dream][梦境总结] 已将梦境结果发送给配置的目标用户: {platform}:{user_id}" + ) + else: + logger.error( + f"[dream][梦境总结] 向 {platform}:{user_id} 发送梦境结果失败" + ) + except Exception as send_exc: + logger.error(f"[dream][梦境总结] 发送梦境结果到配置用户时出错: {send_exc}", exc_info=True) + else: + logger.warning("[dream][梦境总结] 未能生成梦境总结") + + except Exception as e: + logger.error(f"[dream][梦境总结] 生成梦境总结失败: {e}", exc_info=True) + + +init_dream_summary_prompt() diff --git a/src/dream/tools/__init__.py b/src/dream/tools/__init__.py new file mode 100644 index 00000000..da5c237e --- /dev/null +++ b/src/dream/tools/__init__.py @@ -0,0 +1,7 @@ +""" +dream agent 工具实现模块。 + +每个工具的具体实现放在独立文件中,通过 make_xxx(chat_id) 工厂函数 +生成绑定到特定 chat_id 的协程函数,由 dream_agent.init_dream_tools 统一注册。 +""" + diff --git a/src/dream/tools/create_chat_history_tool.py b/src/dream/tools/create_chat_history_tool.py new file mode 100644 index 00000000..ccf27e4e --- /dev/null +++ b/src/dream/tools/create_chat_history_tool.py @@ -0,0 +1,63 @@ +import time + +from src.common.logger import get_logger +from src.common.database.database_model import ChatHistory + +logger = get_logger("dream_agent") + + +def make_create_chat_history(chat_id: str): + async def create_chat_history( + theme: str, + summary: str, + keywords: str, + key_point: str, + start_time: float, + end_time: float, + ) -> str: + """创建一条新的 ChatHistory 概括记录(用于整理/合并后的新记忆)""" + try: + logger.info( + f"[dream][tool] 调用 create_chat_history(" + f"theme={bool(theme)}, summary={bool(summary)}, " + f"keywords={bool(keywords)}, key_point={bool(key_point)}, " + f"start_time={start_time}, end_time={end_time}) (chat_id={chat_id})" + ) + + now_ts = time.time() + + # 将传入的 start_time/end_time(如果有)解析为时间戳;否则回退为当前时间 + def _parse_ts(value, default): + if value is None: + return default + try: + return float(value) + except (TypeError, ValueError): + return default + + start_ts = _parse_ts(start_time, now_ts) + end_ts = _parse_ts(end_time, now_ts) + + record = ChatHistory.create( + chat_id=chat_id, + theme=theme, + summary=summary, + keywords=keywords, + key_point=key_point, + # 对于由 dream 整理产生的新概括,时间范围优先使用工具提供的时间,否则使用当前时间占位 + start_time=start_ts, + end_time=end_ts, + ) + + msg = ( + f"已创建新的 ChatHistory 记录,ID={record.id}," + f"theme={record.theme or '无'},summary={'有' if record.summary else '无'}。" + ) + logger.info(f"[dream][tool] create_chat_history 完成: {msg}") + return msg + except Exception as e: + logger.error(f"create_chat_history 失败: {e}") + return f"create_chat_history 执行失败: {e}" + + return create_chat_history + diff --git a/src/dream/tools/delete_chat_history_tool.py b/src/dream/tools/delete_chat_history_tool.py new file mode 100644 index 00000000..6a14d57f --- /dev/null +++ b/src/dream/tools/delete_chat_history_tool.py @@ -0,0 +1,26 @@ +from src.common.logger import get_logger +from src.common.database.database_model import ChatHistory + +logger = get_logger("dream_agent") + + +def make_delete_chat_history(chat_id: str): # chat_id 目前未直接使用,预留以备扩展 + async def delete_chat_history(memory_id: int) -> str: + """删除一条 chat_history 记录""" + try: + logger.info(f"[dream][tool] 调用 delete_chat_history(memory_id={memory_id})") + record = ChatHistory.get_or_none(ChatHistory.id == memory_id) + if not record: + msg = f"未找到 ID={memory_id} 的 ChatHistory 记录,无法删除。" + logger.info(f"[dream][tool] delete_chat_history 未找到记录: {msg}") + return msg + rows = ChatHistory.delete().where(ChatHistory.id == memory_id).execute() + msg = f"已删除 ID={memory_id} 的 ChatHistory 记录,受影响行数={rows}。" + logger.info(f"[dream][tool] delete_chat_history 完成: {msg}") + return msg + except Exception as e: + logger.error(f"delete_chat_history 失败: {e}") + return f"delete_chat_history 执行失败: {e}" + + return delete_chat_history + diff --git a/src/dream/tools/delete_jargon_tool.py b/src/dream/tools/delete_jargon_tool.py new file mode 100644 index 00000000..cfab51aa --- /dev/null +++ b/src/dream/tools/delete_jargon_tool.py @@ -0,0 +1,26 @@ +from src.common.logger import get_logger +from src.common.database.database_model import Jargon + +logger = get_logger("dream_agent") + + +def make_delete_jargon(chat_id: str): # chat_id 目前未直接使用,预留以备扩展 + async def delete_jargon(jargon_id: int) -> str: + """删除一条 Jargon 记录""" + try: + logger.info(f"[dream][tool] 调用 delete_jargon(jargon_id={jargon_id})") + record = Jargon.get_or_none(Jargon.id == jargon_id) + if not record: + msg = f"未找到 ID={jargon_id} 的 Jargon 记录,无法删除。" + logger.info(f"[dream][tool] delete_jargon 未找到记录: {msg}") + return msg + rows = Jargon.delete().where(Jargon.id == jargon_id).execute() + msg = f"已删除 ID={jargon_id} 的 Jargon 记录(内容:{record.content}),受影响行数={rows}。" + logger.info(f"[dream][tool] delete_jargon 完成: {msg}") + return msg + except Exception as e: + logger.error(f"delete_jargon 失败: {e}") + return f"delete_jargon 执行失败: {e}" + + return delete_jargon + diff --git a/src/dream/tools/finish_maintenance_tool.py b/src/dream/tools/finish_maintenance_tool.py new file mode 100644 index 00000000..c2dda545 --- /dev/null +++ b/src/dream/tools/finish_maintenance_tool.py @@ -0,0 +1,17 @@ +from typing import Optional + +from src.common.logger import get_logger + +logger = get_logger("dream_agent") + + +def make_finish_maintenance(chat_id: str): # chat_id 目前未直接使用,预留以备扩展 + async def finish_maintenance(reason: Optional[str] = None) -> str: + """结束本次 dream 维护任务。当你认为当前 chat_id 下的维护工作已经完成,没有更多需要整理的内容时,调用此工具来结束本次运行。""" + reason_text = f",原因:{reason}" if reason else "" + msg = f"DREAM_MAINTENANCE_COMPLETE{reason_text}" + logger.info(f"[dream][tool] 调用 finish_maintenance,结束本次维护{reason_text}") + return msg + + return finish_maintenance + diff --git a/src/dream/tools/get_chat_history_detail_tool.py b/src/dream/tools/get_chat_history_detail_tool.py new file mode 100644 index 00000000..47c427d0 --- /dev/null +++ b/src/dream/tools/get_chat_history_detail_tool.py @@ -0,0 +1,45 @@ +import time + +from src.common.logger import get_logger +from src.common.database.database_model import ChatHistory + +logger = get_logger("dream_agent") + + +def make_get_chat_history_detail(chat_id: str): # chat_id 目前未直接使用,预留以备扩展 + async def get_chat_history_detail(memory_id: int) -> str: + """获取单条 chat_history 的完整内容""" + try: + logger.info(f"[dream][tool] 调用 get_chat_history_detail(memory_id={memory_id})") + record = ChatHistory.get_or_none(ChatHistory.id == memory_id) + if not record: + msg = f"未找到 ID={memory_id} 的 ChatHistory 记录。" + logger.info(f"[dream][tool] get_chat_history_detail 未找到记录: {msg}") + return msg + + # 将时间戳转换为可读时间格式 + start_time_str = ( + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.start_time)) if record.start_time else "未知" + ) + end_time_str = ( + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.end_time)) if record.end_time else "未知" + ) + + result = ( + f"ID={record.id}\n" + # f"chat_id={record.chat_id}\n" + f"时间范围={start_time_str} 至 {end_time_str}\n" + f"主题={record.theme or '无'}\n" + f"关键词={record.keywords or '无'}\n" + f"参与者={record.participants or '无'}\n" + f"概括={record.summary or '无'}\n" + f"关键信息={record.key_point or '无'}" + ) + logger.debug(f"[dream][tool] get_chat_history_detail 成功,预览: {result[:200].replace(chr(10), ' ')}") + return result + except Exception as e: + logger.error(f"get_chat_history_detail 失败: {e}") + return f"get_chat_history_detail 执行失败: {e}" + + return get_chat_history_detail + diff --git a/src/dream/tools/search_chat_history_tool.py b/src/dream/tools/search_chat_history_tool.py new file mode 100644 index 00000000..1de0f253 --- /dev/null +++ b/src/dream/tools/search_chat_history_tool.py @@ -0,0 +1,215 @@ +import json +from typing import List, Optional + +from src.common.logger import get_logger +from src.common.database.database_model import ChatHistory +from src.chat.utils.utils import parse_keywords_string + +logger = get_logger("dream_agent") + + +def make_search_chat_history(chat_id: str): + async def search_chat_history( + keyword: Optional[str] = None, + participant: Optional[str] = None, + ) -> str: + """根据关键词或参与人查询记忆,返回匹配的记忆id、记忆标题theme和关键词keywords(dream 维护专用版本)""" + try: + # 检查参数 + if not keyword and not participant: + return "未指定查询参数(需要提供keyword或participant之一)" + + logger.info( + f"[dream][tool] 调用 search_chat_history(keyword={keyword}, participant={participant}) " + f"(作用域 chat_id={chat_id})" + ) + + # 构建查询条件 + query = ChatHistory.select().where(ChatHistory.chat_id == chat_id) + + # 执行查询(按时间倒序,最近的在前) + records = list(query.order_by(ChatHistory.start_time.desc()).limit(50)) + + filtered_records: List[ChatHistory] = [] + + for record in records: + participant_matched = True # 如果没有participant条件,默认为True + keyword_matched = True # 如果没有keyword条件,默认为True + + # 检查参与人匹配 + if participant: + participant_matched = False + participants_list: List[str] = [] + if record.participants: + try: + participants_data = ( + json.loads(record.participants) + if isinstance(record.participants, str) + else record.participants + ) + if isinstance(participants_data, list): + participants_list = [str(p).lower() for p in participants_data] + except (json.JSONDecodeError, TypeError, ValueError): + pass + + participant_lower = participant.lower().strip() + if participant_lower and any(participant_lower in p for p in participants_list): + participant_matched = True + + # 检查关键词匹配 + if keyword: + keyword_matched = False + # 解析多个关键词(支持空格、逗号等分隔符) + keywords_list = parse_keywords_string(keyword) + if not keywords_list: + keywords_list = [keyword.strip()] if keyword.strip() else [] + + # 转换为小写以便匹配 + keywords_lower = [kw.lower() for kw in keywords_list if kw.strip()] + + if keywords_lower: + # 在theme、keywords、summary、original_text中搜索 + theme = (record.theme or "").lower() + summary = (record.summary or "").lower() + original_text = (record.original_text or "").lower() + + # 解析record中的keywords JSON + record_keywords_list: List[str] = [] + if record.keywords: + try: + keywords_data = ( + json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + ) + if isinstance(keywords_data, list): + record_keywords_list = [str(k).lower() for k in keywords_data] + except (json.JSONDecodeError, TypeError, ValueError): + pass + + # 有容错的全匹配:如果关键词数量>2,允许n-1个关键词匹配;否则必须全部匹配 + matched_count = 0 + for kw in keywords_lower: + kw_matched = ( + kw in theme + or kw in summary + or kw in original_text + or any(kw in k for k in record_keywords_list) + ) + if kw_matched: + matched_count += 1 + + # 计算需要匹配的关键词数量 + total_keywords = len(keywords_lower) + if total_keywords > 2: + # 关键词数量>2,允许n-1个关键词匹配 + required_matches = total_keywords - 1 + else: + # 关键词数量<=2,必须全部匹配 + required_matches = total_keywords + + keyword_matched = matched_count >= required_matches + + # 两者都匹配(如果同时有participant和keyword,需要两者都匹配;如果只有一个条件,只需要该条件匹配) + matched = participant_matched and keyword_matched + + if matched: + filtered_records.append(record) + + if not filtered_records: + if keyword and participant: + keywords_str = "、".join(parse_keywords_string(keyword) if keyword else []) + return f"未找到包含关键词'{keywords_str}'且参与人包含'{participant}'的聊天记录" + elif keyword: + keywords_list = parse_keywords_string(keyword) + keywords_str = "、".join(keywords_list) + if len(keywords_list) > 2: + required_count = len(keywords_list) - 1 + return f"未找到包含至少{required_count}个关键词(共{len(keywords_list)}个)'{keywords_str}'的聊天记录" + else: + return f"未找到包含所有关键词'{keywords_str}'的聊天记录" + elif participant: + return f"未找到参与人包含'{participant}'的聊天记录" + else: + return "未找到相关聊天记录" + + # 如果匹配结果超过20条,不返回具体记录,只返回提示和所有相关关键词 + if len(filtered_records) > 20: + all_keywords_set = set() + for record in filtered_records: + if record.keywords: + try: + keywords_data = ( + json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + ) + if isinstance(keywords_data, list): + for k in keywords_data: + k_str = str(k).strip() + if k_str: + all_keywords_set.add(k_str) + except (json.JSONDecodeError, TypeError, ValueError): + continue + + search_label = keyword or participant or "当前条件" + + if all_keywords_set: + keywords_str = "、".join(sorted(all_keywords_set)) + response_text = ( + f"包含“{search_label}”的结果过多,请尝试更多关键词精确查找\n\n" + f'有关"{search_label}"的关键词:\n' + f"{keywords_str}" + ) + else: + response_text = ( + f"包含“{search_label}”的结果过多,请尝试更多关键词精确查找\n\n" + f'有关"{search_label}"的关键词信息为空' + ) + + logger.info( + f"[dream][tool] search_chat_history 匹配结果超过20条,返回关键词汇总提示,总数={len(filtered_records)}" + ) + return response_text + + # 构建结果文本,返回id、theme和keywords(最多20条) + results: List[str] = [] + for record in filtered_records[:20]: + result_parts: List[str] = [] + + # 记忆ID + result_parts.append(f"记忆ID:{record.id}") + + # 主题 + if record.theme: + result_parts.append(f"主题:{record.theme}") + else: + result_parts.append("主题:(无)") + + # 关键词 + if record.keywords: + try: + keywords_data = ( + json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + ) + if isinstance(keywords_data, list) and keywords_data: + keywords_str = "、".join([str(k) for k in keywords_data]) + result_parts.append(f"关键词:{keywords_str}") + else: + result_parts.append("关键词:(无)") + except (json.JSONDecodeError, TypeError, ValueError): + result_parts.append("关键词:(无)") + else: + result_parts.append("关键词:(无)") + + results.append("\n".join(result_parts)) + + if not results: + return "未找到相关聊天记录" + + response_text = "\n\n---\n\n".join(results) + + logger.info(f"[dream][tool] search_chat_history 返回 {len(filtered_records)} 条匹配记录") + return response_text + except Exception as e: + logger.error(f"search_chat_history 失败: {e}") + return f"search_chat_history 执行失败: {e}" + + return search_chat_history + diff --git a/src/dream/tools/search_jargon_tool.py b/src/dream/tools/search_jargon_tool.py new file mode 100644 index 00000000..139536ac --- /dev/null +++ b/src/dream/tools/search_jargon_tool.py @@ -0,0 +1,102 @@ +from typing import List + +from src.common.logger import get_logger +from src.common.database.database_model import Jargon +from src.config.config import global_config +from src.chat.utils.utils import parse_keywords_string +from src.bw_learner.learner_utils import parse_chat_id_list, chat_id_list_contains + +logger = get_logger("dream_agent") + + +def make_search_jargon(chat_id: str): + async def search_jargon(keyword: str) -> str: + """根据一个或多个关键词搜索当前 chat_id 相关的 Jargon 记录概览(只包含 is_jargon=True,是否跨 chat_id 由 all_global 决定)""" + try: + if not keyword or not keyword.strip(): + return "未指定查询关键词(参数 keyword 为必填,且不能为空)" + + logger.info(f"[dream][tool] 调用 search_jargon(keyword={keyword}) (作用域 chat_id={chat_id})") + + # 基础条件:只查 is_jargon=True 的记录 + query = Jargon.select().where(Jargon.is_jargon) + + # 根据 all_global 配置决定 chat_id 作用域 + if global_config.expression.all_global_jargon: + # 开启全局黑话:只看 is_global=True 的记录,不区分 chat_id + query = query.where(Jargon.is_global) + else: + # 关闭全局黑话:后续在 Python 层按 chat_id 列表过滤(包含 is_global=True) + pass + + # 先按使用次数排序取一批候选,做一个安全上限 + query = query.order_by(Jargon.count.desc()).limit(200) + candidates = list(query) + + if not candidates: + msg = "未找到符合条件的 Jargon 记录。" + logger.info(f"[dream][tool] search_jargon 无记录: {msg}") + return msg + + # 关键词为必填,因此此处必然执行关键词过滤(支持多个关键词,大小写不敏感) + keywords_list = parse_keywords_string(keyword) or [] + if not keywords_list and keyword.strip(): + keywords_list = [keyword.strip()] + keywords_lower = [kw.lower() for kw in keywords_list if kw.strip()] + + # 先按关键词过滤(仅对 content 字段进行匹配) + filtered_keyword: List[Jargon] = [] + for r in candidates: + content = (r.content or "").lower() + + # 只要命中任意一个关键词即可视为匹配(OR 逻辑) + any_matched = False + for kw in keywords_lower: + if not kw: + continue + if kw in content: + any_matched = True + break + + if any_matched: + filtered_keyword.append(r) + + if global_config.expression.all_global_jargon: + # 全局黑话模式:不再做 chat_id 过滤,直接使用关键词过滤结果 + records = filtered_keyword + else: + # 非全局模式:仅保留全局黑话或 chat_id 列表中包含当前 chat_id 的记录 + records = [] + for r in filtered_keyword: + if r.is_global: + records.append(r) + continue + chat_id_list = parse_chat_id_list(r.chat_id) + if chat_id_list_contains(chat_id_list, chat_id): + records.append(r) + + if not records: + scope_note = ( + "(当前为全局黑话模式,仅统计 is_global=True 的条目)" + if global_config.expression.all_global_jargon + else "(当前为按 chat_id 作用域模式,仅统计全局黑话或与当前 chat_id 相关的条目)" + ) + return f"未找到包含关键词'{keyword}'的 Jargon 记录{scope_note}" + + lines: List[str] = [] + for r in records: + is_jargon_str = "是" if r.is_jargon else "否" if r.is_jargon is False else "未判定" + is_global_str = "全局" if r.is_global else "非全局" + lines.append( + f"ID={r.id} | 内容={r.content} | 含义={r.meaning or '无'} | " + f"chat_id={r.chat_id} | {is_global_str} | 是否黑话={is_jargon_str}" + ) + + result = "\n".join(lines) + logger.info(f"[dream][tool] search_jargon 返回 {len(records)} 条记录") + return result + except Exception as e: + logger.error(f"search_jargon 失败: {e}") + return f"search_jargon 执行失败: {e}" + + return search_jargon diff --git a/src/dream/tools/update_chat_history_tool.py b/src/dream/tools/update_chat_history_tool.py new file mode 100644 index 00000000..c2e92fb9 --- /dev/null +++ b/src/dream/tools/update_chat_history_tool.py @@ -0,0 +1,52 @@ +from typing import Any, Dict, Optional + +from src.common.logger import get_logger +from src.common.database.database_model import ChatHistory +from src.plugin_system.apis import database_api + +logger = get_logger("dream_agent") + + +def make_update_chat_history(chat_id: str): # chat_id 目前未直接使用,预留以备扩展 + async def update_chat_history( + memory_id: int, + theme: Optional[str] = None, + summary: Optional[str] = None, + keywords: Optional[str] = None, + key_point: Optional[str] = None, + ) -> str: + """按字段更新 chat_history(字符串字段要求 JSON 的字段须传入已序列化的字符串)""" + try: + logger.info( + f"[dream][tool] 调用 update_chat_history(memory_id={memory_id}, " + f"theme={bool(theme)}, summary={bool(summary)}, keywords={bool(keywords)}, key_point={bool(key_point)})" + ) + record = ChatHistory.get_or_none(ChatHistory.id == memory_id) + if not record: + msg = f"未找到 ID={memory_id} 的 ChatHistory 记录,无法更新。" + logger.info(f"[dream][tool] update_chat_history 未找到记录: {msg}") + return msg + + data: Dict[str, Any] = {} + if theme is not None: + data["theme"] = theme + if summary is not None: + data["summary"] = summary + if keywords is not None: + data["keywords"] = keywords + if key_point is not None: + data["key_point"] = key_point + + if not data: + return "未提供任何需要更新的字段。" + + await database_api.db_save(ChatHistory, data=data, key_field="id", key_value=memory_id) + msg = f"已更新 ChatHistory 记录 ID={memory_id},更新字段={list(data.keys())}。" + logger.info(f"[dream][tool] update_chat_history 完成: {msg}") + return msg + except Exception as e: + logger.error(f"update_chat_history 失败: {e}") + return f"update_chat_history 执行失败: {e}" + + return update_chat_history + diff --git a/src/dream/tools/update_jargon_tool.py b/src/dream/tools/update_jargon_tool.py new file mode 100644 index 00000000..59ea1230 --- /dev/null +++ b/src/dream/tools/update_jargon_tool.py @@ -0,0 +1,52 @@ +from typing import Any, Dict, Optional + +from src.common.logger import get_logger +from src.common.database.database_model import Jargon +from src.plugin_system.apis import database_api + +logger = get_logger("dream_agent") + + +def make_update_jargon(chat_id: str): # chat_id 目前未直接使用,预留以备扩展 + async def update_jargon( + jargon_id: int, + meaning: Optional[str] = None, + is_global: Optional[bool] = None, + is_jargon: Optional[bool] = None, + content: Optional[str] = None, + ) -> str: + """按字段更新 Jargon 记录,可用于修正含义、调整全局性、标记是否为黑话等""" + try: + logger.info( + f"[dream][tool] 调用 update_jargon(jargon_id={jargon_id}, " + f"meaning={bool(meaning)}, is_global={is_global}, is_jargon={is_jargon}, content={bool(content)})" + ) + record = Jargon.get_or_none(Jargon.id == jargon_id) + if not record: + msg = f"未找到 ID={jargon_id} 的 Jargon 记录,无法更新。" + logger.info(f"[dream][tool] update_jargon 未找到记录: {msg}") + return msg + + data: Dict[str, Any] = {} + if meaning is not None: + data["meaning"] = meaning + if is_global is not None: + data["is_global"] = is_global + if is_jargon is not None: + data["is_jargon"] = is_jargon + if content is not None: + data["content"] = content + + if not data: + return "未提供任何需要更新的字段。" + + await database_api.db_save(Jargon, data=data, key_field="id", key_value=jargon_id) + msg = f"已更新 Jargon 记录 ID={jargon_id},更新字段={list(data.keys())}。" + logger.info(f"[dream][tool] update_jargon 完成: {msg}") + return msg + except Exception as e: + logger.error(f"update_jargon 失败: {e}") + return f"update_jargon 执行失败: {e}" + + return update_jargon + diff --git a/src/express/express_utils.py b/src/express/express_utils.py deleted file mode 100644 index 20095561..00000000 --- a/src/express/express_utils.py +++ /dev/null @@ -1,132 +0,0 @@ -import re -import difflib -import random -from datetime import datetime -from typing import Optional, List, Dict - - -def filter_message_content(content: Optional[str]) -> str: - """ - 过滤消息内容,移除回复、@、图片等格式 - - Args: - content: 原始消息内容 - - Returns: - str: 过滤后的内容 - """ - if not content: - return "" - - # 移除以[回复开头、]结尾的部分,包括后面的",说:"部分 - content = re.sub(r"\[回复.*?\],说:\s*", "", content) - # 移除@<...>格式的内容 - content = re.sub(r"@<[^>]*>", "", content) - # 移除[picid:...]格式的图片ID - content = re.sub(r"\[picid:[^\]]*\]", "", content) - # 移除[表情包:...]格式的内容 - content = re.sub(r"\[表情包:[^\]]*\]", "", content) - - return content.strip() - - -def calculate_similarity(text1: str, text2: str) -> float: - """ - 计算两个文本的相似度,返回0-1之间的值 - 使用SequenceMatcher计算相似度 - - Args: - text1: 第一个文本 - text2: 第二个文本 - - Returns: - float: 相似度值,范围0-1 - """ - return difflib.SequenceMatcher(None, text1, text2).ratio() - - -def format_create_date(timestamp: float) -> str: - """ - 将时间戳格式化为可读的日期字符串 - - Args: - timestamp: 时间戳 - - Returns: - str: 格式化后的日期字符串 - """ - try: - return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S") - except (ValueError, OSError): - return "未知时间" - - -def _compute_weights(population: List[Dict]) -> List[float]: - """ - 根据表达的count计算权重,范围限定在1~3之间。 - count越高,权重越高,但最多为基础权重的3倍。 - """ - if not population: - return [] - - counts = [] - for item in population: - count = item.get("count", 1) - try: - count_value = float(count) - except (TypeError, ValueError): - count_value = 1.0 - counts.append(max(count_value, 0.0)) - - min_count = min(counts) - max_count = max(counts) - - if max_count == min_count: - return [1.0 for _ in counts] - - weights = [] - for count_value in counts: - # 线性映射到[1,3]区间 - normalized = (count_value - min_count) / (max_count - min_count) - weights.append(1.0 + normalized * 2.0) # 1~3 - return weights - - -def weighted_sample(population: List[Dict], k: int) -> List[Dict]: - """ - 随机抽样函数 - - Args: - population: 总体数据列表 - k: 需要抽取的数量 - - Returns: - List[Dict]: 抽取的数据列表 - """ - if not population or k <= 0: - return [] - - if len(population) <= k: - return population.copy() - - selected: List[Dict] = [] - population_copy = population.copy() - - for _ in range(min(k, len(population_copy))): - weights = _compute_weights(population_copy) - total_weight = sum(weights) - if total_weight <= 0: - # 回退到均匀随机 - idx = random.randint(0, len(population_copy) - 1) - selected.append(population_copy.pop(idx)) - continue - - threshold = random.uniform(0, total_weight) - cumulative = 0.0 - for idx, weight in enumerate(weights): - cumulative += weight - if threshold <= cumulative: - selected.append(population_copy.pop(idx)) - break - - return selected diff --git a/src/express/expression_learner.py b/src/express/expression_learner.py deleted file mode 100644 index 57c03e77..00000000 --- a/src/express/expression_learner.py +++ /dev/null @@ -1,628 +0,0 @@ -import time -import json -import os -from typing import List, Optional, Tuple -import traceback -from src.common.logger import get_logger -from src.common.database.database_model import Expression -from src.llm_models.utils_model import LLMRequest -from src.config.config import model_config, global_config -from src.chat.utils.chat_message_builder import ( - get_raw_msg_by_timestamp_with_chat_inclusive, - build_anonymous_messages, - build_bare_messages, -) -from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.chat.message_receive.chat_stream import get_chat_manager -from src.express.express_utils import filter_message_content, calculate_similarity -from json_repair import repair_json - - -# MAX_EXPRESSION_COUNT = 300 - -logger = get_logger("expressor") - - -def init_prompt() -> None: - learn_style_prompt = """ -{chat_str} - -请从上面这段群聊中概括除了人名为"SELF"之外的人的语言风格 -1. 只考虑文字,不要考虑表情包和图片 -2. 不要涉及具体的人名,但是可以涉及具体名词 -3. 思考有没有特殊的梗,一并总结成语言风格 -4. 例子仅供参考,请严格根据群聊内容总结!!! -注意:总结成如下格式的规律,总结的内容要详细,但具有概括性: -例如:当"AAAAA"时,可以"BBBBB", AAAAA代表某个具体的场景,不超过20个字。BBBBB代表对应的语言风格,特定句式或表达方式,不超过20个字。 - -例如: -当"对某件事表示十分惊叹"时,使用"我嘞个xxxx" -当"表示讽刺的赞同,不讲道理"时,使用"对对对" -当"想说明某个具体的事实观点,但懒得明说,使用"懂的都懂" -当"当涉及游戏相关时,夸赞,略带戏谑意味"时,使用"这么强!" - -请注意:不要总结你自己(SELF)的发言,尽量保证总结内容的逻辑性 -现在请你概括 -""" - Prompt(learn_style_prompt, "learn_style_prompt") - - match_expression_context_prompt = """ -**聊天内容** -{chat_str} - -**从聊天内容总结的表达方式pairs** -{expression_pairs} - -请你为上面的每一条表达方式,找到该表达方式的原文句子,并输出匹配结果,expression_pair不能有重复,每个expression_pair仅输出一个最合适的context。 -如果找不到原句,就不输出该句的匹配结果。 -以json格式输出: -格式如下: -{{ - "expression_pair": "表达方式pair的序号(数字)", - "context": "与表达方式对应的原文句子的原始内容,不要修改原文句子的内容", -}}, -{{ - "expression_pair": "表达方式pair的序号(数字)", - "context": "与表达方式对应的原文句子的原始内容,不要修改原文句子的内容", -}}, -... - -现在请你输出匹配结果: -""" - Prompt(match_expression_context_prompt, "match_expression_context_prompt") - - -class ExpressionLearner: - def __init__(self, chat_id: str) -> None: - self.express_learn_model: LLMRequest = LLMRequest( - model_set=model_config.model_task_config.utils, request_type="expression.learner" - ) - self.summary_model: LLMRequest = LLMRequest( - model_set=model_config.model_task_config.utils_small, request_type="expression.summary" - ) - self.embedding_model: LLMRequest = LLMRequest( - model_set=model_config.model_task_config.embedding, request_type="expression.embedding" - ) - self.chat_id = chat_id - self.chat_stream = get_chat_manager().get_stream(chat_id) - self.chat_name = get_chat_manager().get_stream_name(chat_id) or chat_id - - # 维护每个chat的上次学习时间 - self.last_learning_time: float = time.time() - - # 学习参数 - _, self.enable_learning, self.learning_intensity = global_config.expression.get_expression_config_for_chat( - self.chat_id - ) - self.min_messages_for_learning = 15 / self.learning_intensity # 触发学习所需的最少消息数 - self.min_learning_interval = 120 / self.learning_intensity - - def should_trigger_learning(self) -> bool: - """ - 检查是否应该触发学习 - - Args: - chat_id: 聊天流ID - - Returns: - bool: 是否应该触发学习 - """ - # 检查是否允许学习 - if not self.enable_learning: - return False - - # 检查时间间隔 - time_diff = time.time() - self.last_learning_time - if time_diff < self.min_learning_interval: - return False - - # 检查消息数量(只检查指定聊天流的消息) - recent_messages = get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id=self.chat_id, - timestamp_start=self.last_learning_time, - timestamp_end=time.time(), - ) - - if not recent_messages or len(recent_messages) < self.min_messages_for_learning: - return False - - return True - - async def trigger_learning_for_chat(self): - """ - 为指定聊天流触发学习 - - Args: - chat_id: 聊天流ID - - Returns: - bool: 是否成功触发学习 - """ - if not self.should_trigger_learning(): - return - - try: - logger.info(f"在聊天流 {self.chat_name} 学习表达方式") - # 学习语言风格 - learnt_style = await self.learn_and_store(num=25) - - # 更新学习时间 - self.last_learning_time = time.time() - - if learnt_style: - logger.info(f"聊天流 {self.chat_name} 表达学习完成") - else: - logger.warning(f"聊天流 {self.chat_name} 表达学习未获得有效结果") - - except Exception as e: - logger.error(f"为聊天流 {self.chat_name} 触发学习失败: {e}") - traceback.print_exc() - return - - async def learn_and_store(self, num: int = 10) -> List[Tuple[str, str, str]]: - """ - 学习并存储表达方式 - """ - learnt_expressions = await self.learn_expression(num) - - if learnt_expressions is None: - logger.info("没有学习到表达风格") - return [] - - # 展示学到的表达方式 - learnt_expressions_str = "" - for ( - situation, - style, - _context, - _up_content, - ) in learnt_expressions: - learnt_expressions_str += f"{situation}->{style}\n" - logger.info(f"在 {self.chat_name} 学习到表达风格:\n{learnt_expressions_str}") - - current_time = time.time() - - # 存储到数据库 Expression 表 - for ( - situation, - style, - context, - up_content, - ) in learnt_expressions: - await self._upsert_expression_record( - situation=situation, - style=style, - context=context, - up_content=up_content, - current_time=current_time, - ) - - return learnt_expressions - - async def match_expression_context( - self, expression_pairs: List[Tuple[str, str]], random_msg_match_str: str - ) -> List[Tuple[str, str, str]]: - # 为expression_pairs逐个条目赋予编号,并构建成字符串 - numbered_pairs = [] - for i, (situation, style) in enumerate(expression_pairs, 1): - numbered_pairs.append(f'{i}. 当"{situation}"时,使用"{style}"') - - expression_pairs_str = "\n".join(numbered_pairs) - - prompt = "match_expression_context_prompt" - prompt = await global_prompt_manager.format_prompt( - prompt, - expression_pairs=expression_pairs_str, - chat_str=random_msg_match_str, - ) - - response, _ = await self.express_learn_model.generate_response_async(prompt, temperature=0.3) - - # print(f"match_expression_context_prompt: {prompt}") - # print(f"{response}") - - # 解析JSON响应 - match_responses = [] - try: - response = response.strip() - # 检查是否已经是标准JSON数组格式 - if response.startswith("[") and response.endswith("]"): - match_responses = json.loads(response) - else: - # 尝试直接解析多个JSON对象 - try: - # 如果是多个JSON对象用逗号分隔,包装成数组 - if response.startswith("{") and not response.startswith("["): - response = "[" + response + "]" - match_responses = json.loads(response) - else: - # 使用repair_json处理响应 - repaired_content = repair_json(response) - - # 确保repaired_content是列表格式 - if isinstance(repaired_content, str): - try: - parsed_data = json.loads(repaired_content) - if isinstance(parsed_data, dict): - # 如果是字典,包装成列表 - match_responses = [parsed_data] - elif isinstance(parsed_data, list): - match_responses = parsed_data - else: - match_responses = [] - except json.JSONDecodeError: - match_responses = [] - elif isinstance(repaired_content, dict): - # 如果是字典,包装成列表 - match_responses = [repaired_content] - elif isinstance(repaired_content, list): - match_responses = repaired_content - else: - match_responses = [] - except json.JSONDecodeError: - # 如果还是失败,尝试repair_json - repaired_content = repair_json(response) - if isinstance(repaired_content, str): - parsed_data = json.loads(repaired_content) - match_responses = parsed_data if isinstance(parsed_data, list) else [parsed_data] - else: - match_responses = repaired_content if isinstance(repaired_content, list) else [repaired_content] - - except (json.JSONDecodeError, Exception) as e: - logger.error(f"解析匹配响应JSON失败: {e}, 响应内容: \n{response}") - return [] - - # 确保 match_responses 是一个列表 - if not isinstance(match_responses, list): - if isinstance(match_responses, dict): - match_responses = [match_responses] - else: - logger.error(f"match_responses 不是列表或字典类型: {type(match_responses)}, 内容: {match_responses}") - return [] - - matched_expressions = [] - used_pair_indices = set() # 用于跟踪已经使用的expression_pair索引 - - logger.debug(f"match_responses 类型: {type(match_responses)}, 长度: {len(match_responses)}") - logger.debug(f"match_responses 内容: {match_responses}") - - for match_response in match_responses: - try: - # 检查 match_response 的类型 - if not isinstance(match_response, dict): - logger.error(f"match_response 不是字典类型: {type(match_response)}, 内容: {match_response}") - continue - - # 获取表达方式序号 - if "expression_pair" not in match_response: - logger.error(f"match_response 缺少 'expression_pair' 字段: {match_response}") - continue - - pair_index = int(match_response["expression_pair"]) - 1 # 转换为0-based索引 - - # 检查索引是否有效且未被使用过 - if 0 <= pair_index < len(expression_pairs) and pair_index not in used_pair_indices: - situation, style = expression_pairs[pair_index] - context = match_response.get("context", "") - matched_expressions.append((situation, style, context)) - used_pair_indices.add(pair_index) # 标记该索引已使用 - logger.debug(f"成功匹配表达方式 {pair_index + 1}: {situation} -> {style}") - elif pair_index in used_pair_indices: - logger.debug(f"跳过重复的表达方式 {pair_index + 1}") - except (ValueError, KeyError, IndexError, TypeError) as e: - logger.error(f"解析匹配条目失败: {e}, 条目: {match_response}") - continue - - return matched_expressions - - async def learn_expression(self, num: int = 10) -> Optional[List[Tuple[str, str, str, str]]]: - """从指定聊天流学习表达方式 - - Args: - num: 学习数量 - """ - current_time = time.time() - - # 获取上次学习之后的消息 - random_msg = get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id=self.chat_id, - timestamp_start=self.last_learning_time, - timestamp_end=current_time, - limit=num, - ) - # print(random_msg) - if not random_msg or random_msg == []: - return None - - # 学习用 - random_msg_str: str = await build_anonymous_messages(random_msg) - # 溯源用 - random_msg_match_str: str = await build_bare_messages(random_msg) - - prompt: str = await global_prompt_manager.format_prompt( - "learn_style_prompt", - chat_str=random_msg_str, - ) - - # print(f"random_msg_str:{random_msg_str}") - # logger.info(f"学习{type_str}的prompt: {prompt}") - - try: - response, _ = await self.express_learn_model.generate_response_async(prompt, temperature=0.3) - except Exception as e: - logger.error(f"学习表达方式失败,模型生成出错: {e}") - return None - expressions: List[Tuple[str, str]] = self.parse_expression_response(response) - expressions = self._filter_self_reference_styles(expressions) - if not expressions: - logger.info("过滤后没有可用的表达方式(style 与机器人名称重复)") - return None - # logger.debug(f"学习{type_str}的response: {response}") - - # 对表达方式溯源 - matched_expressions: List[Tuple[str, str, str]] = await self.match_expression_context( - expressions, random_msg_match_str - ) - # 为每条消息构建精简文本列表,保留到原消息索引的映射 - bare_lines: List[Tuple[int, str]] = self._build_bare_lines(random_msg) - # 将 matched_expressions 结合上一句 up_content(若不存在上一句则跳过) - filtered_with_up: List[Tuple[str, str, str, str]] = [] # (situation, style, context, up_content) - for situation, style, context in matched_expressions: - # 在 bare_lines 中找到第一处相似度达到85%的行 - pos = None - for i, (_, c) in enumerate(bare_lines): - similarity = calculate_similarity(c, context) - if similarity >= 0.85: # 85%相似度阈值 - pos = i - break - - if pos is None or pos == 0: - # 没有匹配到目标句或没有上一句,跳过该表达 - continue - - # 检查目标句是否为空 - target_content = bare_lines[pos][1] - if not target_content: - # 目标句为空,跳过该表达 - continue - - prev_original_idx = bare_lines[pos - 1][0] - up_content = filter_message_content(random_msg[prev_original_idx].processed_plain_text or "") - if not up_content: - # 上一句为空,跳过该表达 - continue - filtered_with_up.append((situation, style, context, up_content)) - - if not filtered_with_up: - return None - - return filtered_with_up - - def parse_expression_response(self, response: str) -> List[Tuple[str, str, str]]: - """ - 解析LLM返回的表达风格总结,每一行提取"当"和"使用"之间的内容,存储为(situation, style)元组 - """ - expressions: List[Tuple[str, str, str]] = [] - for line in response.splitlines(): - line = line.strip() - if not line: - continue - # 查找"当"和下一个引号 - idx_when = line.find('当"') - if idx_when == -1: - continue - idx_quote1 = idx_when + 1 - idx_quote2 = line.find('"', idx_quote1 + 1) - if idx_quote2 == -1: - continue - situation = line[idx_quote1 + 1 : idx_quote2] - # 查找"使用" - idx_use = line.find('使用"', idx_quote2) - if idx_use == -1: - continue - idx_quote3 = idx_use + 2 - idx_quote4 = line.find('"', idx_quote3 + 1) - if idx_quote4 == -1: - continue - style = line[idx_quote3 + 1 : idx_quote4] - expressions.append((situation, style)) - return expressions - - def _filter_self_reference_styles(self, expressions: List[Tuple[str, str]]) -> List[Tuple[str, str]]: - """ - 过滤掉style与机器人名称/昵称重复的表达 - """ - banned_names = set() - bot_nickname = (global_config.bot.nickname or "").strip() - if bot_nickname: - banned_names.add(bot_nickname) - - alias_names = global_config.bot.alias_names or [] - for alias in alias_names: - alias = alias.strip() - if alias: - banned_names.add(alias) - - banned_casefold = {name.casefold() for name in banned_names if name} - - filtered: List[Tuple[str, str]] = [] - removed_count = 0 - for situation, style in expressions: - normalized_style = (style or "").strip() - if normalized_style and normalized_style.casefold() not in banned_casefold: - filtered.append((situation, style)) - else: - removed_count += 1 - - if removed_count: - logger.debug(f"已过滤 {removed_count} 条style与机器人名称重复的表达方式") - - return filtered - - async def _upsert_expression_record( - self, - situation: str, - style: str, - context: str, - up_content: str, - current_time: float, - ) -> None: - expr_obj = Expression.select().where((Expression.chat_id == self.chat_id) & (Expression.style == style)).first() - - if expr_obj: - await self._update_existing_expression( - expr_obj=expr_obj, - situation=situation, - context=context, - up_content=up_content, - current_time=current_time, - ) - return - - await self._create_expression_record( - situation=situation, - style=style, - context=context, - up_content=up_content, - current_time=current_time, - ) - - async def _create_expression_record( - self, - situation: str, - style: str, - context: str, - up_content: str, - current_time: float, - ) -> None: - content_list = [situation] - formatted_situation = await self._compose_situation_text(content_list, 1, situation) - - Expression.create( - situation=formatted_situation, - style=style, - content_list=json.dumps(content_list, ensure_ascii=False), - count=1, - last_active_time=current_time, - chat_id=self.chat_id, - create_date=current_time, - context=context, - up_content=up_content, - ) - - async def _update_existing_expression( - self, - expr_obj: Expression, - situation: str, - context: str, - up_content: str, - current_time: float, - ) -> None: - content_list = self._parse_content_list(expr_obj.content_list) - content_list.append(situation) - - expr_obj.content_list = json.dumps(content_list, ensure_ascii=False) - expr_obj.count = (expr_obj.count or 0) + 1 - expr_obj.last_active_time = current_time - expr_obj.context = context - expr_obj.up_content = up_content - - new_situation = await self._compose_situation_text( - content_list=content_list, - count=expr_obj.count, - fallback=expr_obj.situation, - ) - expr_obj.situation = new_situation - - expr_obj.save() - - def _parse_content_list(self, stored_list: Optional[str]) -> List[str]: - if not stored_list: - return [] - try: - data = json.loads(stored_list) - except json.JSONDecodeError: - return [] - return [str(item) for item in data if isinstance(item, str)] if isinstance(data, list) else [] - - async def _compose_situation_text(self, content_list: List[str], count: int, fallback: str = "") -> str: - sanitized = [c.strip() for c in content_list if c.strip()] - summary = await self._summarize_situations(sanitized) - if summary: - return summary - return "/".join(sanitized) if sanitized else fallback - - async def _summarize_situations(self, situations: List[str]) -> Optional[str]: - if not situations: - return None - - prompt = ( - "请阅读以下多个聊天情境描述,并将它们概括成一句简短的话," - "长度不超过20个字,保留共同特点:\n" - f"{chr(10).join(f'- {s}' for s in situations[-10:])}\n只输出概括内容。" - ) - - try: - summary, _ = await self.summary_model.generate_response_async(prompt, temperature=0.2) - summary = summary.strip() - if summary: - return summary - except Exception as e: - logger.error(f"概括表达情境失败: {e}") - return None - - def _build_bare_lines(self, messages: List) -> List[Tuple[int, str]]: - """ - 为每条消息构建精简文本列表,保留到原消息索引的映射 - - Args: - messages: 消息列表 - - Returns: - List[Tuple[int, str]]: (original_index, bare_content) 元组列表 - """ - bare_lines: List[Tuple[int, str]] = [] - - for idx, msg in enumerate(messages): - content = msg.processed_plain_text or "" - content = filter_message_content(content) - # 即使content为空也要记录,防止错位 - bare_lines.append((idx, content)) - - return bare_lines - - -init_prompt() - - -class ExpressionLearnerManager: - def __init__(self): - self.expression_learners = {} - - self._ensure_expression_directories() - - def get_expression_learner(self, chat_id: str) -> ExpressionLearner: - if chat_id not in self.expression_learners: - self.expression_learners[chat_id] = ExpressionLearner(chat_id) - return self.expression_learners[chat_id] - - def _ensure_expression_directories(self): - """ - 确保表达方式相关的目录结构存在 - """ - base_dir = os.path.join("data", "expression") - directories_to_create = [ - base_dir, - os.path.join(base_dir, "learnt_style"), - os.path.join(base_dir, "learnt_grammar"), - ] - - for directory in directories_to_create: - try: - os.makedirs(directory, exist_ok=True) - logger.debug(f"确保目录存在: {directory}") - except Exception as e: - logger.error(f"创建目录失败 {directory}: {e}") - - -expression_learner_manager = ExpressionLearnerManager() diff --git a/src/hippo_memorizer/chat_history_summarizer.py b/src/hippo_memorizer/chat_history_summarizer.py new file mode 100644 index 00000000..c8d4a943 --- /dev/null +++ b/src/hippo_memorizer/chat_history_summarizer.py @@ -0,0 +1,1031 @@ +""" +聊天内容概括器 +用于累积、打包和压缩聊天记录 +""" + +import asyncio +import json +import time +import re +import difflib +from pathlib import Path +from typing import Any, Dict, List, Optional, Set +from dataclasses import dataclass, field +from json_repair import repair_json + +from src.common.logger import get_logger +from src.common.data_models.database_data_model import DatabaseMessages +from src.config.config import global_config, model_config +from src.llm_models.utils_model import LLMRequest +from src.plugin_system.apis import message_api +from src.chat.utils.chat_message_builder import build_readable_messages +from src.person_info.person_info import Person +from src.chat.message_receive.chat_stream import get_chat_manager +from src.chat.utils.prompt_builder import Prompt, global_prompt_manager + +logger = get_logger("chat_history_summarizer") + +HIPPO_CACHE_DIR = Path(__file__).resolve().parents[2] / "data" / "hippo_memorizer" + + +def init_prompt(): + """初始化提示词模板""" + + topic_analysis_prompt = """【历史话题标题列表】(仅标题,不含具体内容): +{history_topics_block} +【历史话题标题列表结束】 + +【本次聊天记录】(每条消息前有编号,用于后续引用): +{messages_block} +【本次聊天记录结束】 + +请完成以下任务: +**识别话题** +1. 识别【本次聊天记录】中正在进行的一个或多个话题; +2. 【本次聊天记录】的中的消息可能与历史话题有关,也可能毫无关联。 +2. 判断【历史话题标题列表】中的话题是否在【本次聊天记录】中出现,如果出现,则直接使用该历史话题标题字符串; + +**选取消息** +1. 对于每个话题(新话题或历史话题),从上述带编号的消息中选出与该话题强相关的消息编号列表; +2. 每个话题用一句话清晰地描述正在发生的事件,必须包含时间(大致即可)、人物、主要事件和主题,保证精准且有区分度; + +请先输出一段简短思考,说明有什么话题,哪些是不包含在历史话题中的,哪些是包含在历史话题中的,并说明为什么; +然后严格以 JSON 格式输出【本次聊天记录】中涉及的话题,格式如下: +[ + {{ + "topic": "话题", + "message_indices": [1, 2, 5] + }}, + ... +] +""" + Prompt(topic_analysis_prompt, "hippo_topic_analysis_prompt") + + topic_summary_prompt = """ +请基于以下话题,对聊天记录片段进行概括,提取以下信息: + +**话题**:{topic} + +**要求**: +1. 关键词:提取与话题相关的关键词,用列表形式返回(3-10个关键词) +2. 概括:对这段话的平文本概括(50-200字),要求: + - 仔细地转述发生的事件和聊天内容; + - 可以适当摘取聊天记录中的原文; + - 重点突出事件的发展过程和结果; + - 围绕话题这个中心进行概括。 +3. 关键信息:提取话题中的关键信息点,用列表形式返回(3-8个关键信息点),每个关键信息点应该简洁明了。 + +请以JSON格式返回,格式如下: +{{ + "keywords": ["关键词1", "关键词2", ...], + "summary": "概括内容", + "key_point": ["关键信息1", "关键信息2", ...] +}} + +聊天记录: +{original_text} + +请直接返回JSON,不要包含其他内容。 +""" + Prompt(topic_summary_prompt, "hippo_topic_summary_prompt") + + +@dataclass +class MessageBatch: + """消息批次(用于触发话题检查的原始消息累积)""" + + messages: List[DatabaseMessages] + start_time: float + end_time: float + + +@dataclass +class TopicCacheItem: + """ + 话题缓存项 + + Attributes: + topic: 话题标题(一句话描述时间、人物、事件和主题) + messages: 与该话题相关的消息字符串列表(已经通过 build 函数转成可读文本) + participants: 涉及到的发言人昵称集合 + no_update_checks: 连续多少次“检查”没有新增内容 + """ + + topic: str + messages: List[str] = field(default_factory=list) + participants: Set[str] = field(default_factory=set) + no_update_checks: int = 0 + + +class ChatHistorySummarizer: + """聊天内容概括器""" + + def __init__(self, chat_id: str, check_interval: int = 60): + """ + 初始化聊天内容概括器 + + Args: + chat_id: 聊天ID + check_interval: 定期检查间隔(秒),默认60秒 + """ + self.chat_id = chat_id + self._chat_display_name = self._get_chat_display_name() + self.log_prefix = f"[{self._chat_display_name}]" + + # 记录时间点,用于计算新消息 + self.last_check_time = time.time() + + # 记录上一次话题检查的时间,用于判断是否需要触发检查 + self.last_topic_check_time = time.time() + + # 当前累积的消息批次 + self.current_batch: Optional[MessageBatch] = None + + # 话题缓存:topic_str -> TopicCacheItem + # 在内存中维护,并通过本地文件实时持久化 + self.topic_cache: Dict[str, TopicCacheItem] = {} + self._safe_chat_id = self._sanitize_chat_id(self.chat_id) + self._topic_cache_file = HIPPO_CACHE_DIR / f"{self._safe_chat_id}.json" + # 注意:批次加载需要异步查询消息,所以在 start() 中调用 + + # LLM请求器,用于压缩聊天内容 + self.summarizer_llm = LLMRequest( + model_set=model_config.model_task_config.utils, request_type="chat_history_summarizer" + ) + + # 后台循环相关 + self.check_interval = check_interval # 检查间隔(秒) + self._periodic_task: Optional[asyncio.Task] = None + self._running = False + + def _get_chat_display_name(self) -> str: + """获取聊天显示名称""" + try: + chat_name = get_chat_manager().get_stream_name(self.chat_id) + if chat_name: + return chat_name + # 如果获取失败,使用简化的chat_id显示 + if len(self.chat_id) > 20: + return f"{self.chat_id[:8]}..." + return self.chat_id + except Exception: + # 如果获取失败,使用简化的chat_id显示 + if len(self.chat_id) > 20: + return f"{self.chat_id[:8]}..." + return self.chat_id + + def _sanitize_chat_id(self, chat_id: str) -> str: + """用于生成可作为文件名的 chat_id""" + return re.sub(r"[^a-zA-Z0-9_.-]", "_", chat_id) + + def _load_topic_cache_from_disk(self): + """在启动时加载本地话题缓存(同步部分),支持重启后继续""" + try: + if not self._topic_cache_file.exists(): + return + + with self._topic_cache_file.open("r", encoding="utf-8") as f: + data = json.load(f) + + self.last_topic_check_time = data.get("last_topic_check_time", self.last_topic_check_time) + topics_data = data.get("topics", {}) + loaded_count = 0 + for topic, payload in topics_data.items(): + self.topic_cache[topic] = TopicCacheItem( + topic=topic, + messages=payload.get("messages", []), + participants=set(payload.get("participants", [])), + no_update_checks=payload.get("no_update_checks", 0), + ) + loaded_count += 1 + + if loaded_count: + logger.info(f"{self.log_prefix} 已加载 {loaded_count} 个话题缓存,继续追踪") + except Exception as e: + logger.error(f"{self.log_prefix} 加载话题缓存失败: {e}") + + async def _load_batch_from_disk(self): + """在启动时加载聊天批次,支持重启后继续""" + try: + if not self._topic_cache_file.exists(): + return + + with self._topic_cache_file.open("r", encoding="utf-8") as f: + data = json.load(f) + + batch_data = data.get("current_batch") + if not batch_data: + return + + start_time = batch_data.get("start_time") + end_time = batch_data.get("end_time") + if not start_time or not end_time: + return + + # 根据时间范围重新查询消息 + messages = message_api.get_messages_by_time_in_chat( + chat_id=self.chat_id, + start_time=start_time, + end_time=end_time, + limit=0, + limit_mode="latest", + filter_mai=False, + filter_command=False, + ) + + if messages: + self.current_batch = MessageBatch( + messages=messages, + start_time=start_time, + end_time=end_time, + ) + logger.info(f"{self.log_prefix} 已恢复聊天批次,包含 {len(messages)} 条消息") + except Exception as e: + logger.error(f"{self.log_prefix} 加载聊天批次失败: {e}") + + def _persist_topic_cache(self): + """实时持久化话题缓存和聊天批次,避免重启后丢失""" + try: + # 如果既没有话题缓存也没有批次,删除缓存文件 + if not self.topic_cache and not self.current_batch: + if self._topic_cache_file.exists(): + self._topic_cache_file.unlink() + return + + HIPPO_CACHE_DIR.mkdir(parents=True, exist_ok=True) + data = { + "chat_id": self.chat_id, + "last_topic_check_time": self.last_topic_check_time, + "topics": { + topic: { + "messages": item.messages, + "participants": list(item.participants), + "no_update_checks": item.no_update_checks, + } + for topic, item in self.topic_cache.items() + }, + } + + # 保存当前批次的时间范围(如果有) + if self.current_batch: + data["current_batch"] = { + "start_time": self.current_batch.start_time, + "end_time": self.current_batch.end_time, + } + + with self._topic_cache_file.open("w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=2) + except Exception as e: + logger.error(f"{self.log_prefix} 持久化话题缓存失败: {e}") + + async def process(self, current_time: Optional[float] = None): + """ + 处理聊天内容概括 + + Args: + current_time: 当前时间戳,如果为None则使用time.time() + """ + if current_time is None: + current_time = time.time() + + try: + # 获取从上次检查时间到当前时间的新消息 + new_messages = message_api.get_messages_by_time_in_chat( + chat_id=self.chat_id, + start_time=self.last_check_time, + end_time=current_time, + limit=0, + limit_mode="latest", + filter_mai=False, # 不过滤bot消息,因为需要检查bot是否发言 + filter_command=False, + ) + + if not new_messages: + # 没有新消息,检查是否需要进行“话题检查” + if self.current_batch and self.current_batch.messages: + await self._check_and_run_topic_check(current_time) + self.last_check_time = current_time + return + + logger.debug( + f"{self.log_prefix} 开始处理聊天概括,时间窗口: {self.last_check_time:.2f} -> {current_time:.2f}" + ) + + # 有新消息,更新最后检查时间 + self.last_check_time = current_time + + # 如果有当前批次,添加新消息 + if self.current_batch: + before_count = len(self.current_batch.messages) + self.current_batch.messages.extend(new_messages) + self.current_batch.end_time = current_time + logger.info( + f"{self.log_prefix} 更新聊天检查批次: {before_count} -> {len(self.current_batch.messages)} 条消息" + ) + # 更新批次后持久化 + self._persist_topic_cache() + else: + # 创建新批次 + self.current_batch = MessageBatch( + messages=new_messages, + start_time=new_messages[0].time if new_messages else current_time, + end_time=current_time, + ) + logger.debug(f"{self.log_prefix} 新建聊天检查批次: {len(new_messages)} 条消息") + # 创建批次后持久化 + self._persist_topic_cache() + + # 检查是否需要触发“话题检查” + await self._check_and_run_topic_check(current_time) + + except Exception as e: + logger.error(f"{self.log_prefix} 处理聊天内容概括时出错: {e}") + import traceback + + traceback.print_exc() + + async def _check_and_run_topic_check(self, current_time: float): + """ + 检查是否需要进行一次“话题检查” + + 触发条件: + - 当前批次消息数 >= 100,或者 + - 距离上一次检查的时间 > 3600 秒(1小时) + """ + if not self.current_batch or not self.current_batch.messages: + return + + messages = self.current_batch.messages + message_count = len(messages) + time_since_last_check = current_time - self.last_topic_check_time + + # 格式化时间差显示 + if time_since_last_check < 60: + time_str = f"{time_since_last_check:.1f}秒" + elif time_since_last_check < 3600: + time_str = f"{time_since_last_check / 60:.1f}分钟" + else: + time_str = f"{time_since_last_check / 3600:.1f}小时" + + logger.debug(f"{self.log_prefix} 批次状态检查 | 消息数: {message_count} | 距上次检查: {time_str}") + + # 检查“话题检查”触发条件 + should_check = False + + # 条件1: 消息数量 >= 100,触发一次检查 + if message_count >= 80: + should_check = True + logger.info(f"{self.log_prefix} 触发检查条件: 消息数量达到 {message_count} 条(阈值: 100条)") + + # 条件2: 距离上一次检查 > 3600 * 8 秒(8小时)且消息数量 >= 20 条,触发一次检查 + elif time_since_last_check > 3600 * 8 and message_count >= 20: + should_check = True + logger.info(f"{self.log_prefix} 触发检查条件: 距上次检查 {time_str}(阈值: 8小时)且消息数量达到 {message_count} 条(阈值: 20条)") + + if should_check: + await self._run_topic_check_and_update_cache(messages) + # 本批次已经被处理为话题信息,可以清空 + self.current_batch = None + # 更新上一次检查时间,并持久化 + self.last_topic_check_time = current_time + self._persist_topic_cache() + + async def _run_topic_check_and_update_cache(self, messages: List[DatabaseMessages]): + """ + 执行一次“话题检查”: + 1. 首先确认这段消息里是否有 Bot 发言,没有则直接丢弃本次批次; + 2. 将消息编号并转成字符串,构造 LLM Prompt; + 3. 把历史话题标题列表放入 Prompt,要求 LLM: + - 识别当前聊天中的话题(1 个或多个); + - 为每个话题选出相关消息编号; + - 若话题属于历史话题,则沿用原话题标题; + 4. LLM 返回 JSON:多个 {topic, message_indices}; + 5. 更新本地话题缓存,并根据规则触发“话题打包存储”。 + """ + if not messages: + return + + start_time = messages[0].time + end_time = messages[-1].time + + logger.info( + f"{self.log_prefix} 开始话题检查 | 消息数: {len(messages)} | 时间范围: {start_time:.2f} - {end_time:.2f}" + ) + + # 1. 检查当前批次内是否有 bot 发言(只检查当前批次,不往前推) + # 原因:我们要记录的是 bot 参与过的对话片段,如果当前批次内 bot 没有发言, + # 说明 bot 没有参与这段对话,不应该记录 + bot_user_id = str(global_config.bot.qq_account) + has_bot_message = False + + for msg in messages: + if msg.user_info.user_id == bot_user_id: + has_bot_message = True + break + + if not has_bot_message: + logger.info( + f"{self.log_prefix} 当前批次内无 Bot 发言,丢弃本次检查 | 时间范围: {start_time:.2f} - {end_time:.2f}" + ) + return + + # 2. 构造编号后的消息字符串和参与者信息 + numbered_lines, index_to_msg_str, index_to_msg_text, index_to_participants = ( + self._build_numbered_messages_for_llm(messages) + ) + + # 3. 调用 LLM 识别话题,并得到 topic -> indices(失败时最多重试 3 次) + existing_topics = list(self.topic_cache.keys()) + max_retries = 3 + attempt = 0 + success = False + topic_to_indices: Dict[str, List[int]] = {} + + while attempt < max_retries: + attempt += 1 + success, topic_to_indices = await self._analyze_topics_with_llm( + numbered_lines=numbered_lines, + existing_topics=existing_topics, + ) + + if success and topic_to_indices: + if attempt > 1: + logger.info( + f"{self.log_prefix} 话题识别在第 {attempt} 次重试后成功 | 话题数: {len(topic_to_indices)}" + ) + break + + logger.warning( + f"{self.log_prefix} 话题识别失败或无有效话题,第 {attempt} 次尝试失败" + + ("" if attempt >= max_retries else ",准备重试") + ) + + if not success or not topic_to_indices: + logger.error(f"{self.log_prefix} 话题识别连续 {max_retries} 次失败或始终无有效话题,本次检查放弃") + # 即使识别失败,也认为是一次"检查",但不更新 no_update_checks(保持原状) + return + + # 3.5. 检查新话题是否与历史话题相似(相似度>=90%则使用历史标题) + topic_mapping = self._build_topic_mapping(topic_to_indices, similarity_threshold=0.9) + + # 应用话题映射:将相似的新话题标题替换为历史话题标题 + if topic_mapping: + new_topic_to_indices: Dict[str, List[int]] = {} + for new_topic, indices in topic_to_indices.items(): + # 如果这个新话题需要映射到历史话题 + if new_topic in topic_mapping: + historical_topic = topic_mapping[new_topic] + # 如果历史话题已经存在,合并消息索引 + if historical_topic in new_topic_to_indices: + # 合并索引并去重 + combined_indices = list(set(new_topic_to_indices[historical_topic] + indices)) + new_topic_to_indices[historical_topic] = combined_indices + else: + new_topic_to_indices[historical_topic] = indices + else: + # 不需要映射,保持原样 + new_topic_to_indices[new_topic] = indices + topic_to_indices = new_topic_to_indices + + # 4. 统计哪些话题在本次检查中有新增内容 + updated_topics: Set[str] = set() + + for topic, indices in topic_to_indices.items(): + if not indices: + continue + + item = self.topic_cache.get(topic) + if not item: + # 新话题 + item = TopicCacheItem(topic=topic) + self.topic_cache[topic] = item + + # 收集属于该话题的消息文本(不带编号) + topic_msg_texts: List[str] = [] + new_participants: Set[str] = set() + for idx in indices: + msg_text = index_to_msg_text.get(idx) + if not msg_text: + continue + topic_msg_texts.append(msg_text) + new_participants.update(index_to_participants.get(idx, set())) + + if not topic_msg_texts: + continue + + # 将本次检查中属于该话题的所有消息合并为一个字符串(不带编号) + merged_text = "\n".join(topic_msg_texts) + item.messages.append(merged_text) + item.participants.update(new_participants) + # 本次检查中该话题有更新,重置计数 + item.no_update_checks = 0 + updated_topics.add(topic) + + # 5. 对于本次没有更新的历史话题,no_update_checks + 1 + for topic, item in list(self.topic_cache.items()): + if topic not in updated_topics: + item.no_update_checks += 1 + + # 6. 检查是否有话题需要打包存储 + topics_to_finalize: List[str] = [] + for topic, item in self.topic_cache.items(): + if item.no_update_checks >= 3: + logger.info(f"{self.log_prefix} 话题[{topic}] 连续 3 次检查无新增内容,触发打包存储") + topics_to_finalize.append(topic) + continue + if len(item.messages) > 5: + logger.info(f"{self.log_prefix} 话题[{topic}] 消息条数超过 4,触发打包存储") + topics_to_finalize.append(topic) + + for topic in topics_to_finalize: + item = self.topic_cache.get(topic) + if not item: + continue + try: + await self._finalize_and_store_topic( + topic=topic, + item=item, + # 这里的时间范围尽量覆盖最近一次检查的区间 + start_time=start_time, + end_time=end_time, + ) + finally: + # 无论成功与否,都从缓存中删除,避免重复 + self.topic_cache.pop(topic, None) + + def _find_most_similar_topic( + self, new_topic: str, existing_topics: List[str], similarity_threshold: float = 0.9 + ) -> Optional[tuple[str, float]]: + """ + 查找与给定新话题最相似的历史话题 + + Args: + new_topic: 新话题标题 + existing_topics: 历史话题标题列表 + similarity_threshold: 相似度阈值,默认0.9(90%) + + Returns: + Optional[tuple[str, float]]: 如果找到相似度>=阈值的历史话题,返回(历史话题标题, 相似度), + 否则返回None + """ + if not existing_topics: + return None + + best_match = None + best_similarity = 0.0 + + for existing_topic in existing_topics: + similarity = difflib.SequenceMatcher(None, new_topic, existing_topic).ratio() + if similarity > best_similarity: + best_similarity = similarity + best_match = existing_topic + + # 如果相似度达到阈值,返回匹配结果 + if best_match and best_similarity >= similarity_threshold: + return (best_match, best_similarity) + + return None + + def _build_topic_mapping( + self, topic_to_indices: Dict[str, List[int]], similarity_threshold: float = 0.9 + ) -> Dict[str, str]: + """ + 构建新话题到历史话题的映射(如果相似度>=阈值) + + Args: + topic_to_indices: 新话题到消息索引的映射 + similarity_threshold: 相似度阈值,默认0.9(90%) + + Returns: + Dict[str, str]: 新话题 -> 历史话题的映射字典 + """ + existing_topics_list = list(self.topic_cache.keys()) + topic_mapping: Dict[str, str] = {} + + for new_topic in topic_to_indices.keys(): + # 如果新话题已经在历史话题中,不需要检查 + if new_topic in existing_topics_list: + continue + + # 查找最相似的历史话题 + result = self._find_most_similar_topic(new_topic, existing_topics_list, similarity_threshold) + if result: + historical_topic, similarity = result + topic_mapping[new_topic] = historical_topic + logger.info( + f"{self.log_prefix} 话题相似度检查: '{new_topic}' 与历史话题 '{historical_topic}' 相似度 {similarity:.2%},使用历史标题" + ) + + return topic_mapping + + def _build_numbered_messages_for_llm( + self, messages: List[DatabaseMessages] + ) -> tuple[List[str], Dict[int, str], Dict[int, str], Dict[int, Set[str]]]: + """ + 将消息转为带编号的字符串,供 LLM 选择使用。 + + 返回: + numbered_lines: ["1. xxx", "2. yyy", ...] # 带编号,用于 LLM 选择 + index_to_msg_str: idx -> "idx. xxx" # 带编号,用于 LLM 选择 + index_to_msg_text: idx -> "xxx" # 不带编号,用于最终存储 + index_to_participants: idx -> {nickname1, nickname2, ...} + """ + numbered_lines: List[str] = [] + index_to_msg_str: Dict[int, str] = {} + index_to_msg_text: Dict[int, str] = {} # 不带编号的消息文本 + index_to_participants: Dict[int, Set[str]] = {} + + for idx, msg in enumerate(messages, start=1): + # 使用 build_readable_messages 生成可读文本 + try: + text = build_readable_messages( + messages=[msg], + replace_bot_name=True, + timestamp_mode="normal_no_YMD", + read_mark=0.0, + truncate=False, + show_actions=False, + ).strip() + except Exception: + # 回退到简单文本 + text = getattr(msg, "processed_plain_text", "") or "" + + # 获取发言人昵称 + participants: Set[str] = set() + try: + platform = ( + getattr(msg, "user_platform", None) + or (msg.user_info.platform if msg.user_info else None) + or msg.chat_info.platform + ) + user_id = msg.user_info.user_id if msg.user_info else None + if platform and user_id: + person = Person(platform=platform, user_id=user_id) + if person.person_name: + participants.add(person.person_name) + except Exception: + pass + + # 带编号的字符串(用于 LLM 选择) + line = f"{idx}. {text}" + numbered_lines.append(line) + index_to_msg_str[idx] = line + # 不带编号的文本(用于最终存储) + index_to_msg_text[idx] = text + index_to_participants[idx] = participants + + return numbered_lines, index_to_msg_str, index_to_msg_text, index_to_participants + + async def _analyze_topics_with_llm( + self, + numbered_lines: List[str], + existing_topics: List[str], + ) -> tuple[bool, Dict[str, List[int]]]: + """ + 使用 LLM 识别本次检查中的话题,并为每个话题选择相关消息编号。 + + 要求: + - 话题用一句话清晰描述正在发生的事件,包括时间、人物、主要事件和主题; + - 可以有 1 个或多个话题; + - 若某个话题与历史话题列表中的某个话题是同一件事,请直接使用历史话题的字符串; + - 输出 JSON,格式: + [ + { + "topic": "话题标题字符串", + "message_indices": [1, 2, 5] + }, + ... + ] + """ + if not numbered_lines: + return False, {} + + history_topics_block = "\n".join(f"- {t}" for t in existing_topics) if existing_topics else "(当前无历史话题)" + messages_block = "\n".join(numbered_lines) + + prompt = await global_prompt_manager.format_prompt( + "hippo_topic_analysis_prompt", + history_topics_block=history_topics_block, + messages_block=messages_block, + ) + + try: + response, _ = await self.summarizer_llm.generate_response_async( + prompt=prompt, + temperature=0.3, + ) + + logger.info(f"{self.log_prefix} 话题识别LLM Prompt: {prompt}") + logger.info(f"{self.log_prefix} 话题识别LLM Response: {response}") + + # 尝试从响应中提取JSON代码块 + json_str = None + json_pattern = r"```json\s*(.*?)\s*```" + matches = re.findall(json_pattern, response, re.DOTALL) + + if matches: + # 找到JSON代码块,使用第一个匹配 + json_str = matches[0].strip() + else: + # 如果没有找到代码块,尝试查找JSON数组的开始和结束位置 + # 查找第一个 [ 和最后一个 ] + start_idx = response.find("[") + end_idx = response.rfind("]") + if start_idx != -1 and end_idx != -1 and end_idx > start_idx: + json_str = response[start_idx : end_idx + 1].strip() + else: + # 如果还是找不到,尝试直接使用整个响应(移除可能的markdown标记) + json_str = response.strip() + json_str = re.sub(r"^```json\s*", "", json_str, flags=re.MULTILINE) + json_str = re.sub(r"^```\s*", "", json_str, flags=re.MULTILINE) + json_str = json_str.strip() + + # 使用json_repair修复可能的JSON错误 + if json_str: + try: + repaired_json = repair_json(json_str) + result = json.loads(repaired_json) if isinstance(repaired_json, str) else repaired_json + except Exception as repair_error: + # 如果repair失败,尝试直接解析 + logger.warning(f"{self.log_prefix} JSON修复失败,尝试直接解析: {repair_error}") + result = json.loads(json_str) + else: + raise ValueError("无法从响应中提取JSON内容") + + if not isinstance(result, list): + logger.error(f"{self.log_prefix} 话题识别返回的 JSON 不是列表: {result}") + return False, {} + + topic_to_indices: Dict[str, List[int]] = {} + for item in result: + if not isinstance(item, dict): + continue + topic = item.get("topic") + indices = item.get("message_indices") or item.get("messages") or [] + if not topic or not isinstance(topic, str): + continue + if isinstance(indices, list): + valid_indices: List[int] = [] + for v in indices: + try: + iv = int(v) + if iv > 0: + valid_indices.append(iv) + except (TypeError, ValueError): + continue + if valid_indices: + topic_to_indices[topic] = valid_indices + + return True, topic_to_indices + + except Exception as e: + logger.error(f"{self.log_prefix} 话题识别 LLM 调用或解析失败: {e}") + logger.error(f"{self.log_prefix} LLM响应: {response if 'response' in locals() else 'N/A'}") + return False, {} + + async def _finalize_and_store_topic( + self, + topic: str, + item: TopicCacheItem, + start_time: float, + end_time: float, + ): + """ + 对某个话题进行最终打包存储: + 1. 将 messages(list[str]) 拼接为 original_text; + 2. 使用 LLM 对 original_text 进行总结,得到 summary 和 keywords,theme 直接使用话题字符串; + 3. 写入数据库 ChatHistory; + 4. 完成后,调用方会从缓存中删除该话题。 + """ + if not item.messages: + logger.info(f"{self.log_prefix} 话题[{topic}] 无消息内容,跳过打包") + return + + original_text = "\n".join(item.messages) + + logger.info( + f"{self.log_prefix} 开始打包话题[{topic}] | 消息数: {len(item.messages)} | 时间范围: {start_time:.2f} - {end_time:.2f}" + ) + + # 使用 LLM 进行总结(基于话题名) + success, keywords, summary, key_point = await self._compress_with_llm(original_text, topic) + if not success: + logger.warning(f"{self.log_prefix} 话题[{topic}] LLM 概括失败,不写入数据库") + return + + participants = list(item.participants) + + await self._store_to_database( + start_time=start_time, + end_time=end_time, + original_text=original_text, + participants=participants, + theme=topic, # 主题直接使用话题名 + keywords=keywords, + summary=summary, + key_point=key_point, + ) + + logger.info( + f"{self.log_prefix} 话题[{topic}] 成功打包并存储 | 消息数: {len(item.messages)} | 参与者数: {len(participants)}" + ) + + async def _compress_with_llm(self, original_text: str, topic: str) -> tuple[bool, List[str], str, List[str]]: + """ + 使用LLM压缩聊天内容(用于单个话题的最终总结) + + Args: + original_text: 聊天记录原文 + topic: 话题名称 + + Returns: + tuple[bool, List[str], str, List[str]]: (是否成功, 关键词列表, 概括, 关键信息列表) + """ + prompt = await global_prompt_manager.format_prompt( + "hippo_topic_summary_prompt", + topic=topic, + original_text=original_text, + ) + + try: + response, _ = await self.summarizer_llm.generate_response_async( + prompt=prompt, + temperature=0.3, + max_tokens=500, + ) + + # 解析JSON响应 + json_str = response.strip() + json_str = re.sub(r"^```json\s*", "", json_str, flags=re.MULTILINE) + json_str = re.sub(r"^```\s*", "", json_str, flags=re.MULTILINE) + json_str = json_str.strip() + + # 查找JSON对象的开始与结束 + start_idx = json_str.find("{") + if start_idx == -1: + raise ValueError("未找到JSON对象开始标记") + + end_idx = json_str.rfind("}") + if end_idx == -1 or end_idx <= start_idx: + logger.warning(f"{self.log_prefix} JSON缺少结束标记,尝试自动修复") + extracted_json = json_str[start_idx:] + else: + extracted_json = json_str[start_idx : end_idx + 1] + + def _parse_with_quote_fix(payload: str) -> Dict[str, Any]: + fixed_chars: List[str] = [] + in_string = False + escape_next = False + i = 0 + while i < len(payload): + char = payload[i] + if escape_next: + fixed_chars.append(char) + escape_next = False + elif char == "\\": + fixed_chars.append(char) + escape_next = True + elif char == '"' and not escape_next: + fixed_chars.append(char) + in_string = not in_string + elif in_string and char in {"“", "”"}: + # 在字符串值内部,将中文引号替换为转义的英文引号 + fixed_chars.append('\\"') + else: + fixed_chars.append(char) + i += 1 + + repaired = "".join(fixed_chars) + return json.loads(repaired) + + try: + result = json.loads(extracted_json) + except json.JSONDecodeError: + try: + repaired_json = repair_json(extracted_json) + if isinstance(repaired_json, str): + result = json.loads(repaired_json) + else: + result = repaired_json + except Exception as repair_error: + logger.warning(f"{self.log_prefix} repair_json 失败,使用引号修复: {repair_error}") + result = _parse_with_quote_fix(extracted_json) + + keywords = result.get("keywords", []) + summary = result.get("summary", "无概括") + key_point = result.get("key_point", []) + + # 确保keywords和key_point是列表 + if isinstance(keywords, str): + keywords = [keywords] + if isinstance(key_point, str): + key_point = [key_point] + + return True, keywords, summary, key_point + + except Exception as e: + logger.error(f"{self.log_prefix} LLM压缩聊天内容时出错: {e}") + logger.error(f"{self.log_prefix} LLM响应: {response if 'response' in locals() else 'N/A'}") + # 返回失败标志和默认值 + return False, [], "压缩失败,无法生成概括", [] + + async def _store_to_database( + self, + start_time: float, + end_time: float, + original_text: str, + participants: List[str], + theme: str, + keywords: List[str], + summary: str, + key_point: Optional[List[str]] = None, + ): + """存储到数据库""" + try: + from src.common.database.database_model import ChatHistory + from src.plugin_system.apis import database_api + + # 准备数据 + data = { + "chat_id": self.chat_id, + "start_time": start_time, + "end_time": end_time, + "original_text": original_text, + "participants": json.dumps(participants, ensure_ascii=False), + "theme": theme, + "keywords": json.dumps(keywords, ensure_ascii=False), + "summary": summary, + "count": 0, + } + + # 存储 key_point(如果存在) + if key_point is not None: + data["key_point"] = json.dumps(key_point, ensure_ascii=False) + + # 使用db_save存储(使用start_time和chat_id作为唯一标识) + # 由于可能有多条记录,我们使用组合键,但peewee不支持,所以使用start_time作为唯一标识 + # 但为了避免冲突,我们使用组合键:chat_id + start_time + # 由于peewee不支持组合键,我们直接创建新记录(不提供key_field和key_value) + saved_record = await database_api.db_save( + ChatHistory, + data=data, + ) + + if saved_record: + logger.debug(f"{self.log_prefix} 成功存储聊天历史记录到数据库") + else: + logger.warning(f"{self.log_prefix} 存储聊天历史记录到数据库失败") + + except Exception as e: + logger.error(f"{self.log_prefix} 存储到数据库时出错: {e}") + import traceback + + traceback.print_exc() + raise + + async def start(self): + """启动后台定期检查循环""" + if self._running: + logger.warning(f"{self.log_prefix} 后台循环已在运行,无需重复启动") + return + + # 加载聊天批次(如果有) + await self._load_batch_from_disk() + + self._running = True + self._periodic_task = asyncio.create_task(self._periodic_check_loop()) + logger.info(f"{self.log_prefix} 已启动后台定期检查循环 | 检查间隔: {self.check_interval}秒") + + async def stop(self): + """停止后台定期检查循环""" + self._running = False + if self._periodic_task: + self._periodic_task.cancel() + try: + await self._periodic_task + except asyncio.CancelledError: + pass + self._periodic_task = None + logger.info(f"{self.log_prefix} 已停止后台定期检查循环") + + async def _periodic_check_loop(self): + """后台定期检查循环""" + try: + while self._running: + # 执行一次检查 + await self.process() + + # 等待指定间隔后再次检查 + await asyncio.sleep(self.check_interval) + except asyncio.CancelledError: + logger.info(f"{self.log_prefix} 后台检查循环被取消") + raise + except Exception as e: + logger.error(f"{self.log_prefix} 后台检查循环出错: {e}") + import traceback + + traceback.print_exc() + self._running = False + + +init_prompt() diff --git a/src/chat/utils/memory_forget_task.py b/src/hippo_memorizer/memory_forget_task.py similarity index 97% rename from src/chat/utils/memory_forget_task.py rename to src/hippo_memorizer/memory_forget_task.py index 15a912b4..ce2a9b2a 100644 --- a/src/chat/utils/memory_forget_task.py +++ b/src/hippo_memorizer/memory_forget_task.py @@ -25,15 +25,15 @@ class MemoryForgetTask(AsyncTask): """执行遗忘检查""" try: current_time = time.time() - logger.info("[记忆遗忘] 开始遗忘检查...") + # logger.info("[记忆遗忘] 开始遗忘检查...") # 执行4个阶段的遗忘检查 - await self._forget_stage_1(current_time) - await self._forget_stage_2(current_time) - await self._forget_stage_3(current_time) - await self._forget_stage_4(current_time) + # await self._forget_stage_1(current_time) + # await self._forget_stage_2(current_time) + # await self._forget_stage_3(current_time) + # await self._forget_stage_4(current_time) - logger.info("[记忆遗忘] 遗忘检查完成") + # logger.info("[记忆遗忘] 遗忘检查完成") except Exception as e: logger.error(f"[记忆遗忘] 执行遗忘检查时出错: {e}", exc_info=True) diff --git a/src/jargon/__init__.py b/src/jargon/__init__.py deleted file mode 100644 index 37b61644..00000000 --- a/src/jargon/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .jargon_miner import extract_and_store_jargon - -__all__ = [ - "extract_and_store_jargon", -] diff --git a/src/jargon/jargon_miner.py b/src/jargon/jargon_miner.py deleted file mode 100644 index 4319ad3d..00000000 --- a/src/jargon/jargon_miner.py +++ /dev/null @@ -1,858 +0,0 @@ -import time -import json -import asyncio -from typing import List, Dict, Optional, Any -from json_repair import repair_json -from peewee import fn - -from src.common.logger import get_logger -from src.common.database.database_model import Jargon -from src.llm_models.utils_model import LLMRequest -from src.config.config import model_config, global_config -from src.chat.message_receive.chat_stream import get_chat_manager -from src.plugin_system.apis import llm_api -from src.chat.utils.chat_message_builder import ( - build_anonymous_messages, - get_raw_msg_by_timestamp_with_chat_inclusive, - get_raw_msg_before_timestamp_with_chat, - build_readable_messages_with_list, -) -from src.chat.utils.prompt_builder import Prompt, global_prompt_manager - - -logger = get_logger("jargon") - - -def _contains_bot_self_name(content: str) -> bool: - """ - 判断词条是否包含机器人的昵称或别名 - """ - if not content: - return False - - bot_config = getattr(global_config, "bot", None) - if not bot_config: - return False - - target = content.strip().lower() - nickname = str(getattr(bot_config, "nickname", "") or "").strip().lower() - alias_names = [str(alias or "").strip().lower() for alias in getattr(bot_config, "alias_names", []) or []] - - candidates = [name for name in [nickname, *alias_names] if name] - - return any(name in target for name in candidates if target) - - -def _init_prompt() -> None: - prompt_str = """ -**聊天内容,其中的SELF是你自己的发言** -{chat_str} - -请从上面这段聊天内容中提取"可能是黑话"的候选项(黑话/俚语/网络缩写/口头禅)。 -- 必须为对话中真实出现过的短词或短语 -- 必须是你无法理解含义的词语,没有明确含义的词语 -- 请不要选择有明确含义,或者含义清晰的词语 -- 排除:人名、@、表情包/图片中的内容、纯标点、常规功能词(如的、了、呢、啊等) -- 每个词条长度建议 2-8 个字符(不强制),尽量短小 -- 合并重复项,去重 - -黑话必须为以下几种类型: -- 由字母构成的,汉语拼音首字母的简写词,例如:nb、yyds、xswl -- 英文词语的缩写,用英文字母概括一个词汇或含义,例如:CPU、GPU、API -- 中文词语的缩写,用几个汉字概括一个词汇或含义,例如:社死、内卷 - -以 JSON 数组输出,元素为对象(严格按以下结构): -[ - {{"content": "词条", "raw_content": "包含该词条的完整对话上下文原文"}}, - {{"content": "词条2", "raw_content": "包含该词条的完整对话上下文原文"}} -] - -现在请输出: -""" - Prompt(prompt_str, "extract_jargon_prompt") - - -def _init_inference_prompts() -> None: - """初始化含义推断相关的prompt""" - # Prompt 1: 基于raw_content和content推断 - prompt1_str = """ -**词条内容** -{content} -**词条出现的上下文(raw_content)其中的SELF是你自己的发言** -{raw_content_list} - -请根据以上词条内容和上下文,推断这个词条的含义。 -- 如果这是一个黑话、俚语或网络用语,请推断其含义 -- 如果含义明确(常规词汇),也请说明 -- 如果上下文信息不足,无法推断含义,请设置 no_info 为 true - -以 JSON 格式输出: -{{ - "meaning": "详细含义说明(包含使用场景、来源、具体解释等)", - "no_info": false -}} -注意:如果信息不足无法推断,请设置 "no_info": true,此时 meaning 可以为空字符串 -""" - Prompt(prompt1_str, "jargon_inference_with_context_prompt") - - # Prompt 2: 仅基于content推断 - prompt2_str = """ -**词条内容** -{content} - -请仅根据这个词条本身,推断其含义。 -- 如果这是一个黑话、俚语或网络用语,请推断其含义 -- 如果含义明确(常规词汇),也请说明 - -以 JSON 格式输出: -{{ - "meaning": "详细含义说明(包含使用场景、来源、具体解释等)" -}} -""" - Prompt(prompt2_str, "jargon_inference_content_only_prompt") - - # Prompt 3: 比较两个推断结果 - prompt3_str = """ -**推断结果1(基于上下文)** -{inference1} - -**推断结果2(仅基于词条)** -{inference2} - -请比较这两个推断结果,判断它们是否相同或类似。 -- 如果两个推断结果的"含义"相同或类似,说明这个词条不是黑话(含义明确) -- 如果两个推断结果有差异,说明这个词条可能是黑话(需要上下文才能理解) - -以 JSON 格式输出: -{{ - "is_similar": true/false, - "reason": "判断理由" -}} -""" - Prompt(prompt3_str, "jargon_compare_inference_prompt") - - -_init_prompt() -_init_inference_prompts() - - -async def _enrich_raw_content_if_needed( - content: str, - raw_content_list: List[str], - chat_id: str, - messages: List[Any], - extraction_start_time: float, - extraction_end_time: float, -) -> List[str]: - """ - 检查raw_content是否只包含黑话本身,如果是,则获取该消息的前三条消息作为原始内容 - - Args: - content: 黑话内容 - raw_content_list: 原始raw_content列表 - chat_id: 聊天ID - messages: 当前时间窗口内的消息列表 - extraction_start_time: 提取开始时间 - extraction_end_time: 提取结束时间 - - Returns: - 处理后的raw_content列表 - """ - enriched_list = [] - - for raw_content in raw_content_list: - # 检查raw_content是否只包含黑话本身(去除空白字符后比较) - raw_content_clean = raw_content.strip() - content_clean = content.strip() - - # 如果raw_content只包含黑话本身(可能有一些标点或空白),则尝试获取上下文 - # 去除所有空白字符后比较,确保只包含黑话本身 - raw_content_normalized = raw_content_clean.replace(" ", "").replace("\n", "").replace("\t", "") - content_normalized = content_clean.replace(" ", "").replace("\n", "").replace("\t", "") - - if raw_content_normalized == content_normalized: - # 在消息列表中查找只包含该黑话的消息(去除空白后比较) - target_message = None - for msg in messages: - msg_content = (msg.processed_plain_text or msg.display_message or "").strip() - msg_content_normalized = msg_content.replace(" ", "").replace("\n", "").replace("\t", "") - # 检查消息内容是否只包含黑话本身(去除空白后完全匹配) - if msg_content_normalized == content_normalized: - target_message = msg - break - - if target_message and target_message.time: - # 获取该消息的前三条消息 - try: - previous_messages = get_raw_msg_before_timestamp_with_chat( - chat_id=chat_id, timestamp=target_message.time, limit=3 - ) - - if previous_messages: - # 将前三条消息和当前消息一起格式化 - context_messages = previous_messages + [target_message] - # 按时间排序 - context_messages.sort(key=lambda x: x.time or 0) - - # 格式化为可读消息 - formatted_context, _ = await build_readable_messages_with_list( - context_messages, - replace_bot_name=True, - timestamp_mode="relative", - truncate=False, - ) - - if formatted_context.strip(): - enriched_list.append(formatted_context.strip()) - logger.warning(f"为黑话 {content} 补充了上下文消息") - else: - # 如果格式化失败,使用原始raw_content - enriched_list.append(raw_content) - else: - # 没有找到前三条消息,使用原始raw_content - enriched_list.append(raw_content) - except Exception as e: - logger.warning(f"获取黑话 {content} 的上下文消息失败: {e}") - # 出错时使用原始raw_content - enriched_list.append(raw_content) - else: - # 没有找到包含黑话的消息,使用原始raw_content - enriched_list.append(raw_content) - else: - # raw_content包含更多内容,直接使用 - enriched_list.append(raw_content) - - return enriched_list - - -def _should_infer_meaning(jargon_obj: Jargon) -> bool: - """ - 判断是否需要进行含义推断 - 在 count 达到 3,6, 10, 20, 40, 60, 100 时进行推断 - 并且count必须大于last_inference_count,避免重启后重复判定 - 如果is_complete为True,不再进行推断 - """ - # 如果已完成所有推断,不再推断 - if jargon_obj.is_complete: - return False - - count = jargon_obj.count or 0 - last_inference = jargon_obj.last_inference_count or 0 - - # 阈值列表:3,6, 10, 20, 40, 60, 100 - thresholds = [3, 6, 10, 20, 40, 60, 100] - - if count < thresholds[0]: - return False - - # 如果count没有超过上次判定值,不需要判定 - if count <= last_inference: - return False - - # 找到第一个大于last_inference的阈值 - next_threshold = None - for threshold in thresholds: - if threshold > last_inference: - next_threshold = threshold - break - - # 如果没有找到下一个阈值,说明已经超过100,不应该再推断 - if next_threshold is None: - return False - - # 检查count是否达到或超过这个阈值 - return count >= next_threshold - - -class JargonMiner: - def __init__(self, chat_id: str) -> None: - self.chat_id = chat_id - self.last_learning_time: float = time.time() - # 频率控制,可按需调整 - self.min_messages_for_learning: int = 10 - self.min_learning_interval: float = 20 - - self.llm = LLMRequest( - model_set=model_config.model_task_config.utils, - request_type="jargon.extract", - ) - - # 初始化stream_name作为类属性,避免重复提取 - chat_manager = get_chat_manager() - stream_name = chat_manager.get_stream_name(self.chat_id) - self.stream_name = stream_name if stream_name else self.chat_id - - async def _infer_meaning_by_id(self, jargon_id: int) -> None: - """通过ID加载对象并推断""" - try: - jargon_obj = Jargon.get_by_id(jargon_id) - # 再次检查is_complete,因为可能在异步任务执行时已被标记为完成 - if jargon_obj.is_complete: - logger.debug(f"jargon {jargon_obj.content} 已完成所有推断,跳过") - return - await self.infer_meaning(jargon_obj) - except Exception as e: - logger.error(f"通过ID推断jargon失败: {e}") - - async def infer_meaning(self, jargon_obj: Jargon) -> None: - """ - 对jargon进行含义推断 - """ - try: - content = jargon_obj.content - raw_content_str = jargon_obj.raw_content or "" - - # 解析raw_content列表 - raw_content_list = [] - if raw_content_str: - try: - raw_content_list = ( - json.loads(raw_content_str) if isinstance(raw_content_str, str) else raw_content_str - ) - if not isinstance(raw_content_list, list): - raw_content_list = [raw_content_list] if raw_content_list else [] - except (json.JSONDecodeError, TypeError): - raw_content_list = [raw_content_str] if raw_content_str else [] - - if not raw_content_list: - logger.warning(f"jargon {content} 没有raw_content,跳过推断") - return - - # 步骤1: 基于raw_content和content推断 - raw_content_text = "\n".join(raw_content_list) - prompt1 = await global_prompt_manager.format_prompt( - "jargon_inference_with_context_prompt", - content=content, - raw_content_list=raw_content_text, - ) - - response1, _ = await self.llm.generate_response_async(prompt1, temperature=0.3) - if not response1: - logger.warning(f"jargon {content} 推断1失败:无响应") - return - - # 解析推断1结果 - inference1 = None - try: - resp1 = response1.strip() - if resp1.startswith("{") and resp1.endswith("}"): - inference1 = json.loads(resp1) - else: - repaired = repair_json(resp1) - inference1 = json.loads(repaired) if isinstance(repaired, str) else repaired - if not isinstance(inference1, dict): - logger.warning(f"jargon {content} 推断1结果格式错误") - return - except Exception as e: - logger.error(f"jargon {content} 推断1解析失败: {e}") - return - - # 检查推断1是否表示信息不足无法推断 - no_info = inference1.get("no_info", False) - meaning1 = inference1.get("meaning", "").strip() - if no_info or not meaning1: - logger.info(f"jargon {content} 推断1表示信息不足无法推断,放弃本次推断,待下次更新") - # 更新最后一次判定的count值,避免在同一阈值重复尝试 - jargon_obj.last_inference_count = jargon_obj.count or 0 - jargon_obj.save() - return - - # 步骤2: 仅基于content推断 - prompt2 = await global_prompt_manager.format_prompt( - "jargon_inference_content_only_prompt", - content=content, - ) - - response2, _ = await self.llm.generate_response_async(prompt2, temperature=0.3) - if not response2: - logger.warning(f"jargon {content} 推断2失败:无响应") - return - - # 解析推断2结果 - inference2 = None - try: - resp2 = response2.strip() - if resp2.startswith("{") and resp2.endswith("}"): - inference2 = json.loads(resp2) - else: - repaired = repair_json(resp2) - inference2 = json.loads(repaired) if isinstance(repaired, str) else repaired - if not isinstance(inference2, dict): - logger.warning(f"jargon {content} 推断2结果格式错误") - return - except Exception as e: - logger.error(f"jargon {content} 推断2解析失败: {e}") - return - - # logger.info(f"jargon {content} 推断2提示词: {prompt2}") - # logger.info(f"jargon {content} 推断2结果: {response2}") - # logger.info(f"jargon {content} 推断1提示词: {prompt1}") - # logger.info(f"jargon {content} 推断1结果: {response1}") - - if global_config.debug.show_jargon_prompt: - logger.info(f"jargon {content} 推断2提示词: {prompt2}") - logger.info(f"jargon {content} 推断2结果: {response2}") - logger.info(f"jargon {content} 推断1提示词: {prompt1}") - logger.info(f"jargon {content} 推断1结果: {response1}") - else: - logger.debug(f"jargon {content} 推断2提示词: {prompt2}") - logger.debug(f"jargon {content} 推断2结果: {response2}") - logger.debug(f"jargon {content} 推断1提示词: {prompt1}") - logger.debug(f"jargon {content} 推断1结果: {response1}") - - # 步骤3: 比较两个推断结果 - prompt3 = await global_prompt_manager.format_prompt( - "jargon_compare_inference_prompt", - inference1=json.dumps(inference1, ensure_ascii=False), - inference2=json.dumps(inference2, ensure_ascii=False), - ) - - if global_config.debug.show_jargon_prompt: - logger.info(f"jargon {content} 比较提示词: {prompt3}") - - response3, _ = await self.llm.generate_response_async(prompt3, temperature=0.3) - if not response3: - logger.warning(f"jargon {content} 比较失败:无响应") - return - - # 解析比较结果 - comparison = None - try: - resp3 = response3.strip() - if resp3.startswith("{") and resp3.endswith("}"): - comparison = json.loads(resp3) - else: - repaired = repair_json(resp3) - comparison = json.loads(repaired) if isinstance(repaired, str) else repaired - if not isinstance(comparison, dict): - logger.warning(f"jargon {content} 比较结果格式错误") - return - except Exception as e: - logger.error(f"jargon {content} 比较解析失败: {e}") - return - - # 判断是否为黑话 - is_similar = comparison.get("is_similar", False) - is_jargon = not is_similar # 如果相似,说明不是黑话;如果有差异,说明是黑话 - - # 更新数据库记录 - jargon_obj.is_jargon = is_jargon - if is_jargon: - # 是黑话,使用推断1的结果(基于上下文,更准确) - jargon_obj.meaning = inference1.get("meaning", "") - else: - # 不是黑话,也记录含义(使用推断2的结果,因为含义明确) - jargon_obj.meaning = inference2.get("meaning", "") - - # 更新最后一次判定的count值,避免重启后重复判定 - jargon_obj.last_inference_count = jargon_obj.count or 0 - - # 如果count>=100,标记为完成,不再进行推断 - if (jargon_obj.count or 0) >= 100: - jargon_obj.is_complete = True - - jargon_obj.save() - logger.debug( - f"jargon {content} 推断完成: is_jargon={is_jargon}, meaning={jargon_obj.meaning}, last_inference_count={jargon_obj.last_inference_count}, is_complete={jargon_obj.is_complete}" - ) - - # 固定输出推断结果,格式化为可读形式 - if is_jargon: - # 是黑话,输出格式:[聊天名]xxx的含义是 xxxxxxxxxxx - meaning = jargon_obj.meaning or "无详细说明" - is_global = jargon_obj.is_global - if is_global: - logger.info(f"[黑话]{content}的含义是 {meaning}") - else: - logger.info(f"[{self.stream_name}]{content}的含义是 {meaning}") - else: - # 不是黑话,输出格式:[聊天名]xxx 不是黑话 - logger.info(f"[{self.stream_name}]{content} 不是黑话") - - except Exception as e: - logger.error(f"jargon推断失败: {e}") - import traceback - - traceback.print_exc() - - def should_trigger(self) -> bool: - # 冷却时间检查 - if time.time() - self.last_learning_time < self.min_learning_interval: - return False - - # 拉取最近消息数量是否足够 - recent_messages = get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id=self.chat_id, - timestamp_start=self.last_learning_time, - timestamp_end=time.time(), - ) - return bool(recent_messages and len(recent_messages) >= self.min_messages_for_learning) - - async def run_once(self) -> None: - try: - if not self.should_trigger(): - return - - chat_stream = get_chat_manager().get_stream(self.chat_id) - if not chat_stream: - return - - # 记录本次提取的时间窗口,避免重复提取 - extraction_start_time = self.last_learning_time - extraction_end_time = time.time() - - # 拉取学习窗口内的消息 - messages = get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id=self.chat_id, - timestamp_start=extraction_start_time, - timestamp_end=extraction_end_time, - limit=20, - ) - if not messages: - return - - chat_str: str = await build_anonymous_messages(messages) - if not chat_str.strip(): - return - - prompt: str = await global_prompt_manager.format_prompt( - "extract_jargon_prompt", - chat_str=chat_str, - ) - - response, _ = await self.llm.generate_response_async(prompt, temperature=0.2) - if not response: - return - - if global_config.debug.show_jargon_prompt: - logger.info(f"jargon提取提示词: {prompt}") - logger.info(f"jargon提取结果: {response}") - - # 解析为JSON - entries: List[dict] = [] - try: - resp = response.strip() - parsed = None - if resp.startswith("[") and resp.endswith("]"): - parsed = json.loads(resp) - else: - repaired = repair_json(resp) - if isinstance(repaired, str): - parsed = json.loads(repaired) - else: - parsed = repaired - - if isinstance(parsed, dict): - parsed = [parsed] - - if not isinstance(parsed, list): - return - - for item in parsed: - if not isinstance(item, dict): - continue - content = str(item.get("content", "")).strip() - raw_content_value = item.get("raw_content", "") - - # 处理raw_content:可能是字符串或列表 - raw_content_list = [] - if isinstance(raw_content_value, list): - raw_content_list = [str(rc).strip() for rc in raw_content_value if str(rc).strip()] - # 去重 - raw_content_list = list(dict.fromkeys(raw_content_list)) - elif isinstance(raw_content_value, str): - raw_content_str = raw_content_value.strip() - if raw_content_str: - raw_content_list = [raw_content_str] - - if content and raw_content_list: - if _contains_bot_self_name(content): - logger.debug(f"解析阶段跳过包含机器人昵称/别名的词条: {content}") - continue - entries.append({"content": content, "raw_content": raw_content_list}) - except Exception as e: - logger.error(f"解析jargon JSON失败: {e}; 原始: {response}") - return - - if not entries: - return - - # 去重并写入DB(按 chat_id + content 去重) - # 使用content作为去重键 - seen = set() - uniq_entries = [] - for entry in entries: - content_key = entry["content"] - if content_key not in seen: - seen.add(content_key) - uniq_entries.append(entry) - - saved = 0 - updated = 0 - for entry in uniq_entries: - content = entry["content"] - raw_content_list = entry["raw_content"] # 已经是列表 - - # 检查并补充raw_content:如果只包含黑话本身,则获取前三条消息作为上下文 - raw_content_list = await _enrich_raw_content_if_needed( - content=content, - raw_content_list=raw_content_list, - chat_id=self.chat_id, - messages=messages, - extraction_start_time=extraction_start_time, - extraction_end_time=extraction_end_time, - ) - - try: - # 根据all_global配置决定查询逻辑 - if global_config.jargon.all_global: - # 开启all_global:无视chat_id,查询所有content匹配的记录(所有记录都是全局的) - query = Jargon.select().where(Jargon.content == content) - else: - # 关闭all_global:只查询chat_id匹配的记录(不考虑is_global) - query = Jargon.select().where((Jargon.chat_id == self.chat_id) & (Jargon.content == content)) - - if query.exists(): - obj = query.get() - try: - obj.count = (obj.count or 0) + 1 - except Exception: - obj.count = 1 - - # 合并raw_content列表:读取现有列表,追加新值,去重 - existing_raw_content = [] - if obj.raw_content: - try: - existing_raw_content = ( - json.loads(obj.raw_content) if isinstance(obj.raw_content, str) else obj.raw_content - ) - if not isinstance(existing_raw_content, list): - existing_raw_content = [existing_raw_content] if existing_raw_content else [] - except (json.JSONDecodeError, TypeError): - existing_raw_content = [obj.raw_content] if obj.raw_content else [] - - # 合并并去重 - merged_list = list(dict.fromkeys(existing_raw_content + raw_content_list)) - obj.raw_content = json.dumps(merged_list, ensure_ascii=False) - - # 开启all_global时,确保记录标记为is_global=True - if global_config.jargon.all_global: - obj.is_global = True - # 关闭all_global时,保持原有is_global不变(不修改) - - obj.save() - - # 检查是否需要推断(达到阈值且超过上次判定值) - if _should_infer_meaning(obj): - # 异步触发推断,不阻塞主流程 - # 重新加载对象以确保数据最新 - jargon_id = obj.id - asyncio.create_task(self._infer_meaning_by_id(jargon_id)) - - updated += 1 - else: - # 没找到匹配记录,创建新记录 - if global_config.jargon.all_global: - # 开启all_global:新记录默认为is_global=True - is_global_new = True - else: - # 关闭all_global:新记录is_global=False - is_global_new = False - - Jargon.create( - content=content, - raw_content=json.dumps(raw_content_list, ensure_ascii=False), - chat_id=self.chat_id, - is_global=is_global_new, - count=1, - ) - saved += 1 - except Exception as e: - logger.error(f"保存jargon失败: chat_id={self.chat_id}, content={content}, err={e}") - continue - - # 固定输出提取的jargon结果,格式化为可读形式(只要有提取结果就输出) - if uniq_entries: - # 收集所有提取的jargon内容 - jargon_list = [entry["content"] for entry in uniq_entries] - jargon_str = ",".join(jargon_list) - - # 输出格式化的结果(使用logger.info会自动应用jargon模块的颜色) - logger.info(f"[{self.stream_name}]疑似黑话: {jargon_str}") - - # 更新为本次提取的结束时间,确保不会重复提取相同的消息窗口 - self.last_learning_time = extraction_end_time - - if saved or updated: - logger.info(f"jargon写入: 新增 {saved} 条,更新 {updated} 条,chat_id={self.chat_id}") - except Exception as e: - logger.error(f"JargonMiner 运行失败: {e}") - - -class JargonMinerManager: - def __init__(self) -> None: - self._miners: dict[str, JargonMiner] = {} - - def get_miner(self, chat_id: str) -> JargonMiner: - if chat_id not in self._miners: - self._miners[chat_id] = JargonMiner(chat_id) - return self._miners[chat_id] - - -miner_manager = JargonMinerManager() - - -async def extract_and_store_jargon(chat_id: str) -> None: - miner = miner_manager.get_miner(chat_id) - await miner.run_once() - - -def search_jargon( - keyword: str, chat_id: Optional[str] = None, limit: int = 10, case_sensitive: bool = False, fuzzy: bool = True -) -> List[Dict[str, str]]: - """ - 搜索jargon,支持大小写不敏感和模糊搜索 - - Args: - keyword: 搜索关键词 - chat_id: 可选的聊天ID - - 如果开启了all_global:此参数被忽略,查询所有is_global=True的记录 - - 如果关闭了all_global:如果提供则优先搜索该聊天或global的jargon - limit: 返回结果数量限制,默认10 - case_sensitive: 是否大小写敏感,默认False(不敏感) - fuzzy: 是否模糊搜索,默认True(使用LIKE匹配) - - Returns: - List[Dict[str, str]]: 包含content, meaning的字典列表 - """ - if not keyword or not keyword.strip(): - return [] - - keyword = keyword.strip() - - # 构建查询 - query = Jargon.select(Jargon.content, Jargon.meaning) - - # 构建搜索条件 - if case_sensitive: - # 大小写敏感 - if fuzzy: - # 模糊搜索 - search_condition = Jargon.content.contains(keyword) - else: - # 精确匹配 - search_condition = Jargon.content == keyword - else: - # 大小写不敏感 - if fuzzy: - # 模糊搜索(使用LOWER函数) - search_condition = fn.LOWER(Jargon.content).contains(keyword.lower()) - else: - # 精确匹配(使用LOWER函数) - search_condition = fn.LOWER(Jargon.content) == keyword.lower() - - query = query.where(search_condition) - - # 根据all_global配置决定查询逻辑 - if global_config.jargon.all_global: - # 开启all_global:所有记录都是全局的,查询所有is_global=True的记录(无视chat_id) - query = query.where(Jargon.is_global) - else: - # 关闭all_global:如果提供了chat_id,优先搜索该聊天或global的jargon - if chat_id: - query = query.where((Jargon.chat_id == chat_id) | Jargon.is_global) - - # 只返回有meaning的记录 - query = query.where((Jargon.meaning.is_null(False)) & (Jargon.meaning != "")) - - # 按count降序排序,优先返回出现频率高的 - query = query.order_by(Jargon.count.desc()) - - # 限制结果数量 - query = query.limit(limit) - - # 执行查询并返回结果 - results = [] - for jargon in query: - results.append({"content": jargon.content or "", "meaning": jargon.meaning or ""}) - - return results - - -async def store_jargon_from_answer(jargon_keyword: str, answer: str, chat_id: str) -> None: - """将黑话存入jargon系统 - - Args: - jargon_keyword: 黑话关键词 - answer: 答案内容(将概括为raw_content) - chat_id: 聊天ID - """ - try: - # 概括答案为简短的raw_content - summary_prompt = f"""请将以下答案概括为一句简短的话(不超过50字),作为黑话"{jargon_keyword}"的使用示例: - -答案:{answer} - -只输出概括后的内容,不要输出其他内容:""" - - success, summary, _, _ = await llm_api.generate_with_model( - summary_prompt, - model_config=model_config.model_task_config.utils_small, - request_type="memory.summarize_jargon", - ) - - logger.info(f"概括答案提示: {summary_prompt}") - logger.info(f"概括答案: {summary}") - - if not success: - logger.warning(f"概括答案失败,使用原始答案: {summary}") - summary = answer[:100] # 截取前100字符作为备用 - - raw_content = summary.strip()[:200] # 限制长度 - - # 检查是否已存在 - if global_config.jargon.all_global: - query = Jargon.select().where(Jargon.content == jargon_keyword) - else: - query = Jargon.select().where((Jargon.chat_id == chat_id) & (Jargon.content == jargon_keyword)) - - if query.exists(): - # 更新现有记录 - obj = query.get() - obj.count = (obj.count or 0) + 1 - - # 合并raw_content列表 - existing_raw_content = [] - if obj.raw_content: - try: - existing_raw_content = ( - json.loads(obj.raw_content) if isinstance(obj.raw_content, str) else obj.raw_content - ) - if not isinstance(existing_raw_content, list): - existing_raw_content = [existing_raw_content] if existing_raw_content else [] - except (json.JSONDecodeError, TypeError): - existing_raw_content = [obj.raw_content] if obj.raw_content else [] - - # 合并并去重 - merged_list = list(dict.fromkeys(existing_raw_content + [raw_content])) - obj.raw_content = json.dumps(merged_list, ensure_ascii=False) - - if global_config.jargon.all_global: - obj.is_global = True - - obj.save() - logger.info(f"更新jargon记录: {jargon_keyword}") - else: - # 创建新记录 - is_global_new = True if global_config.jargon.all_global else False - Jargon.create( - content=jargon_keyword, - raw_content=json.dumps([raw_content], ensure_ascii=False), - chat_id=chat_id, - is_global=is_global_new, - count=1, - ) - logger.info(f"创建新jargon记录: {jargon_keyword}") - - except Exception as e: - logger.error(f"存储jargon失败: {e}") diff --git a/src/llm_models/exceptions.py b/src/llm_models/exceptions.py index 65e49f74..25452e0b 100644 --- a/src/llm_models/exceptions.py +++ b/src/llm_models/exceptions.py @@ -18,11 +18,12 @@ error_code_mapping = { class NetworkConnectionError(Exception): """连接异常,常见于网络问题或服务器不可用""" - def __init__(self): - super().__init__() + def __init__(self, message: str | None = None): + super().__init__(message) + self.message = message def __str__(self): - return "连接异常,请检查网络连接状态或URL是否正确" + return self.message or "连接异常,请检查网络连接状态或URL是否正确" class ReqAbortException(Exception): diff --git a/src/llm_models/model_client/gemini_client.py b/src/llm_models/model_client/gemini_client.py index b3fafca0..33afacaa 100644 --- a/src/llm_models/model_client/gemini_client.py +++ b/src/llm_models/model_client/gemini_client.py @@ -98,7 +98,10 @@ def _convert_messages( content: List[Part] = [] for item in message.content: if isinstance(item, tuple): - image_format = "jpeg" if item[0].lower() == "jpg" else item[0].lower() + image_format = item[0].lower() + # 规范 JPEG MIME 类型后缀,统一使用 image/jpeg + if image_format in ("jpg", "jpeg"): + image_format = "jpeg" content.append(Part.from_bytes(data=base64.b64decode(item[1]), mime_type=f"image/{image_format}")) elif isinstance(item, str): content.append(Part.from_text(text=item)) @@ -143,10 +146,14 @@ def _convert_tool_options(tool_options: list[ToolOption]) -> list[FunctionDeclar :param tool_option_param: 工具参数对象 :return: 转换后的工具参数字典 """ - # JSON Schema要求使用"boolean"而不是"bool" + # JSON Schema 类型名称修正: + # - 布尔类型使用 "boolean" 而不是 "bool" + # - 浮点数使用 "number" 而不是 "float" param_type_value = tool_option_param.param_type.value if param_type_value == "bool": param_type_value = "boolean" + elif param_type_value == "float": + param_type_value = "number" return_dict: dict[str, Any] = { "type": param_type_value, diff --git a/src/llm_models/model_client/openai_client.py b/src/llm_models/model_client/openai_client.py index f573d33e..5372d95b 100644 --- a/src/llm_models/model_client/openai_client.py +++ b/src/llm_models/model_client/openai_client.py @@ -61,10 +61,16 @@ def _convert_messages(messages: list[Message]) -> list[ChatCompletionMessagePara content = [] for item in message.content: if isinstance(item, tuple): + image_format = item[0].lower() + # 规范 JPEG MIME 类型后缀,统一使用 image/jpeg + if image_format in ("jpg", "jpeg"): + mime_suffix = "jpeg" + else: + mime_suffix = image_format content.append( { "type": "image_url", - "image_url": {"url": f"data:image/{item[0].lower()};base64,{item[1]}"}, + "image_url": {"url": f"data:image/{mime_suffix};base64,{item[1]}"}, } ) elif isinstance(item, str): @@ -118,10 +124,14 @@ def _convert_tool_options(tool_options: list[ToolOption]) -> list[dict[str, Any] :param tool_option_param: 工具参数对象 :return: 转换后的工具参数字典 """ - # JSON Schema要求使用"boolean"而不是"bool" + # JSON Schema 类型名称修正: + # - 布尔类型使用 "boolean" 而不是 "bool" + # - 浮点数使用 "number" 而不是 "float" param_type_value = tool_option_param.param_type.value if param_type_value == "bool": param_type_value = "boolean" + elif param_type_value == "float": + param_type_value = "number" return_dict: dict[str, Any] = { "type": param_type_value, diff --git a/src/llm_models/utils_model.py b/src/llm_models/utils_model.py index 1ed74e03..df22c9cd 100644 --- a/src/llm_models/utils_model.py +++ b/src/llm_models/utils_model.py @@ -47,6 +47,21 @@ class LLMRequest: } """模型使用量记录,用于进行负载均衡,对应为(total_tokens, penalty, usage_penalty),惩罚值是为了能在某个模型请求不给力或正在被使用的时候进行调整""" + def _check_slow_request(self, time_cost: float, model_name: str) -> None: + """检查请求是否过慢并输出警告日志 + + Args: + time_cost: 请求耗时(秒) + model_name: 使用的模型名称 + """ + threshold = self.model_for_task.slow_threshold + if time_cost > threshold: + request_type_display = self.request_type or "未知任务" + logger.warning( + f"LLM请求耗时过长: {request_type_display} 使用模型 {model_name} 耗时 {time_cost:.1f}s(阈值: {threshold}s),请考虑使用更快的模型\n" + f" 如果你认为该警告出现得过于频繁,请调整model_config.toml中对应任务的slow_threshold至符合你实际情况的合理值" + ) + async def generate_response_for_image( self, prompt: str, @@ -86,6 +101,8 @@ class LLMRequest: if not reasoning_content and content: content, extracted_reasoning = self._extract_reasoning(content) reasoning_content = extracted_reasoning + time_cost = time.time() - start_time + self._check_slow_request(time_cost, model_info.name) if usage := response.usage: llm_usage_recorder.record_usage_to_database( model_info=model_info, @@ -93,7 +110,7 @@ class LLMRequest: user_id="system", request_type=self.request_type, endpoint="/chat/completions", - time_cost=time.time() - start_time, + time_cost=time_cost, ) return content, (reasoning_content, model_info.name, tool_calls) @@ -198,7 +215,8 @@ class LLMRequest: tool_options=tool_built, ) - logger.debug(f"LLM请求总耗时: {time.time() - start_time}") + time_cost = time.time() - start_time + logger.debug(f"LLM请求总耗时: {time_cost}") logger.debug(f"LLM生成内容: {response}") content = response.content @@ -207,6 +225,7 @@ class LLMRequest: if not reasoning_content and content: content, extracted_reasoning = self._extract_reasoning(content) reasoning_content = extracted_reasoning + self._check_slow_request(time_cost, model_info.name) if usage := response.usage: llm_usage_recorder.record_usage_to_database( model_info=model_info, @@ -214,7 +233,7 @@ class LLMRequest: user_id="system", request_type=self.request_type, endpoint="/chat/completions", - time_cost=time.time() - start_time, + time_cost=time_cost, ) return content or "", (reasoning_content, model_info.name, tool_calls) @@ -296,12 +315,30 @@ class LLMRequest: while retry_remain > 0: try: if request_type == RequestType.RESPONSE: + # 温度优先级:参数传入 > 模型级别配置 > extra_params > 任务配置 + effective_temperature = temperature + if effective_temperature is None: + effective_temperature = model_info.temperature + if effective_temperature is None: + effective_temperature = (model_info.extra_params or {}).get("temperature") + if effective_temperature is None: + effective_temperature = self.model_for_task.temperature + + # max_tokens 优先级:参数传入 > 模型级别配置 > extra_params > 任务配置 + effective_max_tokens = max_tokens + if effective_max_tokens is None: + effective_max_tokens = model_info.max_tokens + if effective_max_tokens is None: + effective_max_tokens = (model_info.extra_params or {}).get("max_tokens") + if effective_max_tokens is None: + effective_max_tokens = self.model_for_task.max_tokens + return await client.get_response( model_info=model_info, message_list=(compressed_messages or message_list), tool_options=tool_options, - max_tokens=self.model_for_task.max_tokens if max_tokens is None else max_tokens, - temperature=self.model_for_task.temperature if temperature is None else temperature, + max_tokens=effective_max_tokens, + temperature=effective_temperature, response_format=response_format, stream_response_handler=stream_response_handler, async_response_parser=async_response_parser, @@ -323,34 +360,49 @@ class LLMRequest: ) except EmptyResponseException as e: # 空回复:通常为临时问题,单独记录并重试 + original_error_info = self._get_original_error_info(e) retry_remain -= 1 if retry_remain <= 0: - logger.error(f"模型 '{model_info.name}' 在多次出现空回复后仍然失败。") + logger.error(f"模型 '{model_info.name}' 在多次出现空回复后仍然失败。{original_error_info}") raise ModelAttemptFailed(f"模型 '{model_info.name}' 重试耗尽", original_exception=e) from e - logger.warning(f"模型 '{model_info.name}' 返回空回复(可重试)。剩余重试次数: {retry_remain}") + logger.warning( + f"模型 '{model_info.name}' 返回空回复(可重试){original_error_info}。剩余重试次数: {retry_remain}" + ) await asyncio.sleep(api_provider.retry_interval) except NetworkConnectionError as e: # 网络错误:单独记录并重试 + # 尝试从链式异常中获取原始错误信息以诊断具体原因 + original_error_info = self._get_original_error_info(e) + retry_remain -= 1 if retry_remain <= 0: - logger.error(f"模型 '{model_info.name}' 在网络错误重试用尽后仍然失败。") + logger.error(f"模型 '{model_info.name}' 在网络错误重试用尽后仍然失败。{original_error_info}") raise ModelAttemptFailed(f"模型 '{model_info.name}' 重试耗尽", original_exception=e) from e - logger.warning(f"模型 '{model_info.name}' 遇到网络错误(可重试): {str(e)}。剩余重试次数: {retry_remain}") + logger.warning( + f"模型 '{model_info.name}' 遇到网络错误(可重试): {str(e)}{original_error_info}\n" + f" 常见原因: 如请求的API正常但APITimeoutError类型错误过多,请尝试调整模型配置中对应API Provider的timeout值\n" + f" 其它可能原因: 网络波动、DNS 故障、连接超时、防火墙限制或代理问题\n" + f" 剩余重试次数: {retry_remain}" + ) await asyncio.sleep(api_provider.retry_interval) except RespNotOkException as e: + original_error_info = self._get_original_error_info(e) + # 可重试的HTTP错误 if e.status_code == 429 or e.status_code >= 500: retry_remain -= 1 if retry_remain <= 0: - logger.error(f"模型 '{model_info.name}' 在遇到 {e.status_code} 错误并用尽重试次数后仍然失败。") + logger.error( + f"模型 '{model_info.name}' 在遇到 {e.status_code} 错误并用尽重试次数后仍然失败。{original_error_info}" + ) raise ModelAttemptFailed(f"模型 '{model_info.name}' 重试耗尽", original_exception=e) from e logger.warning( - f"模型 '{model_info.name}' 遇到可重试的HTTP错误: {str(e)}。剩余重试次数: {retry_remain}" + f"模型 '{model_info.name}' 遇到可重试的HTTP错误: {str(e)}{original_error_info}。剩余重试次数: {retry_remain}" ) await asyncio.sleep(api_provider.retry_interval) continue @@ -363,13 +415,15 @@ class LLMRequest: continue # 不可重试的HTTP错误 - logger.warning(f"模型 '{model_info.name}' 遇到不可重试的HTTP错误: {str(e)}") + logger.warning(f"模型 '{model_info.name}' 遇到不可重试的HTTP错误: {str(e)}{original_error_info}") raise ModelAttemptFailed(f"模型 '{model_info.name}' 遇到硬错误", original_exception=e) from e except Exception as e: logger.error(traceback.format_exc()) - logger.warning(f"模型 '{model_info.name}' 遇到未知的不可重试错误: {str(e)}") + original_error_info = self._get_original_error_info(e) + + logger.warning(f"模型 '{model_info.name}' 遇到未知的不可重试错误: {str(e)}{original_error_info}") raise ModelAttemptFailed(f"模型 '{model_info.name}' 遇到硬错误", original_exception=e) from e raise ModelAttemptFailed(f"模型 '{model_info.name}' 未被尝试,因为重试次数已配置为0或更少。") @@ -483,3 +537,12 @@ class LLMRequest: content = re.sub(r"(?:)?.*?", "", content, flags=re.DOTALL, count=1).strip() reasoning = match[1].strip() if match else "" return content, reasoning + + @staticmethod + def _get_original_error_info(e: Exception) -> str: + """获取原始错误信息""" + if e.__cause__: + original_error_type = type(e.__cause__).__name__ + original_error_msg = str(e.__cause__) + return f"\n 底层异常类型: {original_error_type}\n 底层异常信息: {original_error_msg}" + return "" diff --git a/src/main.py b/src/main.py index 09ead248..57950bf9 100644 --- a/src/main.py +++ b/src/main.py @@ -13,9 +13,9 @@ from src.config.config import global_config from src.chat.message_receive.bot import chat_bot from src.common.logger import get_logger from src.common.server import get_global_server, Server -from src.mood.mood_manager import mood_manager from src.chat.knowledge import lpmm_start_up from rich.traceback import install + # from src.api.main import start_api_server # 导入新的插件管理器 @@ -23,6 +23,7 @@ from src.plugin_system.core.plugin_manager import plugin_manager # 导入消息API和traceback模块 from src.common.message import get_global_api +from src.dream.dream_agent import start_dream_scheduler # 插件系统现在使用统一的插件加载器 @@ -43,30 +44,17 @@ class MainSystem: def _setup_webui_server(self): """设置独立的 WebUI 服务器""" - import os + from src.config.config import global_config - webui_enabled = os.getenv("WEBUI_ENABLED", "false").lower() == "true" - if not webui_enabled: + if not global_config.webui.enabled: logger.info("WebUI 已禁用") return - webui_mode = os.getenv("WEBUI_MODE", "production").lower() - try: from src.webui.webui_server import get_webui_server self.webui_server = get_webui_server() - - if webui_mode == "development": - logger.info("📝 WebUI 开发模式已启用") - logger.info("🌐 后端 API 将运行在 http://0.0.0.0:8001") - logger.info("💡 请手动启动前端开发服务器: cd MaiBot-Dashboard && bun dev") - logger.info("💡 前端将运行在 http://localhost:7999") - else: - logger.info("✅ WebUI 生产模式已启用") - logger.info(f"🌐 WebUI 将运行在 http://0.0.0.0:8001") - logger.info("💡 请确保已构建前端: cd MaiBot-Dashboard && bun run build") - + except Exception as e: logger.error(f"❌ 初始化 WebUI 服务器失败: {e}") @@ -106,7 +94,7 @@ class MainSystem: await async_task_manager.add_task(TelemetryHeartBeatTask()) # 添加记忆遗忘任务 - from src.chat.utils.memory_forget_task import MemoryForgetTask + from src.hippo_memorizer.memory_forget_task import MemoryForgetTask await async_task_manager.add_task(MemoryForgetTask()) @@ -124,11 +112,6 @@ class MainSystem: get_emoji_manager().initialize() logger.info("表情包管理器初始化成功") - # 启动情绪管理器 - if global_config.mood.enable_mood: - await mood_manager.start() - logger.info("情绪管理器初始化成功") - # 初始化聊天管理器 await get_chat_manager()._initialize() asyncio.create_task(get_chat_manager()._auto_save_task()) @@ -156,9 +139,10 @@ class MainSystem: async def schedule_tasks(self): """调度定时任务""" - while True: + try: tasks = [ get_emoji_manager().start_periodic_check_register(), + start_dream_scheduler(), self.app.run(), self.server.run(), ] @@ -168,6 +152,9 @@ class MainSystem: tasks.append(self.webui_server.start()) await asyncio.gather(*tasks) + except asyncio.CancelledError: + logger.info("调度任务已取消") + raise # async def forget_memory_task(self): # """记忆遗忘任务""" diff --git a/src/memory_system/memory_retrieval.py b/src/memory_system/memory_retrieval.py index 7d129bbc..9aafb9ef 100644 --- a/src/memory_system/memory_retrieval.py +++ b/src/memory_system/memory_retrieval.py @@ -1,18 +1,17 @@ import time import json -import re -import random import asyncio -from typing import List, Dict, Any, Optional, Tuple +import re +from typing import List, Dict, Any, Optional, Tuple, Set from src.common.logger import get_logger from src.config.config import global_config, model_config from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.plugin_system.apis import llm_api from src.common.database.database_model import ThinkingBack -from json_repair import repair_json from src.memory_system.retrieval_tools import get_tool_registry, init_all_tools -from src.memory_system.retrieval_tools.query_lpmm_knowledge import query_lpmm_knowledge +from src.memory_system.memory_utils import parse_questions_json from src.llm_models.payload_content.message import MessageBuilder, RoleType, Message +from src.bw_learner.jargon_explainer import match_jargon_from_text, retrieve_concepts_with_jargon logger = get_logger("memory_retrieval") @@ -63,39 +62,28 @@ def init_memory_retrieval_prompt(): 2. 是否有需要回忆的内容(比如"之前说过"、"上次"、"以前"等) 3. 是否有需要查找历史信息的问题 4. 是否有问题可以搜集信息帮助你聊天 -5. 对话中是否包含黑话、俚语、缩写等可能需要查询的概念 重要提示: - **每次只能提出一个问题**,选择最需要查询的关键问题 - 如果"最近已查询的问题和结果"中已经包含了类似的问题并得到了答案,请避免重复生成相同或相似的问题,不需要重复查询 - 如果之前已经查询过某个问题但未找到答案,可以尝试用不同的方式提问或更具体的问题 -如果你认为需要从记忆中检索信息来回答,请: -1. 识别对话中可能需要查询的概念(黑话/俚语/缩写/专有名词等关键词),放入"concepts"字段 -2. 根据上下文提出**一个**最关键的问题来帮助你回复目标消息,放入"questions"字段 +如果你认为需要从记忆中检索信息来回答,请根据上下文提出**一个**最关键的问题来帮助你回复目标消息,放入"questions"字段 问题格式示例: - "xxx在前几天干了什么" -- "xxx是什么" +- "xxx是什么,在什么时候提到过?" - "xxxx和xxx的关系是什么" - "xxx在某个时间点发生了什么" -输出格式示例(需要检索时): +问题要说明前因后果和上下文,使其全面且精准 + +输出格式示例: ```json {{ - "concepts": ["AAA", "BBB", "CCC"], #需要检索的概念列表(字符串数组),如果不需要检索概念则输出空数组[] "questions": ["张三在前几天干了什么"] #问题数组(字符串数组),如果不需要检索记忆则输出空数组[],如果需要检索则只输出包含一个问题的数组 }} ``` - -输出格式示例(不需要检索时): -```json -{{ - "concepts": [], - "questions": [] -}} -``` - 请只输出JSON对象,不要输出其他内容: """, name="memory_retrieval_question_prompt", @@ -105,36 +93,20 @@ def init_memory_retrieval_prompt(): Prompt( """你的名字是{bot_name}。现在是{time_now}。 你正在参与聊天,你需要搜集信息来回答问题,帮助你参与聊天。 - -**重要限制:** -- 最大查询轮数:{max_iterations}轮(当前第{current_iteration}轮,剩余{remaining_iterations}轮) -- 必须尽快得出答案,避免不必要的查询 -- 思考要简短,直接切入要点 -- 必须严格使用检索到的信息回答问题,不要编造信息 - -当前问题:{question} +当前需要解答的问题:{question} 已收集的信息: {collected_info} -**执行步骤:** -**第一步:思考(Think)** -在思考中分析: -- 当前信息是否足够回答问题? -- **如果信息足够且能找到明确答案**,在思考中直接给出答案,格式为:found_answer(answer="你的答案内容") -- **如果需要尝试搜集更多信息,进一步调用工具,进入第二步行动环节 -- **如果已有信息不足或无法找到答案**,在思考中给出:not_enough_info(reason="信息不足或无法找到答案的原因") - -**第二步:行动(Action)** -- 如果涉及过往事件,可以使用聊天记录查询工具查询过往事件 -- 如果涉及概念,可以用jargon查询,或根据关键词检索聊天记录 +**工具说明:** +- 如果涉及过往事件,或者查询某个过去可能提到过的概念,或者某段时间发生的事件。可以使用聊天记录查询工具查询过往事件 - 如果涉及人物,可以使用人物信息查询工具查询人物信息 -- 如果不确定查询类别,也可以使用lpmm知识库查询 -- 如果信息不足且需要继续查询,说明最需要查询什么,并输出为纯文本说明,然后调用相应工具查询(可并行调用多个工具) +- 如果没有可靠信息,且查询时间充足,或者不确定查询类别,也可以使用lpmm知识库查询,作为辅助信息 -**重要规则:** -- **只有在检索到明确、有关的信息并得出答案时,才使用found_answer** -- **如果信息不足、无法确定、找不到相关信息,必须使用not_enough_info,不要使用found_answer** -- 答案必须在思考中给出,格式为 found_answer(answer="...") 或 not_enough_info(reason="...") +**思考** +- 你可以对查询思路给出简短的思考:思考要简短,直接切入要点 +- 先思考当前信息是否足够回答问题 +- 如果信息不足,则需要使用tool查询信息,你必须给出使用什么工具进行查询 +- 如果当前已收集的信息足够或信息不足确定无法找到答案,你必须调用finish_search工具结束查询 """, name="memory_retrieval_react_prompt_head", ) @@ -148,14 +120,12 @@ def init_memory_retrieval_prompt(): 已收集的信息: {collected_info} -**执行步骤:** 分析: - 当前信息是否足够回答问题? - **如果信息足够且能找到明确答案**,在思考中直接给出答案,格式为:found_answer(answer="你的答案内容") - **如果信息不足或无法找到答案**,在思考中给出:not_enough_info(reason="信息不足或无法找到答案的原因") **重要规则:** -- 你已经经过几轮查询,尝试了信息搜集,现在你需要总结信息,选择回答问题或判断问题无法回答 - 必须严格使用检索到的信息回答问题,不要编造信息 - 答案必须精简,不要过多解释 - **只有在检索到明确、具体的答案时,才使用found_answer** @@ -166,122 +136,73 @@ def init_memory_retrieval_prompt(): ) -def _parse_react_response(response: str) -> Optional[Dict[str, Any]]: - """解析ReAct Agent的响应 +def _log_conversation_messages( + conversation_messages: List[Message], + head_prompt: Optional[str] = None, + final_status: Optional[str] = None, +) -> None: + """输出对话消息列表的日志 Args: - response: LLM返回的响应 - - Returns: - Dict[str, Any]: 解析后的动作信息,如果解析失败返回None - 格式: {"thought": str, "actions": List[Dict[str, Any]]} - 每个action格式: {"action_type": str, "action_params": dict} + conversation_messages: 对话消息列表 + head_prompt: 第一条系统消息(head_prompt)的内容,可选 + final_status: 最终结果状态描述(例如:找到答案/未找到答案),可选 """ - try: - # 尝试提取JSON(可能包含在```json代码块中) - json_pattern = r"```json\s*(.*?)\s*```" - matches = re.findall(json_pattern, response, re.DOTALL) + if not global_config.debug.show_memory_prompt: + return - if matches: - json_str = matches[0] - else: - # 尝试直接解析整个响应 - json_str = response.strip() + log_lines: List[str] = [] - # 修复可能的JSON错误 - repaired_json = repair_json(json_str) + # 如果有head_prompt,先添加为第一条消息 + if head_prompt: + msg_info = "========================================\n[消息 1] 角色: System\n-----------------------------" + msg_info += f"\n{head_prompt}" + log_lines.append(msg_info) + start_idx = 2 + else: + start_idx = 1 - # 解析JSON - action_info = json.loads(repaired_json) + if not conversation_messages and not head_prompt: + return - if not isinstance(action_info, dict): - logger.warning(f"解析的JSON不是对象格式: {action_info}") - return None + for idx, msg in enumerate(conversation_messages, start_idx): + role_name = msg.role.value if hasattr(msg.role, "value") else str(msg.role) - # 确保actions字段存在且为列表 - if "actions" not in action_info: - logger.warning(f"响应中缺少actions字段: {action_info}") - return None + # 构建单条消息的日志信息 + # msg_info = f"\n========================================\n[消息 {idx}] 角色: {role_name} 内容类型: {content_type}\n-----------------------------" + msg_info = ( + f"\n========================================\n[消息 {idx}] 角色: {role_name}\n-----------------------------" + ) - if not isinstance(action_info["actions"], list): - logger.warning(f"actions字段不是数组格式: {action_info['actions']}") - return None + # if full_content: + # msg_info += f"\n{full_content}" + if msg.content: + msg_info += f"\n{msg.content}" - # 确保actions不为空 - if len(action_info["actions"]) == 0: - logger.warning("actions数组为空") - return None + if msg.tool_calls: + msg_info += f"\n 工具调用: {len(msg.tool_calls)}个" + for tool_call in msg.tool_calls: + msg_info += f"\n - {tool_call.func_name}: {json.dumps(tool_call.args, ensure_ascii=False)}" - return action_info + # if msg.tool_call_id: + # msg_info += f"\n 工具调用ID: {msg.tool_call_id}" - except Exception as e: - logger.error(f"解析ReAct响应失败: {e}, 响应内容: {response[:200]}...") - return None + log_lines.append(msg_info) - -async def _retrieve_concepts_with_jargon(concepts: List[str], chat_id: str) -> str: - """对概念列表进行jargon检索 - - Args: - concepts: 概念列表 - chat_id: 聊天ID - - Returns: - str: 检索结果字符串 - """ - if not concepts: - return "" - - from src.jargon.jargon_miner import search_jargon - - results = [] - for concept in concepts: - concept = concept.strip() - if not concept: - continue - - # 先尝试精确匹配 - jargon_results = search_jargon(keyword=concept, chat_id=chat_id, limit=10, case_sensitive=False, fuzzy=False) - - is_fuzzy_match = False - - # 如果精确匹配未找到,尝试模糊搜索 - if not jargon_results: - jargon_results = search_jargon(keyword=concept, chat_id=chat_id, limit=10, case_sensitive=False, fuzzy=True) - is_fuzzy_match = True - - if jargon_results: - # 找到结果 - if is_fuzzy_match: - # 模糊匹配 - output_parts = [f"未精确匹配到'{concept}'"] - for result in jargon_results: - found_content = result.get("content", "").strip() - meaning = result.get("meaning", "").strip() - if found_content and meaning: - output_parts.append(f"找到 '{found_content}' 的含义为:{meaning}") - results.append(",".join(output_parts)) - logger.info(f"在jargon库中找到匹配(模糊搜索): {concept},找到{len(jargon_results)}条结果") - else: - # 精确匹配 - output_parts = [] - for result in jargon_results: - meaning = result.get("meaning", "").strip() - if meaning: - output_parts.append(f"'{concept}' 为黑话或者网络简写,含义为:{meaning}") - results.append(";".join(output_parts) if len(output_parts) > 1 else output_parts[0]) - logger.info(f"在jargon库中找到匹配(精确匹配): {concept},找到{len(jargon_results)}条结果") - else: - # 未找到,不返回占位信息,只记录日志 - logger.info(f"在jargon库中未找到匹配: {concept}") - - if results: - return "【概念检索结果】\n" + "\n".join(results) + "\n" - return "" + total_count = len(conversation_messages) + (1 if head_prompt else 0) + log_text = f"消息列表 (共{total_count}条):{''.join(log_lines)}" + if final_status: + log_text += f"\n\n[最终结果] {final_status}" + logger.info(log_text) async def _react_agent_solve_question( - question: str, chat_id: str, max_iterations: int = 5, timeout: float = 30.0, initial_info: str = "" + question: str, + chat_id: str, + max_iterations: int = 5, + timeout: float = 30.0, + initial_info: str = "", + initial_jargon_concepts: Optional[List[str]] = None, ) -> Tuple[bool, str, List[Dict[str, Any]], bool]: """使用ReAct架构的Agent来解决问题 @@ -291,16 +212,26 @@ async def _react_agent_solve_question( max_iterations: 最大迭代次数 timeout: 超时时间(秒) initial_info: 初始信息(如概念检索结果),将作为collected_info的初始值 + initial_jargon_concepts: 预先已解析过的黑话列表,避免重复解释 Returns: Tuple[bool, str, List[Dict[str, Any]], bool]: (是否找到答案, 答案内容, 思考步骤列表, 是否超时) """ start_time = time.time() collected_info = initial_info if initial_info else "" + enable_jargon_detection = global_config.memory.enable_jargon_detection + seen_jargon_concepts: Set[str] = set() + if enable_jargon_detection and initial_jargon_concepts: + for concept in initial_jargon_concepts: + concept = (concept or "").strip() + if concept: + seen_jargon_concepts.add(concept) thinking_steps = [] is_timeout = False conversation_messages: List[Message] = [] + first_head_prompt: Optional[str] = None # 保存第一次使用的head_prompt(用于日志显示) + # 正常迭代:max_iterations 次(最终评估单独处理,不算在迭代中) for iteration in range(max_iterations): # 检查超时 if time.time() - start_time > timeout: @@ -320,146 +251,8 @@ async def _react_agent_solve_question( # 计算剩余迭代次数 current_iteration = iteration + 1 remaining_iterations = max_iterations - current_iteration - is_final_iteration = current_iteration >= max_iterations - if is_final_iteration: - # 最后一次迭代,使用最终prompt - tool_definitions = [] - logger.info( - f"ReAct Agent 第 {iteration + 1} 次迭代,问题: {question}|可用工具数量: 0(最后一次迭代,不提供工具调用)" - ) - - prompt = await global_prompt_manager.format_prompt( - "memory_retrieval_react_final_prompt", - bot_name=bot_name, - time_now=time_now, - question=question, - collected_info=collected_info if collected_info else "暂无信息", - current_iteration=current_iteration, - remaining_iterations=remaining_iterations, - max_iterations=max_iterations, - ) - - if global_config.debug.show_memory_prompt: - logger.info(f"ReAct Agent 第 {iteration + 1} 次Prompt: {prompt}") - success, response, reasoning_content, model_name, tool_calls = await llm_api.generate_with_model_with_tools( - prompt, - model_config=model_config.model_task_config.tool_use, - tool_options=tool_definitions, - request_type="memory.react", - ) - else: - # 非最终迭代,使用head_prompt - tool_definitions = tool_registry.get_tool_definitions() - logger.info( - f"ReAct Agent 第 {iteration + 1} 次迭代,问题: {question}|可用工具数量: {len(tool_definitions)}" - ) - - head_prompt = await global_prompt_manager.format_prompt( - "memory_retrieval_react_prompt_head", - bot_name=bot_name, - time_now=time_now, - question=question, - collected_info=collected_info if collected_info else "", - current_iteration=current_iteration, - remaining_iterations=remaining_iterations, - max_iterations=max_iterations, - ) - - def message_factory( - _client, - *, - _head_prompt: str = head_prompt, - _conversation_messages: List[Message] = conversation_messages, - ) -> List[Message]: - messages: List[Message] = [] - - system_builder = MessageBuilder() - system_builder.set_role(RoleType.System) - system_builder.add_text_content(_head_prompt) - messages.append(system_builder.build()) - - messages.extend(_conversation_messages) - - if global_config.debug.show_memory_prompt: - # 优化日志展示 - 合并所有消息到一条日志 - log_lines = [] - for idx, msg in enumerate(messages, 1): - role_name = msg.role.value if hasattr(msg.role, "value") else str(msg.role) - - # 处理内容 - 显示完整内容,不截断 - if isinstance(msg.content, str): - full_content = msg.content - content_type = "文本" - elif isinstance(msg.content, list): - text_parts = [item for item in msg.content if isinstance(item, str)] - image_count = len([item for item in msg.content if isinstance(item, tuple)]) - full_content = "".join(text_parts) if text_parts else "" - content_type = f"混合({len(text_parts)}段文本, {image_count}张图片)" - else: - full_content = str(msg.content) - content_type = "未知" - - # 构建单条消息的日志信息 - msg_info = f"\n[消息 {idx}] 角色: {role_name} 内容类型: {content_type}\n========================================" - - if full_content: - msg_info += f"\n{full_content}" - - if msg.tool_calls: - msg_info += f"\n 工具调用: {len(msg.tool_calls)}个" - for tool_call in msg.tool_calls: - msg_info += f"\n - {tool_call}" - - if msg.tool_call_id: - msg_info += f"\n 工具调用ID: {msg.tool_call_id}" - - log_lines.append(msg_info) - - # 合并所有消息为一条日志输出 - logger.info(f"消息列表 (共{len(messages)}条):{''.join(log_lines)}") - - return messages - - ( - success, - response, - reasoning_content, - model_name, - tool_calls, - ) = await llm_api.generate_with_model_with_tools_by_message_factory( - message_factory, - model_config=model_config.model_task_config.tool_use, - tool_options=tool_definitions, - request_type="memory.react", - ) - - logger.info( - f"ReAct Agent 第 {iteration + 1} 次迭代 模型: {model_name} ,调用工具数量: {len(tool_calls) if tool_calls else 0} ,调用工具响应: {response}" - ) - - if not success: - logger.error(f"ReAct Agent LLM调用失败: {response}") - break - - assistant_message: Optional[Message] = None - if tool_calls: - assistant_builder = MessageBuilder() - assistant_builder.set_role(RoleType.Assistant) - if response and response.strip(): - assistant_builder.add_text_content(response) - assistant_builder.set_tool_calls(tool_calls) - assistant_message = assistant_builder.build() - elif response and response.strip(): - assistant_builder = MessageBuilder() - assistant_builder.set_role(RoleType.Assistant) - assistant_builder.add_text_content(response) - assistant_message = assistant_builder.build() - - # 记录思考步骤 - step = {"iteration": iteration + 1, "thought": response, "actions": [], "observations": []} - - # 优先从思考内容中提取found_answer或not_enough_info + # 提取函数调用中参数的值,支持单引号和双引号 def extract_quoted_content(text, func_name, param_name): """从文本中提取函数调用中参数的值,支持单引号和双引号 @@ -517,45 +310,85 @@ async def _react_agent_solve_question( return None - # 从LLM的直接输出内容中提取found_answer或not_enough_info - found_answer_content = None - not_enough_info_reason = None + # 正常迭代:使用head_prompt决定调用哪些工具(包含finish_search工具) + tool_definitions = tool_registry.get_tool_definitions() + # tool_names = [tool_def["name"] for tool_def in tool_definitions] + # logger.debug(f"ReAct Agent 第 {iteration + 1} 次迭代,问题: {question}|可用工具: {', '.join(tool_names)} (共{len(tool_definitions)}个)") - # 只检查response(LLM的直接输出内容),不检查reasoning_content - if response: - found_answer_content = extract_quoted_content(response, "found_answer", "answer") - if not found_answer_content: - not_enough_info_reason = extract_quoted_content(response, "not_enough_info", "reason") + # head_prompt应该只构建一次,使用初始的collected_info,后续迭代都复用同一个 + if first_head_prompt is None: + # 第一次构建,使用初始的collected_info(即initial_info) + initial_collected_info = initial_info if initial_info else "" + first_head_prompt = await global_prompt_manager.format_prompt( + "memory_retrieval_react_prompt_head", + bot_name=bot_name, + time_now=time_now, + question=question, + collected_info=initial_collected_info, + current_iteration=current_iteration, + remaining_iterations=remaining_iterations, + max_iterations=max_iterations, + ) - # 如果从输出内容中找到了答案,直接返回 - if found_answer_content: - step["actions"].append({"action_type": "found_answer", "action_params": {"answer": found_answer_content}}) - step["observations"] = ["从LLM输出内容中检测到found_answer"] - thinking_steps.append(step) - logger.info( - f"ReAct Agent 第 {iteration + 1} 次迭代 从LLM输出内容中检测到found_answer: {found_answer_content[:100]}..." - ) - return True, found_answer_content, thinking_steps, False + # 后续迭代都复用第一次构建的head_prompt + head_prompt = first_head_prompt - if not_enough_info_reason: - step["actions"].append( - {"action_type": "not_enough_info", "action_params": {"reason": not_enough_info_reason}} - ) - step["observations"] = ["从LLM输出内容中检测到not_enough_info"] - thinking_steps.append(step) - logger.info( - f"ReAct Agent 第 {iteration + 1} 次迭代 从LLM输出内容中检测到not_enough_info: {not_enough_info_reason[:100]}..." - ) - return False, not_enough_info_reason, thinking_steps, False + def message_factory( + _client, + *, + _head_prompt: str = head_prompt, + _conversation_messages: List[Message] = conversation_messages, + ) -> List[Message]: + messages: List[Message] = [] - if is_final_iteration: - step["actions"].append( - {"action_type": "not_enough_info", "action_params": {"reason": "已到达最后一次迭代,无法找到答案"}} - ) - step["observations"] = ["已到达最后一次迭代,无法找到答案"] - thinking_steps.append(step) - logger.info(f"ReAct Agent 第 {iteration + 1} 次迭代 已到达最后一次迭代,无法找到答案") - return False, "已到达最后一次迭代,无法找到答案", thinking_steps, False + system_builder = MessageBuilder() + system_builder.set_role(RoleType.System) + system_builder.add_text_content(_head_prompt) + messages.append(system_builder.build()) + + messages.extend(_conversation_messages) + + return messages + + ( + success, + response, + reasoning_content, + model_name, + tool_calls, + ) = await llm_api.generate_with_model_with_tools_by_message_factory( + message_factory, + model_config=model_config.model_task_config.tool_use, + tool_options=tool_definitions, + request_type="memory.react", + ) + + # logger.info( + # f"ReAct Agent 第 {iteration + 1} 次迭代 模型: {model_name} ,调用工具数量: {len(tool_calls) if tool_calls else 0} ,调用工具响应: {response}" + # ) + + if not success: + logger.error(f"ReAct Agent LLM调用失败: {response}") + break + + # 注意:这里会检查finish_search工具调用,如果检测到finish_search工具,会根据found_answer参数决定返回答案或退出查询 + + assistant_message: Optional[Message] = None + if tool_calls: + assistant_builder = MessageBuilder() + assistant_builder.set_role(RoleType.Assistant) + if response and response.strip(): + assistant_builder.add_text_content(response) + assistant_builder.set_tool_calls(tool_calls) + assistant_message = assistant_builder.build() + elif response and response.strip(): + assistant_builder = MessageBuilder() + assistant_builder.set_role(RoleType.Assistant) + assistant_builder.add_text_content(response) + assistant_message = assistant_builder.build() + + # 记录思考步骤 + step = {"iteration": iteration + 1, "thought": response, "actions": [], "observations": []} if assistant_message: conversation_messages.append(assistant_message) @@ -568,43 +401,198 @@ async def _react_agent_solve_question( # 处理工具调用 if not tool_calls: - # 没有工具调用,说明LLM在思考中已经给出了答案(已在前面检查),或者需要继续查询 - # 如果思考中没有答案,说明需要继续查询或等待下一轮 + # 如果没有工具调用,检查响应文本中是否包含finish_search函数调用格式 if response and response.strip(): - # 如果响应不为空,记录思考过程,继续下一轮迭代 + # 尝试从文本中解析finish_search函数调用 + def parse_finish_search_from_text(text: str): + """从文本中解析finish_search函数调用,返回(found_answer, answer)元组,如果未找到则返回(None, None)""" + if not text: + return None, None + + # 查找finish_search函数调用位置(不区分大小写) + func_pattern = "finish_search" + text_lower = text.lower() + func_pos = text_lower.find(func_pattern) + if func_pos == -1: + return None, None + + # 查找函数调用的开始和结束位置 + # 从func_pos开始向后查找左括号 + start_pos = text.find("(", func_pos) + if start_pos == -1: + return None, None + + # 查找匹配的右括号(考虑嵌套) + paren_count = 0 + end_pos = start_pos + for i in range(start_pos, len(text)): + if text[i] == "(": + paren_count += 1 + elif text[i] == ")": + paren_count -= 1 + if paren_count == 0: + end_pos = i + break + else: + # 没有找到匹配的右括号 + return None, None + + # 提取函数参数部分 + params_text = text[start_pos + 1 : end_pos] + + # 解析found_answer参数(布尔值,可能是true/false/True/False) + found_answer = None + found_answer_patterns = [ + r"found_answer\s*=\s*true", + r"found_answer\s*=\s*True", + r"found_answer\s*=\s*false", + r"found_answer\s*=\s*False", + ] + for pattern in found_answer_patterns: + match = re.search(pattern, params_text, re.IGNORECASE) + if match: + found_answer = "true" in match.group(0).lower() + break + + # 解析answer参数(字符串,使用extract_quoted_content) + answer = extract_quoted_content(text, "finish_search", "answer") + + return found_answer, answer + + parsed_found_answer, parsed_answer = parse_finish_search_from_text(response) + + if parsed_found_answer is not None: + # 检测到finish_search函数调用格式 + if parsed_found_answer: + # 找到了答案 + if parsed_answer: + step["actions"].append( + { + "action_type": "finish_search", + "action_params": {"found_answer": True, "answer": parsed_answer}, + } + ) + step["observations"] = ["检测到finish_search文本格式调用,找到答案"] + thinking_steps.append(step) + logger.info( + f"ReAct Agent 第 {iteration + 1} 次迭代 通过finish_search文本格式找到关于问题{question}的答案: {parsed_answer}" + ) + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status=f"找到答案:{parsed_answer}", + ) + + return True, parsed_answer, thinking_steps, False + else: + # found_answer为True但没有提供answer,视为错误,继续迭代 + logger.warning( + f"ReAct Agent 第 {iteration + 1} 次迭代 finish_search文本格式found_answer为True但未提供answer" + ) + else: + # 未找到答案,直接退出查询 + step["actions"].append( + {"action_type": "finish_search", "action_params": {"found_answer": False}} + ) + step["observations"] = ["检测到finish_search文本格式调用,未找到答案"] + thinking_steps.append(step) + logger.info(f"ReAct Agent 第 {iteration + 1} 次迭代 通过finish_search文本格式判断未找到答案") + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status="未找到答案:通过finish_search文本格式判断未找到答案", + ) + + return False, "", thinking_steps, False + + # 如果没有检测到finish_search格式,记录思考过程,继续下一轮迭代 step["observations"] = [f"思考完成,但未调用工具。响应: {response}"] - logger.info(f"ReAct Agent 第 {iteration + 1} 次迭代 思考完成但未调用工具: {response[:100]}...") - # 继续下一轮迭代,让LLM有机会在思考中给出found_answer或继续查询 + logger.info(f"ReAct Agent 第 {iteration + 1} 次迭代 思考完成但未调用工具: {response}") collected_info += f"思考: {response}" - thinking_steps.append(step) - continue else: logger.warning(f"ReAct Agent 第 {iteration + 1} 次迭代 无工具调用且无响应") step["observations"] = ["无响应且无工具调用"] - thinking_steps.append(step) - break + thinking_steps.append(step) + continue # 处理工具调用 - tool_tasks = [] + # 首先检查是否有finish_search工具调用,如果有则立即返回,不再处理其他工具 + finish_search_found = None + finish_search_answer = None + for tool_call in tool_calls: + tool_name = tool_call.func_name + tool_args = tool_call.args or {} + if tool_name == "finish_search": + finish_search_found = tool_args.get("found_answer", False) + finish_search_answer = tool_args.get("answer", "") + + if finish_search_found: + # 找到了答案 + if finish_search_answer: + step["actions"].append( + { + "action_type": "finish_search", + "action_params": {"found_answer": True, "answer": finish_search_answer}, + } + ) + step["observations"] = ["检测到finish_search工具调用,找到答案"] + thinking_steps.append(step) + logger.info( + f"ReAct Agent 第 {iteration + 1} 次迭代 通过finish_search工具找到关于问题{question}的答案: {finish_search_answer}" + ) + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status=f"找到答案:{finish_search_answer}", + ) + + return True, finish_search_answer, thinking_steps, False + else: + # found_answer为True但没有提供answer,视为错误 + logger.warning( + f"ReAct Agent 第 {iteration + 1} 次迭代 finish_search工具found_answer为True但未提供answer" + ) + else: + # 未找到答案,直接退出查询 + step["actions"].append({"action_type": "finish_search", "action_params": {"found_answer": False}}) + step["observations"] = ["检测到finish_search工具调用,未找到答案"] + thinking_steps.append(step) + logger.info(f"ReAct Agent 第 {iteration + 1} 次迭代 通过finish_search工具判断未找到答案") + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status="未找到答案:通过finish_search工具判断未找到答案", + ) + + return False, "", thinking_steps, False + + # 如果没有finish_search工具调用,继续处理其他工具 + tool_tasks = [] for i, tool_call in enumerate(tool_calls): tool_name = tool_call.func_name tool_args = tool_call.args or {} - logger.info( + logger.debug( f"ReAct Agent 第 {iteration + 1} 次迭代 工具调用 {i + 1}/{len(tool_calls)}: {tool_name}({tool_args})" ) + # 跳过finish_search工具调用(已经在上面处理过了) + if tool_name == "finish_search": + continue + # 普通工具调用 tool = tool_registry.get_tool(tool_name) if tool: # 准备工具参数(需要添加chat_id如果工具需要) - tool_params = tool_args.copy() - - # 如果工具函数签名需要chat_id,添加它 import inspect sig = inspect.signature(tool.execute_func) + tool_params = tool_args.copy() if "chat_id" in sig.parameters: tool_params["chat_id"] = chat_id @@ -637,34 +625,231 @@ async def _react_agent_solve_question( logger.error(f"ReAct Agent 第 {iteration + 1} 次迭代 工具 {i + 1} 执行异常: {observation}") observation_text = observation if isinstance(observation, str) else str(observation) + stripped_observation = observation_text.strip() step["observations"].append(observation_text) collected_info += f"\n{observation_text}\n" - if observation_text.strip(): + if stripped_observation: + # 检查工具输出中是否有新的jargon,如果有则追加到工具结果中 + if enable_jargon_detection: + jargon_concepts = match_jargon_from_text(stripped_observation, chat_id) + if jargon_concepts: + new_concepts = [] + for concept in jargon_concepts: + normalized_concept = concept.strip() + if normalized_concept and normalized_concept not in seen_jargon_concepts: + new_concepts.append(normalized_concept) + seen_jargon_concepts.add(normalized_concept) + if new_concepts: + jargon_info = await retrieve_concepts_with_jargon(new_concepts, chat_id) + if jargon_info: + # 将jargon查询结果追加到工具结果中 + observation_text += f"\n\n{jargon_info}" + collected_info += f"\n{jargon_info}\n" + logger.info(f"工具输出触发黑话解析: {new_concepts}") + tool_builder = MessageBuilder() tool_builder.set_role(RoleType.Tool) tool_builder.add_text_content(observation_text) tool_builder.add_tool_call(tool_call_item.call_id) conversation_messages.append(tool_builder.build()) - # logger.info(f"ReAct Agent 第 {iteration + 1} 次迭代 工具 {i+1} 执行结果: {observation_text}") thinking_steps.append(step) - # 达到最大迭代次数或超时,但Agent没有明确返回found_answer - # 迭代超时应该直接视为not_enough_info,而不是使用已有信息 - # 只有Agent明确返回found_answer时,才认为找到了答案 - if collected_info: - logger.warning( - f"ReAct Agent达到最大迭代次数或超时,但未明确返回found_answer。已收集信息: {collected_info[:100]}..." - ) + # 正常迭代结束后,如果达到最大迭代次数或超时,执行最终评估 + # 最终评估单独处理,不算在迭代中 + should_do_final_evaluation = False if is_timeout: - logger.warning("ReAct Agent超时,直接视为not_enough_info") - else: - logger.warning("ReAct Agent达到最大迭代次数,直接视为not_enough_info") - return False, "未找到相关信息", thinking_steps, is_timeout + should_do_final_evaluation = True + logger.warning(f"ReAct Agent超时,已迭代{iteration + 1}次,进入最终评估") + elif iteration + 1 >= max_iterations: + should_do_final_evaluation = True + logger.info(f"ReAct Agent达到最大迭代次数(已迭代{iteration + 1}次),进入最终评估") + + if should_do_final_evaluation: + # 获取必要变量用于最终评估 + tool_registry = get_tool_registry() + bot_name = global_config.bot.nickname + time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + current_iteration = iteration + 1 + remaining_iterations = 0 + + # 提取函数调用中参数的值,支持单引号和双引号 + def extract_quoted_content(text, func_name, param_name): + """从文本中提取函数调用中参数的值,支持单引号和双引号 + + Args: + text: 要搜索的文本 + func_name: 函数名,如 'found_answer' + param_name: 参数名,如 'answer' + + Returns: + 提取的参数值,如果未找到则返回None + """ + if not text: + return None + + # 查找函数调用位置(不区分大小写) + func_pattern = func_name.lower() + text_lower = text.lower() + func_pos = text_lower.find(func_pattern) + if func_pos == -1: + return None + + # 查找参数名和等号 + param_pattern = f"{param_name}=" + param_pos = text_lower.find(param_pattern, func_pos) + if param_pos == -1: + return None + + # 跳过参数名、等号和空白 + start_pos = param_pos + len(param_pattern) + while start_pos < len(text) and text[start_pos] in " \t\n": + start_pos += 1 + + if start_pos >= len(text): + return None + + # 确定引号类型 + quote_char = text[start_pos] + if quote_char not in ['"', "'"]: + return None + + # 查找匹配的结束引号(考虑转义) + end_pos = start_pos + 1 + while end_pos < len(text): + if text[end_pos] == quote_char: + # 检查是否是转义的引号 + if end_pos > start_pos + 1 and text[end_pos - 1] == "\\": + end_pos += 1 + continue + # 找到匹配的引号 + content = text[start_pos + 1 : end_pos] + # 处理转义字符 + content = content.replace('\\"', '"').replace("\\'", "'").replace("\\\\", "\\") + return content + end_pos += 1 + + return None + + # 执行最终评估 + evaluation_prompt = await global_prompt_manager.format_prompt( + "memory_retrieval_react_final_prompt", + bot_name=bot_name, + time_now=time_now, + question=question, + collected_info=collected_info if collected_info else "暂无信息", + current_iteration=current_iteration, + remaining_iterations=remaining_iterations, + max_iterations=max_iterations, + ) + + ( + eval_success, + eval_response, + eval_reasoning_content, + eval_model_name, + eval_tool_calls, + ) = await llm_api.generate_with_model_with_tools( + evaluation_prompt, + model_config=model_config.model_task_config.tool_use, + tool_options=[], # 最终评估阶段不提供工具 + request_type="memory.react.final", + ) + + if not eval_success: + logger.error(f"ReAct Agent 最终评估阶段 LLM调用失败: {eval_response}") + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status="未找到答案:最终评估阶段LLM调用失败", + ) + return False, "最终评估阶段LLM调用失败", thinking_steps, is_timeout + + if global_config.debug.show_memory_prompt: + logger.info(f"ReAct Agent 最终评估Prompt: {evaluation_prompt}") + logger.info(f"ReAct Agent 最终评估响应: {eval_response}") + + # 从最终评估响应中提取found_answer或not_enough_info + found_answer_content = None + not_enough_info_reason = None + + if eval_response: + found_answer_content = extract_quoted_content(eval_response, "found_answer", "answer") + if not found_answer_content: + not_enough_info_reason = extract_quoted_content(eval_response, "not_enough_info", "reason") + + # 如果找到答案,返回(找到答案时,无论是否超时,都视为成功完成) + if found_answer_content: + eval_step = { + "iteration": current_iteration, + "thought": f"[最终评估] {eval_response}", + "actions": [{"action_type": "found_answer", "action_params": {"answer": found_answer_content}}], + "observations": ["最终评估阶段检测到found_answer"], + } + thinking_steps.append(eval_step) + logger.info(f"ReAct Agent 最终评估阶段找到关于问题{question}的答案: {found_answer_content}") + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status=f"找到答案:{found_answer_content}", + ) + + return True, found_answer_content, thinking_steps, False + + # 如果评估为not_enough_info,返回空字符串(不返回任何信息) + if not_enough_info_reason: + eval_step = { + "iteration": current_iteration, + "thought": f"[最终评估] {eval_response}", + "actions": [{"action_type": "not_enough_info", "action_params": {"reason": not_enough_info_reason}}], + "observations": ["最终评估阶段检测到not_enough_info"], + } + thinking_steps.append(eval_step) + logger.info(f"ReAct Agent 最终评估阶段判断信息不足: {not_enough_info_reason}") + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status=f"未找到答案:{not_enough_info_reason}", + ) + + return False, "", thinking_steps, is_timeout + + # 如果没有明确判断,视为not_enough_info,返回空字符串(不返回任何信息) + eval_step = { + "iteration": current_iteration, + "thought": f"[最终评估] {eval_response}", + "actions": [ + {"action_type": "not_enough_info", "action_params": {"reason": "已到达最大迭代次数,无法找到答案"}} + ], + "observations": ["已到达最大迭代次数,无法找到答案"], + } + thinking_steps.append(eval_step) + logger.info("ReAct Agent 已到达最大迭代次数,无法找到答案") + + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status="未找到答案:已到达最大迭代次数,无法找到答案", + ) + + return False, "", thinking_steps, is_timeout + + # 如果正常迭代过程中提前找到答案返回,不会到达这里 + # 如果正常迭代结束但没有触发最终评估(理论上不应该发生),直接返回 + logger.warning("ReAct Agent正常迭代结束,但未触发最终评估") + _log_conversation_messages( + conversation_messages, + head_prompt=first_head_prompt, + final_status="未找到答案:正常迭代结束", + ) + + return False, "", thinking_steps, is_timeout -def _get_recent_query_history(chat_id: str, time_window_seconds: float = 300.0) -> str: - """获取最近一段时间内的查询历史 +def _get_recent_query_history(chat_id: str, time_window_seconds: float = 600.0) -> str: + """获取最近一段时间内的查询历史(用于避免重复查询) Args: chat_id: 聊天ID @@ -714,169 +899,49 @@ def _get_recent_query_history(chat_id: str, time_window_seconds: float = 300.0) return "" -def _get_cached_memories(chat_id: str, time_window_seconds: float = 300.0) -> List[str]: - """获取最近一段时间内缓存的记忆(只返回找到答案的记录) +def _get_recent_found_answers(chat_id: str, time_window_seconds: float = 600.0) -> List[str]: + """获取最近一段时间内已找到答案的查询记录(用于返回给 replyer) Args: chat_id: 聊天ID - time_window_seconds: 时间窗口(秒),默认300秒(5分钟) + time_window_seconds: 时间窗口(秒),默认10分钟 Returns: - List[str]: 格式化的记忆列表,每个元素格式为 "问题:xxx\n答案:xxx" + List[str]: 格式化的答案列表,每个元素格式为 "问题:xxx\n答案:xxx" """ try: current_time = time.time() start_time = current_time - time_window_seconds - # 查询最近时间窗口内找到答案的记录,按更新时间倒序 + # 查询最近时间窗口内已找到答案的记录,按更新时间倒序 records = ( ThinkingBack.select() .where( (ThinkingBack.chat_id == chat_id) & (ThinkingBack.update_time >= start_time) & (ThinkingBack.found_answer == 1) + & (ThinkingBack.answer.is_null(False)) + & (ThinkingBack.answer != "") ) .order_by(ThinkingBack.update_time.desc()) - .limit(5) # 最多返回5条最近的记录 + .limit(3) # 最多返回5条最近的记录 ) if not records.exists(): return [] - cached_memories = [] + found_answers = [] for record in records: if record.answer: - cached_memories.append(f"问题:{record.question}\n答案:{record.answer}") + found_answers.append(f"问题:{record.question}\n答案:{record.answer}") - return cached_memories + return found_answers except Exception as e: - logger.error(f"获取缓存记忆失败: {e}") + logger.error(f"获取最近已找到答案的记录失败: {e}") return [] -def _query_thinking_back(chat_id: str, question: str) -> Optional[Tuple[bool, str]]: - """从thinking_back数据库中查询是否有现成的答案 - - Args: - chat_id: 聊天ID - question: 问题 - - Returns: - Optional[Tuple[bool, str]]: 如果找到记录,返回(found_answer, answer),否则返回None - found_answer: 是否找到答案(True表示found_answer=1,False表示found_answer=0) - answer: 答案内容 - """ - try: - # 查询相同chat_id和问题的所有记录(包括found_answer为0和1的) - # 按更新时间倒序,获取最新的记录 - records = ( - ThinkingBack.select() - .where((ThinkingBack.chat_id == chat_id) & (ThinkingBack.question == question)) - .order_by(ThinkingBack.update_time.desc()) - .limit(1) - ) - - if records.exists(): - record = records.get() - found_answer = bool(record.found_answer) - answer = record.answer or "" - logger.info(f"在thinking_back中找到记录,问题: {question[:50]}...,found_answer: {found_answer}") - return found_answer, answer - - return None - - except Exception as e: - logger.error(f"查询thinking_back失败: {e}") - return None - - -async def _analyze_question_answer(question: str, answer: str, chat_id: str) -> None: - """异步分析问题和答案的类别,并存储到相应系统 - - Args: - question: 问题 - answer: 答案 - chat_id: 聊天ID - """ - try: - # 使用LLM分析类别 - analysis_prompt = f"""请分析以下问题和答案的类别: - -问题:{question} -答案:{answer} - -类别说明: -1. 人物信息:有关某个用户的个体信息(如某人的喜好、习惯、经历等) -2. 黑话:对特定概念、缩写词、谐音词、自创词的解释(如"yyds"、"社死"等) -3. 其他:除此之外的其他内容 - -请输出JSON格式: -{{ - "category": "人物信息" | "黑话" | "其他", - "jargon_keyword": "如果是黑话,提取关键词(如'yyds'),否则为空字符串", - "person_name": "如果是人物信息,提取人物名称,否则为空字符串", - "memory_content": "如果是人物信息,提取要存储的记忆内容(简短概括),否则为空字符串" -}} - -只输出JSON,不要输出其他内容:""" - - success, response, _, _ = await llm_api.generate_with_model( - analysis_prompt, - model_config=model_config.model_task_config.utils, - request_type="memory.analyze_qa", - ) - - if not success: - logger.error(f"分析问题和答案失败: {response}") - return - - # 解析JSON响应 - try: - json_pattern = r"```json\s*(.*?)\s*```" - matches = re.findall(json_pattern, response, re.DOTALL) - - if matches: - json_str = matches[0] - else: - json_str = response.strip() - - repaired_json = repair_json(json_str) - analysis_result = json.loads(repaired_json) - - category = analysis_result.get("category", "").strip() - - if category == "黑话": - # 处理黑话 - jargon_keyword = analysis_result.get("jargon_keyword", "").strip() - if jargon_keyword: - from src.jargon.jargon_miner import store_jargon_from_answer - - await store_jargon_from_answer(jargon_keyword, answer, chat_id) - else: - logger.warning(f"分析为黑话但未提取到关键词,问题: {question[:50]}...") - - elif category == "人物信息": - # 处理人物信息 - # person_name = analysis_result.get("person_name", "").strip() - # memory_content = analysis_result.get("memory_content", "").strip() - # if person_name and memory_content: - # from src.person_info.person_info import store_person_memory_from_answer - # await store_person_memory_from_answer(person_name, memory_content, chat_id) - # else: - # logger.warning(f"分析为人物信息但未提取到人物名称或记忆内容,问题: {question[:50]}...") - pass # 功能暂时禁用 - - else: - logger.info(f"问题和答案类别为'其他',不进行存储,问题: {question[:50]}...") - - except Exception as e: - logger.error(f"解析分析结果失败: {e}, 响应: {response[:200]}...") - - except Exception as e: - logger.error(f"分析问题和答案时发生异常: {e}") - - def _store_thinking_back( chat_id: str, question: str, context: str, found_answer: bool, answer: str, thinking_steps: List[Dict[str, Any]] ) -> None: @@ -923,99 +988,70 @@ def _store_thinking_back( create_time=now, update_time=now, ) - logger.info(f"已创建思考过程到数据库,问题: {question[:50]}...") + # logger.info(f"已创建思考过程到数据库,问题: {question[:50]}...") except Exception as e: logger.error(f"存储思考过程失败: {e}") -async def _process_single_question(question: str, chat_id: str, context: str, initial_info: str = "") -> Optional[str]: - """处理单个问题的查询(包含缓存检查逻辑) +async def _process_single_question( + question: str, + chat_id: str, + context: str, + initial_info: str = "", + initial_jargon_concepts: Optional[List[str]] = None, + max_iterations: Optional[int] = None, +) -> Optional[str]: + """处理单个问题的查询 Args: question: 要查询的问题 chat_id: 聊天ID context: 上下文信息 initial_info: 初始信息(如概念检索结果),将传递给ReAct Agent + initial_jargon_concepts: 已经处理过的黑话概念列表,用于ReAct阶段的去重 Returns: Optional[str]: 如果找到答案,返回格式化的结果字符串,否则返回None """ - logger.info(f"开始处理问题: {question}") + # logger.info(f"开始处理问题: {question}") _cleanup_stale_not_found_thinking_back() question_initial_info = initial_info or "" - # 预先进行一次LPMM知识库查询,作为后续ReAct Agent的辅助信息 - if global_config.lpmm_knowledge.enable: - try: - lpmm_result = await query_lpmm_knowledge(question, limit=2) - if lpmm_result and lpmm_result.startswith("你从LPMM知识库中找到"): - if question_initial_info: - question_initial_info += "\n" - question_initial_info += f"【LPMM知识库预查询】\n{lpmm_result}" - logger.info(f"LPMM预查询命中,问题: {question[:50]}...") - else: - logger.info(f"LPMM预查询未命中或未找到信息,问题: {question[:50]}...") - except Exception as e: - logger.error(f"LPMM预查询失败,问题: {question[:50]}... 错误: {e}") + # 直接使用ReAct Agent查询(不再从thinking_back获取缓存) + # logger.info(f"使用ReAct Agent查询,问题: {question[:50]}...") - # 先检查thinking_back数据库中是否有现成答案 - cached_result = _query_thinking_back(chat_id, question) - should_requery = False + jargon_concepts_for_agent = initial_jargon_concepts if global_config.memory.enable_jargon_detection else None - if cached_result: - cached_found_answer, cached_answer = cached_result + # 如果未指定max_iterations,使用配置的默认值 + if max_iterations is None: + max_iterations = global_config.memory.max_agent_iterations - if cached_found_answer: # found_answer == 1 (True) - # found_answer == 1:20%概率重新查询 - if random.random() < 0.5: - should_requery = True - logger.info(f"found_answer=1,触发20%概率重新查询,问题: {question[:50]}...") + found_answer, answer, thinking_steps, is_timeout = await _react_agent_solve_question( + question=question, + chat_id=chat_id, + max_iterations=max_iterations, + timeout=global_config.memory.agent_timeout_seconds, + initial_info=question_initial_info, + initial_jargon_concepts=jargon_concepts_for_agent, + ) - if not should_requery and cached_answer: - logger.info(f"从thinking_back缓存中获取答案,问题: {question[:50]}...") - return f"问题:{question}\n答案:{cached_answer}" - elif not cached_answer: - should_requery = True - logger.info(f"found_answer=1 但缓存答案为空,重新查询,问题: {question[:50]}...") - else: - # found_answer == 0:不使用缓存,直接重新查询 - should_requery = True - logger.info(f"thinking_back存在但未找到答案,忽略缓存重新查询,问题: {question[:50]}...") - - # 如果没有缓存答案或需要重新查询,使用ReAct Agent查询 - if not cached_result or should_requery: - if should_requery: - logger.info(f"概率触发重新查询,使用ReAct Agent查询,问题: {question[:50]}...") - else: - logger.info(f"未找到缓存答案,使用ReAct Agent查询,问题: {question[:50]}...") - - found_answer, answer, thinking_steps, is_timeout = await _react_agent_solve_question( - question=question, + # 存储查询历史到数据库(超时时不存储) + if not is_timeout: + _store_thinking_back( chat_id=chat_id, - max_iterations=global_config.memory.max_agent_iterations, - timeout=120.0, - initial_info=question_initial_info, + question=question, + context=context, + found_answer=found_answer, + answer=answer, + thinking_steps=thinking_steps, ) + else: + logger.info(f"ReAct Agent超时,不存储到数据库,问题: {question[:50]}...") - # 存储到数据库(超时时不存储) - if not is_timeout: - _store_thinking_back( - chat_id=chat_id, - question=question, - context=context, - found_answer=found_answer, - answer=answer, - thinking_steps=thinking_steps, - ) - else: - logger.info(f"ReAct Agent超时,不存储到数据库,问题: {question[:50]}...") - - if found_answer and answer: - # 创建异步任务分析问题和答案 - asyncio.create_task(_analyze_question_answer(question, answer, chat_id)) - return f"问题:{question}\n答案:{answer}" + if found_answer and answer: + return f"问题:{question}\n答案:{answer}" return None @@ -1025,7 +1061,7 @@ async def build_memory_retrieval_prompt( sender: str, target: str, chat_stream, - tool_executor, + think_level: int = 1, ) -> str: """构建记忆检索提示 使用两段式查询:第一步生成问题,第二步使用ReAct Agent查询答案 @@ -1048,8 +1084,8 @@ async def build_memory_retrieval_prompt( bot_name = global_config.bot.nickname chat_id = chat_stream.stream_id - # 获取最近查询历史(最近1小时内的查询) - recent_query_history = _get_recent_query_history(chat_id, time_window_seconds=300.0) + # 获取最近查询历史(最近10分钟内的查询,用于避免重复查询) + recent_query_history = _get_recent_query_history(chat_id, time_window_seconds=600.0) if not recent_query_history: recent_query_history = "最近没有查询记录。" @@ -1072,57 +1108,68 @@ async def build_memory_retrieval_prompt( if global_config.debug.show_memory_prompt: logger.info(f"记忆检索问题生成提示词: {question_prompt}") - logger.info(f"记忆检索问题生成响应: {response}") + # logger.info(f"记忆检索问题生成响应: {response}") if not success: logger.error(f"LLM生成问题失败: {response}") return "" # 解析概念列表和问题列表 - concepts, questions = _parse_questions_json(response) - logger.info(f"解析到 {len(concepts)} 个概念: {concepts}") - logger.info(f"解析到 {len(questions)} 个问题: {questions}") + _, questions = parse_questions_json(response) + if questions: + logger.info(f"解析到 {len(questions)} 个问题: {questions}") - # 对概念进行jargon检索,作为初始信息 + enable_jargon_detection = global_config.memory.enable_jargon_detection + concepts: List[str] = [] + + if enable_jargon_detection: + # 使用匹配逻辑自动识别聊天中的黑话概念 + concepts = match_jargon_from_text(message, chat_id) + if concepts: + logger.info(f"黑话匹配命中 {len(concepts)} 个概念: {concepts}") + else: + logger.debug("黑话匹配未命中任何概念") + else: + logger.debug("已禁用记忆检索中的黑话识别") + + # 对匹配到的概念进行jargon检索,作为初始信息 initial_info = "" - if concepts: - logger.info(f"开始对 {len(concepts)} 个概念进行jargon检索") - concept_info = await _retrieve_concepts_with_jargon(concepts, chat_id) + if enable_jargon_detection and concepts: + concept_info = await retrieve_concepts_with_jargon(concepts, chat_id) if concept_info: initial_info += concept_info - logger.info(f"概念检索完成,结果: {concept_info[:200]}...") + logger.debug(f"概念检索完成,结果: {concept_info}") else: - logger.info("概念检索未找到任何结果") - - # 获取缓存的记忆(与question时使用相同的时间窗口和数量限制) - cached_memories = _get_cached_memories(chat_id, time_window_seconds=300.0) + logger.debug("概念检索未找到任何结果") if not questions: - logger.debug("模型认为不需要检索记忆或解析失败") - # 即使没有当次查询,也返回缓存的记忆和概念检索结果 - all_results = [] - if initial_info: - all_results.append(initial_info.strip()) - if cached_memories: - all_results.extend(cached_memories) + logger.debug("模型认为不需要检索记忆或解析失败,不返回任何查询结果") + end_time = time.time() + logger.info(f"无当次查询,不返回任何结果,耗时: {(end_time - start_time):.3f}秒") + return "" - if all_results: - retrieved_memory = "\n\n".join(all_results) - end_time = time.time() - logger.info(f"无当次查询,返回缓存记忆和概念检索结果,耗时: {(end_time - start_time):.3f}秒") - return f"你回忆起了以下信息:\n{retrieved_memory}\n如果与回复内容相关,可以参考这些回忆的信息。\n" - else: - return "" - - logger.info(f"解析到 {len(questions)} 个问题: {questions}") - - # 第二步:并行处理所有问题(使用配置的最大迭代次数/120秒超时) - max_iterations = global_config.memory.max_agent_iterations - logger.info(f"问题数量: {len(questions)},设置最大迭代次数: {max_iterations},超时时间: 120秒") + # 第二步:并行处理所有问题(使用配置的最大迭代次数和超时时间) + base_max_iterations = global_config.memory.max_agent_iterations + # 根据think_level调整迭代次数:think_level=1时不变,think_level=0时减半 + if think_level == 0: + max_iterations = max(1, base_max_iterations // 2) # 至少为1 + else: + max_iterations = base_max_iterations + timeout_seconds = global_config.memory.agent_timeout_seconds + logger.debug( + f"问题数量: {len(questions)},think_level={think_level},设置最大迭代次数: {max_iterations}(基础值: {base_max_iterations}),超时时间: {timeout_seconds}秒" + ) # 并行处理所有问题,将概念检索结果作为初始信息传递 question_tasks = [ - _process_single_question(question=question, chat_id=chat_id, context=message, initial_info=initial_info) + _process_single_question( + question=question, + chat_id=chat_id, + context=message, + initial_info=initial_info, + initial_jargon_concepts=concepts if enable_jargon_detection else None, + max_iterations=max_iterations, + ) for question in questions ] @@ -1130,90 +1177,53 @@ async def build_memory_retrieval_prompt( results = await asyncio.gather(*question_tasks, return_exceptions=True) # 收集所有有效结果 - all_results = [] - current_questions = set() # 用于去重,避免缓存和当次查询重复 + question_results: List[str] = [] for i, result in enumerate(results): if isinstance(result, Exception): logger.error(f"处理问题 '{questions[i]}' 时发生异常: {result}") elif result is not None: - all_results.append(result) - # 提取问题用于去重 - if result.startswith("问题:"): - question = result.split("\n")[0].replace("问题:", "").strip() - current_questions.add(question) + question_results.append(result) - # 将缓存的记忆添加到结果中(排除当次查询已包含的问题,避免重复) - for cached_memory in cached_memories: - if cached_memory.startswith("问题:"): - question = cached_memory.split("\n")[0].replace("问题:", "").strip() - # 只有当次查询中没有相同问题时,才添加缓存记忆 - if question not in current_questions: - all_results.append(cached_memory) - logger.debug(f"添加缓存记忆: {question[:50]}...") + # 获取最近10分钟内已找到答案的缓存记录 + cached_answers = _get_recent_found_answers(chat_id, time_window_seconds=600.0) + + # 合并当前查询结果和缓存答案(去重:如果当前查询的问题在缓存中已存在,优先使用当前结果) + all_results = [] + + # 先添加当前查询的结果 + current_questions = set() + for result in question_results: + # 提取问题(格式为 "问题:xxx\n答案:xxx") + if result.startswith("问题:"): + question_end = result.find("\n答案:") + if question_end != -1: + current_questions.add(result[4:question_end]) + all_results.append(result) + + # 添加缓存答案(排除当前查询中已存在的问题) + for cached_answer in cached_answers: + if cached_answer.startswith("问题:"): + question_end = cached_answer.find("\n答案:") + if question_end != -1: + cached_question = cached_answer[4:question_end] + if cached_question not in current_questions: + all_results.append(cached_answer) end_time = time.time() if all_results: retrieved_memory = "\n\n".join(all_results) + current_count = len(question_results) + cached_count = len(all_results) - current_count logger.info( - f"记忆检索成功,耗时: {(end_time - start_time):.3f}秒,包含 {len(all_results)} 条记忆(含缓存)" + f"记忆检索成功,耗时: {(end_time - start_time):.3f}秒," + f"当前查询 {current_count} 条记忆,缓存 {cached_count} 条记忆,共 {len(all_results)} 条记忆" ) return f"你回忆起了以下信息:\n{retrieved_memory}\n如果与回复内容相关,可以参考这些回忆的信息。\n" else: - logger.debug("所有问题均未找到答案,且无缓存记忆") + logger.debug("所有问题均未找到答案,且无缓存答案") return "" except Exception as e: logger.error(f"记忆检索时发生异常: {str(e)}") return "" - - -def _parse_questions_json(response: str) -> Tuple[List[str], List[str]]: - """解析问题JSON,返回概念列表和问题列表 - - Args: - response: LLM返回的响应 - - Returns: - Tuple[List[str], List[str]]: (概念列表, 问题列表) - """ - try: - # 尝试提取JSON(可能包含在```json代码块中) - json_pattern = r"```json\s*(.*?)\s*```" - matches = re.findall(json_pattern, response, re.DOTALL) - - if matches: - json_str = matches[0] - else: - # 尝试直接解析整个响应 - json_str = response.strip() - - # 修复可能的JSON错误 - repaired_json = repair_json(json_str) - - # 解析JSON - parsed = json.loads(repaired_json) - - # 只支持新格式:包含concepts和questions的对象 - if not isinstance(parsed, dict): - logger.warning(f"解析的JSON不是对象格式: {parsed}") - return [], [] - - concepts_raw = parsed.get("concepts", []) - questions_raw = parsed.get("questions", []) - - # 确保是列表 - if not isinstance(concepts_raw, list): - concepts_raw = [] - if not isinstance(questions_raw, list): - questions_raw = [] - - # 确保所有元素都是字符串 - concepts = [c for c in concepts_raw if isinstance(c, str) and c.strip()] - questions = [q for q in questions_raw if isinstance(q, str) and q.strip()] - - return concepts, questions - - except Exception as e: - logger.error(f"解析问题JSON失败: {e}, 响应内容: {response[:200]}...") - return [], [] diff --git a/src/memory_system/memory_utils.py b/src/memory_system/memory_utils.py index bff39f95..9886142c 100644 --- a/src/memory_system/memory_utils.py +++ b/src/memory_system/memory_utils.py @@ -8,7 +8,8 @@ import json import re from datetime import datetime from typing import Tuple -from difflib import SequenceMatcher +from typing import List +from json_repair import repair_json from src.common.logger import get_logger @@ -16,100 +17,55 @@ from src.common.logger import get_logger logger = get_logger("memory_utils") -def parse_md_json(json_text: str) -> list[str]: - """从Markdown格式的内容中提取JSON对象和推理内容""" - json_objects = [] - reasoning_content = "" - - # 使用正则表达式查找```json包裹的JSON内容 - json_pattern = r"```json\s*(.*?)\s*```" - matches = re.findall(json_pattern, json_text, re.DOTALL) - - # 提取JSON之前的内容作为推理文本 - if matches: - # 找到第一个```json的位置 - first_json_pos = json_text.find("```json") - if first_json_pos > 0: - reasoning_content = json_text[:first_json_pos].strip() - # 清理推理内容中的注释标记 - reasoning_content = re.sub(r"^//\s*", "", reasoning_content, flags=re.MULTILINE) - reasoning_content = reasoning_content.strip() - - for match in matches: - try: - # 清理可能的注释和格式问题 - json_str = re.sub(r"//.*?\n", "\n", match) # 移除单行注释 - json_str = re.sub(r"/\*.*?\*/", "", json_str, flags=re.DOTALL) # 移除多行注释 - if json_str := json_str.strip(): - json_obj = json.loads(json_str) - if isinstance(json_obj, dict): - json_objects.append(json_obj) - elif isinstance(json_obj, list): - for item in json_obj: - if isinstance(item, dict): - json_objects.append(item) - except Exception as e: - logger.warning(f"解析JSON块失败: {e}, 块内容: {match[:100]}...") - continue - - return json_objects, reasoning_content - - -def calculate_similarity(text1: str, text2: str) -> float: - """ - 计算两个文本的相似度 +def parse_questions_json(response: str) -> Tuple[List[str], List[str]]: + """解析问题JSON,返回概念列表和问题列表 Args: - text1: 第一个文本 - text2: 第二个文本 + response: LLM返回的响应 Returns: - float: 相似度分数 (0-1) + Tuple[List[str], List[str]]: (概念列表, 问题列表) """ try: - # 预处理文本 - text1 = preprocess_text(text1) - text2 = preprocess_text(text2) + # 尝试提取JSON(可能包含在```json代码块中) + json_pattern = r"```json\s*(.*?)\s*```" + matches = re.findall(json_pattern, response, re.DOTALL) - # 使用SequenceMatcher计算相似度 - similarity = SequenceMatcher(None, text1, text2).ratio() + if matches: + json_str = matches[0] + else: + # 尝试直接解析整个响应 + json_str = response.strip() - # 如果其中一个文本包含另一个,提高相似度 - if text1 in text2 or text2 in text1: - similarity = max(similarity, 0.8) + # 修复可能的JSON错误 + repaired_json = repair_json(json_str) - return similarity + # 解析JSON + parsed = json.loads(repaired_json) + + # 只支持新格式:包含concepts和questions的对象 + if not isinstance(parsed, dict): + logger.warning(f"解析的JSON不是对象格式: {parsed}") + return [], [] + + concepts_raw = parsed.get("concepts", []) + questions_raw = parsed.get("questions", []) + + # 确保是列表 + if not isinstance(concepts_raw, list): + concepts_raw = [] + if not isinstance(questions_raw, list): + questions_raw = [] + + # 确保所有元素都是字符串 + concepts = [c for c in concepts_raw if isinstance(c, str) and c.strip()] + questions = [q for q in questions_raw if isinstance(q, str) and q.strip()] + + return concepts, questions except Exception as e: - logger.error(f"计算相似度时出错: {e}") - return 0.0 - - -def preprocess_text(text: str) -> str: - """ - 预处理文本,提高匹配准确性 - - Args: - text: 原始文本 - - Returns: - str: 预处理后的文本 - """ - try: - # 转换为小写 - text = text.lower() - - # 移除标点符号和特殊字符 - text = re.sub(r"[^\w\s]", "", text) - - # 移除多余空格 - text = re.sub(r"\s+", " ", text).strip() - - return text - - except Exception as e: - logger.error(f"预处理文本时出错: {e}") - return text + logger.error(f"解析问题JSON失败: {e}, 响应内容: {response[:200]}...") + return [], [] def parse_datetime_to_timestamp(value: str) -> float: @@ -140,29 +96,3 @@ def parse_datetime_to_timestamp(value: str) -> float: except Exception as e: last_err = e raise ValueError(f"无法解析时间: {value} ({last_err})") - - -def parse_time_range(time_range: str) -> Tuple[float, float]: - """ - 解析时间范围字符串,返回开始和结束时间戳 - - Args: - time_range: 时间范围字符串,格式:"YYYY-MM-DD HH:MM:SS - YYYY-MM-DD HH:MM:SS" - - Returns: - Tuple[float, float]: (开始时间戳, 结束时间戳) - """ - if " - " not in time_range: - raise ValueError(f"时间范围格式错误,应为 '开始时间 - 结束时间': {time_range}") - - parts = time_range.split(" - ", 1) - if len(parts) != 2: - raise ValueError(f"时间范围格式错误: {time_range}") - - start_str = parts[0].strip() - end_str = parts[1].strip() - - start_timestamp = parse_datetime_to_timestamp(start_str) - end_timestamp = parse_datetime_to_timestamp(end_str) - - return start_timestamp, end_timestamp diff --git a/src/memory_system/retrieval_tools/README.md b/src/memory_system/retrieval_tools/README.md deleted file mode 100644 index 50c36dbe..00000000 --- a/src/memory_system/retrieval_tools/README.md +++ /dev/null @@ -1,161 +0,0 @@ -# 记忆检索工具模块 - -这个模块提供了统一的工具注册和管理系统,用于记忆检索功能。 - -## 目录结构 - -``` -retrieval_tools/ -├── __init__.py # 模块导出 -├── tool_registry.py # 工具注册系统 -├── tool_utils.py # 工具函数库(共用函数) -├── query_jargon.py # 查询jargon工具 -├── query_chat_history.py # 查询聊天历史工具 -├── query_lpmm_knowledge.py # 查询LPMM知识库工具 -└── README.md # 本文件 -``` - -## 模块说明 - -### `tool_registry.py` -包含工具注册系统的核心类: -- `MemoryRetrievalTool`: 工具基类 -- `MemoryRetrievalToolRegistry`: 工具注册器 -- `register_memory_retrieval_tool()`: 便捷注册函数 -- `get_tool_registry()`: 获取注册器实例 - -### `tool_utils.py` -包含所有工具共用的工具函数: -- `parse_datetime_to_timestamp()`: 解析时间字符串为时间戳 -- `parse_time_range()`: 解析时间范围字符串 - -### 工具文件 -每个工具都有独立的文件: -- `query_jargon.py`: 根据关键词在jargon库中查询 -- `query_chat_history.py`: 根据时间或关键词在chat_history中查询(支持查询时间点事件、时间范围事件、关键词搜索) - -## 如何添加新工具 - -1. 创建新的工具文件,例如 `query_new_tool.py`: - -```python -""" -新工具 - 工具实现 -""" - -from src.common.logger import get_logger -from .tool_registry import register_memory_retrieval_tool -from .tool_utils import parse_datetime_to_timestamp # 如果需要使用工具函数 - -logger = get_logger("memory_retrieval_tools") - - -async def query_new_tool(param1: str, param2: str, chat_id: str) -> str: - """新工具的实现 - - Args: - param1: 参数1 - param2: 参数2 - chat_id: 聊天ID - - Returns: - str: 查询结果 - """ - try: - # 实现逻辑 - return "结果" - except Exception as e: - logger.error(f"新工具执行失败: {e}") - return f"查询失败: {str(e)}" - - -def register_tool(): - """注册工具""" - register_memory_retrieval_tool( - name="query_new_tool", - description="新工具的描述", - parameters=[ - { - "name": "param1", - "type": "string", - "description": "参数1的描述", - "required": True - }, - { - "name": "param2", - "type": "string", - "description": "参数2的描述", - "required": True - } - ], - execute_func=query_new_tool - ) -``` - -2. 在 `__init__.py` 中导入并注册新工具: - -```python -from .query_new_tool import register_tool as register_query_new_tool - -def init_all_tools(): - """初始化并注册所有记忆检索工具""" - register_query_jargon() - register_query_chat_history() - register_query_new_tool() # 添加新工具 -``` - -3. 工具会自动: - - 出现在 ReAct Agent 的 prompt 中 - - 在动作类型列表中可用 - - 被 ReAct Agent 自动调用 - -## 使用示例 - -```python -from src.memory_system.retrieval_tools import init_all_tools, get_tool_registry - -# 初始化所有工具 -init_all_tools() - -# 获取工具注册器 -registry = get_tool_registry() - -# 获取特定工具 -tool = registry.get_tool("query_chat_history") - -# 执行工具(查询时间点事件) -result = await tool.execute(time_point="2025-01-15 14:30:00", chat_id="chat123") - -# 或者查询关键词 -result = await tool.execute(keyword="小丑AI", chat_id="chat123") - -# 或者查询时间范围 -result = await tool.execute(time_range="2025-01-15 10:00:00 - 2025-01-15 20:00:00", chat_id="chat123") -``` - -## 现有工具说明 - -### query_jargon -根据关键词在jargon库中查询黑话/俚语/缩写的含义 -- 参数:`keyword` (必填) - 关键词 - -### query_chat_history -根据时间或关键词在chat_history中查询相关聊天记录。可以查询某个时间点发生了什么、某个时间范围内的事件,或根据关键词搜索消息 -- 参数: - - `keyword` (可选) - 关键词,用于搜索消息内容 - - `time_point` (可选) - 时间点,格式:YYYY-MM-DD HH:MM:SS,用于查询某个时间点附近发生了什么(与time_range二选一) - - `time_range` (可选) - 时间范围,格式:'YYYY-MM-DD HH:MM:SS - YYYY-MM-DD HH:MM:SS'(与time_point二选一) - -### query_lpmm_knowledge -从LPMM知识库中检索与关键词相关的知识内容 -- 参数: - - `query` (必填) - 查询的关键词或问题描述 - -## 注意事项 - -- 所有工具函数必须是异步函数(`async def`) -- 如果工具函数签名需要 `chat_id` 参数,系统会自动添加(通过函数签名检测) -- 工具参数定义中的 `required` 字段用于生成 prompt 描述 -- 工具执行失败时应返回错误信息字符串,而不是抛出异常 -- 共用函数放在 `tool_utils.py` 中,避免代码重复 - diff --git a/src/memory_system/retrieval_tools/__init__.py b/src/memory_system/retrieval_tools/__init__.py index 4b5c40c0..f30fd779 100644 --- a/src/memory_system/retrieval_tools/__init__.py +++ b/src/memory_system/retrieval_tools/__init__.py @@ -11,18 +11,18 @@ from .tool_registry import ( ) # 导入所有工具的注册函数 -from .query_jargon import register_tool as register_query_jargon from .query_chat_history import register_tool as register_query_chat_history from .query_lpmm_knowledge import register_tool as register_lpmm_knowledge from .query_person_info import register_tool as register_query_person_info +from .found_answer import register_tool as register_finish_search from src.config.config import global_config def init_all_tools(): """初始化并注册所有记忆检索工具""" - register_query_jargon() register_query_chat_history() register_query_person_info() + register_finish_search() # 注册finish_search工具 if global_config.lpmm_knowledge.lpmm_mode == "agent": register_lpmm_knowledge() diff --git a/src/memory_system/retrieval_tools/found_answer.py b/src/memory_system/retrieval_tools/found_answer.py new file mode 100644 index 00000000..bbed96b3 --- /dev/null +++ b/src/memory_system/retrieval_tools/found_answer.py @@ -0,0 +1,49 @@ +""" +finish_search工具 - 用于在记忆检索过程中结束查询 +""" + +from src.common.logger import get_logger +from .tool_registry import register_memory_retrieval_tool + +logger = get_logger("memory_retrieval_tools") + + +async def finish_search(found_answer: bool, answer: str = "") -> str: + """结束查询 + + Args: + found_answer: 是否找到了答案 + answer: 如果找到了答案,提供答案内容;如果未找到,可以为空 + + Returns: + str: 确认信息 + """ + if found_answer: + logger.info(f"找到答案: {answer}") + return f"已确认找到答案: {answer}" + else: + logger.info("未找到答案,结束查询") + return "未找到答案,查询结束" + + +def register_tool(): + """注册finish_search工具""" + register_memory_retrieval_tool( + name="finish_search", + description="当你决定结束查询时,调用此工具。如果找到了明确答案,设置found_answer为true并在answer中提供答案;如果未找到答案,设置found_answer为false。只有在检索到明确、具体的答案时才设置found_answer为true,不要编造信息。", + parameters=[ + { + "name": "found_answer", + "type": "boolean", + "description": "是否找到了答案", + "required": True, + }, + { + "name": "answer", + "type": "string", + "description": "如果found_answer为true,提供找到的答案内容,必须基于已收集的信息,不要编造;如果found_answer为false,可以为空", + "required": False, + }, + ], + execute_func=finish_search, + ) diff --git a/src/memory_system/retrieval_tools/query_chat_history.py b/src/memory_system/retrieval_tools/query_chat_history.py index 407bba05..351d0606 100644 --- a/src/memory_system/retrieval_tools/query_chat_history.py +++ b/src/memory_system/retrieval_tools/query_chat_history.py @@ -1,111 +1,111 @@ """ -根据时间或关键词在chat_history中查询 - 工具实现 +根据关键词或参与人在chat_history中查询记忆 - 工具实现 从ChatHistory表的聊天记录概述库中查询 """ import json from typing import Optional +from datetime import datetime + from src.common.logger import get_logger from src.common.database.database_model import ChatHistory from src.chat.utils.utils import parse_keywords_string +from src.config.config import global_config from .tool_registry import register_memory_retrieval_tool -from ..memory_utils import parse_datetime_to_timestamp, parse_time_range logger = get_logger("memory_retrieval_tools") -async def query_chat_history( - chat_id: str, keyword: Optional[str] = None, time_range: Optional[str] = None, fuzzy: bool = True -) -> str: - """根据时间或关键词在chat_history表中查询聊天记录概述 +async def search_chat_history(chat_id: str, keyword: Optional[str] = None, participant: Optional[str] = None) -> str: + """根据关键词或参与人查询记忆,返回匹配的记忆id、记忆标题theme和关键词keywords Args: chat_id: 聊天ID - keyword: 关键词(可选,支持多个关键词,可用空格、逗号等分隔) - time_range: 时间范围或时间点,格式: - - 时间范围:"YYYY-MM-DD HH:MM:SS - YYYY-MM-DD HH:MM:SS" - - 时间点:"YYYY-MM-DD HH:MM:SS"(查询包含该时间点的记录) - fuzzy: 是否使用模糊匹配模式(默认True) - - True: 模糊匹配,只要包含任意一个关键词即匹配(OR关系) - - False: 全匹配,必须包含所有关键词才匹配(AND关系) + keyword: 关键词(可选,支持多个关键词,可用空格、逗号等分隔。匹配规则:如果关键词数量<=2,必须全部匹配;如果关键词数量>2,允许n-1个关键词匹配) + participant: 参与人昵称(可选) Returns: - str: 查询结果 + str: 查询结果,包含记忆id、theme和keywords """ try: # 检查参数 - if not keyword and not time_range: - return "未指定查询参数(需要提供keyword或time_range之一)" + if not keyword and not participant: + return "未指定查询参数(需要提供keyword或participant之一)" # 构建查询条件 - query = ChatHistory.select().where(ChatHistory.chat_id == chat_id) + # 根据配置决定是否限制在当前 chat_id 内查询 + use_global_search = global_config.memory.global_memory - # 时间过滤条件 - if time_range: - # 判断是时间点还是时间范围 - if " - " in time_range: - # 时间范围:查询与时间范围有交集的记录 - start_timestamp, end_timestamp = parse_time_range(time_range) - # 交集条件:start_time < end_timestamp AND end_time > start_timestamp - time_filter = (ChatHistory.start_time < end_timestamp) & (ChatHistory.end_time > start_timestamp) - else: - # 时间点:查询包含该时间点的记录(start_time <= time_point <= end_time) - target_timestamp = parse_datetime_to_timestamp(time_range) - time_filter = (ChatHistory.start_time <= target_timestamp) & (ChatHistory.end_time >= target_timestamp) - query = query.where(time_filter) + if use_global_search: + # 全局查询所有聊天记录 + query = ChatHistory.select() + logger.debug( + f"search_chat_history 启用全局查询模式,忽略 chat_id 过滤,keyword={keyword}, participant={participant}" + ) + else: + # 仅在当前聊天流内查询 + query = ChatHistory.select().where(ChatHistory.chat_id == chat_id) # 执行查询 records = list(query.order_by(ChatHistory.start_time.desc()).limit(50)) - # 如果有关键词,进一步过滤 - if keyword: - # 解析多个关键词(支持空格、逗号等分隔符) - keywords_list = parse_keywords_string(keyword) - if not keywords_list: - keywords_list = [keyword.strip()] if keyword.strip() else [] + filtered_records = [] - # 转换为小写以便匹配 - keywords_lower = [kw.lower() for kw in keywords_list if kw.strip()] + for record in records: + participant_matched = True # 如果没有participant条件,默认为True + keyword_matched = True # 如果没有keyword条件,默认为True - if not keywords_lower: - return "关键词为空" - - filtered_records = [] - - for record in records: - # 在theme、keywords、summary、original_text中搜索 - theme = (record.theme or "").lower() - summary = (record.summary or "").lower() - original_text = (record.original_text or "").lower() - - # 解析record中的keywords JSON - record_keywords_list = [] - if record.keywords: + # 检查参与人匹配 + if participant: + participant_matched = False + participants_list = [] + if record.participants: try: - keywords_data = ( - json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + participants_data = ( + json.loads(record.participants) + if isinstance(record.participants, str) + else record.participants ) - if isinstance(keywords_data, list): - record_keywords_list = [str(k).lower() for k in keywords_data] + if isinstance(participants_data, list): + participants_list = [str(p).lower() for p in participants_data] except (json.JSONDecodeError, TypeError, ValueError): pass - # 根据匹配模式检查关键词 - matched = False - if fuzzy: - # 模糊匹配:只要包含任意一个关键词即匹配(OR关系) - for kw in keywords_lower: - if ( - kw in theme - or kw in summary - or kw in original_text - or any(kw in k for k in record_keywords_list) - ): - matched = True - break - else: - # 全匹配:必须包含所有关键词才匹配(AND关系) - matched = True + participant_lower = participant.lower().strip() + if participant_lower and any(participant_lower in p for p in participants_list): + participant_matched = True + + # 检查关键词匹配 + if keyword: + keyword_matched = False + # 解析多个关键词(支持空格、逗号等分隔符) + keywords_list = parse_keywords_string(keyword) + if not keywords_list: + keywords_list = [keyword.strip()] if keyword.strip() else [] + + # 转换为小写以便匹配 + keywords_lower = [kw.lower() for kw in keywords_list if kw.strip()] + + if keywords_lower: + # 在theme、keywords、summary、original_text中搜索 + theme = (record.theme or "").lower() + summary = (record.summary or "").lower() + original_text = (record.original_text or "").lower() + + # 解析record中的keywords JSON + record_keywords_list = [] + if record.keywords: + try: + keywords_data = ( + json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + ) + if isinstance(keywords_data, list): + record_keywords_list = [str(k).lower() for k in keywords_data] + except (json.JSONDecodeError, TypeError, ValueError): + pass + + # 有容错的全匹配:如果关键词数量>2,允许n-1个关键词匹配;否则必须全部匹配 + matched_count = 0 for kw in keywords_lower: kw_matched = ( kw in theme @@ -113,73 +113,112 @@ async def query_chat_history( or kw in original_text or any(kw in k for k in record_keywords_list) ) - if not kw_matched: - matched = False - break + if kw_matched: + matched_count += 1 - if matched: - filtered_records.append(record) + # 计算需要匹配的关键词数量 + total_keywords = len(keywords_lower) + if total_keywords > 2: + # 关键词数量>2,允许n-1个关键词匹配 + required_matches = total_keywords - 1 + else: + # 关键词数量<=2,必须全部匹配 + required_matches = total_keywords - if not filtered_records: - keywords_str = "、".join(keywords_list) - match_mode = "包含任意一个关键词" if fuzzy else "包含所有关键词" - if time_range: - return f"未找到{match_mode}'{keywords_str}'且在指定时间范围内的聊天记录概述" + keyword_matched = matched_count >= required_matches + + # 两者都匹配(如果同时有participant和keyword,需要两者都匹配;如果只有一个条件,只需要该条件匹配) + matched = participant_matched and keyword_matched + + if matched: + filtered_records.append(record) + + if not filtered_records: + if keyword and participant: + keywords_str = "、".join(parse_keywords_string(keyword) if keyword else []) + return f"未找到包含关键词'{keywords_str}'且参与人包含'{participant}'的聊天记录" + elif keyword: + keywords_str = "、".join(parse_keywords_string(keyword)) + keywords_list = parse_keywords_string(keyword) + if len(keywords_list) > 2: + required_count = len(keywords_list) - 1 + return ( + f"未找到包含至少{required_count}个关键词(共{len(keywords_list)}个)'{keywords_str}'的聊天记录" + ) else: - return f"未找到{match_mode}'{keywords_str}'的聊天记录概述" - - records = filtered_records - - # 如果没有记录(可能是时间范围查询但没有匹配的记录) - if not records: - if time_range: - return "未找到指定时间范围内的聊天记录概述" + return f"未找到包含所有关键词'{keywords_str}'的聊天记录" + elif participant: + return f"未找到参与人包含'{participant}'的聊天记录" else: - return "未找到相关聊天记录概述" + return "未找到相关聊天记录" - # 对即将返回的记录增加使用计数 - records_to_use = records[:3] - for record in records_to_use: - try: - ChatHistory.update(count=ChatHistory.count + 1).where(ChatHistory.id == record.id).execute() - record.count = (record.count or 0) + 1 - except Exception as update_error: - logger.error(f"更新聊天记录概述计数失败: {update_error}") + # 如果匹配结果超过20条,不返回具体记录,只返回提示和所有相关关键词 + if len(filtered_records) > 15: + # 统计所有记录上的关键词并去重 + all_keywords_set = set() + for record in filtered_records: + if record.keywords: + try: + keywords_data = ( + json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + ) + if isinstance(keywords_data, list): + for k in keywords_data: + k_str = str(k).strip() + if k_str: + all_keywords_set.add(k_str) + except (json.JSONDecodeError, TypeError, ValueError): + continue - # 构建结果文本 + # xxx 使用用户原始查询词,优先 keyword,其次 participant,最后退化成“当前条件” + search_label = keyword or participant or "当前条件" + + if all_keywords_set: + keywords_str = "、".join(sorted(all_keywords_set)) + return ( + f"包含“{search_label}”的结果过多,请尝试更多关键词精确查找\n\n" + f'有关"{search_label}"的关键词:\n' + f"{keywords_str}" + ) + else: + return ( + f'包含“{search_label}”的结果过多,请尝试更多关键词精确查找\n\n有关"{search_label}"的关键词信息为空' + ) + + # 构建结果文本,返回id、theme和keywords(最多20条) results = [] - for record in records_to_use: # 最多返回3条记录 + for record in filtered_records[:20]: result_parts = [] + # 添加记忆ID + result_parts.append(f"记忆ID:{record.id}") + # 添加主题 if record.theme: result_parts.append(f"主题:{record.theme}") + else: + result_parts.append("主题:(无)") - # 添加时间范围 - from datetime import datetime - - start_str = datetime.fromtimestamp(record.start_time).strftime("%Y-%m-%d %H:%M:%S") - end_str = datetime.fromtimestamp(record.end_time).strftime("%Y-%m-%d %H:%M:%S") - result_parts.append(f"时间:{start_str} - {end_str}") - - # 添加概括(优先使用summary,如果没有则使用original_text的前200字符) - if record.summary: - result_parts.append(f"概括:{record.summary}") - elif record.original_text: - text_preview = record.original_text[:200] - if len(record.original_text) > 200: - text_preview += "..." - result_parts.append(f"内容:{text_preview}") + # 添加关键词 + if record.keywords: + try: + keywords_data = json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + if isinstance(keywords_data, list) and keywords_data: + keywords_str = "、".join([str(k) for k in keywords_data]) + result_parts.append(f"关键词:{keywords_str}") + else: + result_parts.append("关键词:(无)") + except (json.JSONDecodeError, TypeError, ValueError): + result_parts.append("关键词:(无)") + else: + result_parts.append("关键词:(无)") results.append("\n".join(result_parts)) if not results: - return "未找到相关聊天记录概述" + return "未找到相关聊天记录" response_text = "\n\n---\n\n".join(results) - if len(records) > len(records_to_use): - omitted_count = len(records) - len(records_to_use) - response_text += f"\n\n(还有{omitted_count}条历史记录已省略)" return response_text except Exception as e: @@ -187,30 +226,145 @@ async def query_chat_history( return f"查询失败: {str(e)}" +async def get_chat_history_detail(chat_id: str, memory_ids: str) -> str: + """根据记忆ID,展示某条或某几条记忆的具体内容 + + Args: + chat_id: 聊天ID + memory_ids: 记忆ID,可以是单个ID(如"123")或多个ID(用逗号分隔,如"1,2,3") + + Returns: + str: 记忆的详细内容 + """ + try: + # 解析memory_ids + id_list = [] + # 尝试解析为逗号分隔的ID列表 + try: + id_list = [int(id_str.strip()) for id_str in memory_ids.split(",") if id_str.strip()] + except ValueError: + return f"无效的记忆ID格式: {memory_ids},请使用数字ID,多个ID用逗号分隔(如:'123' 或 '123,456')" + + if not id_list: + return "未提供有效的记忆ID" + + # 查询记录 + query = ChatHistory.select().where((ChatHistory.chat_id == chat_id) & (ChatHistory.id.in_(id_list))) + records = list(query.order_by(ChatHistory.start_time.desc())) + + if not records: + return f"未找到ID为{id_list}的记忆记录(可能ID不存在或不属于当前聊天)" + + # 对即将返回的记录增加使用计数 + for record in records: + try: + ChatHistory.update(count=ChatHistory.count + 1).where(ChatHistory.id == record.id).execute() + record.count = (record.count or 0) + 1 + except Exception as update_error: + logger.error(f"更新聊天记录概述计数失败: {update_error}") + + # 构建详细结果 + results = [] + for record in records: + result_parts = [] + + # 添加记忆ID + result_parts.append(f"记忆ID:{record.id}") + + # 添加主题 + if record.theme: + result_parts.append(f"主题:{record.theme}") + + # 添加时间范围 + start_str = datetime.fromtimestamp(record.start_time).strftime("%Y-%m-%d %H:%M:%S") + end_str = datetime.fromtimestamp(record.end_time).strftime("%Y-%m-%d %H:%M:%S") + result_parts.append(f"时间:{start_str} - {end_str}") + + # 添加参与人 + if record.participants: + try: + participants_data = ( + json.loads(record.participants) if isinstance(record.participants, str) else record.participants + ) + if isinstance(participants_data, list) and participants_data: + participants_str = "、".join([str(p) for p in participants_data]) + result_parts.append(f"参与人:{participants_str}") + except (json.JSONDecodeError, TypeError, ValueError): + pass + + # 添加关键词 + if record.keywords: + try: + keywords_data = json.loads(record.keywords) if isinstance(record.keywords, str) else record.keywords + if isinstance(keywords_data, list) and keywords_data: + keywords_str = "、".join([str(k) for k in keywords_data]) + result_parts.append(f"关键词:{keywords_str}") + except (json.JSONDecodeError, TypeError, ValueError): + pass + + # 添加概括 + if record.summary: + result_parts.append(f"概括:{record.summary}") + + # 添加关键信息点 + if record.key_point: + try: + key_point_data = ( + json.loads(record.key_point) if isinstance(record.key_point, str) else record.key_point + ) + if isinstance(key_point_data, list) and key_point_data: + key_point_str = "\n".join([f" - {str(kp)}" for kp in key_point_data]) + result_parts.append(f"关键信息点:\n{key_point_str}") + except (json.JSONDecodeError, TypeError, ValueError): + pass + + results.append("\n".join(result_parts)) + + if not results: + return "未找到相关记忆记录" + + response_text = "\n\n" + "=" * 50 + "\n\n".join(results) + return response_text + + except Exception as e: + logger.error(f"获取记忆详情失败: {e}") + return f"查询失败: {str(e)}" + + def register_tool(): """注册工具""" + # 注册工具1:搜索记忆 register_memory_retrieval_tool( - name="query_chat_history", - description="根据时间或关键词在聊天记录中查询。可以查询某个时间点发生了什么、某个时间范围内的事件,或根据关键词搜索消息概述。支持两种匹配模式:模糊匹配(默认,只要包含任意一个关键词即匹配)和全匹配(必须包含所有关键词才匹配)", + name="search_chat_history", + description="根据关键词或参与人查询记忆,返回匹配的记忆id、记忆标题theme和关键词keywords。用于快速搜索和定位相关记忆。匹配规则:如果关键词数量<=2,必须全部匹配;如果关键词数量>2,允许n-1个关键词匹配(容错匹配)。", parameters=[ { "name": "keyword", "type": "string", - "description": "关键词(可选,支持多个关键词,可用空格、逗号、斜杠等分隔,如:'麦麦 百度网盘' 或 '麦麦,百度网盘'。用于在主题、关键词、概括、原文中搜索)", + "description": "关键词(可选,支持多个关键词,可用空格、逗号、斜杠等分隔,如:'麦麦 百度网盘' 或 '麦麦,百度网盘'。用于在主题、关键词、概括、原文中搜索。匹配规则:如果关键词数量<=2,必须全部匹配;如果关键词数量>2,允许n-1个关键词匹配)", "required": False, }, { - "name": "time_range", + "name": "participant", "type": "string", - "description": "时间范围或时间点(可选)。格式:'YYYY-MM-DD HH:MM:SS - YYYY-MM-DD HH:MM:SS'(时间范围,查询与时间范围有交集的记录)或 'YYYY-MM-DD HH:MM:SS'(时间点,查询包含该时间点的记录)", - "required": False, - }, - { - "name": "fuzzy", - "type": "boolean", - "description": "是否使用模糊匹配模式(默认True)。True表示模糊匹配(只要包含任意一个关键词即匹配,OR关系),False表示全匹配(必须包含所有关键词才匹配,AND关系)", + "description": "参与人昵称(可选),用于查询包含该参与人的记忆", "required": False, }, ], - execute_func=query_chat_history, + execute_func=search_chat_history, + ) + + # 注册工具2:获取记忆详情 + register_memory_retrieval_tool( + name="get_chat_history_detail", + description="根据记忆ID,展示某条或某几条记忆的具体内容。包括主题、时间、参与人、关键词、概括和关键信息点等详细信息。需要先使用search_chat_history工具获取记忆ID。", + parameters=[ + { + "name": "memory_ids", + "type": "string", + "description": "记忆ID,可以是单个ID(如'123')或多个ID(用逗号分隔,如'123,456,789')", + "required": True, + }, + ], + execute_func=get_chat_history_detail, ) diff --git a/src/memory_system/retrieval_tools/query_jargon.py b/src/memory_system/retrieval_tools/query_jargon.py deleted file mode 100644 index 65050b85..00000000 --- a/src/memory_system/retrieval_tools/query_jargon.py +++ /dev/null @@ -1,76 +0,0 @@ -""" -根据关键词在jargon库中查询 - 工具实现 -""" - -from src.common.logger import get_logger -from src.jargon.jargon_miner import search_jargon -from .tool_registry import register_memory_retrieval_tool - -logger = get_logger("memory_retrieval_tools") - - -async def query_jargon(keyword: str, chat_id: str) -> str: - """根据关键词在jargon库中查询 - - Args: - keyword: 关键词(黑话/俚语/缩写) - chat_id: 聊天ID - - Returns: - str: 查询结果 - """ - try: - content = str(keyword).strip() - if not content: - return "关键词为空" - - # 先尝试精确匹配 - results = search_jargon(keyword=content, chat_id=chat_id, limit=10, case_sensitive=False, fuzzy=False) - - is_fuzzy_match = False - - # 如果精确匹配未找到,尝试模糊搜索 - if not results: - results = search_jargon(keyword=content, chat_id=chat_id, limit=10, case_sensitive=False, fuzzy=True) - is_fuzzy_match = True - - if results: - # 如果是模糊匹配,显示找到的实际jargon内容 - if is_fuzzy_match: - # 处理多个结果 - output_parts = [f"未精确匹配到'{content}'"] - for result in results: - found_content = result.get("content", "").strip() - meaning = result.get("meaning", "").strip() - if found_content and meaning: - output_parts.append(f"找到 '{found_content}' 的含义为:{meaning}") - output = ",".join(output_parts) - logger.info(f"在jargon库中找到匹配(当前会话或全局,模糊搜索): {content},找到{len(results)}条结果") - else: - # 精确匹配,可能有多条(相同content但不同chat_id的情况) - output_parts = [] - for result in results: - meaning = result.get("meaning", "").strip() - if meaning: - output_parts.append(f"'{content}' 为黑话或者网络简写,含义为:{meaning}") - output = ";".join(output_parts) if len(output_parts) > 1 else output_parts[0] - logger.info(f"在jargon库中找到匹配(当前会话或全局,精确匹配): {content},找到{len(results)}条结果") - return output - - # 未命中 - logger.info(f"在jargon库中未找到匹配(当前会话或全局,精确匹配和模糊搜索都未找到): {content}") - return f"未在jargon库中找到'{content}'的解释" - - except Exception as e: - logger.error(f"查询jargon失败: {e}") - return f"查询失败: {str(e)}" - - -def register_tool(): - """注册工具""" - register_memory_retrieval_tool( - name="query_jargon", - description="根据关键词在jargon库中查询黑话/俚语/缩写的含义。支持大小写不敏感搜索,默认会先尝试精确匹配,如果找不到则自动使用模糊搜索。仅搜索当前会话或全局jargon。", - parameters=[{"name": "keyword", "type": "string", "description": "关键词(黑话/俚语/缩写)", "required": True}], - execute_func=query_jargon, - ) diff --git a/src/memory_system/retrieval_tools/query_person_info.py b/src/memory_system/retrieval_tools/query_person_info.py index bc192722..0f335cf1 100644 --- a/src/memory_system/retrieval_tools/query_person_info.py +++ b/src/memory_system/retrieval_tools/query_person_info.py @@ -12,6 +12,25 @@ from .tool_registry import register_memory_retrieval_tool logger = get_logger("memory_retrieval_tools") +def _calculate_similarity(query: str, target: str) -> float: + """计算查询词在目标字符串中的相似度比例 + + Args: + query: 查询词 + target: 目标字符串 + + Returns: + float: 相似度比例(0.0-1.0),查询词长度 / 目标字符串长度 + """ + if not query or not target: + return 0.0 + query_len = len(query) + target_len = len(target) + if target_len == 0: + return 0.0 + return query_len / target_len + + def _format_group_nick_names(group_nick_name_field) -> str: """格式化群昵称信息 @@ -81,11 +100,29 @@ async def query_person_info(person_name: str) -> str: if not records: return f"未找到模糊匹配'{person_name}'的用户信息" + # 根据相似度过滤结果:查询词在目标字符串中至少占50% + SIMILARITY_THRESHOLD = 0.5 + filtered_records = [] + for record in records: + if not record.person_name: + continue + # 精确匹配总是保留(相似度100%) + if record.person_name.strip() == person_name: + filtered_records.append(record) + else: + # 模糊匹配需要检查相似度 + similarity = _calculate_similarity(person_name, record.person_name.strip()) + if similarity >= SIMILARITY_THRESHOLD: + filtered_records.append(record) + + if not filtered_records: + return f"未找到相似度≥50%的匹配'{person_name}'的用户信息" + # 区分精确匹配和模糊匹配的结果 exact_matches = [] fuzzy_matches = [] - for record in records: + for record in filtered_records: # 检查是否是精确匹配 if record.person_name and record.person_name.strip() == person_name: exact_matches.append(record) @@ -248,7 +285,7 @@ async def query_person_info(person_name: str) -> str: response_text = "\n\n---\n\n".join(results) # 添加统计信息 - total_count = len(records) + total_count = len(filtered_records) exact_count = len(exact_matches) fuzzy_count = len(fuzzy_matches) diff --git a/src/mood/mood_manager.py b/src/mood/mood_manager.py deleted file mode 100644 index 7cc64801..00000000 --- a/src/mood/mood_manager.py +++ /dev/null @@ -1,230 +0,0 @@ -import time - -from src.common.logger import get_logger -from src.config.config import global_config, model_config -from src.chat.message_receive.chat_stream import get_chat_manager -from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_by_timestamp_with_chat_inclusive -from src.llm_models.utils_model import LLMRequest -from src.manager.async_task_manager import AsyncTask, async_task_manager - - -logger = get_logger("mood") - - -def init_prompt(): - Prompt( - """ -{chat_talking_prompt} -以上是群里正在进行的聊天记录 - -{identity_block} -你先前的情绪状态是:{mood_state} -你的情绪特点是:{emotion_style} - -现在,请你根据先前的情绪状态和现在的聊天内容,总结推断你现在的情绪状态,用简短的词句来描述情绪状态 -请只输出新的情绪状态,不要输出其他内容: -""", - "get_mood_prompt", - ) - - Prompt( - """ -{chat_talking_prompt} -以上是群里最近的聊天记录 - -{identity_block} -你之前的情绪状态是:{mood_state} - -距离你上次关注群里消息已经过去了一段时间,你冷静了下来,请你输出一句话或几个词来描述你现在的情绪状态 -你的情绪特点是:{emotion_style} -请只输出新的情绪状态,不要输出其他内容: -""", - "regress_mood_prompt", - ) - - -class ChatMood: - def __init__(self, chat_id: str): - self.chat_id: str = chat_id - - chat_manager = get_chat_manager() - self.chat_stream = chat_manager.get_stream(self.chat_id) - - if not self.chat_stream: - raise ValueError(f"Chat stream for chat_id {chat_id} not found") - - self.log_prefix = f"[{self.chat_stream.group_info.group_name if self.chat_stream.group_info else self.chat_stream.user_info.user_nickname}]" - - self.mood_state: str = "感觉很平静" - - self.regression_count: int = 0 - - self.mood_model = LLMRequest(model_set=model_config.model_task_config.utils, request_type="mood") - - self.last_change_time: float = 0 - - async def get_mood(self) -> str: - self.regression_count = 0 - - current_time = time.time() - - logger.info(f"{self.log_prefix} 获取情绪状态") - message_list_before_now = get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id=self.chat_id, - timestamp_start=self.last_change_time, - timestamp_end=current_time, - limit=int(global_config.chat.max_context_size / 3), - limit_mode="last", - ) - - chat_talking_prompt = build_readable_messages( - message_list_before_now, - replace_bot_name=True, - timestamp_mode="normal_no_YMD", - read_mark=0.0, - truncate=True, - show_actions=True, - ) - - bot_name = global_config.bot.nickname - if global_config.bot.alias_names: - bot_nickname = f",也有人叫你{','.join(global_config.bot.alias_names)}" - else: - bot_nickname = "" - - identity_block = f"你的名字是{bot_name}{bot_nickname}" - - prompt = await global_prompt_manager.format_prompt( - "get_mood_prompt", - chat_talking_prompt=chat_talking_prompt, - identity_block=identity_block, - mood_state=self.mood_state, - emotion_style=global_config.mood.emotion_style, - ) - - response, (reasoning_content, _, _) = await self.mood_model.generate_response_async( - prompt=prompt, temperature=0.7 - ) - if global_config.debug.show_prompt: - logger.info(f"{self.log_prefix} prompt: {prompt}") - logger.info(f"{self.log_prefix} response: {response}") - logger.info(f"{self.log_prefix} reasoning_content: {reasoning_content}") - - logger.info(f"{self.log_prefix} 情绪状态更新为: {response}") - - self.mood_state = response - - self.last_change_time = current_time - - return response - - async def regress_mood(self): - message_time = time.time() - message_list_before_now = get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id=self.chat_id, - timestamp_start=self.last_change_time, - timestamp_end=message_time, - limit=15, - limit_mode="last", - ) - - chat_talking_prompt = build_readable_messages( - message_list_before_now, - replace_bot_name=True, - timestamp_mode="normal_no_YMD", - read_mark=0.0, - truncate=True, - show_actions=True, - ) - - bot_name = global_config.bot.nickname - if global_config.bot.alias_names: - bot_nickname = f",也有人叫你{','.join(global_config.bot.alias_names)}" - else: - bot_nickname = "" - - identity_block = f"你的名字是{bot_name}{bot_nickname}" - - prompt = await global_prompt_manager.format_prompt( - "regress_mood_prompt", - chat_talking_prompt=chat_talking_prompt, - identity_block=identity_block, - mood_state=self.mood_state, - emotion_style=global_config.mood.emotion_style, - ) - - response, (reasoning_content, _, _) = await self.mood_model.generate_response_async( - prompt=prompt, temperature=0.7 - ) - - if global_config.debug.show_prompt: - logger.info(f"{self.log_prefix} prompt: {prompt}") - logger.info(f"{self.log_prefix} response: {response}") - logger.info(f"{self.log_prefix} reasoning_content: {reasoning_content}") - - logger.info(f"{self.log_prefix} 情绪状态转变为: {response}") - - self.mood_state = response - - self.regression_count += 1 - - -class MoodRegressionTask(AsyncTask): - def __init__(self, mood_manager: "MoodManager"): - super().__init__(task_name="MoodRegressionTask", run_interval=45) - self.mood_manager = mood_manager - - async def run(self): - logger.debug("开始情绪回归任务...") - now = time.time() - for mood in self.mood_manager.mood_list: - if mood.last_change_time == 0: - continue - - if now - mood.last_change_time > 200: - if mood.regression_count >= 2: - continue - - logger.debug(f"{mood.log_prefix} 开始情绪回归, 第 {mood.regression_count + 1} 次") - await mood.regress_mood() - - -class MoodManager: - def __init__(self): - self.mood_list: list[ChatMood] = [] - """当前情绪状态""" - self.task_started: bool = False - - async def start(self): - """启动情绪回归后台任务""" - if self.task_started: - return - - task = MoodRegressionTask(self) - await async_task_manager.add_task(task) - self.task_started = True - logger.info("情绪回归任务已启动") - - def get_mood_by_chat_id(self, chat_id: str) -> ChatMood: - for mood in self.mood_list: - if mood.chat_id == chat_id: - return mood - - new_mood = ChatMood(chat_id) - self.mood_list.append(new_mood) - return new_mood - - def reset_mood_by_chat_id(self, chat_id: str): - for mood in self.mood_list: - if mood.chat_id == chat_id: - mood.mood_state = "感觉很平静" - mood.regression_count = 0 - return - self.mood_list.append(ChatMood(chat_id)) - - -init_prompt() - -mood_manager = MoodManager() -"""全局情绪管理器""" diff --git a/src/plugin_system/__init__.py b/src/plugin_system/__init__.py index a3561f0e..7e92a60d 100644 --- a/src/plugin_system/__init__.py +++ b/src/plugin_system/__init__.py @@ -11,6 +11,9 @@ from .base import ( BaseCommand, BaseTool, ConfigField, + ConfigSection, + ConfigLayout, + ConfigTab, ComponentType, ActionActivationType, ChatMode, @@ -116,6 +119,9 @@ __all__ = [ # 装饰器 "register_plugin", "ConfigField", + "ConfigSection", + "ConfigLayout", + "ConfigTab", # 工具函数 "ManifestValidator", "get_logger", diff --git a/src/plugin_system/apis/__init__.py b/src/plugin_system/apis/__init__.py index 730ee907..a872bfc7 100644 --- a/src/plugin_system/apis/__init__.py +++ b/src/plugin_system/apis/__init__.py @@ -19,7 +19,6 @@ from src.plugin_system.apis import ( send_api, tool_api, frequency_api, - mood_api, auto_talk_api, ) from .logging_api import get_logger @@ -42,6 +41,5 @@ __all__ = [ "register_plugin", "tool_api", "frequency_api", - "mood_api", "auto_talk_api", ] diff --git a/src/plugin_system/apis/emoji_api.py b/src/plugin_system/apis/emoji_api.py index e1661887..e4d6fcd7 100644 --- a/src/plugin_system/apis/emoji_api.py +++ b/src/plugin_system/apis/emoji_api.py @@ -104,7 +104,7 @@ async def get_random(count: Optional[int] = 1) -> List[Tuple[str, str, str]]: return [] if len(valid_emojis) < count: - logger.warning( + logger.debug( f"[EmojiAPI] 有效表情包数量 ({len(valid_emojis)}) 少于请求的数量 ({count}),将返回所有有效表情包" ) count = len(valid_emojis) diff --git a/src/plugin_system/apis/frequency_api.py b/src/plugin_system/apis/frequency_api.py index bc906186..9cde1d90 100644 --- a/src/plugin_system/apis/frequency_api.py +++ b/src/plugin_system/apis/frequency_api.py @@ -1,5 +1,5 @@ from src.common.logger import get_logger -from src.chat.frequency_control.frequency_control import frequency_control_manager +from src.chat.heart_flow.frequency_control import frequency_control_manager from src.config.config import global_config logger = get_logger("frequency_api") diff --git a/src/plugin_system/apis/generator_api.py b/src/plugin_system/apis/generator_api.py index 29d0b66d..4f7b63fc 100644 --- a/src/plugin_system/apis/generator_api.py +++ b/src/plugin_system/apis/generator_api.py @@ -81,10 +81,12 @@ async def generate_reply( chat_id: Optional[str] = None, action_data: Optional[Dict[str, Any]] = None, reply_message: Optional["DatabaseMessages"] = None, + think_level: int = 1, extra_info: str = "", reply_reason: str = "", available_actions: Optional[Dict[str, ActionInfo]] = None, chosen_actions: Optional[List["ActionPlannerInfo"]] = None, + unknown_words: Optional[List[str]] = None, enable_tool: bool = False, enable_splitter: bool = True, enable_chinese_typo: bool = True, @@ -103,6 +105,7 @@ async def generate_reply( reply_reason: 回复原因 available_actions: 可用动作 chosen_actions: 已选动作 + unknown_words: Planner 在 reply 动作中给出的未知词语列表,用于黑话检索 enable_tool: 是否启用工具调用 enable_splitter: 是否启用消息分割器 enable_chinese_typo: 是否启用错字生成器 @@ -122,11 +125,24 @@ async def generate_reply( logger.error("[GeneratorAPI] 无法获取回复器") return False, None - if not extra_info and action_data: - extra_info = action_data.get("extra_info", "") - - if not reply_reason and action_data: - reply_reason = action_data.get("reason", "") + if action_data: + if not extra_info: + extra_info = action_data.get("extra_info", "") + if not reply_reason: + reply_reason = action_data.get("reason", "") + # 仅在 reply 场景下使用的未知词语解析(Planner JSON 中下发) + if unknown_words is None: + uw = action_data.get("unknown_words") + if isinstance(uw, list): + # 只保留非空字符串 + cleaned: List[str] = [] + for item in uw: + if isinstance(item, str): + s = item.strip() + if s: + cleaned.append(s) + if cleaned: + unknown_words = cleaned # 调用回复器生成回复 success, llm_response = await replyer.generate_reply_with_context( @@ -136,6 +152,8 @@ async def generate_reply( enable_tool=enable_tool, reply_message=reply_message, reply_reason=reply_reason, + unknown_words=unknown_words, + think_level=think_level, from_plugin=from_plugin, stream_id=chat_stream.stream_id if chat_stream else chat_id, reply_time_point=reply_time_point, diff --git a/src/plugin_system/apis/llm_api.py b/src/plugin_system/apis/llm_api.py index a4e2dd30..fb4de48d 100644 --- a/src/plugin_system/apis/llm_api.py +++ b/src/plugin_system/apis/llm_api.py @@ -108,8 +108,8 @@ async def generate_with_model_with_tools( """ try: model_name_list = model_config.model_list - logger.info(f"[LLMAPI] 使用模型集合 {model_name_list} 生成内容") - logger.debug(f"[LLMAPI] 完整提示词: {prompt}") + logger.info(f"使用模型{model_name_list}生成内容") + logger.debug(f"完整提示词: {prompt}") llm_request = LLMRequest(model_set=model_config, request_type=request_type) @@ -147,7 +147,7 @@ async def generate_with_model_with_tools_by_message_factory( """ try: model_name_list = model_config.model_list - logger.info(f"[LLMAPI] 使用模型集合 {model_name_list} 生成内容(消息工厂)") + logger.info(f"使用模型 {model_name_list} 生成内容") llm_request = LLMRequest(model_set=model_config, request_type=request_type) diff --git a/src/plugin_system/apis/message_api.py b/src/plugin_system/apis/message_api.py index cfacd558..94ee9cbc 100644 --- a/src/plugin_system/apis/message_api.py +++ b/src/plugin_system/apis/message_api.py @@ -72,6 +72,7 @@ def get_messages_by_time_in_chat( limit_mode: str = "latest", filter_mai: bool = False, filter_command: bool = False, + filter_intercept_message_level: Optional[int] = None, ) -> List[DatabaseMessages]: """ 获取指定聊天中指定时间范围内的消息 @@ -110,6 +111,7 @@ def get_messages_by_time_in_chat( limit_mode=limit_mode, filter_bot=filter_mai, filter_command=filter_command, + filter_intercept_message_level=filter_intercept_message_level, ) @@ -121,6 +123,7 @@ def get_messages_by_time_in_chat_inclusive( limit_mode: str = "latest", filter_mai: bool = False, filter_command: bool = False, + filter_intercept_message_level: Optional[int] = None, ) -> List[DatabaseMessages]: """ 获取指定聊天中指定时间范围内的消息(包含边界) @@ -147,15 +150,19 @@ def get_messages_by_time_in_chat_inclusive( raise ValueError("chat_id 不能为空") if not isinstance(chat_id, str): raise ValueError("chat_id 必须是字符串类型") - if filter_mai: - return filter_mai_messages( - get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id, start_time, end_time, limit, limit_mode, filter_command - ) - ) - return get_raw_msg_by_timestamp_with_chat_inclusive( - chat_id, start_time, end_time, limit, limit_mode, filter_command + messages = get_raw_msg_by_timestamp_with_chat_inclusive( + chat_id=chat_id, + timestamp_start=start_time, + timestamp_end=end_time, + limit=limit, + limit_mode=limit_mode, + filter_bot=filter_mai, + filter_command=filter_command, + filter_intercept_message_level=filter_intercept_message_level, ) + if filter_mai: + return filter_mai_messages(messages) + return messages def get_messages_by_time_in_chat_for_users( @@ -273,7 +280,11 @@ def get_messages_before_time(timestamp: float, limit: int = 0, filter_mai: bool def get_messages_before_time_in_chat( - chat_id: str, timestamp: float, limit: int = 0, filter_mai: bool = False + chat_id: str, + timestamp: float, + limit: int = 0, + filter_mai: bool = False, + filter_intercept_message_level: Optional[int] = None, ) -> List[DatabaseMessages]: """ 获取指定聊天中指定时间戳之前的消息 @@ -298,9 +309,15 @@ def get_messages_before_time_in_chat( raise ValueError("chat_id 不能为空") if not isinstance(chat_id, str): raise ValueError("chat_id 必须是字符串类型") + messages = get_raw_msg_before_timestamp_with_chat( + chat_id=chat_id, + timestamp=timestamp, + limit=limit, + filter_intercept_message_level=filter_intercept_message_level, + ) if filter_mai: - return filter_mai_messages(get_raw_msg_before_timestamp_with_chat(chat_id, timestamp, limit)) - return get_raw_msg_before_timestamp_with_chat(chat_id, timestamp, limit) + return filter_mai_messages(messages) + return messages def get_messages_before_time_for_users( diff --git a/src/plugin_system/apis/mood_api.py b/src/plugin_system/apis/mood_api.py deleted file mode 100644 index d5300e9f..00000000 --- a/src/plugin_system/apis/mood_api.py +++ /dev/null @@ -1,13 +0,0 @@ -import asyncio -from typing import Optional - -from src.common.logger import get_logger -from src.mood.mood_manager import mood_manager - -logger = get_logger("mood_api") - - -async def get_mood_by_chat_id(chat_id: str) -> Optional[float]: - chat_mood = mood_manager.get_mood_by_chat_id(chat_id) - mood = asyncio.create_task(chat_mood.get_mood()) - return mood diff --git a/src/plugin_system/base/__init__.py b/src/plugin_system/base/__init__.py index a8c320bf..9f930b5a 100644 --- a/src/plugin_system/base/__init__.py +++ b/src/plugin_system/base/__init__.py @@ -29,7 +29,7 @@ from .component_types import ( ForwardNode, ReplySetModel, ) -from .config_types import ConfigField +from .config_types import ConfigField, ConfigSection, ConfigLayout, ConfigTab __all__ = [ "BasePlugin", @@ -46,6 +46,9 @@ __all__ = [ "PluginInfo", "PythonDependency", "ConfigField", + "ConfigSection", + "ConfigLayout", + "ConfigTab", "EventHandlerInfo", "EventType", "BaseEventHandler", diff --git a/src/plugin_system/base/base_command.py b/src/plugin_system/base/base_command.py index 4b098869..0cfdb5d0 100644 --- a/src/plugin_system/base/base_command.py +++ b/src/plugin_system/base/base_command.py @@ -55,11 +55,11 @@ class BaseCommand(ABC): self.matched_groups = groups @abstractmethod - async def execute(self) -> Tuple[bool, Optional[str], bool]: + async def execute(self) -> Tuple[bool, Optional[str], int]: """执行Command的抽象方法,子类必须实现 Returns: - Tuple[bool, Optional[str], bool]: (是否执行成功, 可选的回复消息, 是否拦截消息 不进行 后续处理) + Tuple[bool, Optional[str], int]: (是否执行成功, 可选的回复消息, 拦截消息力度,0代表不拦截,1代表仅不触发回复,replyer可见,2代表不触发回复,replyer不可见) """ pass diff --git a/src/plugin_system/base/config_types.py b/src/plugin_system/base/config_types.py index 752b3345..18a98614 100644 --- a/src/plugin_system/base/config_types.py +++ b/src/plugin_system/base/config_types.py @@ -1,18 +1,273 @@ """ 插件系统配置类型定义 + +提供插件配置的类型定义,支持 WebUI 可视化配置编辑。 """ -from typing import Any, Optional, List +from typing import Any, Optional, List, Dict, Union from dataclasses import dataclass, field @dataclass class ConfigField: - """配置字段定义""" + """ + 配置字段定义 - type: type # 字段类型 + 用于定义插件配置项的元数据,支持类型验证、UI 渲染等功能。 + + 基础示例: + ConfigField(type=str, default="", description="API密钥") + + 完整示例: + ConfigField( + type=str, + default="", + description="API密钥", + input_type="password", + placeholder="请输入API密钥", + required=True, + hint="从服务商控制台获取", + order=1 + ) + """ + + # === 基础字段(必需) === + type: type # 字段类型: str, int, float, bool, list, dict default: Any # 默认值 - description: str # 字段描述 - example: Optional[str] = None # 示例值 + description: str # 字段描述(也用作默认标签) + + # === 验证相关 === + example: Optional[str] = None # 示例值(用于生成配置文件注释) required: bool = False # 是否必需 - choices: Optional[List[Any]] = field(default_factory=list) # 可选值列表 + choices: Optional[List[Any]] = field(default_factory=list) # 可选值列表(用于下拉选择) + min: Optional[float] = None # 最小值(数字类型) + max: Optional[float] = None # 最大值(数字类型) + step: Optional[float] = None # 步进值(数字类型) + pattern: Optional[str] = None # 正则验证(字符串类型) + max_length: Optional[int] = None # 最大长度(字符串类型) + + # === UI 显示控制 === + label: Optional[str] = None # 显示标签(默认使用 description) + placeholder: Optional[str] = None # 输入框占位符 + hint: Optional[str] = None # 字段下方的提示文字 + icon: Optional[str] = None # 字段图标名称 + hidden: bool = False # 是否在 UI 中隐藏 + disabled: bool = False # 是否禁用编辑 + order: int = 0 # 排序权重(数字越小越靠前) + + # === 输入控件类型 === + # 可选值: text, password, textarea, number, color, code, file, json + # 不指定时根据 type 和 choices 自动推断 + input_type: Optional[str] = None + + # === textarea 专用 === + rows: int = 3 # 文本域行数 + + # === 分组与布局 === + group: Optional[str] = None # 字段分组(在 section 内再细分) + + # === 条件显示 === + depends_on: Optional[str] = None # 依赖的字段路径,如 "section.field" + depends_value: Any = None # 依赖字段需要的值(当依赖字段等于此值时显示) + + # === 列表类型专用 === + item_type: Optional[str] = None # 数组元素类型: "string", "number", "object" + item_fields: Optional[Dict[str, Any]] = None # 当 item_type="object" 时,定义对象的字段结构 + min_items: Optional[int] = None # 数组最小元素数量 + max_items: Optional[int] = None # 数组最大元素数量 + + def get_ui_type(self) -> str: + """ + 获取 UI 控件类型 + + 如果指定了 input_type 则直接返回,否则根据 type 和 choices 自动推断。 + + Returns: + 控件类型字符串 + """ + if self.input_type: + return self.input_type + + # 根据 type 和 choices 自动推断 + if self.type is bool: + return "switch" + elif self.type in (int, float): + if self.min is not None and self.max is not None: + return "slider" + return "number" + elif self.type is str: + if self.choices: + return "select" + return "text" + elif self.type is list: + return "list" + elif self.type is dict: + return "json" + else: + return "text" + + def to_dict(self) -> Dict[str, Any]: + """ + 转换为可序列化的字典(用于 API 传输) + + Returns: + 包含所有配置信息的字典 + """ + return { + "type": self.type.__name__ if isinstance(self.type, type) else str(self.type), + "default": self.default, + "description": self.description, + "example": self.example, + "required": self.required, + "choices": self.choices if self.choices else None, + "min": self.min, + "max": self.max, + "step": self.step, + "pattern": self.pattern, + "max_length": self.max_length, + "label": self.label or self.description, + "placeholder": self.placeholder, + "hint": self.hint, + "icon": self.icon, + "hidden": self.hidden, + "disabled": self.disabled, + "order": self.order, + "input_type": self.input_type, + "ui_type": self.get_ui_type(), + "rows": self.rows, + "group": self.group, + "depends_on": self.depends_on, + "depends_value": self.depends_value, + "item_type": self.item_type, + "item_fields": self.item_fields, + "min_items": self.min_items, + "max_items": self.max_items, + } + + +@dataclass +class ConfigSection: + """ + 配置节定义 + + 用于描述配置文件中一个 section 的元数据。 + + 示例: + ConfigSection( + title="API配置", + description="外部API连接参数", + icon="cloud", + order=1 + ) + """ + + title: str # 显示标题 + description: Optional[str] = None # 详细描述 + icon: Optional[str] = None # 图标名称 + collapsed: bool = False # 默认是否折叠 + order: int = 0 # 排序权重 + + def to_dict(self) -> Dict[str, Any]: + """转换为可序列化的字典""" + return { + "title": self.title, + "description": self.description, + "icon": self.icon, + "collapsed": self.collapsed, + "order": self.order, + } + + +@dataclass +class ConfigTab: + """ + 配置标签页定义 + + 用于将多个 section 组织到一个标签页中。 + + 示例: + ConfigTab( + id="general", + title="通用设置", + icon="settings", + sections=["plugin", "api"] + ) + """ + + id: str # 标签页 ID + title: str # 显示标题 + sections: List[str] = field(default_factory=list) # 包含的 section 名称列表 + icon: Optional[str] = None # 图标名称 + order: int = 0 # 排序权重 + badge: Optional[str] = None # 角标文字(如 "Beta", "New") + + def to_dict(self) -> Dict[str, Any]: + """转换为可序列化的字典""" + return { + "id": self.id, + "title": self.title, + "sections": self.sections, + "icon": self.icon, + "order": self.order, + "badge": self.badge, + } + + +@dataclass +class ConfigLayout: + """ + 配置页面布局定义 + + 用于定义插件配置页面的整体布局结构。 + + 布局类型: + - "auto": 自动布局,sections 作为折叠面板显示 + - "tabs": 标签页布局 + - "pages": 分页布局(左侧导航 + 右侧内容) + + 简单示例(标签页布局): + ConfigLayout( + type="tabs", + tabs=[ + ConfigTab(id="basic", title="基础", sections=["plugin", "api"]), + ConfigTab(id="advanced", title="高级", sections=["debug"]), + ] + ) + """ + + type: str = "auto" # 布局类型: auto, tabs, pages + tabs: List[ConfigTab] = field(default_factory=list) # 标签页列表 + + def to_dict(self) -> Dict[str, Any]: + """转换为可序列化的字典""" + return { + "type": self.type, + "tabs": [tab.to_dict() for tab in self.tabs], + } + + +def section_meta( + title: str, description: Optional[str] = None, icon: Optional[str] = None, collapsed: bool = False, order: int = 0 +) -> Union[str, ConfigSection]: + """ + 便捷函数:创建 section 元数据 + + 可以在 config_section_descriptions 中使用,提供比纯字符串更丰富的信息。 + + Args: + title: 显示标题 + description: 详细描述 + icon: 图标名称 + collapsed: 默认是否折叠 + order: 排序权重 + + Returns: + ConfigSection 实例 + + 示例: + config_section_descriptions = { + "api": section_meta("API配置", icon="cloud", order=1), + "debug": section_meta("调试设置", collapsed=True, order=99), + } + """ + return ConfigSection(title=title, description=description, icon=icon, collapsed=collapsed, order=order) diff --git a/src/plugin_system/base/plugin_base.py b/src/plugin_system/base/plugin_base.py index 0b7f15d1..f21c2a40 100644 --- a/src/plugin_system/base/plugin_base.py +++ b/src/plugin_system/base/plugin_base.py @@ -12,7 +12,11 @@ from src.plugin_system.base.component_types import ( PluginInfo, PythonDependency, ) -from src.plugin_system.base.config_types import ConfigField +from src.plugin_system.base.config_types import ( + ConfigField, + ConfigSection, + ConfigLayout, +) from src.plugin_system.utils.manifest_utils import ManifestValidator logger = get_logger("plugin_base") @@ -60,7 +64,10 @@ class PluginBase(ABC): def config_schema(self) -> Dict[str, Union[Dict[str, ConfigField], str]]: return {} - config_section_descriptions: Dict[str, str] = {} + config_section_descriptions: Dict[str, Union[str, ConfigSection]] = {} + + # 布局配置(可选,不定义则使用自动布局) + config_layout: ConfigLayout = None def __init__(self, plugin_dir: str): """初始化插件 @@ -205,6 +212,22 @@ class PluginBase(ABC): return value + def _format_toml_value(self, value: Any) -> str: + """将Python值格式化为合法的TOML字符串""" + if isinstance(value, str): + return json.dumps(value, ensure_ascii=False) + if isinstance(value, bool): + return str(value).lower() + if isinstance(value, (int, float)): + return str(value) + if isinstance(value, list): + inner = ", ".join(self._format_toml_value(item) for item in value) + return f"[{inner}]" + if isinstance(value, dict): + items = [f"{k} = {self._format_toml_value(v)}" for k, v in value.items()] + return "{ " + ", ".join(items) + " }" + return json.dumps(value, ensure_ascii=False) + def _generate_and_save_default_config(self, config_file_path: str): """根据插件的Schema生成并保存默认配置文件""" if not self.config_schema: @@ -244,12 +267,7 @@ class PluginBase(ABC): # 添加字段值 value = field.default - if isinstance(value, str): - toml_str += f'{field_name} = "{value}"\n' - elif isinstance(value, bool): - toml_str += f"{field_name} = {str(value).lower()}\n" - else: - toml_str += f"{field_name} = {value}\n" + toml_str += f"{field_name} = {self._format_toml_value(value)}\n" toml_str += "\n" toml_str += "\n" @@ -422,19 +440,7 @@ class PluginBase(ABC): # 添加字段值(使用迁移后的值) value = section_data.get(field_name, field.default) - if isinstance(value, str): - toml_str += f'{field_name} = "{value}"\n' - elif isinstance(value, bool): - toml_str += f"{field_name} = {str(value).lower()}\n" - elif isinstance(value, list): - # 格式化列表 - if all(isinstance(item, str) for item in value): - formatted_list = "[" + ", ".join(f'"{item}"' for item in value) + "]" - else: - formatted_list = str(value) - toml_str += f"{field_name} = {formatted_list}\n" - else: - toml_str += f"{field_name} = {value}\n" + toml_str += f"{field_name} = {self._format_toml_value(value)}\n" toml_str += "\n" toml_str += "\n" @@ -564,6 +570,93 @@ class PluginBase(ABC): return current + def get_webui_config_schema(self) -> Dict[str, Any]: + """ + 获取 WebUI 配置 Schema + + 返回完整的配置 schema,包含: + - 插件基本信息 + - 所有 section 及其字段定义 + - 布局配置 + + 用于 WebUI 动态生成配置表单。 + + Returns: + Dict: 完整的配置 schema + """ + schema = { + "plugin_id": self.plugin_name, + "plugin_info": { + "name": self.display_name, + "version": self.plugin_version, + "description": self.plugin_description, + "author": self.plugin_author, + }, + "sections": {}, + "layout": None, + } + + # 处理 sections + for section_name, fields in self.config_schema.items(): + if not isinstance(fields, dict): + continue + + section_data = { + "name": section_name, + "title": section_name, + "description": None, + "icon": None, + "collapsed": False, + "order": 0, + "fields": {}, + } + + # 获取 section 元数据 + section_meta = self.config_section_descriptions.get(section_name) + if section_meta: + if isinstance(section_meta, str): + section_data["title"] = section_meta + elif isinstance(section_meta, ConfigSection): + section_data["title"] = section_meta.title + section_data["description"] = section_meta.description + section_data["icon"] = section_meta.icon + section_data["collapsed"] = section_meta.collapsed + section_data["order"] = section_meta.order + elif isinstance(section_meta, dict): + section_data.update(section_meta) + + # 处理字段 + for field_name, field_def in fields.items(): + if isinstance(field_def, ConfigField): + field_data = field_def.to_dict() + field_data["name"] = field_name + section_data["fields"][field_name] = field_data + + schema["sections"][section_name] = section_data + + # 处理布局 + if self.config_layout: + schema["layout"] = self.config_layout.to_dict() + else: + # 自动布局:按 section order 排序 + schema["layout"] = { + "type": "auto", + "tabs": [], + } + + return schema + + def get_current_config_values(self) -> Dict[str, Any]: + """ + 获取当前配置值 + + 返回插件当前的配置值(已从配置文件加载)。 + + Returns: + Dict: 当前配置值 + """ + return self.config.copy() + @abstractmethod def register_plugin(self) -> bool: """ diff --git a/src/plugin_system/core/tool_use.py b/src/plugin_system/core/tool_use.py index 915ed7aa..6d60ee77 100644 --- a/src/plugin_system/core/tool_use.py +++ b/src/plugin_system/core/tool_use.py @@ -95,7 +95,7 @@ class ToolExecutor: # 如果没有可用工具,直接返回空内容 if not tools: - logger.info(f"{self.log_prefix}没有可用工具,直接返回空内容") + logger.debug(f"{self.log_prefix}没有可用工具,直接返回空内容") if return_details: return [], [], "" else: diff --git a/src/plugins/built_in/emoji_plugin/emoji.py b/src/plugins/built_in/emoji_plugin/emoji.py index 3783886a..8599620a 100644 --- a/src/plugins/built_in/emoji_plugin/emoji.py +++ b/src/plugins/built_in/emoji_plugin/emoji.py @@ -47,7 +47,7 @@ class EmojiAction(BaseAction): try: # 1. 获取发送表情的原因 # reason = self.action_data.get("reason", "表达当前情绪") - reason = self.reasoning + reason = self.action_reasoning # 2. 随机获取20个表情包 sampled_emojis = await emoji_api.get_random(30) diff --git a/src/plugins/built_in/knowledge/lpmm_get_knowledge.py b/src/plugins/built_in/knowledge/lpmm_get_knowledge.py index 174bef1c..bb627e5e 100644 --- a/src/plugins/built_in/knowledge/lpmm_get_knowledge.py +++ b/src/plugins/built_in/knowledge/lpmm_get_knowledge.py @@ -15,7 +15,7 @@ class SearchKnowledgeFromLPMMTool(BaseTool): description = "从知识库中搜索相关信息,如果你需要知识,就使用这个工具" parameters = [ ("query", ToolParamType.STRING, "搜索查询关键词", True, None), - ("limit", ToolParamType.INTEGER, "希望返回的相关知识条数,默认5", False, 5), + ("limit", ToolParamType.INTEGER, "希望返回的相关知识条数,默认5", False, None), ] available_for_llm = global_config.lpmm_knowledge.enable diff --git a/src/webui/anti_crawler.py b/src/webui/anti_crawler.py new file mode 100644 index 00000000..28d87170 --- /dev/null +++ b/src/webui/anti_crawler.py @@ -0,0 +1,796 @@ +""" +WebUI 防爬虫模块 +提供爬虫检测和阻止功能,保护 WebUI 不被搜索引擎和恶意爬虫访问 +""" + +import os +import time +import ipaddress +import re +from collections import deque +from typing import Optional +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.requests import Request +from starlette.responses import PlainTextResponse + +from src.common.logger import get_logger + +logger = get_logger("webui.anti_crawler") + +# 常见爬虫 User-Agent 列表(使用更精确的关键词,避免误报) +CRAWLER_USER_AGENTS = { + # 搜索引擎爬虫(精确匹配) + "googlebot", + "bingbot", + "baiduspider", + "yandexbot", + "slurp", # Yahoo + "duckduckbot", + "sogou", + "exabot", + "facebot", + "ia_archiver", # Internet Archive + # 通用爬虫(移除过于宽泛的关键词) + "crawler", + "spider", + "scraper", + "wget", # 保留wget,因为通常用于自动化脚本 + "scrapy", # 保留scrapy,因为这是爬虫框架 + # 安全扫描工具(这些是明确的扫描工具) + "masscan", + "nmap", + "nikto", + "sqlmap", + # 注意:移除了以下过于宽泛的关键词以避免误报: + # - "bot" (会误匹配GitHub-Robot等) + # - "curl" (正常工具) + # - "python-requests" (正常库) + # - "httpx" (正常库) + # - "aiohttp" (正常库) +} + +# 资产测绘工具 User-Agent 标识 +ASSET_SCANNER_USER_AGENTS = { + # 知名资产测绘平台 + "shodan", + "censys", + "zoomeye", + "fofa", + "quake", + "hunter", + "binaryedge", + "onyphe", + "securitytrails", + "virustotal", + "passivetotal", + # 安全扫描工具 + "acunetix", + "appscan", + "burpsuite", + "nessus", + "openvas", + "qualys", + "rapid7", + "tenable", + "veracode", + "zap", + "awvs", # Acunetix Web Vulnerability Scanner + "netsparker", + "skipfish", + "w3af", + "arachni", + # 其他扫描工具 + "masscan", + "zmap", + "nmap", + "whatweb", + "wpscan", + "joomscan", + "dnsenum", + "subfinder", + "amass", + "sublist3r", + "theharvester", +} + +# 资产测绘工具常用的HTTP头标识 +ASSET_SCANNER_HEADERS = { + # 常见的扫描工具自定义头 + "x-scan": {"shodan", "censys", "zoomeye", "fofa"}, + "x-scanner": {"nmap", "masscan", "zmap"}, + "x-probe": {"masscan", "zmap"}, + # 其他可疑头(移除反向代理标准头) + "x-originating-ip": set(), + "x-remote-ip": set(), + "x-remote-addr": set(), + # 注意:移除了以下反向代理标准头以避免误报: + # - "x-forwarded-proto" (反向代理标准头) + # - "x-real-ip" (反向代理标准头,已在_get_client_ip中使用) +} + +# 仅检查特定HTTP头中的可疑模式(收紧匹配范围) +# 只检查这些特定头,不检查所有头 +SCANNER_SPECIFIC_HEADERS = { + "x-scan", + "x-scanner", + "x-probe", + "x-originating-ip", + "x-remote-ip", + "x-remote-addr", +} + +# 防爬虫模式配置 +# false: 禁用 +# strict: 严格模式(更严格的检测,更低的频率限制) +# loose: 宽松模式(较宽松的检测,较高的频率限制) +# basic: 基础模式(只记录恶意访问,不阻止,不限制请求数,不跟踪IP) + +# IP白名单配置(从配置文件读取,逗号分隔) +# 支持格式: +# - 精确IP:127.0.0.1, 192.168.1.100 +# - CIDR格式:192.168.1.0/24, 172.17.0.0/16 (适用于Docker网络) +# - 通配符:192.168.*.*, 10.*.*.*, *.*.*.* (匹配所有) +# - IPv6:::1, 2001:db8::/32 +def _parse_allowed_ips(ip_string: str) -> list: + """ + 解析IP白名单字符串,支持精确IP、CIDR格式和通配符 + + Args: + ip_string: 逗号分隔的IP字符串 + + Returns: + IP白名单列表,每个元素可能是: + - ipaddress.IPv4Network/IPv6Network对象(CIDR格式) + - ipaddress.IPv4Address/IPv6Address对象(精确IP) + - str(通配符模式,已转换为正则表达式) + """ + allowed = [] + if not ip_string: + return allowed + + for ip_entry in ip_string.split(","): + ip_entry = ip_entry.strip() # 去除空格 + if not ip_entry: + continue + + # 跳过注释行(以#开头) + if ip_entry.startswith("#"): + continue + + # 检查通配符格式(包含*) + if "*" in ip_entry: + # 处理通配符 + pattern = _convert_wildcard_to_regex(ip_entry) + if pattern: + allowed.append(pattern) + else: + logger.warning(f"无效的通配符IP格式,已忽略: {ip_entry}") + continue + + try: + # 尝试解析为CIDR格式(包含/) + if "/" in ip_entry: + allowed.append(ipaddress.ip_network(ip_entry, strict=False)) + else: + # 精确IP地址 + allowed.append(ipaddress.ip_address(ip_entry)) + except (ValueError, AttributeError) as e: + logger.warning(f"无效的IP白名单条目,已忽略: {ip_entry} ({e})") + + return allowed + + +def _convert_wildcard_to_regex(wildcard_pattern: str) -> Optional[str]: + """ + 将通配符IP模式转换为正则表达式 + + 支持的格式: + - 192.168.*.* 或 192.168.* + - 10.*.*.* 或 10.* + - *.*.*.* 或 * + + Args: + wildcard_pattern: 通配符模式字符串 + + Returns: + 正则表达式字符串,如果格式无效则返回None + """ + # 去除空格 + pattern = wildcard_pattern.strip() + + # 处理单个*(匹配所有) + if pattern == "*": + return r".*" + + # 处理IPv4通配符格式 + # 支持:192.168.*.*, 192.168.*, 10.*.*.*, 10.* 等 + parts = pattern.split(".") + + if len(parts) > 4: + return None # IPv4最多4段 + + # 构建正则表达式 + regex_parts = [] + for part in parts: + part = part.strip() + if part == "*": + regex_parts.append(r"\d+") # 匹配任意数字 + elif part.isdigit(): + # 验证数字范围(0-255) + num = int(part) + if 0 <= num <= 255: + regex_parts.append(re.escape(part)) + else: + return None # 无效的数字 + else: + return None # 无效的格式 + + # 如果部分少于4段,补充.* + while len(regex_parts) < 4: + regex_parts.append(r"\d+") + + # 组合成正则表达式 + regex = r"^" + r"\.".join(regex_parts) + r"$" + return regex + + +# 从配置读取防爬虫设置(延迟导入避免循环依赖) +def _get_anti_crawler_config(): + """获取防爬虫配置""" + from src.config.config import global_config + return { + 'mode': global_config.webui.anti_crawler_mode, + 'allowed_ips': _parse_allowed_ips(global_config.webui.allowed_ips), + 'trusted_proxies': _parse_allowed_ips(global_config.webui.trusted_proxies), + 'trust_xff': global_config.webui.trust_xff + } + +# 初始化配置(将在模块加载时执行) +_config = _get_anti_crawler_config() +ANTI_CRAWLER_MODE = _config['mode'] +ALLOWED_IPS = _config['allowed_ips'] +TRUSTED_PROXIES = _config['trusted_proxies'] +TRUST_XFF = _config['trust_xff'] + + +def _get_mode_config(mode: str) -> dict: + """ + 根据模式获取配置参数 + + Args: + mode: 防爬虫模式 (false/strict/loose/basic) + + Returns: + 配置字典,包含所有相关参数 + """ + mode = mode.lower() + + if mode == "false": + return { + "enabled": False, + "rate_limit_window": 60, + "rate_limit_max_requests": 1000, # 禁用时设置很高的值 + "max_tracked_ips": 0, + "check_user_agent": False, + "check_asset_scanner": False, + "check_rate_limit": False, + "block_on_detect": False, # 不阻止 + } + elif mode == "strict": + return { + "enabled": True, + "rate_limit_window": 60, + "rate_limit_max_requests": 15, # 严格模式:更低的请求数 + "max_tracked_ips": 20000, + "check_user_agent": True, + "check_asset_scanner": True, + "check_rate_limit": True, + "block_on_detect": True, # 阻止恶意访问 + } + elif mode == "loose": + return { + "enabled": True, + "rate_limit_window": 60, + "rate_limit_max_requests": 60, # 宽松模式:更高的请求数 + "max_tracked_ips": 5000, + "check_user_agent": True, + "check_asset_scanner": True, + "check_rate_limit": True, + "block_on_detect": True, # 阻止恶意访问 + } + else: # basic (默认模式) + return { + "enabled": True, + "rate_limit_window": 60, + "rate_limit_max_requests": 1000, # 不限制请求数 + "max_tracked_ips": 0, # 不跟踪IP + "check_user_agent": True, # 检测但不阻止 + "check_asset_scanner": True, # 检测但不阻止 + "check_rate_limit": False, # 不限制请求频率 + "block_on_detect": False, # 只记录,不阻止 + } + + +class AntiCrawlerMiddleware(BaseHTTPMiddleware): + """防爬虫中间件""" + + def __init__(self, app, mode: str = "standard"): + """ + 初始化防爬虫中间件 + + Args: + app: FastAPI 应用实例 + mode: 防爬虫模式 (false/strict/loose/standard) + """ + super().__init__(app) + self.mode = mode.lower() + # 根据模式获取配置 + config = _get_mode_config(self.mode) + self.enabled = config["enabled"] + self.rate_limit_window = config["rate_limit_window"] + self.rate_limit_max_requests = config["rate_limit_max_requests"] + self.max_tracked_ips = config["max_tracked_ips"] + self.check_user_agent = config["check_user_agent"] + self.check_asset_scanner = config["check_asset_scanner"] + self.check_rate_limit = config["check_rate_limit"] + self.block_on_detect = config["block_on_detect"] # 是否阻止检测到的恶意访问 + + # 用于存储每个IP的请求时间戳(使用deque提高性能) + self.request_times: dict[str, deque] = {} + # 上次清理时间 + self.last_cleanup = time.time() + # 将关键词列表转换为集合以提高查找性能 + self.crawler_keywords_set = set(CRAWLER_USER_AGENTS) + self.scanner_keywords_set = set(ASSET_SCANNER_USER_AGENTS) + + def _is_crawler_user_agent(self, user_agent: Optional[str]) -> bool: + """ + 检测是否为爬虫 User-Agent + + Args: + user_agent: User-Agent 字符串 + + Returns: + 如果是爬虫则返回 True + """ + if not user_agent: + # 没有 User-Agent 的请求记录日志但不直接阻止 + # 改为只记录,让频率限制来处理 + logger.debug("请求缺少User-Agent") + return False # 不再直接阻止无User-Agent的请求 + + user_agent_lower = user_agent.lower() + + # 使用集合查找提高性能(检查是否包含爬虫关键词) + for crawler_keyword in self.crawler_keywords_set: + if crawler_keyword in user_agent_lower: + return True + + return False + + def _is_asset_scanner_header(self, request: Request) -> bool: + """ + 检测是否为资产测绘工具的HTTP头(只检查特定头,收紧匹配) + + Args: + request: 请求对象 + + Returns: + 如果检测到资产测绘工具头则返回 True + """ + # 只检查特定的扫描工具头,不检查所有头 + for header_name, header_value in request.headers.items(): + header_name_lower = header_name.lower() + header_value_lower = header_value.lower() if header_value else "" + + # 检查已知的扫描工具头 + if header_name_lower in ASSET_SCANNER_HEADERS: + # 如果该头有特定的工具集合,检查值是否匹配 + expected_tools = ASSET_SCANNER_HEADERS[header_name_lower] + if expected_tools: + for tool in expected_tools: + if tool in header_value_lower: + return True + else: + # 如果没有特定工具集合,只要存在该头就视为可疑 + if header_value_lower: + return True + + # 只检查特定头中的可疑模式(收紧匹配) + if header_name_lower in SCANNER_SPECIFIC_HEADERS: + # 检查头值中是否包含已知扫描工具名称 + for tool in self.scanner_keywords_set: + if tool in header_value_lower: + return True + + return False + + def _detect_asset_scanner(self, request: Request) -> tuple[bool, Optional[str]]: + """ + 检测资产测绘工具 + + Args: + request: 请求对象 + + Returns: + (是否检测到, 检测到的工具名称) + """ + user_agent = request.headers.get("User-Agent") + + # 检查 User-Agent(使用集合查找提高性能) + if user_agent: + user_agent_lower = user_agent.lower() + for scanner_keyword in self.scanner_keywords_set: + if scanner_keyword in user_agent_lower: + return True, scanner_keyword + + # 检查HTTP头 + if self._is_asset_scanner_header(request): + # 尝试从User-Agent或头中提取工具名称 + detected_tool = None + if user_agent: + user_agent_lower = user_agent.lower() + for tool in self.scanner_keywords_set: + if tool in user_agent_lower: + detected_tool = tool + break + + # 检查HTTP头中的工具标识(只检查特定头) + if not detected_tool: + for header_name, header_value in request.headers.items(): + header_name_lower = header_name.lower() + if header_name_lower in SCANNER_SPECIFIC_HEADERS: + header_value_lower = (header_value or "").lower() + for tool in self.scanner_keywords_set: + if tool in header_value_lower: + detected_tool = tool + break + if detected_tool: + break + + return True, detected_tool or "unknown_scanner" + + return False, None + + def _check_rate_limit(self, client_ip: str) -> bool: + """ + 检查请求频率限制 + + Args: + client_ip: 客户端IP地址 + + Returns: + 如果超过限制则返回 True(需要阻止) + """ + # 检查IP白名单 + if self._is_ip_allowed(client_ip): + return False + + current_time = time.time() + + # 定期清理过期的请求记录(每5分钟清理一次) + if current_time - self.last_cleanup > 300: + self._cleanup_old_requests(current_time) + self.last_cleanup = current_time + + # 限制跟踪的IP数量,防止内存泄漏 + if self.max_tracked_ips > 0 and len(self.request_times) > self.max_tracked_ips: + # 清理最旧的记录(删除最久未访问的IP) + self._cleanup_oldest_ips() + + # 获取或创建该IP的请求时间deque(不使用maxlen,避免限流变松) + if client_ip not in self.request_times: + self.request_times[client_ip] = deque() + + request_times = self.request_times[client_ip] + + # 移除时间窗口外的请求记录(从左侧弹出过期记录) + while request_times and current_time - request_times[0] >= self.rate_limit_window: + request_times.popleft() + + # 检查是否超过限制 + if len(request_times) >= self.rate_limit_max_requests: + return True + + # 记录当前请求时间 + request_times.append(current_time) + return False + + def _cleanup_old_requests(self, current_time: float): + """清理过期的请求记录(只清理当前需要检查的IP,不全量遍历)""" + # 这个方法现在主要用于定期清理,实际清理在_check_rate_limit中按需进行 + # 清理最久未访问的IP记录 + if len(self.request_times) > self.max_tracked_ips * 0.8: + self._cleanup_oldest_ips() + + def _cleanup_oldest_ips(self): + """清理最久未访问的IP记录(全量遍历找真正的oldest)""" + if not self.request_times: + return + + # 先收集空deque的IP(优先删除) + empty_ips = [] + # 找到最久未访问的IP(最旧时间戳) + oldest_ip = None + oldest_time = float("inf") + + # 全量遍历找真正的oldest(超限时性能可接受) + for ip, times in self.request_times.items(): + if not times: + # 空deque,记录待删除 + empty_ips.append(ip) + else: + # 找到最旧的时间戳 + if times[0] < oldest_time: + oldest_time = times[0] + oldest_ip = ip + + # 先删除空deque的IP + for ip in empty_ips: + del self.request_times[ip] + + # 如果没有空deque可删除,且仍需要清理,删除最旧的一个IP + if not empty_ips and oldest_ip: + del self.request_times[oldest_ip] + + def _is_trusted_proxy(self, ip: str) -> bool: + """ + 检查IP是否在信任的代理列表中 + + Args: + ip: IP地址字符串 + + Returns: + 如果是信任的代理则返回 True + """ + if not TRUSTED_PROXIES or ip == "unknown": + return False + + # 检查代理列表中的每个条目 + for trusted_entry in TRUSTED_PROXIES: + # 通配符模式(字符串,正则表达式) + if isinstance(trusted_entry, str): + try: + if re.match(trusted_entry, ip): + return True + except re.error: + continue + # CIDR格式(网络对象) + elif isinstance(trusted_entry, (ipaddress.IPv4Network, ipaddress.IPv6Network)): + try: + client_ip_obj = ipaddress.ip_address(ip) + if client_ip_obj in trusted_entry: + return True + except (ValueError, AttributeError): + continue + # 精确IP(地址对象) + elif isinstance(trusted_entry, (ipaddress.IPv4Address, ipaddress.IPv6Address)): + try: + client_ip_obj = ipaddress.ip_address(ip) + if client_ip_obj == trusted_entry: + return True + except (ValueError, AttributeError): + continue + + return False + + def _get_client_ip(self, request: Request) -> str: + """ + 获取客户端真实IP地址(带基本验证和代理信任检查) + + Args: + request: 请求对象 + + Returns: + 客户端IP地址 + """ + # 获取直接连接的客户端IP(用于验证代理) + direct_client_ip = None + if request.client: + direct_client_ip = request.client.host + + # 检查是否信任X-Forwarded-For头 + # TRUST_XFF 只表示"启用代理解析能力",但仍要求直连 IP 在 TRUSTED_PROXIES 中 + use_xff = False + if TRUST_XFF and TRUSTED_PROXIES and direct_client_ip: + # 只有在启用 TRUST_XFF 且直连 IP 在信任列表中时,才信任 XFF + use_xff = self._is_trusted_proxy(direct_client_ip) + + # 如果信任代理,优先从 X-Forwarded-For 获取 + if use_xff: + forwarded_for = request.headers.get("X-Forwarded-For") + if forwarded_for: + # X-Forwarded-For 可能包含多个IP,取第一个 + ip = forwarded_for.split(",")[0].strip() + # 基本验证IP格式 + if self._validate_ip(ip): + return ip + + # 从 X-Real-IP 获取(如果信任代理) + if use_xff: + real_ip = request.headers.get("X-Real-IP") + if real_ip: + ip = real_ip.strip() + if self._validate_ip(ip): + return ip + + # 使用直接连接的客户端IP + if direct_client_ip and self._validate_ip(direct_client_ip): + return direct_client_ip + + return "unknown" + + def _validate_ip(self, ip: str) -> bool: + """ + 验证IP地址格式 + + Args: + ip: IP地址字符串 + + Returns: + 如果格式有效则返回 True + """ + try: + ipaddress.ip_address(ip) + return True + except (ValueError, AttributeError): + return False + + def _is_ip_allowed(self, ip: str) -> bool: + """ + 检查IP是否在白名单中(支持精确IP、CIDR格式和通配符) + + Args: + ip: 客户端IP地址 + + Returns: + 如果IP在白名单中则返回 True + """ + if not ALLOWED_IPS or ip == "unknown": + return False + + # 检查白名单中的每个条目 + for allowed_entry in ALLOWED_IPS: + # 通配符模式(字符串,正则表达式) + if isinstance(allowed_entry, str): + try: + if re.match(allowed_entry, ip): + return True + except re.error: + # 正则表达式错误,跳过 + continue + # CIDR格式(网络对象) + elif isinstance(allowed_entry, (ipaddress.IPv4Network, ipaddress.IPv6Network)): + try: + client_ip_obj = ipaddress.ip_address(ip) + if client_ip_obj in allowed_entry: + return True + except (ValueError, AttributeError): + # IP格式无效,跳过 + continue + # 精确IP(地址对象) + elif isinstance(allowed_entry, (ipaddress.IPv4Address, ipaddress.IPv6Address)): + try: + client_ip_obj = ipaddress.ip_address(ip) + if client_ip_obj == allowed_entry: + return True + except (ValueError, AttributeError): + # IP格式无效,跳过 + continue + + return False + + async def dispatch(self, request: Request, call_next): + """ + 处理请求 + + Args: + request: 请求对象 + call_next: 下一个中间件或路由处理函数 + + Returns: + 响应对象 + """ + # 如果未启用,直接通过 + if not self.enabled: + return await call_next(request) + + # 允许访问 robots.txt(由专门的路由处理) + if request.url.path == "/robots.txt": + return await call_next(request) + + # 允许访问静态资源(CSS、JS、图片等) + # 注意:.json 已移除,避免 API 路径绕过防护 + # 静态资源只在特定前缀下放行(/static/、/assets/、/dist/) + static_extensions = { + ".css", + ".js", + ".png", + ".jpg", + ".jpeg", + ".gif", + ".svg", + ".ico", + ".woff", + ".woff2", + ".ttf", + ".eot", + } + static_prefixes = {"/static/", "/assets/", "/dist/"} + + # 检查是否是静态资源路径(特定前缀下的静态文件) + path = request.url.path + is_static_path = any(path.startswith(prefix) for prefix in static_prefixes) and any( + path.endswith(ext) for ext in static_extensions + ) + + # 也允许根路径下的静态文件(如 /favicon.ico) + is_root_static = path.count("/") == 1 and any(path.endswith(ext) for ext in static_extensions) + + if is_static_path or is_root_static: + return await call_next(request) + + # 获取客户端IP(只获取一次,避免重复调用) + client_ip = self._get_client_ip(request) + + # 检查IP白名单(优先检查,白名单IP直接通过) + if self._is_ip_allowed(client_ip): + return await call_next(request) + + # 获取 User-Agent + user_agent = request.headers.get("User-Agent") + + # 检测资产测绘工具(优先检测,因为更危险) + if self.check_asset_scanner: + is_scanner, scanner_name = self._detect_asset_scanner(request) + if is_scanner: + logger.warning( + f"🚫 检测到资产测绘工具请求 - IP: {client_ip}, 工具: {scanner_name}, " + f"User-Agent: {user_agent}, Path: {request.url.path}" + ) + # 根据配置决定是否阻止 + if self.block_on_detect: + return PlainTextResponse( + "Access Denied: Asset scanning tools are not allowed", + status_code=403, + ) + + # 检测爬虫 User-Agent + if self.check_user_agent and self._is_crawler_user_agent(user_agent): + logger.warning(f"🚫 检测到爬虫请求 - IP: {client_ip}, User-Agent: {user_agent}, Path: {request.url.path}") + # 根据配置决定是否阻止 + if self.block_on_detect: + return PlainTextResponse( + "Access Denied: Crawlers are not allowed", + status_code=403, + ) + + # 检查请求频率限制 + if self.check_rate_limit and self._check_rate_limit(client_ip): + logger.warning(f"🚫 请求频率过高 - IP: {client_ip}, User-Agent: {user_agent}, Path: {request.url.path}") + return PlainTextResponse( + "Too Many Requests: Rate limit exceeded", + status_code=429, + ) + + # 正常请求,继续处理 + return await call_next(request) + + +def create_robots_txt_response() -> PlainTextResponse: + """ + 创建 robots.txt 响应 + + Returns: + robots.txt 响应对象 + """ + robots_content = """User-agent: * +Disallow: / + +# 禁止所有爬虫访问 +""" + return PlainTextResponse( + content=robots_content, + media_type="text/plain", + headers={"Cache-Control": "public, max-age=86400"}, # 缓存24小时 + ) diff --git a/src/webui/auth.py b/src/webui/auth.py new file mode 100644 index 00000000..db0fc675 --- /dev/null +++ b/src/webui/auth.py @@ -0,0 +1,183 @@ +""" +WebUI 认证模块 +提供统一的认证依赖,支持 Cookie 和 Header 两种方式 +""" + +from typing import Optional +from fastapi import HTTPException, Cookie, Header, Response, Request +from src.common.logger import get_logger +from src.config.config import global_config +from .token_manager import get_token_manager + +logger = get_logger("webui.auth") + +# Cookie 配置 +COOKIE_NAME = "maibot_session" +COOKIE_MAX_AGE = 7 * 24 * 60 * 60 # 7天 + + +def _is_secure_environment() -> bool: + """ + 检测是否应该启用安全 Cookie(HTTPS) + + Returns: + bool: 如果应该使用 secure cookie 则返回 True + """ + # 从配置读取 + if global_config.webui.secure_cookie: + logger.info("配置中启用了 secure_cookie") + return True + + # 检查是否是生产环境 + if global_config.webui.mode == "production": + logger.info("WebUI运行在生产模式,启用 secure cookie") + return True + + # 默认:开发环境不启用(因为通常是 HTTP) + logger.debug("WebUI运行在开发模式,禁用 secure cookie") + return False + + +def get_current_token( + request: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> str: + """ + 获取当前请求的 token,优先从 Cookie 获取,其次从 Header 获取 + + Args: + request: FastAPI Request 对象 + maibot_session: Cookie 中的 token + authorization: Authorization Header (Bearer token) + + Returns: + 验证通过的 token + + Raises: + HTTPException: 认证失败时抛出 401 错误 + """ + token = None + + # 优先从 Cookie 获取 + if maibot_session: + token = maibot_session + # 其次从 Header 获取(兼容旧版本) + elif authorization and authorization.startswith("Bearer "): + token = authorization.replace("Bearer ", "") + + if not token: + raise HTTPException(status_code=401, detail="未提供有效的认证信息") + + # 验证 token + token_manager = get_token_manager() + if not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="Token 无效或已过期") + + return token + + +def set_auth_cookie(response: Response, token: str, request: Optional[Request] = None) -> None: + """ + 设置认证 Cookie + + Args: + response: FastAPI Response 对象 + token: 要设置的 token + request: FastAPI Request 对象(可选,用于检测协议) + """ + # 根据环境和实际请求协议决定安全设置 + is_secure = _is_secure_environment() + + # 如果提供了 request,检测实际使用的协议 + if request: + # 检查 X-Forwarded-Proto header(代理/负载均衡器) + forwarded_proto = request.headers.get("x-forwarded-proto", "").lower() + if forwarded_proto: + is_https = forwarded_proto == "https" + logger.debug(f"检测到 X-Forwarded-Proto: {forwarded_proto}, is_https={is_https}") + else: + # 检查 request.url.scheme + is_https = request.url.scheme == "https" + logger.debug(f"检测到 scheme: {request.url.scheme}, is_https={is_https}") + + # 如果是 HTTP 连接,强制禁用 secure 标志 + if not is_https and is_secure: + logger.warning("=" * 80) + logger.warning("检测到 HTTP 连接但环境配置要求 HTTPS (secure cookie)") + logger.warning("已自动禁用 secure 标志以允许登录,但建议修改配置:") + logger.warning("1. 在配置文件中设置: webui.secure_cookie = false") + logger.warning("2. 如果使用反向代理,请确保正确配置 X-Forwarded-Proto 头") + logger.warning("=" * 80) + is_secure = False + + # 设置 Cookie + response.set_cookie( + key=COOKIE_NAME, + value=token, + max_age=COOKIE_MAX_AGE, + httponly=True, # 防止 JS 读取,阻止 XSS 窃取 + samesite="lax", # 使用 lax 以兼容更多场景(开发和生产) + secure=is_secure, # 根据实际协议决定 + path="/", # 确保 Cookie 在所有路径下可用 + ) + + logger.info(f"已设置认证 Cookie: {token[:8]}... (secure={is_secure}, samesite=lax, httponly=True, path=/, max_age={COOKIE_MAX_AGE})") + logger.debug(f"完整 token 前缀: {token[:20]}...") + + +def clear_auth_cookie(response: Response) -> None: + """ + 清除认证 Cookie + + Args: + response: FastAPI Response 对象 + """ + # 保持与 set_auth_cookie 相同的安全设置 + is_secure = _is_secure_environment() + + response.delete_cookie( + key=COOKIE_NAME, + httponly=True, + samesite="strict" if is_secure else "lax", + secure=is_secure, + path="/", + ) + logger.debug("已清除认证 Cookie") + + +def verify_auth_token_from_cookie_or_header( + maibot_session: Optional[str] = None, + authorization: Optional[str] = None, +) -> bool: + """ + 验证认证 Token,支持从 Cookie 或 Header 获取 + + Args: + maibot_session: Cookie 中的 token + authorization: Authorization header (Bearer token) + + Returns: + 验证成功返回 True + + Raises: + HTTPException: 认证失败时抛出 401 错误 + """ + token = None + + # 优先从 Cookie 获取 + if maibot_session: + token = maibot_session + # 其次从 Header 获取(兼容旧版本) + elif authorization and authorization.startswith("Bearer "): + token = authorization.replace("Bearer ", "") + + if not token: + raise HTTPException(status_code=401, detail="未提供有效的认证信息") + + # 验证 token + token_manager = get_token_manager() + if not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="Token 无效或已过期") + + return True diff --git a/src/webui/chat_routes.py b/src/webui/chat_routes.py new file mode 100644 index 00000000..6535b9e9 --- /dev/null +++ b/src/webui/chat_routes.py @@ -0,0 +1,782 @@ +"""本地聊天室路由 - WebUI 与麦麦直接对话 + +支持两种模式: +1. WebUI 模式:使用 WebUI 平台独立身份聊天 +2. 虚拟身份模式:使用真实平台用户的身份,在虚拟群聊中与麦麦对话 +""" + +import time +import uuid +from typing import Dict, Any, Optional, List +from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query, Depends, Cookie, Header +from pydantic import BaseModel + +from src.common.logger import get_logger +from src.common.database.database_model import Messages, PersonInfo +from src.config.config import global_config +from src.chat.message_receive.bot import chat_bot +from src.webui.auth import verify_auth_token_from_cookie_or_header +from src.webui.token_manager import get_token_manager +from src.webui.ws_auth import verify_ws_token + +logger = get_logger("webui.chat") + +router = APIRouter(prefix="/api/chat", tags=["LocalChat"]) + + +def require_auth( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> bool: + """认证依赖:验证用户是否已登录""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) + + +# WebUI 聊天的虚拟群组 ID +WEBUI_CHAT_GROUP_ID = "webui_local_chat" +WEBUI_CHAT_PLATFORM = "webui" + +# 虚拟身份模式的群 ID 前缀 +VIRTUAL_GROUP_ID_PREFIX = "webui_virtual_group_" + +# 固定的 WebUI 用户 ID 前缀 +WEBUI_USER_ID_PREFIX = "webui_user_" + + +class VirtualIdentityConfig(BaseModel): + """虚拟身份配置""" + + enabled: bool = False # 是否启用虚拟身份模式 + platform: Optional[str] = None # 目标平台(如 qq, discord 等) + person_id: Optional[str] = None # PersonInfo 的 person_id + user_id: Optional[str] = None # 原始平台用户 ID + user_nickname: Optional[str] = None # 用户昵称 + group_id: Optional[str] = None # 虚拟群 ID(自动生成或用户指定) + group_name: Optional[str] = None # 虚拟群名(用户自定义) + + +class ChatHistoryMessage(BaseModel): + """聊天历史消息""" + + id: str + type: str # 'user' | 'bot' | 'system' + content: str + timestamp: float + sender_name: str + sender_id: Optional[str] = None + is_bot: bool = False + + +class ChatHistoryManager: + """聊天历史管理器 - 使用 SQLite 数据库存储""" + + def __init__(self, max_messages: int = 200): + self.max_messages = max_messages + + def _message_to_dict(self, msg: Messages, group_id: Optional[str] = None) -> Dict[str, Any]: + """将数据库消息转换为前端格式 + + Args: + msg: 数据库消息对象 + group_id: 群 ID,用于判断是否是虚拟群 + """ + # 判断是否是机器人消息 + user_id = msg.user_id or "" + + # 对于虚拟群,通过比较机器人 QQ 账号来判断 + # 对于普通 WebUI 群,检查 user_id 是否以 webui_ 开头 + if group_id and group_id.startswith(VIRTUAL_GROUP_ID_PREFIX): + # 虚拟群:user_id 等于机器人 QQ 账号的是机器人消息 + bot_qq = str(global_config.bot.qq_account) + is_bot = user_id == bot_qq + else: + # 普通 WebUI 群:不以 webui_ 开头的是机器人消息 + is_bot = not user_id.startswith("webui_") and not user_id.startswith(WEBUI_USER_ID_PREFIX) + + return { + "id": msg.message_id, + "type": "bot" if is_bot else "user", + "content": msg.processed_plain_text or msg.display_message or "", + "timestamp": msg.time, + "sender_name": msg.user_nickname or (global_config.bot.nickname if is_bot else "未知用户"), + "sender_id": "bot" if is_bot else user_id, + "is_bot": is_bot, + } + + def get_history(self, limit: int = 50, group_id: Optional[str] = None) -> List[Dict[str, Any]]: + """从数据库获取最近的历史记录 + + Args: + limit: 获取的消息数量 + group_id: 群 ID,默认为 WEBUI_CHAT_GROUP_ID + """ + target_group_id = group_id if group_id else WEBUI_CHAT_GROUP_ID + try: + # 查询指定群的消息,按时间排序 + messages = ( + Messages.select() + .where(Messages.chat_info_group_id == target_group_id) + .order_by(Messages.time.desc()) + .limit(limit) + ) + + # 转换为列表并反转(使最旧的消息在前) + # 传递 group_id 以便正确判断虚拟群中的机器人消息 + result = [self._message_to_dict(msg, target_group_id) for msg in messages] + result.reverse() + + logger.debug(f"从数据库加载了 {len(result)} 条聊天记录 (group_id={target_group_id})") + return result + except Exception as e: + logger.error(f"从数据库加载聊天记录失败: {e}") + return [] + + def clear_history(self, group_id: Optional[str] = None) -> int: + """清空聊天历史记录 + + Args: + group_id: 群 ID,默认清空 WebUI 默认聊天室 + """ + target_group_id = group_id if group_id else WEBUI_CHAT_GROUP_ID + try: + deleted = Messages.delete().where(Messages.chat_info_group_id == target_group_id).execute() + logger.info(f"已清空 {deleted} 条聊天记录 (group_id={target_group_id})") + return deleted + except Exception as e: + logger.error(f"清空聊天记录失败: {e}") + return 0 + + +# 全局聊天历史管理器 +chat_history = ChatHistoryManager() + + +# 存储 WebSocket 连接 +class ChatConnectionManager: + """聊天连接管理器""" + + def __init__(self): + self.active_connections: Dict[str, WebSocket] = {} + self.user_sessions: Dict[str, str] = {} # user_id -> session_id 映射 + + async def connect(self, websocket: WebSocket, session_id: str, user_id: str): + await websocket.accept() + self.active_connections[session_id] = websocket + self.user_sessions[user_id] = session_id + logger.info(f"WebUI 聊天会话已连接: session={session_id}, user={user_id}") + + def disconnect(self, session_id: str, user_id: str): + if session_id in self.active_connections: + del self.active_connections[session_id] + if user_id in self.user_sessions and self.user_sessions[user_id] == session_id: + del self.user_sessions[user_id] + logger.info(f"WebUI 聊天会话已断开: session={session_id}") + + async def send_message(self, session_id: str, message: dict): + if session_id in self.active_connections: + try: + await self.active_connections[session_id].send_json(message) + except Exception as e: + logger.error(f"发送消息失败: {e}") + + async def broadcast(self, message: dict): + """广播消息给所有连接""" + for session_id in list(self.active_connections.keys()): + await self.send_message(session_id, message) + + +chat_manager = ChatConnectionManager() + + +def create_message_data( + content: str, + user_id: str, + user_name: str, + message_id: Optional[str] = None, + is_at_bot: bool = True, + virtual_config: Optional[VirtualIdentityConfig] = None, +) -> Dict[str, Any]: + """创建符合麦麦消息格式的消息数据 + + Args: + content: 消息内容 + user_id: 用户 ID + user_name: 用户昵称 + message_id: 消息 ID(可选,自动生成) + is_at_bot: 是否 @ 机器人 + virtual_config: 虚拟身份配置(可选,启用后使用真实平台身份) + """ + if message_id is None: + message_id = str(uuid.uuid4()) + + # 确定使用的平台、群信息和用户信息 + if virtual_config and virtual_config.enabled: + # 虚拟身份模式:使用真实平台身份 + platform = virtual_config.platform or WEBUI_CHAT_PLATFORM + group_id = virtual_config.group_id or f"{VIRTUAL_GROUP_ID_PREFIX}{uuid.uuid4().hex[:8]}" + group_name = virtual_config.group_name or "WebUI虚拟群聊" + actual_user_id = virtual_config.user_id or user_id + actual_user_name = virtual_config.user_nickname or user_name + else: + # 标准 WebUI 模式 + platform = WEBUI_CHAT_PLATFORM + group_id = WEBUI_CHAT_GROUP_ID + group_name = "WebUI本地聊天室" + actual_user_id = user_id + actual_user_name = user_name + + return { + "message_info": { + "platform": platform, + "message_id": message_id, + "time": time.time(), + "group_info": { + "group_id": group_id, + "group_name": group_name, + "platform": platform, + }, + "user_info": { + "user_id": actual_user_id, + "user_nickname": actual_user_name, + "user_cardname": actual_user_name, + "platform": platform, + }, + "additional_config": { + "at_bot": is_at_bot, + }, + }, + "message_segment": { + "type": "seglist", + "data": [ + { + "type": "text", + "data": content, + }, + { + "type": "mention_bot", + "data": "1.0", + }, + ], + }, + "raw_message": content, + "processed_plain_text": content, + } + + +@router.get("/history") +async def get_chat_history( + limit: int = Query(default=50, ge=1, le=200), + user_id: Optional[str] = Query(default=None), # 保留参数兼容性,但不用于过滤 + group_id: Optional[str] = Query(default=None), # 可选:指定群 ID 获取历史 + _auth: bool = Depends(require_auth), +): + """获取聊天历史记录 + + 所有 WebUI 用户共享同一个聊天室,因此返回所有历史记录 + 如果指定了 group_id,则获取该虚拟群的历史记录 + """ + target_group_id = group_id if group_id else WEBUI_CHAT_GROUP_ID + history = chat_history.get_history(limit, target_group_id) + return { + "success": True, + "messages": history, + "total": len(history), + } + + +@router.get("/platforms") +async def get_available_platforms(_auth: bool = Depends(require_auth)): + """获取可用平台列表 + + 从 PersonInfo 表中获取所有已知的平台 + """ + try: + from peewee import fn + + # 查询所有不同的平台 + platforms = ( + PersonInfo.select(PersonInfo.platform, fn.COUNT(PersonInfo.id).alias("count")) + .group_by(PersonInfo.platform) + .order_by(fn.COUNT(PersonInfo.id).desc()) + ) + + result = [] + for p in platforms: + if p.platform: # 排除空平台 + result.append({"platform": p.platform, "count": p.count}) + + return {"success": True, "platforms": result} + except Exception as e: + logger.error(f"获取平台列表失败: {e}") + return {"success": False, "error": str(e), "platforms": []} + + +@router.get("/persons") +async def get_persons_by_platform( + platform: str = Query(..., description="平台名称"), + search: Optional[str] = Query(default=None, description="搜索关键词"), + limit: int = Query(default=50, ge=1, le=200), + _auth: bool = Depends(require_auth), +): + """获取指定平台的用户列表 + + Args: + platform: 平台名称(如 qq, discord 等) + search: 搜索关键词(匹配昵称、用户名、user_id) + limit: 返回数量限制 + """ + try: + # 构建查询 + query = PersonInfo.select().where(PersonInfo.platform == platform) + + # 搜索过滤 + if search: + query = query.where( + (PersonInfo.person_name.contains(search)) + | (PersonInfo.nickname.contains(search)) + | (PersonInfo.user_id.contains(search)) + ) + + # 按最后交互时间排序,优先显示活跃用户 + from peewee import Case + + query = query.order_by(Case(None, [(PersonInfo.last_know.is_null(), 1)], 0), PersonInfo.last_know.desc()) + query = query.limit(limit) + + result = [] + for person in query: + result.append( + { + "person_id": person.person_id, + "user_id": person.user_id, + "person_name": person.person_name, + "nickname": person.nickname, + "is_known": person.is_known, + "platform": person.platform, + "display_name": person.person_name or person.nickname or person.user_id, + } + ) + + return {"success": True, "persons": result, "total": len(result)} + except Exception as e: + logger.error(f"获取用户列表失败: {e}") + return {"success": False, "error": str(e), "persons": []} + + +@router.delete("/history") +async def clear_chat_history(group_id: Optional[str] = Query(default=None), _auth: bool = Depends(require_auth)): + """清空聊天历史记录 + + Args: + group_id: 可选,指定要清空的群 ID,默认清空 WebUI 默认聊天室 + """ + deleted = chat_history.clear_history(group_id) + return { + "success": True, + "message": f"已清空 {deleted} 条聊天记录", + } + + +@router.websocket("/ws") +async def websocket_chat( + websocket: WebSocket, + user_id: Optional[str] = Query(default=None), + user_name: Optional[str] = Query(default="WebUI用户"), + platform: Optional[str] = Query(default=None), + person_id: Optional[str] = Query(default=None), + group_name: Optional[str] = Query(default=None), + group_id: Optional[str] = Query(default=None), # 前端传递的稳定 group_id + token: Optional[str] = Query(default=None), # 认证 token +): + """WebSocket 聊天端点 + + Args: + user_id: 用户唯一标识(由前端生成并持久化) + user_name: 用户显示昵称(可修改) + platform: 虚拟身份模式的平台(可选) + person_id: 虚拟身份模式的用户 person_id(可选) + group_name: 虚拟身份模式的群名(可选) + group_id: 虚拟身份模式的群 ID(可选,由前端生成并持久化) + token: 认证 token(可选,也可从 Cookie 获取) + + 虚拟身份模式可通过 URL 参数直接配置,或通过消息中的 set_virtual_identity 配置 + + 支持三种认证方式(按优先级): + 1. query 参数 token(推荐,通过 /api/webui/ws-token 获取临时 token) + 2. Cookie 中的 maibot_session + 3. 直接使用 session token(兼容) + + 示例:ws://host/api/chat/ws?token=xxx + """ + is_authenticated = False + + # 方式 1: 尝试验证临时 WebSocket token(推荐方式) + if token and verify_ws_token(token): + is_authenticated = True + logger.debug("聊天 WebSocket 使用临时 token 认证成功") + + # 方式 2: 尝试从 Cookie 获取 session token + if not is_authenticated: + cookie_token = websocket.cookies.get("maibot_session") + if cookie_token: + token_manager = get_token_manager() + if token_manager.verify_token(cookie_token): + is_authenticated = True + logger.debug("聊天 WebSocket 使用 Cookie 认证成功") + + # 方式 3: 尝试直接验证 query 参数作为 session token(兼容旧方式) + if not is_authenticated and token: + token_manager = get_token_manager() + if token_manager.verify_token(token): + is_authenticated = True + logger.debug("聊天 WebSocket 使用 session token 认证成功") + + if not is_authenticated: + logger.warning("聊天 WebSocket 连接被拒绝:认证失败") + await websocket.close(code=4001, reason="认证失败,请重新登录") + return + + # 生成会话 ID(每次连接都是新的) + session_id = str(uuid.uuid4()) + + # 如果没有提供 user_id,生成一个新的 + if not user_id: + user_id = f"{WEBUI_USER_ID_PREFIX}{uuid.uuid4().hex[:16]}" + elif not user_id.startswith(WEBUI_USER_ID_PREFIX): + # 确保 user_id 有正确的前缀 + user_id = f"{WEBUI_USER_ID_PREFIX}{user_id}" + + # 当前会话的虚拟身份配置(可通过消息动态更新) + current_virtual_config: Optional[VirtualIdentityConfig] = None + + # 如果 URL 参数中提供了虚拟身份信息,自动配置 + if platform and person_id: + try: + person = PersonInfo.get_or_none(PersonInfo.person_id == person_id) + if person: + # 使用前端传递的 group_id,如果没有则生成一个稳定的 + virtual_group_id = group_id or f"{VIRTUAL_GROUP_ID_PREFIX}{platform}_{person.user_id}" + current_virtual_config = VirtualIdentityConfig( + enabled=True, + platform=person.platform, + person_id=person.person_id, + user_id=person.user_id, + user_nickname=person.person_name or person.nickname or person.user_id, + group_id=virtual_group_id, + group_name=group_name or "WebUI虚拟群聊", + ) + logger.info( + f"虚拟身份模式已通过 URL 参数激活: {current_virtual_config.user_nickname} @ {current_virtual_config.platform}, group_id={virtual_group_id}" + ) + except Exception as e: + logger.warning(f"通过 URL 参数配置虚拟身份失败: {e}") + + await chat_manager.connect(websocket, session_id, user_id) + + try: + # 构建会话信息 + session_info_data = { + "type": "session_info", + "session_id": session_id, + "user_id": user_id, + "user_name": user_name, + "bot_name": global_config.bot.nickname, + } + + # 如果有虚拟身份配置,添加到会话信息中 + if current_virtual_config and current_virtual_config.enabled: + session_info_data["virtual_mode"] = True + session_info_data["group_id"] = current_virtual_config.group_id + session_info_data["virtual_identity"] = { + "platform": current_virtual_config.platform, + "user_id": current_virtual_config.user_id, + "user_nickname": current_virtual_config.user_nickname, + "group_name": current_virtual_config.group_name, + } + + # 发送会话信息(包含用户 ID,前端需要保存) + await chat_manager.send_message(session_id, session_info_data) + + # 发送历史记录(根据模式选择不同的群) + if current_virtual_config and current_virtual_config.enabled: + history = chat_history.get_history(50, current_virtual_config.group_id) + else: + history = chat_history.get_history(50) + if history: + await chat_manager.send_message( + session_id, + { + "type": "history", + "messages": history, + }, + ) + + # 发送欢迎消息(不保存到历史) + if current_virtual_config and current_virtual_config.enabled: + welcome_msg = f"已以 {current_virtual_config.user_nickname} 的身份连接到「{current_virtual_config.group_name}」,开始与 {global_config.bot.nickname} 对话吧!" + else: + welcome_msg = f"已连接到本地聊天室,可以开始与 {global_config.bot.nickname} 对话了!" + + await chat_manager.send_message( + session_id, + { + "type": "system", + "content": welcome_msg, + "timestamp": time.time(), + }, + ) + + while True: + data = await websocket.receive_json() + + if data.get("type") == "message": + content = data.get("content", "").strip() + if not content: + continue + + # 用户可以更新昵称 + current_user_name = data.get("user_name", user_name) + + message_id = str(uuid.uuid4()) + timestamp = time.time() + + # 确定发送者信息(根据是否使用虚拟身份) + if current_virtual_config and current_virtual_config.enabled: + sender_name = current_virtual_config.user_nickname or current_user_name + sender_user_id = current_virtual_config.user_id or user_id + else: + sender_name = current_user_name + sender_user_id = user_id + + # 广播用户消息给所有连接(包括发送者) + # 注意:用户消息会在 chat_bot.message_process 中自动保存到数据库 + await chat_manager.broadcast( + { + "type": "user_message", + "content": content, + "message_id": message_id, + "timestamp": timestamp, + "sender": { + "name": sender_name, + "user_id": sender_user_id, + "is_bot": False, + }, + "virtual_mode": current_virtual_config.enabled if current_virtual_config else False, + } + ) + + # 创建麦麦消息格式 + message_data = create_message_data( + content=content, + user_id=user_id, + user_name=current_user_name, + message_id=message_id, + is_at_bot=True, + virtual_config=current_virtual_config, + ) + + try: + # 显示正在输入状态 + await chat_manager.broadcast( + { + "type": "typing", + "is_typing": True, + } + ) + + # 调用麦麦的消息处理 + await chat_bot.message_process(message_data) + + except Exception as e: + logger.error(f"处理消息时出错: {e}") + await chat_manager.send_message( + session_id, + { + "type": "error", + "content": f"处理消息时出错: {str(e)}", + "timestamp": time.time(), + }, + ) + finally: + await chat_manager.broadcast( + { + "type": "typing", + "is_typing": False, + } + ) + + elif data.get("type") == "ping": + await chat_manager.send_message( + session_id, + { + "type": "pong", + "timestamp": time.time(), + }, + ) + + elif data.get("type") == "update_nickname": + # 允许用户更新昵称 + if new_name := data.get("user_name", "").strip(): + current_user_name = new_name + await chat_manager.send_message( + session_id, + { + "type": "nickname_updated", + "user_name": current_user_name, + "timestamp": time.time(), + }, + ) + + elif data.get("type") == "set_virtual_identity": + # 设置或更新虚拟身份配置 + virtual_data = data.get("config", {}) + if virtual_data.get("enabled"): + # 验证必要字段 + if not virtual_data.get("platform") or not virtual_data.get("person_id"): + await chat_manager.send_message( + session_id, + { + "type": "error", + "content": "虚拟身份配置缺少必要字段: platform 和 person_id", + "timestamp": time.time(), + }, + ) + continue + + # 获取用户信息 + try: + person = PersonInfo.get_or_none(PersonInfo.person_id == virtual_data.get("person_id")) + if not person: + await chat_manager.send_message( + session_id, + { + "type": "error", + "content": f"找不到用户: {virtual_data.get('person_id')}", + "timestamp": time.time(), + }, + ) + continue + + # 生成虚拟群 ID + custom_group_id = virtual_data.get("group_id") + if custom_group_id: + group_id = f"{VIRTUAL_GROUP_ID_PREFIX}{custom_group_id}" + else: + group_id = f"{VIRTUAL_GROUP_ID_PREFIX}{session_id[:8]}" + + current_virtual_config = VirtualIdentityConfig( + enabled=True, + platform=person.platform, + person_id=person.person_id, + user_id=person.user_id, + user_nickname=person.person_name or person.nickname or person.user_id, + group_id=group_id, + group_name=virtual_data.get("group_name", "WebUI虚拟群聊"), + ) + + # 发送虚拟身份已激活的消息 + await chat_manager.send_message( + session_id, + { + "type": "virtual_identity_set", + "config": { + "enabled": True, + "platform": current_virtual_config.platform, + "user_id": current_virtual_config.user_id, + "user_nickname": current_virtual_config.user_nickname, + "group_id": current_virtual_config.group_id, + "group_name": current_virtual_config.group_name, + }, + "timestamp": time.time(), + }, + ) + + # 加载虚拟群的历史记录 + virtual_history = chat_history.get_history(50, current_virtual_config.group_id) + await chat_manager.send_message( + session_id, + { + "type": "history", + "messages": virtual_history, + "group_id": current_virtual_config.group_id, + }, + ) + + # 发送系统消息 + await chat_manager.send_message( + session_id, + { + "type": "system", + "content": f"已切换到虚拟身份模式:以 {current_virtual_config.user_nickname} 的身份在「{current_virtual_config.group_name}」与 {global_config.bot.nickname} 对话", + "timestamp": time.time(), + }, + ) + + except Exception as e: + logger.error(f"设置虚拟身份失败: {e}") + await chat_manager.send_message( + session_id, + { + "type": "error", + "content": f"设置虚拟身份失败: {str(e)}", + "timestamp": time.time(), + }, + ) + else: + # 禁用虚拟身份模式 + current_virtual_config = None + await chat_manager.send_message( + session_id, + { + "type": "virtual_identity_set", + "config": {"enabled": False}, + "timestamp": time.time(), + }, + ) + + # 重新加载默认聊天室历史 + default_history = chat_history.get_history(50, WEBUI_CHAT_GROUP_ID) + await chat_manager.send_message( + session_id, + { + "type": "history", + "messages": default_history, + "group_id": WEBUI_CHAT_GROUP_ID, + }, + ) + + await chat_manager.send_message( + session_id, + { + "type": "system", + "content": "已切换回 WebUI 独立用户模式", + "timestamp": time.time(), + }, + ) + + except WebSocketDisconnect: + logger.info(f"WebSocket 断开: session={session_id}, user={user_id}") + except Exception as e: + logger.error(f"WebSocket 错误: {e}") + finally: + chat_manager.disconnect(session_id, user_id) + + +@router.get("/info") +async def get_chat_info(_auth: bool = Depends(require_auth)): + """获取聊天室信息""" + return { + "bot_name": global_config.bot.nickname, + "platform": WEBUI_CHAT_PLATFORM, + "group_id": WEBUI_CHAT_GROUP_ID, + "active_sessions": len(chat_manager.active_connections), + } + + +def get_webui_chat_broadcaster() -> tuple: + """获取 WebUI 聊天广播器,供外部模块使用 + + Returns: + (chat_manager, WEBUI_CHAT_PLATFORM) 元组 + """ + return (chat_manager, WEBUI_CHAT_PLATFORM) diff --git a/src/webui/config_routes.py b/src/webui/config_routes.py index 84c660ae..6a028927 100644 --- a/src/webui/config_routes.py +++ b/src/webui/config_routes.py @@ -4,11 +4,13 @@ import os import tomlkit -from fastapi import APIRouter, HTTPException, Body -from typing import Any +from fastapi import APIRouter, HTTPException, Body, Depends, Cookie, Header +from typing import Any, Annotated, Optional from src.common.logger import get_logger -from src.config.config import Config, APIAdapterConfig, CONFIG_DIR +from src.webui.auth import verify_auth_token_from_cookie_or_header +from src.common.toml_utils import save_toml_with_format, _update_toml_doc +from src.config.config import Config, APIAdapterConfig, CONFIG_DIR, PROJECT_ROOT from src.config.official_configs import ( BotConfig, PersonalityConfig, @@ -28,9 +30,7 @@ from src.config.official_configs import ( ToolConfig, MemoryConfig, DebugConfig, - MoodConfig, VoiceConfig, - JargonConfig, ) from src.config.api_ada_configs import ( ModelTaskConfig, @@ -41,48 +41,28 @@ from src.webui.config_schema import ConfigSchemaGenerator logger = get_logger("webui") +# 模块级别的类型别名(解决 B008 ruff 错误) +ConfigBody = Annotated[dict[str, Any], Body()] +SectionBody = Annotated[Any, Body()] +RawContentBody = Annotated[str, Body(embed=True)] +PathBody = Annotated[dict[str, str], Body()] + router = APIRouter(prefix="/config", tags=["config"]) -# ===== 辅助函数 ===== - - -def _update_dict_preserve_comments(target: Any, source: Any) -> None: - """ - 递归合并字典,保留 target 中的注释和格式 - 将 source 的值更新到 target 中(仅更新已存在的键) - - Args: - target: 目标字典(tomlkit 对象,包含注释) - source: 源字典(普通 dict 或 list) - """ - # 如果 source 是列表,直接替换(数组表没有注释保留的意义) - if isinstance(source, list): - return # 调用者需要直接赋值 - - # 如果都是字典,递归合并 - if isinstance(source, dict) and isinstance(target, dict): - for key, value in source.items(): - if key == "version": - continue # 跳过版本号 - if key in target: - target_value = target[key] - # 递归处理嵌套字典 - if isinstance(value, dict) and isinstance(target_value, dict): - _update_dict_preserve_comments(target_value, value) - else: - # 使用 tomlkit.item 保持类型 - try: - target[key] = tomlkit.item(value) - except (TypeError, ValueError): - target[key] = value +def require_auth( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> bool: + """认证依赖:验证用户是否已登录""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) # ===== 架构获取接口 ===== @router.get("/schema/bot") -async def get_bot_config_schema(): +async def get_bot_config_schema(_auth: bool = Depends(require_auth)): """获取麦麦主程序配置架构""" try: # Config 类包含所有子配置 @@ -90,25 +70,25 @@ async def get_bot_config_schema(): return {"success": True, "schema": schema} except Exception as e: logger.error(f"获取配置架构失败: {e}") - raise HTTPException(status_code=500, detail=f"获取配置架构失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取配置架构失败: {str(e)}") from e @router.get("/schema/model") -async def get_model_config_schema(): +async def get_model_config_schema(_auth: bool = Depends(require_auth)): """获取模型配置架构(包含提供商和模型任务配置)""" try: schema = ConfigSchemaGenerator.generate_config_schema(APIAdapterConfig) return {"success": True, "schema": schema} except Exception as e: logger.error(f"获取模型配置架构失败: {e}") - raise HTTPException(status_code=500, detail=f"获取模型配置架构失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取模型配置架构失败: {str(e)}") from e # ===== 子配置架构获取接口 ===== @router.get("/schema/section/{section_name}") -async def get_config_section_schema(section_name: str): +async def get_config_section_schema(section_name: str, _auth: bool = Depends(require_auth)): """ 获取指定配置节的架构 @@ -131,7 +111,6 @@ async def get_config_section_schema(section_name: str): - tool: ToolConfig - memory: MemoryConfig - debug: DebugConfig - - mood: MoodConfig - voice: VoiceConfig - jargon: JargonConfig - model_task_config: ModelTaskConfig @@ -157,9 +136,7 @@ async def get_config_section_schema(section_name: str): "tool": ToolConfig, "memory": MemoryConfig, "debug": DebugConfig, - "mood": MoodConfig, "voice": VoiceConfig, - "jargon": JargonConfig, "model_task_config": ModelTaskConfig, "api_provider": APIProvider, "model_info": ModelInfo, @@ -174,14 +151,14 @@ async def get_config_section_schema(section_name: str): return {"success": True, "schema": schema} except Exception as e: logger.error(f"获取配置节架构失败: {e}") - raise HTTPException(status_code=500, detail=f"获取配置节架构失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取配置节架构失败: {str(e)}") from e # ===== 配置读取接口 ===== @router.get("/bot") -async def get_bot_config(): +async def get_bot_config(_auth: bool = Depends(require_auth)): """获取麦麦主程序配置""" try: config_path = os.path.join(CONFIG_DIR, "bot_config.toml") @@ -196,11 +173,11 @@ async def get_bot_config(): raise except Exception as e: logger.error(f"读取配置文件失败: {e}") - raise HTTPException(status_code=500, detail=f"读取配置文件失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"读取配置文件失败: {str(e)}") from e @router.get("/model") -async def get_model_config(): +async def get_model_config(_auth: bool = Depends(require_auth)): """获取模型配置(包含提供商和模型任务配置)""" try: config_path = os.path.join(CONFIG_DIR, "model_config.toml") @@ -215,26 +192,25 @@ async def get_model_config(): raise except Exception as e: logger.error(f"读取配置文件失败: {e}") - raise HTTPException(status_code=500, detail=f"读取配置文件失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"读取配置文件失败: {str(e)}") from e # ===== 配置更新接口 ===== @router.post("/bot") -async def update_bot_config(config_data: dict[str, Any] = Body(...)): +async def update_bot_config(config_data: ConfigBody, _auth: bool = Depends(require_auth)): """更新麦麦主程序配置""" try: # 验证配置数据 try: Config.from_dict(config_data) except Exception as e: - raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") + raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e - # 保存配置文件 + # 保存配置文件(自动保留注释和格式) config_path = os.path.join(CONFIG_DIR, "bot_config.toml") - with open(config_path, "w", encoding="utf-8") as f: - tomlkit.dump(config_data, f) + save_toml_with_format(config_data, config_path) logger.info("麦麦主程序配置已更新") return {"success": True, "message": "配置已保存"} @@ -242,23 +218,22 @@ async def update_bot_config(config_data: dict[str, Any] = Body(...)): raise except Exception as e: logger.error(f"保存配置文件失败: {e}") - raise HTTPException(status_code=500, detail=f"保存配置文件失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"保存配置文件失败: {str(e)}") from e @router.post("/model") -async def update_model_config(config_data: dict[str, Any] = Body(...)): +async def update_model_config(config_data: ConfigBody, _auth: bool = Depends(require_auth)): """更新模型配置""" try: # 验证配置数据 try: APIAdapterConfig.from_dict(config_data) except Exception as e: - raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") + raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e - # 保存配置文件 + # 保存配置文件(自动保留注释和格式) config_path = os.path.join(CONFIG_DIR, "model_config.toml") - with open(config_path, "w", encoding="utf-8") as f: - tomlkit.dump(config_data, f) + save_toml_with_format(config_data, config_path) logger.info("模型配置已更新") return {"success": True, "message": "配置已保存"} @@ -266,14 +241,14 @@ async def update_model_config(config_data: dict[str, Any] = Body(...)): raise except Exception as e: logger.error(f"保存配置文件失败: {e}") - raise HTTPException(status_code=500, detail=f"保存配置文件失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"保存配置文件失败: {str(e)}") from e # ===== 配置节更新接口 ===== @router.post("/bot/section/{section_name}") -async def update_bot_config_section(section_name: str, section_data: Any = Body(...)): +async def update_bot_config_section(section_name: str, section_data: SectionBody, _auth: bool = Depends(require_auth)): """更新麦麦主程序配置的指定节(保留注释和格式)""" try: # 读取现有配置 @@ -295,7 +270,7 @@ async def update_bot_config_section(section_name: str, section_data: Any = Body( config_data[section_name] = section_data elif isinstance(section_data, dict) and isinstance(config_data[section_name], dict): # 字典递归合并 - _update_dict_preserve_comments(config_data[section_name], section_data) + _update_toml_doc(config_data[section_name], section_data) else: # 其他类型直接替换 config_data[section_name] = section_data @@ -304,11 +279,10 @@ async def update_bot_config_section(section_name: str, section_data: Any = Body( try: Config.from_dict(config_data) except Exception as e: - raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") + raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e - # 保存配置(tomlkit.dump 会保留注释) - with open(config_path, "w", encoding="utf-8") as f: - tomlkit.dump(config_data, f) + # 保存配置(格式化数组为多行,保留注释) + save_toml_with_format(config_data, config_path) logger.info(f"配置节 '{section_name}' 已更新(保留注释)") return {"success": True, "message": f"配置节 '{section_name}' 已保存"} @@ -316,14 +290,14 @@ async def update_bot_config_section(section_name: str, section_data: Any = Body( raise except Exception as e: logger.error(f"更新配置节失败: {e}") - raise HTTPException(status_code=500, detail=f"更新配置节失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"更新配置节失败: {str(e)}") from e # ===== 原始 TOML 文件操作接口 ===== @router.get("/bot/raw") -async def get_bot_config_raw(): +async def get_bot_config_raw(_auth: bool = Depends(require_auth)): """获取麦麦主程序配置的原始 TOML 内容""" try: config_path = os.path.join(CONFIG_DIR, "bot_config.toml") @@ -338,24 +312,24 @@ async def get_bot_config_raw(): raise except Exception as e: logger.error(f"读取配置文件失败: {e}") - raise HTTPException(status_code=500, detail=f"读取配置文件失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"读取配置文件失败: {str(e)}") from e @router.post("/bot/raw") -async def update_bot_config_raw(raw_content: str = Body(..., embed=True)): +async def update_bot_config_raw(raw_content: RawContentBody, _auth: bool = Depends(require_auth)): """更新麦麦主程序配置(直接保存原始 TOML 内容,会先验证格式)""" try: # 验证 TOML 格式 try: config_data = tomlkit.loads(raw_content) except Exception as e: - raise HTTPException(status_code=400, detail=f"TOML 格式错误: {str(e)}") + raise HTTPException(status_code=400, detail=f"TOML 格式错误: {str(e)}") from e # 验证配置数据结构 try: Config.from_dict(config_data) except Exception as e: - raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") + raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e # 保存配置文件 config_path = os.path.join(CONFIG_DIR, "bot_config.toml") @@ -368,11 +342,13 @@ async def update_bot_config_raw(raw_content: str = Body(..., embed=True)): raise except Exception as e: logger.error(f"保存配置文件失败: {e}") - raise HTTPException(status_code=500, detail=f"保存配置文件失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"保存配置文件失败: {str(e)}") from e @router.post("/model/section/{section_name}") -async def update_model_config_section(section_name: str, section_data: Any = Body(...)): +async def update_model_config_section( + section_name: str, section_data: SectionBody, _auth: bool = Depends(require_auth) +): """更新模型配置的指定节(保留注释和格式)""" try: # 读取现有配置 @@ -394,7 +370,7 @@ async def update_model_config_section(section_name: str, section_data: Any = Bod config_data[section_name] = section_data elif isinstance(section_data, dict) and isinstance(config_data[section_name], dict): # 字典递归合并 - _update_dict_preserve_comments(config_data[section_name], section_data) + _update_toml_doc(config_data[section_name], section_data) else: # 其他类型直接替换 config_data[section_name] = section_data @@ -403,11 +379,21 @@ async def update_model_config_section(section_name: str, section_data: Any = Bod try: APIAdapterConfig.from_dict(config_data) except Exception as e: - raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") + logger.error(f"配置数据验证失败,详细错误: {str(e)}") + # 特殊处理:如果是更新 api_providers,检查是否有模型引用了已删除的provider + if section_name == "api_providers" and "api_provider" in str(e): + provider_names = {p.get("name") for p in section_data if isinstance(p, dict)} + models = config_data.get("models", []) + orphaned_models = [ + m.get("name") for m in models if isinstance(m, dict) and m.get("api_provider") not in provider_names + ] + if orphaned_models: + error_msg = f"以下模型引用了已删除的提供商: {', '.join(orphaned_models)}。请先在模型管理页面删除这些模型,或重新分配它们的提供商。" + raise HTTPException(status_code=400, detail=error_msg) from e + raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e - # 保存配置(tomlkit.dump 会保留注释) - with open(config_path, "w", encoding="utf-8") as f: - tomlkit.dump(config_data, f) + # 保存配置(格式化数组为多行,保留注释) + save_toml_with_format(config_data, config_path) logger.info(f"配置节 '{section_name}' 已更新(保留注释)") return {"success": True, "message": f"配置节 '{section_name}' 已保存"} @@ -415,14 +401,46 @@ async def update_model_config_section(section_name: str, section_data: Any = Bod raise except Exception as e: logger.error(f"更新配置节失败: {e}") - raise HTTPException(status_code=500, detail=f"更新配置节失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"更新配置节失败: {str(e)}") from e # ===== 适配器配置管理接口 ===== +def _normalize_adapter_path(path: str) -> str: + """将路径转换为绝对路径(如果是相对路径,则相对于项目根目录)""" + if not path: + return path + + # 如果已经是绝对路径,直接返回 + if os.path.isabs(path): + return path + + # 相对路径,转换为相对于项目根目录的绝对路径 + return os.path.normpath(os.path.join(PROJECT_ROOT, path)) + + +def _to_relative_path(path: str) -> str: + """尝试将绝对路径转换为相对于项目根目录的相对路径,如果无法转换则返回原路径""" + if not path or not os.path.isabs(path): + return path + + try: + # 尝试获取相对路径 + rel_path = os.path.relpath(path, PROJECT_ROOT) + # 如果相对路径不是以 .. 开头(说明文件在项目目录内),则返回相对路径 + if not rel_path.startswith(".."): + return rel_path + except (ValueError, TypeError): + # 在 Windows 上,如果路径在不同驱动器,relpath 会抛出 ValueError + pass + + # 无法转换为相对路径,返回绝对路径 + return path + + @router.get("/adapter-config/path") -async def get_adapter_config_path(): +async def get_adapter_config_path(_auth: bool = Depends(require_auth)): """获取保存的适配器配置文件路径""" try: # 从 data/webui.json 读取路径偏好 @@ -431,6 +449,7 @@ async def get_adapter_config_path(): return {"success": True, "path": None} import json + with open(webui_data_path, "r", encoding="utf-8") as f: webui_data = json.load(f) @@ -438,22 +457,29 @@ async def get_adapter_config_path(): if not adapter_config_path: return {"success": True, "path": None} + # 将路径规范化为绝对路径 + abs_path = _normalize_adapter_path(adapter_config_path) + # 检查文件是否存在并返回最后修改时间 - if os.path.exists(adapter_config_path): + if os.path.exists(abs_path): import datetime - mtime = os.path.getmtime(adapter_config_path) + + mtime = os.path.getmtime(abs_path) last_modified = datetime.datetime.fromtimestamp(mtime).isoformat() - return {"success": True, "path": adapter_config_path, "lastModified": last_modified} + # 返回相对路径(如果可能) + display_path = _to_relative_path(abs_path) + return {"success": True, "path": display_path, "lastModified": last_modified} else: + # 文件不存在,返回原路径 return {"success": True, "path": adapter_config_path, "lastModified": None} except Exception as e: logger.error(f"获取适配器配置路径失败: {e}") - raise HTTPException(status_code=500, detail=f"获取配置路径失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取配置路径失败: {str(e)}") from e @router.post("/adapter-config/path") -async def save_adapter_config_path(data: dict[str, str] = Body(...)): +async def save_adapter_config_path(data: PathBody, _auth: bool = Depends(require_auth)): """保存适配器配置文件路径偏好""" try: path = data.get("path") @@ -471,55 +497,64 @@ async def save_adapter_config_path(data: dict[str, str] = Body(...)): else: webui_data = {} + # 将路径规范化为绝对路径 + abs_path = _normalize_adapter_path(path) + + # 尝试转换为相对路径保存(如果文件在项目目录内) + save_path = _to_relative_path(abs_path) + # 更新路径 - webui_data["adapter_config_path"] = path + webui_data["adapter_config_path"] = save_path # 保存 os.makedirs("data", exist_ok=True) with open(webui_data_path, "w", encoding="utf-8") as f: json.dump(webui_data, f, ensure_ascii=False, indent=2) - logger.info(f"适配器配置路径已保存: {path}") + logger.info(f"适配器配置路径已保存: {save_path}(绝对路径: {abs_path})") return {"success": True, "message": "路径已保存"} except HTTPException: raise except Exception as e: logger.error(f"保存适配器配置路径失败: {e}") - raise HTTPException(status_code=500, detail=f"保存路径失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"保存路径失败: {str(e)}") from e @router.get("/adapter-config") -async def get_adapter_config(path: str): +async def get_adapter_config(path: str, _auth: bool = Depends(require_auth)): """从指定路径读取适配器配置文件""" try: if not path: raise HTTPException(status_code=400, detail="路径参数不能为空") + # 将路径规范化为绝对路径 + abs_path = _normalize_adapter_path(path) + # 检查文件是否存在 - if not os.path.exists(path): + if not os.path.exists(abs_path): raise HTTPException(status_code=404, detail=f"配置文件不存在: {path}") # 检查文件扩展名 - if not path.endswith(".toml"): + if not abs_path.endswith(".toml"): raise HTTPException(status_code=400, detail="只支持 .toml 格式的配置文件") # 读取文件内容 - with open(path, "r", encoding="utf-8") as f: + with open(abs_path, "r", encoding="utf-8") as f: content = f.read() - logger.info(f"已读取适配器配置: {path}") + logger.info(f"已读取适配器配置: {path} (绝对路径: {abs_path})") return {"success": True, "content": content} except HTTPException: raise except Exception as e: logger.error(f"读取适配器配置失败: {e}") - raise HTTPException(status_code=500, detail=f"读取配置失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"读取配置失败: {str(e)}") from e @router.post("/adapter-config") -async def save_adapter_config(data: dict[str, str] = Body(...)): +async def save_adapter_config(data: PathBody, _auth: bool = Depends(require_auth)): """保存适配器配置到指定路径""" try: path = data.get("path") @@ -530,30 +565,33 @@ async def save_adapter_config(data: dict[str, str] = Body(...)): if content is None: raise HTTPException(status_code=400, detail="配置内容不能为空") + # 将路径规范化为绝对路径 + abs_path = _normalize_adapter_path(path) + # 检查文件扩展名 - if not path.endswith(".toml"): + if not abs_path.endswith(".toml"): raise HTTPException(status_code=400, detail="只支持 .toml 格式的配置文件") # 验证 TOML 格式 try: - import toml - toml.loads(content) + tomlkit.loads(content) except Exception as e: - raise HTTPException(status_code=400, detail=f"TOML 格式错误: {str(e)}") + raise HTTPException(status_code=400, detail=f"TOML 格式错误: {str(e)}") from e # 确保目录存在 - os.makedirs(os.path.dirname(path) if os.path.dirname(path) else ".", exist_ok=True) + dir_path = os.path.dirname(abs_path) + if dir_path: + os.makedirs(dir_path, exist_ok=True) # 保存文件 - with open(path, "w", encoding="utf-8") as f: + with open(abs_path, "w", encoding="utf-8") as f: f.write(content) - logger.info(f"适配器配置已保存: {path}") + logger.info(f"适配器配置已保存: {path} (绝对路径: {abs_path})") return {"success": True, "message": "配置已保存"} except HTTPException: raise except Exception as e: logger.error(f"保存适配器配置失败: {e}") - raise HTTPException(status_code=500, detail=f"保存配置失败: {str(e)}") - + raise HTTPException(status_code=500, detail=f"保存配置失败: {str(e)}") from e diff --git a/src/webui/config_schema.py b/src/webui/config_schema.py index c1608bc4..5c5763fa 100644 --- a/src/webui/config_schema.py +++ b/src/webui/config_schema.py @@ -117,7 +117,7 @@ class ConfigSchemaGenerator: if next_line.startswith('"""') or next_line.startswith("'''"): # 单行文档字符串 if next_line.count('"""') == 2 or next_line.count("'''") == 2: - description_lines.append(next_line.strip('"""').strip("'''").strip()) + description_lines.append(next_line.replace('"""', "").replace("'''", "").strip()) else: # 多行文档字符串 quote = '"""' if next_line.startswith('"""') else "'''" @@ -135,7 +135,7 @@ class ConfigSchemaGenerator: next_line = lines[i + 1].strip() if next_line.startswith('"""') or next_line.startswith("'''"): if next_line.count('"""') == 2 or next_line.count("'''") == 2: - description_lines.append(next_line.strip('"""').strip("'''").strip()) + description_lines.append(next_line.replace('"""', "").replace("'''", "").strip()) else: quote = '"""' if next_line.startswith('"""') else "'''" description_lines.append(next_line.strip(quote).strip()) @@ -199,13 +199,13 @@ class ConfigSchemaGenerator: return FieldType.ARRAY, None, items # 处理基本类型 - if field_type is bool or field_type == bool: + if field_type is bool: return FieldType.BOOLEAN, None, None - elif field_type is int or field_type == int: + elif field_type is int: return FieldType.INTEGER, None, None - elif field_type is float or field_type == float: + elif field_type is float: return FieldType.NUMBER, None, None - elif field_type is str or field_type == str: + elif field_type is str: return FieldType.STRING, None, None elif field_type is dict or origin is dict: return FieldType.OBJECT, None, None @@ -296,7 +296,6 @@ class ConfigSchemaGenerator: "plan_style", "visual_style", "private_plan_style", - "emotion_style", "reaction", "filtration_prompt", ]: diff --git a/src/webui/emoji_routes.py b/src/webui/emoji_routes.py index 471eb6d7..90b2d60b 100644 --- a/src/webui/emoji_routes.py +++ b/src/webui/emoji_routes.py @@ -1,18 +1,176 @@ """表情包管理 API 路由""" -from fastapi import APIRouter, HTTPException, Header, Query -from fastapi.responses import FileResponse +from fastapi import APIRouter, HTTPException, Header, Query, UploadFile, File, Form, Cookie +from fastapi.responses import FileResponse, JSONResponse from pydantic import BaseModel -from typing import Optional, List +from typing import Optional, List, Annotated from src.common.logger import get_logger from src.common.database.database_model import Emoji from .token_manager import get_token_manager -import json +from .auth import verify_auth_token_from_cookie_or_header import time import os +import hashlib +from PIL import Image +import io +from pathlib import Path +import threading +import asyncio +from concurrent.futures import ThreadPoolExecutor logger = get_logger("webui.emoji") +# ==================== 缩略图缓存配置 ==================== +# 缩略图缓存目录 +THUMBNAIL_CACHE_DIR = Path("data/emoji_thumbnails") +# 缩略图尺寸 (宽, 高) +THUMBNAIL_SIZE = (200, 200) +# 缩略图质量 (WebP 格式, 1-100) +THUMBNAIL_QUALITY = 80 +# 缓存锁,防止并发生成同一缩略图 +_thumbnail_locks: dict[str, threading.Lock] = {} +_locks_lock = threading.Lock() +# 缩略图生成专用线程池(避免阻塞事件循环) +_thumbnail_executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="thumbnail") +# 正在生成中的缩略图哈希集合(防止重复提交任务) +_generating_thumbnails: set[str] = set() +_generating_lock = threading.Lock() + + +def _get_thumbnail_lock(file_hash: str) -> threading.Lock: + """获取指定文件哈希的锁,用于防止并发生成同一缩略图""" + with _locks_lock: + if file_hash not in _thumbnail_locks: + _thumbnail_locks[file_hash] = threading.Lock() + return _thumbnail_locks[file_hash] + + +def _background_generate_thumbnail(source_path: str, file_hash: str) -> None: + """ + 后台生成缩略图(在线程池中执行) + + 生成完成后自动从 generating 集合中移除 + """ + try: + _generate_thumbnail(source_path, file_hash) + except Exception as e: + logger.warning(f"后台生成缩略图失败 {file_hash}: {e}") + finally: + with _generating_lock: + _generating_thumbnails.discard(file_hash) + + +def _ensure_thumbnail_cache_dir() -> Path: + """确保缩略图缓存目录存在""" + THUMBNAIL_CACHE_DIR.mkdir(parents=True, exist_ok=True) + return THUMBNAIL_CACHE_DIR + + +def _get_thumbnail_cache_path(file_hash: str) -> Path: + """获取缩略图缓存路径""" + return THUMBNAIL_CACHE_DIR / f"{file_hash}.webp" + + +def _generate_thumbnail(source_path: str, file_hash: str) -> Path: + """ + 生成缩略图并保存到缓存目录 + + Args: + source_path: 原图路径 + file_hash: 文件哈希值,用作缓存文件名 + + Returns: + 缩略图路径 + + Features: + - GIF: 提取第一帧作为缩略图 + - 所有格式统一转为 WebP + - 保持宽高比缩放 + """ + _ensure_thumbnail_cache_dir() + cache_path = _get_thumbnail_cache_path(file_hash) + + # 使用锁防止并发生成同一缩略图 + lock = _get_thumbnail_lock(file_hash) + with lock: + # 双重检查,可能在等待锁时已被其他线程生成 + if cache_path.exists(): + return cache_path + + try: + with Image.open(source_path) as img: + # GIF 处理:提取第一帧 + if hasattr(img, "n_frames") and img.n_frames > 1: + img.seek(0) # 确保在第一帧 + + # 转换为 RGB/RGBA(WebP 支持透明度) + if img.mode in ("P", "PA"): + # 调色板模式转换为 RGBA 以保留透明度 + img = img.convert("RGBA") + elif img.mode == "LA": + img = img.convert("RGBA") + elif img.mode not in ("RGB", "RGBA"): + img = img.convert("RGB") + + # 创建缩略图(保持宽高比) + img.thumbnail(THUMBNAIL_SIZE, Image.Resampling.LANCZOS) + + # 保存为 WebP 格式 + img.save(cache_path, "WEBP", quality=THUMBNAIL_QUALITY, method=6) + + logger.debug(f"生成缩略图: {file_hash} -> {cache_path}") + + except Exception as e: + logger.warning(f"生成缩略图失败 {file_hash}: {e},将返回原图") + # 生成失败时不创建缓存文件,下次会重试 + raise + + return cache_path + + +def cleanup_orphaned_thumbnails() -> tuple[int, int]: + """ + 清理孤立的缩略图缓存(原图已不存在的缩略图) + + Returns: + (清理数量, 保留数量) + """ + if not THUMBNAIL_CACHE_DIR.exists(): + return 0, 0 + + # 获取所有表情包的哈希值 + valid_hashes = set() + for emoji in Emoji.select(Emoji.emoji_hash): + valid_hashes.add(emoji.emoji_hash) + + cleaned = 0 + kept = 0 + + for cache_file in THUMBNAIL_CACHE_DIR.glob("*.webp"): + file_hash = cache_file.stem + if file_hash not in valid_hashes: + try: + cache_file.unlink() + cleaned += 1 + logger.debug(f"清理孤立缩略图: {cache_file.name}") + except Exception as e: + logger.warning(f"清理缩略图失败 {cache_file.name}: {e}") + else: + kept += 1 + + if cleaned > 0: + logger.info(f"清理孤立缩略图: 删除 {cleaned} 个,保留 {kept} 个") + + return cleaned, kept + + +# 模块级别的类型别名(解决 B008 ruff 错误) +EmojiFile = Annotated[UploadFile, File(description="表情包图片文件")] +EmojiFiles = Annotated[List[UploadFile], File(description="多个表情包图片文件")] +DescriptionForm = Annotated[str, Form(description="表情包描述")] +EmotionForm = Annotated[str, Form(description="情感标签,多个用逗号分隔")] +IsRegisteredForm = Annotated[bool, Form(description="是否直接注册")] + # 创建路由器 router = APIRouter(prefix="/emoji", tags=["Emoji"]) @@ -92,18 +250,12 @@ class BatchDeleteResponse(BaseModel): failed_ids: List[int] = [] -def verify_auth_token(authorization: Optional[str]) -> bool: - """验证认证 Token""" - if not authorization or not authorization.startswith("Bearer "): - raise HTTPException(status_code=401, detail="未提供有效的认证信息") - - token = authorization.replace("Bearer ", "") - token_manager = get_token_manager() - - if not token_manager.verify_token(token): - raise HTTPException(status_code=401, detail="Token 无效或已过期") - - return True +def verify_auth_token( + maibot_session: Optional[str] = None, + authorization: Optional[str] = None, +) -> bool: + """验证认证 Token,支持 Cookie 和 Header""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) def emoji_to_response(emoji: Emoji) -> EmojiResponse: @@ -133,6 +285,9 @@ async def get_emoji_list( is_registered: Optional[bool] = Query(None, description="是否已注册筛选"), is_banned: Optional[bool] = Query(None, description="是否被禁用筛选"), format: Optional[str] = Query(None, description="格式筛选"), + sort_by: Optional[str] = Query("usage_count", description="排序字段"), + sort_order: Optional[str] = Query("desc", description="排序方向"), + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None), ): """ @@ -145,13 +300,15 @@ async def get_emoji_list( is_registered: 是否已注册筛选 is_banned: 是否被禁用筛选 format: 格式筛选 + sort_by: 排序字段 (usage_count, register_time, record_time, last_used_time) + sort_order: 排序方向 (asc, desc) authorization: Authorization header Returns: 表情包列表 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) # 构建查询 query = Emoji.select() @@ -172,12 +329,22 @@ async def get_emoji_list( if format: query = query.where(Emoji.format == format) - # 排序:使用次数倒序,然后按记录时间倒序 - from peewee import Case + # 排序字段映射 + sort_field_map = { + "usage_count": Emoji.usage_count, + "register_time": Emoji.register_time, + "record_time": Emoji.record_time, + "last_used_time": Emoji.last_used_time, + } - query = query.order_by( - Emoji.usage_count.desc(), Case(None, [(Emoji.record_time.is_null(), 1)], 0), Emoji.record_time.desc() - ) + # 获取排序字段,默认使用 usage_count + sort_field = sort_field_map.get(sort_by, Emoji.usage_count) + + # 应用排序 + if sort_order == "asc": + query = query.order_by(sort_field.asc()) + else: + query = query.order_by(sort_field.desc()) # 获取总数 total = query.count() @@ -199,7 +366,9 @@ async def get_emoji_list( @router.get("/{emoji_id}", response_model=EmojiDetailResponse) -async def get_emoji_detail(emoji_id: int, authorization: Optional[str] = Header(None)): +async def get_emoji_detail( + emoji_id: int, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 获取表情包详细信息 @@ -211,7 +380,7 @@ async def get_emoji_detail(emoji_id: int, authorization: Optional[str] = Header( 表情包详细信息 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) emoji = Emoji.get_or_none(Emoji.id == emoji_id) @@ -228,7 +397,12 @@ async def get_emoji_detail(emoji_id: int, authorization: Optional[str] = Header( @router.patch("/{emoji_id}", response_model=EmojiUpdateResponse) -async def update_emoji(emoji_id: int, request: EmojiUpdateRequest, authorization: Optional[str] = Header(None)): +async def update_emoji( + emoji_id: int, + request: EmojiUpdateRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 增量更新表情包(只更新提供的字段) @@ -241,7 +415,7 @@ async def update_emoji(emoji_id: int, request: EmojiUpdateRequest, authorization 更新结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) emoji = Emoji.get_or_none(Emoji.id == emoji_id) @@ -280,7 +454,9 @@ async def update_emoji(emoji_id: int, request: EmojiUpdateRequest, authorization @router.delete("/{emoji_id}", response_model=EmojiDeleteResponse) -async def delete_emoji(emoji_id: int, authorization: Optional[str] = Header(None)): +async def delete_emoji( + emoji_id: int, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 删除表情包 @@ -292,7 +468,7 @@ async def delete_emoji(emoji_id: int, authorization: Optional[str] = Header(None 删除结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) emoji = Emoji.get_or_none(Emoji.id == emoji_id) @@ -317,7 +493,7 @@ async def delete_emoji(emoji_id: int, authorization: Optional[str] = Header(None @router.get("/stats/summary") -async def get_emoji_stats(authorization: Optional[str] = Header(None)): +async def get_emoji_stats(maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None)): """ 获取表情包统计数据 @@ -328,7 +504,7 @@ async def get_emoji_stats(authorization: Optional[str] = Header(None)): 统计数据 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) total = Emoji.select().count() registered = Emoji.select().where(Emoji.is_registered).count() @@ -372,7 +548,9 @@ async def get_emoji_stats(authorization: Optional[str] = Header(None)): @router.post("/{emoji_id}/register", response_model=EmojiUpdateResponse) -async def register_emoji(emoji_id: int, authorization: Optional[str] = Header(None)): +async def register_emoji( + emoji_id: int, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 注册表情包(快捷操作) @@ -384,7 +562,7 @@ async def register_emoji(emoji_id: int, authorization: Optional[str] = Header(No 更新结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) emoji = Emoji.get_or_none(Emoji.id == emoji_id) @@ -394,11 +572,9 @@ async def register_emoji(emoji_id: int, authorization: Optional[str] = Header(No if emoji.is_registered: raise HTTPException(status_code=400, detail="该表情包已经注册") - if emoji.is_banned: - raise HTTPException(status_code=400, detail="该表情包已被禁用,无法注册") - - # 注册表情包 + # 注册表情包(如果已封禁,自动解除封禁) emoji.is_registered = True + emoji.is_banned = False # 注册时自动解除封禁 emoji.register_time = time.time() emoji.save() @@ -414,7 +590,9 @@ async def register_emoji(emoji_id: int, authorization: Optional[str] = Header(No @router.post("/{emoji_id}/ban", response_model=EmojiUpdateResponse) -async def ban_emoji(emoji_id: int, authorization: Optional[str] = Header(None)): +async def ban_emoji( + emoji_id: int, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 禁用表情包(快捷操作) @@ -426,7 +604,7 @@ async def ban_emoji(emoji_id: int, authorization: Optional[str] = Header(None)): 更新结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) emoji = Emoji.get_or_none(Emoji.id == emoji_id) @@ -453,28 +631,47 @@ async def ban_emoji(emoji_id: int, authorization: Optional[str] = Header(None)): async def get_emoji_thumbnail( emoji_id: int, token: Optional[str] = Query(None, description="访问令牌"), + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None), + original: bool = Query(False, description="是否返回原图"), ): """ - 获取表情包缩略图 + 获取表情包缩略图(懒加载生成 + 缓存) Args: emoji_id: 表情包ID - token: 访问令牌(通过 query parameter) + token: 访问令牌(通过 query parameter,用于向后兼容) + maibot_session: Cookie 中的 token authorization: Authorization header + original: 是否返回原图(用于详情页查看原图) Returns: - 表情包图片文件 + 表情包缩略图(WebP 格式)或原图 + + Features: + - 懒加载:首次请求时生成缩略图 + - 缓存:后续请求直接返回缓存 + - GIF 支持:提取第一帧作为缩略图 + - 格式统一:所有缩略图统一为 WebP 格式 """ try: - # 优先使用 query parameter 中的 token(用于 img 标签) - if token: - token_manager = get_token_manager() - if not token_manager.verify_token(token): - raise HTTPException(status_code=401, detail="Token 无效或已过期") - else: - # 如果没有 query token,则验证 Authorization header - verify_auth_token(authorization) + token_manager = get_token_manager() + is_valid = False + + # 1. 优先使用 Cookie + if maibot_session and token_manager.verify_token(maibot_session): + is_valid = True + # 2. 其次使用 query parameter(用于向后兼容 img 标签) + elif token and token_manager.verify_token(token): + is_valid = True + # 3. 最后使用 Authorization header + elif authorization and authorization.startswith("Bearer "): + auth_token = authorization.replace("Bearer ", "") + if token_manager.verify_token(auth_token): + is_valid = True + + if not is_valid: + raise HTTPException(status_code=401, detail="Token 无效或已过期") emoji = Emoji.get_or_none(Emoji.id == emoji_id) @@ -485,19 +682,51 @@ async def get_emoji_thumbnail( if not os.path.exists(emoji.full_path): raise HTTPException(status_code=404, detail="表情包文件不存在") - # 根据格式设置 MIME 类型 - mime_types = { - "png": "image/png", - "jpg": "image/jpeg", - "jpeg": "image/jpeg", - "gif": "image/gif", - "webp": "image/webp", - "bmp": "image/bmp", - } + # 如果请求原图,直接返回原文件 + if original: + mime_types = { + "png": "image/png", + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "gif": "image/gif", + "webp": "image/webp", + "bmp": "image/bmp", + } + media_type = mime_types.get(emoji.format.lower(), "application/octet-stream") + return FileResponse( + path=emoji.full_path, media_type=media_type, filename=f"{emoji.emoji_hash}.{emoji.format}" + ) - media_type = mime_types.get(emoji.format.lower(), "application/octet-stream") + # 尝试获取或生成缩略图 + cache_path = _get_thumbnail_cache_path(emoji.emoji_hash) - return FileResponse(path=emoji.full_path, media_type=media_type, filename=f"{emoji.emoji_hash}.{emoji.format}") + # 检查缓存是否存在 + if cache_path.exists(): + # 缓存命中,直接返回 + return FileResponse( + path=str(cache_path), media_type="image/webp", filename=f"{emoji.emoji_hash}_thumb.webp" + ) + + # 缓存未命中,触发后台生成并返回 202 + with _generating_lock: + if emoji.emoji_hash not in _generating_thumbnails: + # 标记为正在生成 + _generating_thumbnails.add(emoji.emoji_hash) + # 提交到线程池后台生成 + _thumbnail_executor.submit(_background_generate_thumbnail, emoji.full_path, emoji.emoji_hash) + + # 返回 202 Accepted,告诉前端缩略图正在生成中 + return JSONResponse( + status_code=202, + content={ + "status": "generating", + "message": "缩略图正在生成中,请稍后重试", + "emoji_id": emoji_id, + }, + headers={ + "Retry-After": "1", # 建议 1 秒后重试 + }, + ) except HTTPException: raise @@ -507,7 +736,11 @@ async def get_emoji_thumbnail( @router.post("/batch/delete", response_model=BatchDeleteResponse) -async def batch_delete_emojis(request: BatchDeleteRequest, authorization: Optional[str] = Header(None)): +async def batch_delete_emojis( + request: BatchDeleteRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 批量删除表情包 @@ -519,7 +752,7 @@ async def batch_delete_emojis(request: BatchDeleteRequest, authorization: Option 批量删除结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) if not request.emoji_ids: raise HTTPException(status_code=400, detail="未提供要删除的表情包ID") @@ -560,3 +793,519 @@ async def batch_delete_emojis(request: BatchDeleteRequest, authorization: Option except Exception as e: logger.exception(f"批量删除表情包失败: {e}") raise HTTPException(status_code=500, detail=f"批量删除失败: {str(e)}") from e + + +# 表情包存储目录 +EMOJI_REGISTERED_DIR = os.path.join("data", "emoji_registed") + + +class EmojiUploadResponse(BaseModel): + """表情包上传响应""" + + success: bool + message: str + data: Optional[EmojiResponse] = None + + +@router.post("/upload", response_model=EmojiUploadResponse) +async def upload_emoji( + file: EmojiFile, + description: DescriptionForm = "", + emotion: EmotionForm = "", + is_registered: IsRegisteredForm = True, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 上传并注册表情包 + + Args: + file: 表情包图片文件 (支持 jpg, jpeg, png, gif, webp) + description: 表情包描述 + emotion: 情感标签,多个用逗号分隔 + is_registered: 是否直接注册,默认为 True + authorization: Authorization header + + Returns: + 上传结果和表情包信息 + """ + try: + verify_auth_token(maibot_session, authorization) + + # 验证文件类型 + if not file.content_type: + raise HTTPException(status_code=400, detail="无法识别文件类型") + + allowed_types = ["image/jpeg", "image/png", "image/gif", "image/webp"] + if file.content_type not in allowed_types: + raise HTTPException( + status_code=400, + detail=f"不支持的文件类型: {file.content_type},支持: {', '.join(allowed_types)}", + ) + + # 读取文件内容 + file_content = await file.read() + + if not file_content: + raise HTTPException(status_code=400, detail="文件内容为空") + + # 验证图片并获取格式 + try: + with Image.open(io.BytesIO(file_content)) as img: + img_format = img.format.lower() if img.format else "png" + # 验证图片可以正常打开 + img.verify() + except Exception as e: + raise HTTPException(status_code=400, detail=f"无效的图片文件: {str(e)}") from e + + # 重新打开图片(verify后需要重新打开) + with Image.open(io.BytesIO(file_content)) as img: + img_format = img.format.lower() if img.format else "png" + + # 计算文件哈希 + emoji_hash = hashlib.md5(file_content).hexdigest() + + # 检查是否已存在相同哈希的表情包 + existing_emoji = Emoji.get_or_none(Emoji.emoji_hash == emoji_hash) + if existing_emoji: + raise HTTPException( + status_code=409, + detail=f"已存在相同的表情包 (ID: {existing_emoji.id})", + ) + + # 确保目录存在 + os.makedirs(EMOJI_REGISTERED_DIR, exist_ok=True) + + # 生成文件名 + timestamp = int(time.time()) + filename = f"emoji_{timestamp}_{emoji_hash[:8]}.{img_format}" + full_path = os.path.join(EMOJI_REGISTERED_DIR, filename) + + # 如果文件已存在,添加随机后缀 + counter = 1 + while os.path.exists(full_path): + filename = f"emoji_{timestamp}_{emoji_hash[:8]}_{counter}.{img_format}" + full_path = os.path.join(EMOJI_REGISTERED_DIR, filename) + counter += 1 + + # 保存文件 + with open(full_path, "wb") as f: + f.write(file_content) + + logger.info(f"表情包文件已保存: {full_path}") + + # 处理情感标签 + emotion_str = ",".join(e.strip() for e in emotion.split(",") if e.strip()) if emotion else "" + + # 创建数据库记录 + current_time = time.time() + emoji = Emoji.create( + full_path=full_path, + format=img_format, + emoji_hash=emoji_hash, + description=description, + emotion=emotion_str, + query_count=0, + is_registered=is_registered, + is_banned=False, + record_time=current_time, + register_time=current_time if is_registered else None, + usage_count=0, + last_used_time=None, + ) + + logger.info(f"表情包已上传并注册: ID={emoji.id}, hash={emoji_hash}") + + return EmojiUploadResponse( + success=True, + message="表情包上传成功" + ("并已注册" if is_registered else ""), + data=emoji_to_response(emoji), + ) + + except HTTPException: + raise + except Exception as e: + logger.exception(f"上传表情包失败: {e}") + raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}") from e + + +@router.post("/batch/upload") +async def batch_upload_emoji( + files: EmojiFiles, + emotion: EmotionForm = "", + is_registered: IsRegisteredForm = True, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 批量上传表情包 + + Args: + files: 多个表情包图片文件 + emotion: 共用的情感标签 + is_registered: 是否直接注册 + authorization: Authorization header + + Returns: + 批量上传结果 + """ + try: + verify_auth_token(maibot_session, authorization) + + results = { + "success": True, + "total": len(files), + "uploaded": 0, + "failed": 0, + "details": [], + } + + allowed_types = ["image/jpeg", "image/png", "image/gif", "image/webp"] + os.makedirs(EMOJI_REGISTERED_DIR, exist_ok=True) + + for file in files: + try: + # 验证文件类型 + if file.content_type not in allowed_types: + results["failed"] += 1 + results["details"].append( + { + "filename": file.filename, + "success": False, + "error": f"不支持的文件类型: {file.content_type}", + } + ) + continue + + # 读取文件内容 + file_content = await file.read() + + if not file_content: + results["failed"] += 1 + results["details"].append( + { + "filename": file.filename, + "success": False, + "error": "文件内容为空", + } + ) + continue + + # 验证图片 + try: + with Image.open(io.BytesIO(file_content)) as img: + img_format = img.format.lower() if img.format else "png" + except Exception as e: + results["failed"] += 1 + results["details"].append( + { + "filename": file.filename, + "success": False, + "error": f"无效的图片: {str(e)}", + } + ) + continue + + # 计算哈希 + emoji_hash = hashlib.md5(file_content).hexdigest() + + # 检查重复 + if Emoji.get_or_none(Emoji.emoji_hash == emoji_hash): + results["failed"] += 1 + results["details"].append( + { + "filename": file.filename, + "success": False, + "error": "已存在相同的表情包", + } + ) + continue + + # 生成文件名并保存 + timestamp = int(time.time()) + filename = f"emoji_{timestamp}_{emoji_hash[:8]}.{img_format}" + full_path = os.path.join(EMOJI_REGISTERED_DIR, filename) + + counter = 1 + while os.path.exists(full_path): + filename = f"emoji_{timestamp}_{emoji_hash[:8]}_{counter}.{img_format}" + full_path = os.path.join(EMOJI_REGISTERED_DIR, filename) + counter += 1 + + with open(full_path, "wb") as f: + f.write(file_content) + + # 处理情感标签 + emotion_str = ",".join(e.strip() for e in emotion.split(",") if e.strip()) if emotion else "" + + # 创建数据库记录 + current_time = time.time() + emoji = Emoji.create( + full_path=full_path, + format=img_format, + emoji_hash=emoji_hash, + description="", # 批量上传暂不设置描述 + emotion=emotion_str, + query_count=0, + is_registered=is_registered, + is_banned=False, + record_time=current_time, + register_time=current_time if is_registered else None, + usage_count=0, + last_used_time=None, + ) + + results["uploaded"] += 1 + results["details"].append( + { + "filename": file.filename, + "success": True, + "id": emoji.id, + } + ) + + except Exception as e: + results["failed"] += 1 + results["details"].append( + { + "filename": file.filename, + "success": False, + "error": str(e), + } + ) + + results["message"] = f"成功上传 {results['uploaded']} 个,失败 {results['failed']} 个" + return results + + except HTTPException: + raise + except Exception as e: + logger.exception(f"批量上传表情包失败: {e}") + raise HTTPException(status_code=500, detail=f"批量上传失败: {str(e)}") from e + + +# ==================== 缩略图缓存管理 API ==================== + + +class ThumbnailCacheStatsResponse(BaseModel): + """缩略图缓存统计响应""" + + success: bool + cache_dir: str + total_count: int + total_size_mb: float + emoji_count: int + coverage_percent: float + + +class ThumbnailCleanupResponse(BaseModel): + """缩略图清理响应""" + + success: bool + message: str + cleaned_count: int + kept_count: int + + +class ThumbnailPreheatResponse(BaseModel): + """缩略图预热响应""" + + success: bool + message: str + generated_count: int + skipped_count: int + failed_count: int + + +@router.get("/thumbnail-cache/stats", response_model=ThumbnailCacheStatsResponse) +async def get_thumbnail_cache_stats( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 获取缩略图缓存统计信息 + + Returns: + 缓存目录、缓存数量、总大小、覆盖率等统计信息 + """ + try: + verify_auth_token(maibot_session, authorization) + + _ensure_thumbnail_cache_dir() + + # 统计缓存文件 + cache_files = list(THUMBNAIL_CACHE_DIR.glob("*.webp")) + total_count = len(cache_files) + total_size = sum(f.stat().st_size for f in cache_files) + total_size_mb = round(total_size / (1024 * 1024), 2) + + # 统计表情包总数 + emoji_count = Emoji.select().count() + + # 计算覆盖率 + coverage_percent = round((total_count / emoji_count * 100) if emoji_count > 0 else 0, 1) + + return ThumbnailCacheStatsResponse( + success=True, + cache_dir=str(THUMBNAIL_CACHE_DIR.absolute()), + total_count=total_count, + total_size_mb=total_size_mb, + emoji_count=emoji_count, + coverage_percent=coverage_percent, + ) + + except HTTPException: + raise + except Exception as e: + logger.exception(f"获取缩略图缓存统计失败: {e}") + raise HTTPException(status_code=500, detail=f"获取统计失败: {str(e)}") from e + + +@router.post("/thumbnail-cache/cleanup", response_model=ThumbnailCleanupResponse) +async def cleanup_thumbnail_cache( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 清理孤立的缩略图缓存(原图已删除的表情包对应的缩略图) + + Returns: + 清理结果 + """ + try: + verify_auth_token(maibot_session, authorization) + + cleaned, kept = cleanup_orphaned_thumbnails() + + return ThumbnailCleanupResponse( + success=True, + message=f"清理完成:删除 {cleaned} 个孤立缓存,保留 {kept} 个有效缓存", + cleaned_count=cleaned, + kept_count=kept, + ) + + except HTTPException: + raise + except Exception as e: + logger.exception(f"清理缩略图缓存失败: {e}") + raise HTTPException(status_code=500, detail=f"清理失败: {str(e)}") from e + + +@router.post("/thumbnail-cache/preheat", response_model=ThumbnailPreheatResponse) +async def preheat_thumbnail_cache( + limit: int = Query(100, ge=1, le=1000, description="最多预热数量"), + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 预热缩略图缓存(提前生成未缓存的缩略图) + + 优先处理使用次数高的表情包 + + Args: + limit: 最多预热数量 (1-1000) + + Returns: + 预热结果 + """ + try: + verify_auth_token(maibot_session, authorization) + + _ensure_thumbnail_cache_dir() + + # 获取使用次数最高的表情包(未缓存的优先) + emojis = ( + Emoji.select() + .where(Emoji.is_banned == False) # noqa: E712 Peewee ORM requires == for boolean comparison + .order_by(Emoji.usage_count.desc()) + .limit(limit * 2) # 多查一些,因为有些可能已缓存 + ) + + generated = 0 + skipped = 0 + failed = 0 + + for emoji in emojis: + if generated >= limit: + break + + cache_path = _get_thumbnail_cache_path(emoji.emoji_hash) + + # 已缓存,跳过 + if cache_path.exists(): + skipped += 1 + continue + + # 原文件不存在,跳过 + if not os.path.exists(emoji.full_path): + failed += 1 + continue + + try: + # 使用线程池异步生成缩略图,避免阻塞事件循环 + loop = asyncio.get_event_loop() + await loop.run_in_executor(_thumbnail_executor, _generate_thumbnail, emoji.full_path, emoji.emoji_hash) + generated += 1 + except Exception as e: + logger.warning(f"预热缩略图失败 {emoji.emoji_hash}: {e}") + failed += 1 + + return ThumbnailPreheatResponse( + success=True, + message=f"预热完成:生成 {generated} 个,跳过 {skipped} 个已缓存,失败 {failed} 个", + generated_count=generated, + skipped_count=skipped, + failed_count=failed, + ) + + except HTTPException: + raise + except Exception as e: + logger.exception(f"预热缩略图缓存失败: {e}") + raise HTTPException(status_code=500, detail=f"预热失败: {str(e)}") from e + + +@router.delete("/thumbnail-cache/clear", response_model=ThumbnailCleanupResponse) +async def clear_all_thumbnail_cache( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 清空所有缩略图缓存(下次访问时会重新生成) + + Returns: + 清理结果 + """ + try: + verify_auth_token(maibot_session, authorization) + + if not THUMBNAIL_CACHE_DIR.exists(): + return ThumbnailCleanupResponse( + success=True, + message="缓存目录不存在,无需清理", + cleaned_count=0, + kept_count=0, + ) + + cleaned = 0 + for cache_file in THUMBNAIL_CACHE_DIR.glob("*.webp"): + try: + cache_file.unlink() + cleaned += 1 + except Exception as e: + logger.warning(f"删除缓存文件失败 {cache_file.name}: {e}") + + logger.info(f"已清空缩略图缓存: 删除 {cleaned} 个文件") + + return ThumbnailCleanupResponse( + success=True, + message=f"已清空所有缩略图缓存:删除 {cleaned} 个文件", + cleaned_count=cleaned, + kept_count=0, + ) + + except HTTPException: + raise + except Exception as e: + logger.exception(f"清空缩略图缓存失败: {e}") + raise HTTPException(status_code=500, detail=f"清空失败: {str(e)}") from e diff --git a/src/webui/expression_routes.py b/src/webui/expression_routes.py index 983918cf..b6ec76b3 100644 --- a/src/webui/expression_routes.py +++ b/src/webui/expression_routes.py @@ -1,11 +1,11 @@ """表达方式管理 API 路由""" -from fastapi import APIRouter, HTTPException, Header, Query -from pydantic import BaseModel -from typing import Optional, List +from fastapi import APIRouter, HTTPException, Header, Query, Cookie +from pydantic import BaseModel, NonNegativeFloat +from typing import Optional, List, Dict from src.common.logger import get_logger -from src.common.database.database_model import Expression -from .token_manager import get_token_manager +from src.common.database.database_model import Expression, ChatStreams +from .auth import verify_auth_token_from_cookie_or_header import time logger = get_logger("webui.expression") @@ -21,7 +21,6 @@ class ExpressionResponse(BaseModel): situation: str style: str context: Optional[str] - up_content: Optional[str] last_active_time: float chat_id: str create_date: Optional[float] @@ -49,8 +48,7 @@ class ExpressionCreateRequest(BaseModel): situation: str style: str - context: Optional[str] = None - up_content: Optional[str] = None + context: Optional[str] = NonNegativeFloat chat_id: str @@ -60,7 +58,6 @@ class ExpressionUpdateRequest(BaseModel): situation: Optional[str] = None style: Optional[str] = None context: Optional[str] = None - up_content: Optional[str] = None chat_id: Optional[str] = None @@ -87,18 +84,12 @@ class ExpressionCreateResponse(BaseModel): data: ExpressionResponse -def verify_auth_token(authorization: Optional[str]) -> bool: - """验证认证 Token""" - if not authorization or not authorization.startswith("Bearer "): - raise HTTPException(status_code=401, detail="未提供有效的认证信息") - - token = authorization.replace("Bearer ", "") - token_manager = get_token_manager() - - if not token_manager.verify_token(token): - raise HTTPException(status_code=401, detail="Token 无效或已过期") - - return True +def verify_auth_token( + maibot_session: Optional[str] = None, + authorization: Optional[str] = None, +) -> bool: + """验证认证 Token,支持 Cookie 和 Header""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) def expression_to_response(expression: Expression) -> ExpressionResponse: @@ -108,19 +99,103 @@ def expression_to_response(expression: Expression) -> ExpressionResponse: situation=expression.situation, style=expression.style, context=expression.context, - up_content=expression.up_content, last_active_time=expression.last_active_time, chat_id=expression.chat_id, create_date=expression.create_date, ) +def get_chat_name(chat_id: str) -> str: + """根据 chat_id 获取聊天名称""" + try: + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == chat_id) + if chat_stream: + # 优先使用群聊名称,否则使用用户昵称 + if chat_stream.group_name: + return chat_stream.group_name + elif chat_stream.user_nickname: + return chat_stream.user_nickname + return chat_id # 找不到时返回原始ID + except Exception: + return chat_id + + +def get_chat_names_batch(chat_ids: List[str]) -> Dict[str, str]: + """批量获取聊天名称""" + result = {cid: cid for cid in chat_ids} # 默认值为原始ID + try: + chat_streams = ChatStreams.select().where(ChatStreams.stream_id.in_(chat_ids)) + for cs in chat_streams: + if cs.group_name: + result[cs.stream_id] = cs.group_name + elif cs.user_nickname: + result[cs.stream_id] = cs.user_nickname + except Exception as e: + logger.warning(f"批量获取聊天名称失败: {e}") + return result + + +class ChatInfo(BaseModel): + """聊天信息""" + + chat_id: str + chat_name: str + platform: Optional[str] = None + is_group: bool = False + + +class ChatListResponse(BaseModel): + """聊天列表响应""" + + success: bool + data: List[ChatInfo] + + +@router.get("/chats", response_model=ChatListResponse) +async def get_chat_list(maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None)): + """ + 获取所有聊天列表(用于下拉选择) + + Args: + authorization: Authorization header + + Returns: + 聊天列表 + """ + try: + verify_auth_token(maibot_session, authorization) + + chat_list = [] + for cs in ChatStreams.select(): + chat_name = cs.group_name if cs.group_name else (cs.user_nickname if cs.user_nickname else cs.stream_id) + chat_list.append( + ChatInfo( + chat_id=cs.stream_id, + chat_name=chat_name, + platform=cs.platform, + is_group=bool(cs.group_id), + ) + ) + + # 按名称排序 + chat_list.sort(key=lambda x: x.chat_name) + + return ChatListResponse(success=True, data=chat_list) + + except HTTPException: + raise + except Exception as e: + logger.exception(f"获取聊天列表失败: {e}") + raise HTTPException(status_code=500, detail=f"获取聊天列表失败: {str(e)}") from e + + @router.get("/list", response_model=ExpressionListResponse) async def get_expression_list( page: int = Query(1, ge=1, description="页码"), page_size: int = Query(20, ge=1, le=100, description="每页数量"), search: Optional[str] = Query(None, description="搜索关键词"), chat_id: Optional[str] = Query(None, description="聊天ID筛选"), + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None), ): """ @@ -137,7 +212,7 @@ async def get_expression_list( 表达方式列表 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) # 构建查询 query = Expression.select() @@ -181,7 +256,9 @@ async def get_expression_list( @router.get("/{expression_id}", response_model=ExpressionDetailResponse) -async def get_expression_detail(expression_id: int, authorization: Optional[str] = Header(None)): +async def get_expression_detail( + expression_id: int, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 获取表达方式详细信息 @@ -193,7 +270,7 @@ async def get_expression_detail(expression_id: int, authorization: Optional[str] 表达方式详细信息 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) expression = Expression.get_or_none(Expression.id == expression_id) @@ -210,7 +287,11 @@ async def get_expression_detail(expression_id: int, authorization: Optional[str] @router.post("/", response_model=ExpressionCreateResponse) -async def create_expression(request: ExpressionCreateRequest, authorization: Optional[str] = Header(None)): +async def create_expression( + request: ExpressionCreateRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 创建新的表达方式 @@ -222,7 +303,7 @@ async def create_expression(request: ExpressionCreateRequest, authorization: Opt 创建结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) current_time = time.time() @@ -231,7 +312,6 @@ async def create_expression(request: ExpressionCreateRequest, authorization: Opt situation=request.situation, style=request.style, context=request.context, - up_content=request.up_content, chat_id=request.chat_id, last_active_time=current_time, create_date=current_time, @@ -252,7 +332,10 @@ async def create_expression(request: ExpressionCreateRequest, authorization: Opt @router.patch("/{expression_id}", response_model=ExpressionUpdateResponse) async def update_expression( - expression_id: int, request: ExpressionUpdateRequest, authorization: Optional[str] = Header(None) + expression_id: int, + request: ExpressionUpdateRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), ): """ 增量更新表达方式(只更新提供的字段) @@ -266,7 +349,7 @@ async def update_expression( 更新结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) expression = Expression.get_or_none(Expression.id == expression_id) @@ -302,7 +385,9 @@ async def update_expression( @router.delete("/{expression_id}", response_model=ExpressionDeleteResponse) -async def delete_expression(expression_id: int, authorization: Optional[str] = Header(None)): +async def delete_expression( + expression_id: int, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 删除表达方式 @@ -314,7 +399,7 @@ async def delete_expression(expression_id: int, authorization: Optional[str] = H 删除结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) expression = Expression.get_or_none(Expression.id == expression_id) @@ -345,7 +430,11 @@ class BatchDeleteRequest(BaseModel): @router.post("/batch/delete", response_model=ExpressionDeleteResponse) -async def batch_delete_expressions(request: BatchDeleteRequest, authorization: Optional[str] = Header(None)): +async def batch_delete_expressions( + request: BatchDeleteRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 批量删除表达方式 @@ -357,7 +446,7 @@ async def batch_delete_expressions(request: BatchDeleteRequest, authorization: O 删除结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) if not request.ids: raise HTTPException(status_code=400, detail="未提供要删除的表达方式ID") @@ -386,7 +475,9 @@ async def batch_delete_expressions(request: BatchDeleteRequest, authorization: O @router.get("/stats/summary") -async def get_expression_stats(authorization: Optional[str] = Header(None)): +async def get_expression_stats( + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 获取表达方式统计数据 @@ -397,7 +488,7 @@ async def get_expression_stats(authorization: Optional[str] = Header(None)): 统计数据 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) total = Expression.select().count() diff --git a/src/webui/git_mirror_service.py b/src/webui/git_mirror_service.py index df00cde9..a6a9b1bc 100644 --- a/src/webui/git_mirror_service.py +++ b/src/webui/git_mirror_service.py @@ -602,9 +602,9 @@ class GitMirrorService: # 执行 git clone(在线程池中运行以避免阻塞) loop = asyncio.get_event_loop() - def run_git_clone(): + def run_git_clone(clone_cmd=cmd): return subprocess.run( - cmd, + clone_cmd, capture_output=True, text=True, timeout=300, # 5分钟超时 diff --git a/src/webui/jargon_routes.py b/src/webui/jargon_routes.py new file mode 100644 index 00000000..8d372688 --- /dev/null +++ b/src/webui/jargon_routes.py @@ -0,0 +1,532 @@ +"""黑话(俚语)管理路由""" + +import json +from typing import Optional, List, Annotated +from fastapi import APIRouter, HTTPException, Query +from pydantic import BaseModel, Field +from peewee import fn + +from src.common.logger import get_logger +from src.common.database.database_model import Jargon, ChatStreams + +logger = get_logger("webui.jargon") + +router = APIRouter(prefix="/jargon", tags=["Jargon"]) + + +# ==================== 辅助函数 ==================== + + +def parse_chat_id_to_stream_ids(chat_id_str: str) -> List[str]: + """ + 解析 chat_id 字段,提取所有 stream_id + chat_id 格式: [["stream_id", user_id], ...] 或直接是 stream_id 字符串 + """ + if not chat_id_str: + return [] + + try: + # 尝试解析为 JSON + parsed = json.loads(chat_id_str) + if isinstance(parsed, list): + # 格式: [["stream_id", user_id], ...] + stream_ids = [] + for item in parsed: + if isinstance(item, list) and len(item) >= 1: + stream_ids.append(str(item[0])) + return stream_ids + else: + # 其他格式,返回原始字符串 + return [chat_id_str] + except (json.JSONDecodeError, TypeError): + # 不是有效的 JSON,可能是直接的 stream_id + return [chat_id_str] + + +def get_display_name_for_chat_id(chat_id_str: str) -> str: + """ + 获取 chat_id 的显示名称 + 尝试解析 JSON 并查询 ChatStreams 表获取群聊名称 + """ + stream_ids = parse_chat_id_to_stream_ids(chat_id_str) + + if not stream_ids: + return chat_id_str + + # 查询所有 stream_id 对应的名称 + names = [] + for stream_id in stream_ids: + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == stream_id) + if chat_stream and chat_stream.group_name: + names.append(chat_stream.group_name) + else: + # 如果没找到,显示截断的 stream_id + names.append(stream_id[:8] + "..." if len(stream_id) > 8 else stream_id) + + return ", ".join(names) if names else chat_id_str + + +# ==================== 请求/响应模型 ==================== + + +class JargonResponse(BaseModel): + """黑话信息响应""" + + id: int + content: str + raw_content: Optional[str] = None + meaning: Optional[str] = None + chat_id: str + stream_id: Optional[str] = None # 解析后的 stream_id,用于前端编辑时匹配 + chat_name: Optional[str] = None # 解析后的聊天名称,用于前端显示 + is_global: bool = False + count: int = 0 + is_jargon: Optional[bool] = None + is_complete: bool = False + inference_with_context: Optional[str] = None + inference_content_only: Optional[str] = None + + +class JargonListResponse(BaseModel): + """黑话列表响应""" + + success: bool = True + total: int + page: int + page_size: int + data: List[JargonResponse] + + +class JargonDetailResponse(BaseModel): + """黑话详情响应""" + + success: bool = True + data: JargonResponse + + +class JargonCreateRequest(BaseModel): + """黑话创建请求""" + + content: str = Field(..., description="黑话内容") + raw_content: Optional[str] = Field(None, description="原始内容") + meaning: Optional[str] = Field(None, description="含义") + chat_id: str = Field(..., description="聊天ID") + is_global: bool = Field(False, description="是否全局") + + +class JargonUpdateRequest(BaseModel): + """黑话更新请求""" + + content: Optional[str] = None + raw_content: Optional[str] = None + meaning: Optional[str] = None + chat_id: Optional[str] = None + is_global: Optional[bool] = None + is_jargon: Optional[bool] = None + + +class JargonCreateResponse(BaseModel): + """黑话创建响应""" + + success: bool = True + message: str + data: JargonResponse + + +class JargonUpdateResponse(BaseModel): + """黑话更新响应""" + + success: bool = True + message: str + data: Optional[JargonResponse] = None + + +class JargonDeleteResponse(BaseModel): + """黑话删除响应""" + + success: bool = True + message: str + deleted_count: int = 0 + + +class BatchDeleteRequest(BaseModel): + """批量删除请求""" + + ids: List[int] = Field(..., description="要删除的黑话ID列表") + + +class JargonStatsResponse(BaseModel): + """黑话统计响应""" + + success: bool = True + data: dict + + +class ChatInfoResponse(BaseModel): + """聊天信息响应""" + + chat_id: str + chat_name: str + platform: Optional[str] = None + is_group: bool = False + + +class ChatListResponse(BaseModel): + """聊天列表响应""" + + success: bool = True + data: List[ChatInfoResponse] + + +# ==================== 工具函数 ==================== + + +def jargon_to_dict(jargon: Jargon) -> dict: + """将 Jargon ORM 对象转换为字典""" + # 解析 chat_id 获取显示名称和 stream_id + chat_name = get_display_name_for_chat_id(jargon.chat_id) if jargon.chat_id else None + stream_ids = parse_chat_id_to_stream_ids(jargon.chat_id) if jargon.chat_id else [] + stream_id = stream_ids[0] if stream_ids else None + + return { + "id": jargon.id, + "content": jargon.content, + "raw_content": jargon.raw_content, + "meaning": jargon.meaning, + "chat_id": jargon.chat_id, + "stream_id": stream_id, + "chat_name": chat_name, + "is_global": jargon.is_global, + "count": jargon.count, + "is_jargon": jargon.is_jargon, + "is_complete": jargon.is_complete, + "inference_with_context": jargon.inference_with_context, + "inference_content_only": jargon.inference_content_only, + } + + +# ==================== API 端点 ==================== + + +@router.get("/list", response_model=JargonListResponse) +async def get_jargon_list( + page: int = Query(1, ge=1, description="页码"), + page_size: int = Query(20, ge=1, le=100, description="每页数量"), + search: Optional[str] = Query(None, description="搜索关键词"), + chat_id: Optional[str] = Query(None, description="按聊天ID筛选"), + is_jargon: Optional[bool] = Query(None, description="按是否是黑话筛选"), + is_global: Optional[bool] = Query(None, description="按是否全局筛选"), +): + """获取黑话列表""" + try: + # 构建查询 + query = Jargon.select() + + # 搜索过滤 + if search: + query = query.where( + (Jargon.content.contains(search)) + | (Jargon.meaning.contains(search)) + | (Jargon.raw_content.contains(search)) + ) + + # 按聊天ID筛选(使用 contains 匹配,因为 chat_id 是 JSON 格式) + if chat_id: + # 从传入的 chat_id 中解析出 stream_id + stream_ids = parse_chat_id_to_stream_ids(chat_id) + if stream_ids: + # 使用第一个 stream_id 进行模糊匹配 + query = query.where(Jargon.chat_id.contains(stream_ids[0])) + else: + # 如果无法解析,使用精确匹配 + query = query.where(Jargon.chat_id == chat_id) + + # 按是否是黑话筛选 + if is_jargon is not None: + query = query.where(Jargon.is_jargon == is_jargon) + + # 按是否全局筛选 + if is_global is not None: + query = query.where(Jargon.is_global == is_global) + + # 获取总数 + total = query.count() + + # 分页和排序(按使用次数降序) + query = query.order_by(Jargon.count.desc(), Jargon.id.desc()) + query = query.paginate(page, page_size) + + # 转换为响应格式 + data = [jargon_to_dict(j) for j in query] + + return JargonListResponse( + success=True, + total=total, + page=page, + page_size=page_size, + data=data, + ) + + except Exception as e: + logger.error(f"获取黑话列表失败: {e}") + raise HTTPException(status_code=500, detail=f"获取黑话列表失败: {str(e)}") from e + + +@router.get("/chats", response_model=ChatListResponse) +async def get_chat_list(): + """获取所有有黑话记录的聊天列表""" + try: + # 获取所有不同的 chat_id + chat_ids = Jargon.select(Jargon.chat_id).distinct().where(Jargon.chat_id.is_null(False)) + + chat_id_list = [j.chat_id for j in chat_ids if j.chat_id] + + # 用于按 stream_id 去重 + seen_stream_ids: set[str] = set() + + for chat_id in chat_id_list: + stream_ids = parse_chat_id_to_stream_ids(chat_id) + if stream_ids: + seen_stream_ids.add(stream_ids[0]) + + result = [] + for stream_id in seen_stream_ids: + # 尝试从 ChatStreams 表获取聊天名称 + chat_stream = ChatStreams.get_or_none(ChatStreams.stream_id == stream_id) + if chat_stream: + result.append( + ChatInfoResponse( + chat_id=stream_id, # 使用 stream_id,方便筛选匹配 + chat_name=chat_stream.group_name or stream_id, + platform=chat_stream.platform, + is_group=True, + ) + ) + else: + result.append( + ChatInfoResponse( + chat_id=stream_id, # 使用 stream_id + chat_name=stream_id[:8] + "..." if len(stream_id) > 8 else stream_id, + platform=None, + is_group=False, + ) + ) + + return ChatListResponse(success=True, data=result) + + except Exception as e: + logger.error(f"获取聊天列表失败: {e}") + raise HTTPException(status_code=500, detail=f"获取聊天列表失败: {str(e)}") from e + + +@router.get("/stats/summary", response_model=JargonStatsResponse) +async def get_jargon_stats(): + """获取黑话统计数据""" + try: + # 总数量 + total = Jargon.select().count() + + # 已确认是黑话的数量 + confirmed_jargon = Jargon.select().where(Jargon.is_jargon).count() + + # 已确认不是黑话的数量 + confirmed_not_jargon = Jargon.select().where(~Jargon.is_jargon).count() + + # 未判定的数量 + pending = Jargon.select().where(Jargon.is_jargon.is_null()).count() + + # 全局黑话数量 + global_count = Jargon.select().where(Jargon.is_global).count() + + # 已完成推断的数量 + complete_count = Jargon.select().where(Jargon.is_complete).count() + + # 关联的聊天数量 + chat_count = Jargon.select(Jargon.chat_id).distinct().where(Jargon.chat_id.is_null(False)).count() + + # 按聊天统计 TOP 5 + top_chats = ( + Jargon.select(Jargon.chat_id, fn.COUNT(Jargon.id).alias("count")) + .group_by(Jargon.chat_id) + .order_by(fn.COUNT(Jargon.id).desc()) + .limit(5) + ) + top_chats_dict = {j.chat_id: j.count for j in top_chats if j.chat_id} + + return JargonStatsResponse( + success=True, + data={ + "total": total, + "confirmed_jargon": confirmed_jargon, + "confirmed_not_jargon": confirmed_not_jargon, + "pending": pending, + "global_count": global_count, + "complete_count": complete_count, + "chat_count": chat_count, + "top_chats": top_chats_dict, + }, + ) + + except Exception as e: + logger.error(f"获取黑话统计失败: {e}") + raise HTTPException(status_code=500, detail=f"获取黑话统计失败: {str(e)}") from e + + +@router.get("/{jargon_id}", response_model=JargonDetailResponse) +async def get_jargon_detail(jargon_id: int): + """获取黑话详情""" + try: + jargon = Jargon.get_or_none(Jargon.id == jargon_id) + if not jargon: + raise HTTPException(status_code=404, detail="黑话不存在") + + return JargonDetailResponse(success=True, data=jargon_to_dict(jargon)) + + except HTTPException: + raise + except Exception as e: + logger.error(f"获取黑话详情失败: {e}") + raise HTTPException(status_code=500, detail=f"获取黑话详情失败: {str(e)}") from e + + +@router.post("/", response_model=JargonCreateResponse) +async def create_jargon(request: JargonCreateRequest): + """创建黑话""" + try: + # 检查是否已存在相同内容的黑话 + existing = Jargon.get_or_none((Jargon.content == request.content) & (Jargon.chat_id == request.chat_id)) + if existing: + raise HTTPException(status_code=400, detail="该聊天中已存在相同内容的黑话") + + # 创建黑话 + jargon = Jargon.create( + content=request.content, + raw_content=request.raw_content, + meaning=request.meaning, + chat_id=request.chat_id, + is_global=request.is_global, + count=0, + is_jargon=None, + is_complete=False, + ) + + logger.info(f"创建黑话成功: id={jargon.id}, content={request.content}") + + return JargonCreateResponse( + success=True, + message="创建成功", + data=jargon_to_dict(jargon), + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"创建黑话失败: {e}") + raise HTTPException(status_code=500, detail=f"创建黑话失败: {str(e)}") from e + + +@router.patch("/{jargon_id}", response_model=JargonUpdateResponse) +async def update_jargon(jargon_id: int, request: JargonUpdateRequest): + """更新黑话(增量更新)""" + try: + jargon = Jargon.get_or_none(Jargon.id == jargon_id) + if not jargon: + raise HTTPException(status_code=404, detail="黑话不存在") + + # 增量更新字段 + update_data = request.model_dump(exclude_unset=True) + if update_data: + for field, value in update_data.items(): + if value is not None or field in ["meaning", "raw_content", "is_jargon"]: + setattr(jargon, field, value) + jargon.save() + + logger.info(f"更新黑话成功: id={jargon_id}") + + return JargonUpdateResponse( + success=True, + message="更新成功", + data=jargon_to_dict(jargon), + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"更新黑话失败: {e}") + raise HTTPException(status_code=500, detail=f"更新黑话失败: {str(e)}") from e + + +@router.delete("/{jargon_id}", response_model=JargonDeleteResponse) +async def delete_jargon(jargon_id: int): + """删除黑话""" + try: + jargon = Jargon.get_or_none(Jargon.id == jargon_id) + if not jargon: + raise HTTPException(status_code=404, detail="黑话不存在") + + content = jargon.content + jargon.delete_instance() + + logger.info(f"删除黑话成功: id={jargon_id}, content={content}") + + return JargonDeleteResponse( + success=True, + message="删除成功", + deleted_count=1, + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"删除黑话失败: {e}") + raise HTTPException(status_code=500, detail=f"删除黑话失败: {str(e)}") from e + + +@router.post("/batch/delete", response_model=JargonDeleteResponse) +async def batch_delete_jargons(request: BatchDeleteRequest): + """批量删除黑话""" + try: + if not request.ids: + raise HTTPException(status_code=400, detail="ID列表不能为空") + + deleted_count = Jargon.delete().where(Jargon.id.in_(request.ids)).execute() + + logger.info(f"批量删除黑话成功: 删除了 {deleted_count} 条记录") + + return JargonDeleteResponse( + success=True, + message=f"成功删除 {deleted_count} 条黑话", + deleted_count=deleted_count, + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"批量删除黑话失败: {e}") + raise HTTPException(status_code=500, detail=f"批量删除黑话失败: {str(e)}") from e + + +@router.post("/batch/set-jargon", response_model=JargonUpdateResponse) +async def batch_set_jargon_status( + ids: Annotated[List[int], Query(description="黑话ID列表")], + is_jargon: Annotated[bool, Query(description="是否是黑话")], +): + """批量设置黑话状态""" + try: + if not ids: + raise HTTPException(status_code=400, detail="ID列表不能为空") + + updated_count = Jargon.update(is_jargon=is_jargon).where(Jargon.id.in_(ids)).execute() + + logger.info(f"批量更新黑话状态成功: 更新了 {updated_count} 条记录,is_jargon={is_jargon}") + + return JargonUpdateResponse( + success=True, + message=f"成功更新 {updated_count} 条黑话状态", + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"批量更新黑话状态失败: {e}") + raise HTTPException(status_code=500, detail=f"批量更新黑话状态失败: {str(e)}") from e diff --git a/src/webui/knowledge_routes.py b/src/webui/knowledge_routes.py new file mode 100644 index 00000000..87b2e7b5 --- /dev/null +++ b/src/webui/knowledge_routes.py @@ -0,0 +1,298 @@ +"""知识库图谱可视化 API 路由""" + +from typing import List, Optional +from fastapi import APIRouter, Query, Depends, Cookie, Header +from pydantic import BaseModel +import logging +from src.webui.auth import verify_auth_token_from_cookie_or_header + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/api/webui/knowledge", tags=["knowledge"]) + + +def require_auth( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> bool: + """认证依赖:验证用户是否已登录""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) + + +class KnowledgeNode(BaseModel): + """知识节点""" + + id: str + type: str # 'entity' or 'paragraph' + content: str + create_time: Optional[float] = None + + +class KnowledgeEdge(BaseModel): + """知识边""" + + source: str + target: str + weight: float + create_time: Optional[float] = None + update_time: Optional[float] = None + + +class KnowledgeGraph(BaseModel): + """知识图谱""" + + nodes: List[KnowledgeNode] + edges: List[KnowledgeEdge] + + +class KnowledgeStats(BaseModel): + """知识库统计信息""" + + total_nodes: int + total_edges: int + entity_nodes: int + paragraph_nodes: int + avg_connections: float + + +def _load_kg_manager(): + """延迟加载 KGManager""" + try: + from src.chat.knowledge.kg_manager import KGManager + + kg_manager = KGManager() + kg_manager.load_from_file() + return kg_manager + except Exception as e: + logger.error(f"加载 KGManager 失败: {e}") + return None + + +def _convert_graph_to_json(kg_manager) -> KnowledgeGraph: + """将 DiGraph 转换为 JSON 格式""" + if kg_manager is None or kg_manager.graph is None: + return KnowledgeGraph(nodes=[], edges=[]) + + graph = kg_manager.graph + nodes = [] + edges = [] + + # 转换节点 + node_list = graph.get_node_list() + for node_id in node_list: + try: + node_data = graph[node_id] + # 节点类型: "ent" -> "entity", "pg" -> "paragraph" + node_type = "entity" if ("type" in node_data and node_data["type"] == "ent") else "paragraph" + content = node_data["content"] if "content" in node_data else node_id + create_time = node_data["create_time"] if "create_time" in node_data else None + + nodes.append(KnowledgeNode(id=node_id, type=node_type, content=content, create_time=create_time)) + except Exception as e: + logger.warning(f"跳过节点 {node_id}: {e}") + continue + + # 转换边 + edge_list = graph.get_edge_list() + for edge_tuple in edge_list: + try: + # edge_tuple 是 (source, target) 元组 + source, target = edge_tuple[0], edge_tuple[1] + # 通过 graph[source, target] 获取边的属性数据 + edge_data = graph[source, target] + + # edge_data 支持 [] 操作符但不支持 .get() + weight = edge_data["weight"] if "weight" in edge_data else 1.0 + create_time = edge_data["create_time"] if "create_time" in edge_data else None + update_time = edge_data["update_time"] if "update_time" in edge_data else None + + edges.append( + KnowledgeEdge( + source=source, target=target, weight=weight, create_time=create_time, update_time=update_time + ) + ) + except Exception as e: + logger.warning(f"跳过边 {edge_tuple}: {e}") + continue + + return KnowledgeGraph(nodes=nodes, edges=edges) + + +@router.get("/graph", response_model=KnowledgeGraph) +async def get_knowledge_graph( + limit: int = Query(100, ge=1, le=10000, description="返回的最大节点数"), + node_type: str = Query("all", description="节点类型过滤: all, entity, paragraph"), + _auth: bool = Depends(require_auth), +): + """获取知识图谱(限制节点数量) + + Args: + limit: 返回的最大节点数,默认 100,最大 10000 + node_type: 节点类型过滤 - all(全部), entity(实体), paragraph(段落) + + Returns: + KnowledgeGraph: 包含指定数量节点和相关边的知识图谱 + """ + try: + kg_manager = _load_kg_manager() + if kg_manager is None: + logger.warning("KGManager 未初始化,返回空图谱") + return KnowledgeGraph(nodes=[], edges=[]) + + graph = kg_manager.graph + all_node_list = graph.get_node_list() + + # 按类型过滤节点 + if node_type == "entity": + all_node_list = [ + n for n in all_node_list if n in graph and "type" in graph[n] and graph[n]["type"] == "ent" + ] + elif node_type == "paragraph": + all_node_list = [n for n in all_node_list if n in graph and "type" in graph[n] and graph[n]["type"] == "pg"] + + # 限制节点数量 + total_nodes = len(all_node_list) + if len(all_node_list) > limit: + node_list = all_node_list[:limit] + else: + node_list = all_node_list + + logger.info(f"总节点数: {total_nodes}, 返回节点: {len(node_list)} (limit={limit}, type={node_type})") + + # 转换节点 + nodes = [] + node_ids = set() + for node_id in node_list: + try: + node_data = graph[node_id] + node_type_val = "entity" if ("type" in node_data and node_data["type"] == "ent") else "paragraph" + content = node_data["content"] if "content" in node_data else node_id + create_time = node_data["create_time"] if "create_time" in node_data else None + + nodes.append(KnowledgeNode(id=node_id, type=node_type_val, content=content, create_time=create_time)) + node_ids.add(node_id) + except Exception as e: + logger.warning(f"跳过节点 {node_id}: {e}") + continue + + # 只获取涉及当前节点集的边(保证图的完整性) + edges = [] + edge_list = graph.get_edge_list() + for edge_tuple in edge_list: + try: + source, target = edge_tuple[0], edge_tuple[1] + # 只包含两端都在当前节点集中的边 + if source not in node_ids or target not in node_ids: + continue + + edge_data = graph[source, target] + weight = edge_data["weight"] if "weight" in edge_data else 1.0 + create_time = edge_data["create_time"] if "create_time" in edge_data else None + update_time = edge_data["update_time"] if "update_time" in edge_data else None + + edges.append( + KnowledgeEdge( + source=source, target=target, weight=weight, create_time=create_time, update_time=update_time + ) + ) + except Exception as e: + logger.warning(f"跳过边 {edge_tuple}: {e}") + continue + + graph_data = KnowledgeGraph(nodes=nodes, edges=edges) + logger.info(f"返回知识图谱: {len(nodes)} 个节点, {len(edges)} 条边") + return graph_data + + except Exception as e: + logger.error(f"获取知识图谱失败: {e}", exc_info=True) + return KnowledgeGraph(nodes=[], edges=[]) + + +@router.get("/stats", response_model=KnowledgeStats) +async def get_knowledge_stats(_auth: bool = Depends(require_auth)): + """获取知识库统计信息 + + Returns: + KnowledgeStats: 统计信息 + """ + try: + kg_manager = _load_kg_manager() + if kg_manager is None or kg_manager.graph is None: + return KnowledgeStats(total_nodes=0, total_edges=0, entity_nodes=0, paragraph_nodes=0, avg_connections=0.0) + + graph = kg_manager.graph + node_list = graph.get_node_list() + edge_list = graph.get_edge_list() + + total_nodes = len(node_list) + total_edges = len(edge_list) + + # 统计节点类型 + entity_nodes = 0 + paragraph_nodes = 0 + for node_id in node_list: + try: + node_data = graph[node_id] + node_type = node_data["type"] if "type" in node_data else "ent" + if node_type == "ent": + entity_nodes += 1 + elif node_type == "pg": + paragraph_nodes += 1 + except Exception: + continue + + # 计算平均连接数 + avg_connections = (total_edges * 2) / total_nodes if total_nodes > 0 else 0.0 + + return KnowledgeStats( + total_nodes=total_nodes, + total_edges=total_edges, + entity_nodes=entity_nodes, + paragraph_nodes=paragraph_nodes, + avg_connections=round(avg_connections, 2), + ) + + except Exception as e: + logger.error(f"获取统计信息失败: {e}", exc_info=True) + return KnowledgeStats(total_nodes=0, total_edges=0, entity_nodes=0, paragraph_nodes=0, avg_connections=0.0) + + +@router.get("/search", response_model=List[KnowledgeNode]) +async def search_knowledge_node(query: str = Query(..., min_length=1), _auth: bool = Depends(require_auth)): + """搜索知识节点 + + Args: + query: 搜索关键词 + + Returns: + List[KnowledgeNode]: 匹配的节点列表 + """ + try: + kg_manager = _load_kg_manager() + if kg_manager is None or kg_manager.graph is None: + return [] + + graph = kg_manager.graph + node_list = graph.get_node_list() + results = [] + query_lower = query.lower() + + # 在节点内容中搜索 + for node_id in node_list: + try: + node_data = graph[node_id] + content = node_data["content"] if "content" in node_data else node_id + node_type = "entity" if ("type" in node_data and node_data["type"] == "ent") else "paragraph" + + if query_lower in content.lower() or query_lower in node_id.lower(): + create_time = node_data["create_time"] if "create_time" in node_data else None + results.append(KnowledgeNode(id=node_id, type=node_type, content=content, create_time=create_time)) + except Exception: + continue + + logger.info(f"搜索 '{query}' 找到 {len(results)} 个节点") + return results[:50] # 限制返回数量 + + except Exception as e: + logger.error(f"搜索节点失败: {e}", exc_info=True) + return [] diff --git a/src/webui/logs_ws.py b/src/webui/logs_ws.py index e0e0a9a1..5ae92189 100644 --- a/src/webui/logs_ws.py +++ b/src/webui/logs_ws.py @@ -1,10 +1,12 @@ """WebSocket 日志推送模块""" -from fastapi import APIRouter, WebSocket, WebSocketDisconnect -from typing import Set +from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query +from typing import Set, Optional import json from pathlib import Path from src.common.logger import get_logger +from src.webui.token_manager import get_token_manager +from src.webui.ws_auth import verify_ws_token logger = get_logger("webui.logs_ws") router = APIRouter() @@ -73,14 +75,48 @@ def load_recent_logs(limit: int = 100) -> list[dict]: @router.websocket("/ws/logs") -async def websocket_logs(websocket: WebSocket): +async def websocket_logs(websocket: WebSocket, token: Optional[str] = Query(None)): """WebSocket 日志推送端点 客户端连接后会持续接收服务器端的日志消息 + 支持三种认证方式(按优先级): + 1. query 参数 token(推荐,通过 /api/webui/ws-token 获取临时 token) + 2. Cookie 中的 maibot_session + 3. 直接使用 session token(兼容) + + 示例:ws://host/ws/logs?token=xxx """ + is_authenticated = False + + # 方式 1: 尝试验证临时 WebSocket token(推荐方式) + if token and verify_ws_token(token): + is_authenticated = True + logger.debug("WebSocket 使用临时 token 认证成功") + + # 方式 2: 尝试从 Cookie 获取 session token + if not is_authenticated: + cookie_token = websocket.cookies.get("maibot_session") + if cookie_token: + token_manager = get_token_manager() + if token_manager.verify_token(cookie_token): + is_authenticated = True + logger.debug("WebSocket 使用 Cookie 认证成功") + + # 方式 3: 尝试直接验证 query 参数作为 session token(兼容旧方式) + if not is_authenticated and token: + token_manager = get_token_manager() + if token_manager.verify_token(token): + is_authenticated = True + logger.debug("WebSocket 使用 session token 认证成功") + + if not is_authenticated: + logger.warning("WebSocket 连接被拒绝:认证失败") + await websocket.close(code=4001, reason="认证失败,请重新登录") + return + await websocket.accept() active_connections.add(websocket) - logger.info(f"📡 WebSocket 客户端已连接,当前连接数: {len(active_connections)}") + logger.info(f"📡 WebSocket 客户端已连接(已认证),当前连接数: {len(active_connections)}") # 连接建立后,立即发送历史日志 try: diff --git a/src/webui/model_routes.py b/src/webui/model_routes.py new file mode 100644 index 00000000..a84241b9 --- /dev/null +++ b/src/webui/model_routes.py @@ -0,0 +1,383 @@ +""" +模型列表获取API路由 + +提供从各个 AI 厂商 API 获取可用模型列表的代理接口 +""" + +import os +import httpx +from fastapi import APIRouter, HTTPException, Query, Depends, Cookie, Header +from typing import Optional +import tomlkit + +from src.common.logger import get_logger +from src.config.config import CONFIG_DIR +from src.webui.auth import verify_auth_token_from_cookie_or_header + +logger = get_logger("webui") + +router = APIRouter(prefix="/models", tags=["models"]) + + +def require_auth( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> bool: + """认证依赖:验证用户是否已登录""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) + + +# 模型获取器配置 +MODEL_FETCHER_CONFIG = { + # OpenAI 兼容格式的提供商 + "openai": { + "endpoint": "/models", + "parser": "openai", + }, + # Gemini 格式 + "gemini": { + "endpoint": "/models", + "parser": "gemini", + }, +} + + +def _normalize_url(url: str) -> str: + """规范化 URL(去掉尾部斜杠)""" + if not url: + return "" + return url.rstrip("/") + + +def _parse_openai_response(data: dict) -> list[dict]: + """ + 解析 OpenAI 格式的模型列表响应 + + 格式: { "data": [{ "id": "gpt-4", "object": "model", ... }] } + """ + models = [] + if "data" in data and isinstance(data["data"], list): + for model in data["data"]: + if isinstance(model, dict) and "id" in model: + models.append( + { + "id": model["id"], + "name": model.get("name") or model["id"], + "owned_by": model.get("owned_by", ""), + } + ) + return models + + +def _parse_gemini_response(data: dict) -> list[dict]: + """ + 解析 Gemini 格式的模型列表响应 + + 格式: { "models": [{ "name": "models/gemini-pro", "displayName": "Gemini Pro", ... }] } + """ + models = [] + if "models" in data and isinstance(data["models"], list): + for model in data["models"]: + if isinstance(model, dict) and "name" in model: + # Gemini 的 name 格式是 "models/gemini-pro",我们只取后面部分 + model_id = model["name"] + if model_id.startswith("models/"): + model_id = model_id[7:] # 去掉 "models/" 前缀 + models.append( + { + "id": model_id, + "name": model.get("displayName") or model_id, + "owned_by": "google", + } + ) + return models + + +async def _fetch_models_from_provider( + base_url: str, + api_key: str, + endpoint: str, + parser: str, + client_type: str = "openai", +) -> list[dict]: + """ + 从提供商 API 获取模型列表 + + Args: + base_url: 提供商的基础 URL + api_key: API 密钥 + endpoint: 获取模型列表的端点 + parser: 响应解析器类型 ('openai' | 'gemini') + client_type: 客户端类型 ('openai' | 'gemini') + + Returns: + 模型列表 + """ + url = f"{_normalize_url(base_url)}{endpoint}" + + # 根据客户端类型设置请求头 + headers = {} + params = {} + + if client_type == "gemini": + # Gemini 使用 URL 参数传递 API Key + params["key"] = api_key + else: + # OpenAI 兼容格式使用 Authorization 头 + headers["Authorization"] = f"Bearer {api_key}" + + try: + async with httpx.AsyncClient(timeout=30.0) as client: + response = await client.get(url, headers=headers, params=params) + response.raise_for_status() + data = response.json() + except httpx.TimeoutException as e: + raise HTTPException(status_code=504, detail="请求超时,请稍后重试") from e + except httpx.HTTPStatusError as e: + # 注意:使用 502 Bad Gateway 而不是原始的 401/403, + # 因为前端的 fetchWithAuth 会把 401 当作 WebUI 认证失败处理 + if e.response.status_code == 401: + raise HTTPException(status_code=502, detail="API Key 无效或已过期") from e + elif e.response.status_code == 403: + raise HTTPException(status_code=502, detail="没有权限访问模型列表,请检查 API Key 权限") from e + elif e.response.status_code == 404: + raise HTTPException(status_code=502, detail="该提供商不支持获取模型列表") from e + else: + raise HTTPException( + status_code=502, detail=f"上游服务请求失败 ({e.response.status_code}): {e.response.text[:200]}" + ) from e + except Exception as e: + logger.error(f"获取模型列表失败: {e}") + raise HTTPException(status_code=500, detail=f"获取模型列表失败: {str(e)}") from e + + # 根据解析器类型解析响应 + if parser == "openai": + return _parse_openai_response(data) + elif parser == "gemini": + return _parse_gemini_response(data) + else: + raise HTTPException(status_code=400, detail=f"不支持的解析器类型: {parser}") + + +def _get_provider_config(provider_name: str) -> Optional[dict]: + """ + 从 model_config.toml 获取指定提供商的配置 + + Args: + provider_name: 提供商名称 + + Returns: + 提供商配置,如果未找到则返回 None + """ + config_path = os.path.join(CONFIG_DIR, "model_config.toml") + if not os.path.exists(config_path): + return None + + try: + with open(config_path, "r", encoding="utf-8") as f: + config_data = tomlkit.load(f) + + providers = config_data.get("api_providers", []) + for provider in providers: + if provider.get("name") == provider_name: + return dict(provider) + + return None + except Exception as e: + logger.error(f"读取提供商配置失败: {e}") + return None + + +@router.get("/list") +async def get_provider_models( + provider_name: str = Query(..., description="提供商名称"), + parser: str = Query("openai", description="响应解析器类型 (openai | gemini)"), + endpoint: str = Query("/models", description="获取模型列表的端点"), + _auth: bool = Depends(require_auth), +): + """ + 获取指定提供商的可用模型列表 + + 通过提供商名称查找配置,然后请求对应的模型列表端点 + """ + # 获取提供商配置 + provider_config = _get_provider_config(provider_name) + if not provider_config: + raise HTTPException(status_code=404, detail=f"未找到提供商: {provider_name}") + + base_url = provider_config.get("base_url") + api_key = provider_config.get("api_key") + client_type = provider_config.get("client_type", "openai") + + if not base_url: + raise HTTPException(status_code=400, detail="提供商配置缺少 base_url") + if not api_key: + raise HTTPException(status_code=400, detail="提供商配置缺少 api_key") + + # 获取模型列表 + models = await _fetch_models_from_provider( + base_url=base_url, + api_key=api_key, + endpoint=endpoint, + parser=parser, + client_type=client_type, + ) + + return { + "success": True, + "models": models, + "provider": provider_name, + "count": len(models), + } + + +@router.get("/list-by-url") +async def get_models_by_url( + base_url: str = Query(..., description="提供商的基础 URL"), + api_key: str = Query(..., description="API Key"), + parser: str = Query("openai", description="响应解析器类型 (openai | gemini)"), + endpoint: str = Query("/models", description="获取模型列表的端点"), + client_type: str = Query("openai", description="客户端类型 (openai | gemini)"), + _auth: bool = Depends(require_auth), +): + """ + 通过 URL 直接获取模型列表(用于自定义提供商) + """ + models = await _fetch_models_from_provider( + base_url=base_url, + api_key=api_key, + endpoint=endpoint, + parser=parser, + client_type=client_type, + ) + + return { + "success": True, + "models": models, + "count": len(models), + } + + +@router.get("/test-connection") +async def test_provider_connection( + base_url: str = Query(..., description="提供商的基础 URL"), + api_key: Optional[str] = Query(None, description="API Key(可选,用于验证 Key 有效性)"), + _auth: bool = Depends(require_auth), +): + """ + 测试提供商连接状态 + + 分两步测试: + 1. 网络连通性测试:向 base_url 发送请求,检查是否能连接 + 2. API Key 验证(可选):如果提供了 api_key,尝试获取模型列表验证 Key 是否有效 + + 返回: + - network_ok: 网络是否连通 + - api_key_valid: API Key 是否有效(仅在提供 api_key 时返回) + - latency_ms: 响应延迟(毫秒) + - error: 错误信息(如果有) + """ + import time + + base_url = _normalize_url(base_url) + if not base_url: + raise HTTPException(status_code=400, detail="base_url 不能为空") + + result = { + "network_ok": False, + "api_key_valid": None, + "latency_ms": None, + "error": None, + "http_status": None, + } + + # 第一步:测试网络连通性 + try: + start_time = time.time() + async with httpx.AsyncClient(timeout=10.0, follow_redirects=True) as client: + # 尝试 GET 请求 base_url(不需要 API Key) + response = await client.get(base_url) + latency = (time.time() - start_time) * 1000 + + result["network_ok"] = True + result["latency_ms"] = round(latency, 2) + result["http_status"] = response.status_code + + except httpx.ConnectError as e: + result["error"] = f"连接失败:无法连接到服务器 ({str(e)})" + return result + except httpx.TimeoutException: + result["error"] = "连接超时:服务器响应时间过长" + return result + except httpx.RequestError as e: + result["error"] = f"请求错误:{str(e)}" + return result + except Exception as e: + result["error"] = f"未知错误:{str(e)}" + return result + + # 第二步:如果提供了 API Key,验证其有效性 + if api_key: + try: + start_time = time.time() + async with httpx.AsyncClient(timeout=15.0, follow_redirects=True) as client: + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json", + } + # 尝试获取模型列表 + models_url = f"{base_url}/models" + response = await client.get(models_url, headers=headers) + + if response.status_code == 200: + result["api_key_valid"] = True + elif response.status_code in (401, 403): + result["api_key_valid"] = False + result["error"] = "API Key 无效或已过期" + else: + # 其他状态码,可能是端点不支持,但 Key 可能是有效的 + result["api_key_valid"] = None + + except Exception as e: + # API Key 验证失败不影响网络连通性结果 + logger.warning(f"API Key 验证失败: {e}") + result["api_key_valid"] = None + + return result + + +@router.post("/test-connection-by-name") +async def test_provider_connection_by_name( + provider_name: str = Query(..., description="提供商名称"), + _auth: bool = Depends(require_auth), +): + """ + 通过提供商名称测试连接(从配置文件读取信息) + """ + # 读取配置文件 + model_config_path = os.path.join(CONFIG_DIR, "model_config.toml") + if not os.path.exists(model_config_path): + raise HTTPException(status_code=404, detail="配置文件不存在") + + with open(model_config_path, "r", encoding="utf-8") as f: + config = tomlkit.load(f) + + # 查找提供商 + providers = config.get("api_providers", []) + provider = None + for p in providers: + if p.get("name") == provider_name: + provider = p + break + + if not provider: + raise HTTPException(status_code=404, detail=f"未找到提供商: {provider_name}") + + base_url = provider.get("base_url", "") + api_key = provider.get("api_key", "") + + if not base_url: + raise HTTPException(status_code=400, detail="提供商配置缺少 base_url") + + # 调用测试接口 + return await test_provider_connection(base_url=base_url, api_key=api_key if api_key else None) diff --git a/src/webui/person_routes.py b/src/webui/person_routes.py index 5935a2fa..9881d44e 100644 --- a/src/webui/person_routes.py +++ b/src/webui/person_routes.py @@ -1,11 +1,11 @@ """人物信息管理 API 路由""" -from fastapi import APIRouter, HTTPException, Header, Query +from fastapi import APIRouter, HTTPException, Header, Query, Cookie from pydantic import BaseModel from typing import Optional, List, Dict from src.common.logger import get_logger from src.common.database.database_model import PersonInfo -from .token_manager import get_token_manager +from .auth import verify_auth_token_from_cookie_or_header import json import time @@ -91,18 +91,12 @@ class BatchDeleteResponse(BaseModel): failed_ids: List[str] = [] -def verify_auth_token(authorization: Optional[str]) -> bool: - """验证认证 Token""" - if not authorization or not authorization.startswith("Bearer "): - raise HTTPException(status_code=401, detail="未提供有效的认证信息") - - token = authorization.replace("Bearer ", "") - token_manager = get_token_manager() - - if not token_manager.verify_token(token): - raise HTTPException(status_code=401, detail="Token 无效或已过期") - - return True +def verify_auth_token( + maibot_session: Optional[str] = None, + authorization: Optional[str] = None, +) -> bool: + """验证认证 Token,支持 Cookie 和 Header""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) def parse_group_nick_name(group_nick_name_str: Optional[str]) -> Optional[List[Dict[str, str]]]: @@ -141,6 +135,7 @@ async def get_person_list( search: Optional[str] = Query(None, description="搜索关键词"), is_known: Optional[bool] = Query(None, description="是否已认识筛选"), platform: Optional[str] = Query(None, description="平台筛选"), + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None), ): """ @@ -158,7 +153,7 @@ async def get_person_list( 人物信息列表 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) # 构建查询 query = PersonInfo.select() @@ -205,7 +200,9 @@ async def get_person_list( @router.get("/{person_id}", response_model=PersonDetailResponse) -async def get_person_detail(person_id: str, authorization: Optional[str] = Header(None)): +async def get_person_detail( + person_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 获取人物详细信息 @@ -217,7 +214,7 @@ async def get_person_detail(person_id: str, authorization: Optional[str] = Heade 人物详细信息 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) person = PersonInfo.get_or_none(PersonInfo.person_id == person_id) @@ -234,7 +231,12 @@ async def get_person_detail(person_id: str, authorization: Optional[str] = Heade @router.patch("/{person_id}", response_model=PersonUpdateResponse) -async def update_person(person_id: str, request: PersonUpdateRequest, authorization: Optional[str] = Header(None)): +async def update_person( + person_id: str, + request: PersonUpdateRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 增量更新人物信息(只更新提供的字段) @@ -247,7 +249,7 @@ async def update_person(person_id: str, request: PersonUpdateRequest, authorizat 更新结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) person = PersonInfo.get_or_none(PersonInfo.person_id == person_id) @@ -283,7 +285,9 @@ async def update_person(person_id: str, request: PersonUpdateRequest, authorizat @router.delete("/{person_id}", response_model=PersonDeleteResponse) -async def delete_person(person_id: str, authorization: Optional[str] = Header(None)): +async def delete_person( + person_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +): """ 删除人物信息 @@ -295,7 +299,7 @@ async def delete_person(person_id: str, authorization: Optional[str] = Header(No 删除结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) person = PersonInfo.get_or_none(PersonInfo.person_id == person_id) @@ -320,7 +324,7 @@ async def delete_person(person_id: str, authorization: Optional[str] = Header(No @router.get("/stats/summary") -async def get_person_stats(authorization: Optional[str] = Header(None)): +async def get_person_stats(maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None)): """ 获取人物信息统计数据 @@ -331,7 +335,7 @@ async def get_person_stats(authorization: Optional[str] = Header(None)): 统计数据 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) total = PersonInfo.select().count() known = PersonInfo.select().where(PersonInfo.is_known).count() @@ -353,7 +357,11 @@ async def get_person_stats(authorization: Optional[str] = Header(None)): @router.post("/batch/delete", response_model=BatchDeleteResponse) -async def batch_delete_persons(request: BatchDeleteRequest, authorization: Optional[str] = Header(None)): +async def batch_delete_persons( + request: BatchDeleteRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 批量删除人物信息 @@ -365,7 +373,7 @@ async def batch_delete_persons(request: BatchDeleteRequest, authorization: Optio 批量删除结果 """ try: - verify_auth_token(authorization) + verify_auth_token(maibot_session, authorization) if not request.person_ids: raise HTTPException(status_code=400, detail="未提供要删除的人物ID") diff --git a/src/webui/plugin_progress_ws.py b/src/webui/plugin_progress_ws.py index 7e0fb647..8d0a18c6 100644 --- a/src/webui/plugin_progress_ws.py +++ b/src/webui/plugin_progress_ws.py @@ -1,10 +1,12 @@ """WebSocket 插件加载进度推送模块""" -from fastapi import APIRouter, WebSocket, WebSocketDisconnect -from typing import Set, Dict, Any +from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query +from typing import Set, Dict, Any, Optional import json import asyncio from src.common.logger import get_logger +from src.webui.token_manager import get_token_manager +from src.webui.ws_auth import verify_ws_token logger = get_logger("webui.plugin_progress") @@ -89,14 +91,48 @@ async def update_progress( @router.websocket("/ws/plugin-progress") -async def websocket_plugin_progress(websocket: WebSocket): +async def websocket_plugin_progress(websocket: WebSocket, token: Optional[str] = Query(None)): """WebSocket 插件加载进度推送端点 客户端连接后会立即收到当前进度状态 + 支持三种认证方式(按优先级): + 1. query 参数 token(推荐,通过 /api/webui/ws-token 获取临时 token) + 2. Cookie 中的 maibot_session + 3. 直接使用 session token(兼容) + + 示例:ws://host/ws/plugin-progress?token=xxx """ + is_authenticated = False + + # 方式 1: 尝试验证临时 WebSocket token(推荐方式) + if token and verify_ws_token(token): + is_authenticated = True + logger.debug("插件进度 WebSocket 使用临时 token 认证成功") + + # 方式 2: 尝试从 Cookie 获取 session token + if not is_authenticated: + cookie_token = websocket.cookies.get("maibot_session") + if cookie_token: + token_manager = get_token_manager() + if token_manager.verify_token(cookie_token): + is_authenticated = True + logger.debug("插件进度 WebSocket 使用 Cookie 认证成功") + + # 方式 3: 尝试直接验证 query 参数作为 session token(兼容旧方式) + if not is_authenticated and token: + token_manager = get_token_manager() + if token_manager.verify_token(token): + is_authenticated = True + logger.debug("插件进度 WebSocket 使用 session token 认证成功") + + if not is_authenticated: + logger.warning("插件进度 WebSocket 连接被拒绝:认证失败") + await websocket.close(code=4001, reason="认证失败,请重新登录") + return + await websocket.accept() active_connections.add(websocket) - logger.info(f"📡 插件进度 WebSocket 客户端已连接,当前连接数: {len(active_connections)}") + logger.info(f"📡 插件进度 WebSocket 客户端已连接(已认证),当前连接数: {len(active_connections)}") try: # 发送当前进度状态 diff --git a/src/webui/plugin_routes.py b/src/webui/plugin_routes.py index cb559fb7..df459e5e 100644 --- a/src/webui/plugin_routes.py +++ b/src/webui/plugin_routes.py @@ -1,10 +1,12 @@ -from fastapi import APIRouter, HTTPException, Header +from fastapi import APIRouter, HTTPException, Header, Cookie from pydantic import BaseModel, Field -from typing import Optional, List, Dict, Any +from typing import Optional, List, Dict, Any, get_origin from pathlib import Path import json from src.common.logger import get_logger +from src.common.toml_utils import save_toml_with_format from src.config.config import MMC_VERSION +from src.plugin_system.base.config_types import ConfigField from .git_mirror_service import get_git_mirror_service, set_update_progress_callback from .token_manager import get_token_manager from .plugin_progress_ws import update_progress @@ -18,6 +20,99 @@ router = APIRouter(prefix="/plugins", tags=["插件管理"]) set_update_progress_callback(update_progress) +def get_token_from_cookie_or_header( + maibot_session: Optional[str] = None, + authorization: Optional[str] = None, +) -> Optional[str]: + """从 Cookie 或 Header 获取 token""" + # 优先从 Cookie 获取 + if maibot_session: + return maibot_session + # 其次从 Header 获取 + if authorization and authorization.startswith("Bearer "): + return authorization.replace("Bearer ", "") + return None + + +def validate_safe_path(user_path: str, base_path: Path) -> Path: + """ + 验证用户提供的路径是否安全,防止路径遍历攻击 + + Args: + user_path: 用户输入的路径(相对路径) + base_path: 允许的基础目录 + + Returns: + 安全的绝对路径 + + Raises: + HTTPException: 如果检测到路径遍历攻击 + """ + # 规范化基础路径 + base_resolved = base_path.resolve() + + # 检查用户路径是否包含可疑字符 + # 禁止: .., 绝对路径开头, 空字节等 + if any(pattern in user_path for pattern in ["..", "\x00"]): + logger.warning(f"检测到可疑路径: {user_path}") + raise HTTPException(status_code=400, detail="路径包含非法字符") + + # 检查是否为绝对路径(Windows 和 Unix) + if user_path.startswith("/") or user_path.startswith("\\") or (len(user_path) > 1 and user_path[1] == ":"): + logger.warning(f"检测到绝对路径: {user_path}") + raise HTTPException(status_code=400, detail="不允许使用绝对路径") + + # 构建目标路径并解析 + target_path = (base_path / user_path).resolve() + + # 验证解析后的路径仍在基础目录内 + try: + target_path.relative_to(base_resolved) + except ValueError as e: + logger.warning(f"路径遍历攻击检测: {user_path} -> {target_path}") + raise HTTPException(status_code=400, detail="路径超出允许范围") from e + + return target_path + + +def validate_plugin_id(plugin_id: str) -> str: + """ + 验证插件 ID 格式是否安全 + + Args: + plugin_id: 插件 ID (支持 author.name 格式,允许中文) + + Returns: + 验证通过的插件 ID + + Raises: + HTTPException: 如果插件 ID 格式不安全 + """ + # 禁止空字符串 + if not plugin_id or not plugin_id.strip(): + logger.warning("非法插件 ID: 空字符串") + raise HTTPException(status_code=400, detail="插件 ID 不能为空") + + # 禁止危险字符: 路径分隔符、空字节、控制字符等 + dangerous_patterns = ["/", "\\", "\x00", "..", "\n", "\r", "\t"] + for pattern in dangerous_patterns: + if pattern in plugin_id: + logger.warning(f"非法插件 ID 格式: {plugin_id} (包含危险字符)") + raise HTTPException(status_code=400, detail="插件 ID 包含非法字符") + + # 禁止以点开头或结尾(防止隐藏文件和路径问题) + if plugin_id.startswith(".") or plugin_id.endswith("."): + logger.warning(f"非法插件 ID: {plugin_id}") + raise HTTPException(status_code=400, detail="插件 ID 不能以点开头或结尾") + + # 禁止特殊名称 + if plugin_id in (".", ".."): + logger.warning(f"非法插件 ID: {plugin_id}") + raise HTTPException(status_code=400, detail="插件 ID 不能为特殊目录名") + + return plugin_id + + def parse_version(version_str: str) -> tuple[int, int, int]: """ 解析版本号字符串 @@ -29,8 +124,11 @@ def parse_version(version_str: str) -> tuple[int, int, int]: Returns: (major, minor, patch) 三元组 """ - # 移除 snapshot 等后缀 - base_version = version_str.split(".snapshot")[0].split(".dev")[0].split(".alpha")[0].split(".beta")[0] + # 移除 snapshot、dev、alpha、beta 等后缀(支持 - 和 . 分隔符) + import re + + # 匹配 -snapshot.X, .snapshot, -dev, .dev, -alpha, .alpha, -beta, .beta 等后缀 + base_version = re.split(r"[-.](?:snapshot|dev|alpha|beta|rc)", version_str, flags=re.IGNORECASE)[0] parts = base_version.split(".") if len(parts) < 3: @@ -47,6 +145,95 @@ def parse_version(version_str: str) -> tuple[int, int, int]: return (0, 0, 0) +# ============ 工具函数(避免在请求内重复定义) ============ + + +def _deep_merge(dst: Dict[str, Any], src: Dict[str, Any]) -> None: + """深度合并两个字典,src 的值会覆盖或合并到 dst 中。""" + for k, v in src.items(): + if k in dst and isinstance(dst[k], dict) and isinstance(v, dict): + _deep_merge(dst[k], v) + else: + dst[k] = v + + +def normalize_dotted_keys(obj: Dict[str, Any]) -> Dict[str, Any]: + """ + 将形如 {'a.b': 1} 的键展开为嵌套结构 {'a': {'b': 1}}。 + 若遇到中间节点已存在且非字典,记录日志并覆盖为字典。 + """ + result: Dict[str, Any] = {} + dotted_items = [] + + # 先处理非点号键,避免后续展开覆盖已有结构 + for k, v in obj.items(): + if "." in k: + dotted_items.append((k, v)) + else: + result[k] = normalize_dotted_keys(v) if isinstance(v, dict) else v + + # 再处理点号键 + for dotted_key, v in dotted_items: + value = normalize_dotted_keys(v) if isinstance(v, dict) else v + parts = dotted_key.split(".") + if "" in parts: + logger.warning(f"键路径包含空段: '{dotted_key}'") + parts = [p for p in parts if p] + if not parts: + logger.warning(f"忽略空键路径: '{dotted_key}'") + continue + current = result + # 中间层 + for idx, part in enumerate(parts[:-1]): + if part in current and not isinstance(current[part], dict): + path_ctx = ".".join(parts[: idx + 1]) + logger.warning(f"键冲突:{part} 已存在且非字典,覆盖为字典以展开 {dotted_key} (路径 {path_ctx})") + current[part] = {} + current = current.setdefault(part, {}) + # 最后一层 + last_part = parts[-1] + if last_part in current and isinstance(current[last_part], dict) and isinstance(value, dict): + _deep_merge(current[last_part], value) + else: + current[last_part] = value + + return result + + +def coerce_types(schema_part: Dict[str, Any], config_part: Dict[str, Any]) -> None: + """ + 根据 schema 将配置中的类型纠正(目前只纠正 list-from-str)。 + """ + + def _is_list_type(tp: Any) -> bool: + origin = get_origin(tp) + return tp is list or origin is list + + for key, schema_val in schema_part.items(): + if key not in config_part: + continue + value = config_part[key] + if isinstance(schema_val, ConfigField): + if _is_list_type(schema_val.type) and isinstance(value, str): + config_part[key] = [item.strip() for item in value.split(",") if item.strip()] + elif isinstance(schema_val, dict) and isinstance(value, dict): + coerce_types(schema_val, value) + + +def find_plugin_instance(plugin_id: str) -> Optional[Any]: + """ + 按 plugin_id 或 plugin_name 查找已加载的插件实例。 + 局部导入 plugin_manager 以规避循环依赖。 + """ + from src.plugin_system.core.plugin_manager import plugin_manager + + for loaded_plugin_name in plugin_manager.list_loaded_plugins(): + instance = plugin_manager.get_plugin_instance(loaded_plugin_name) + if instance and (instance.plugin_name == plugin_id or instance.get_manifest_info("id", "") == plugin_id): + return instance + return None + + # ============ 请求/响应模型 ============ @@ -206,12 +393,14 @@ async def check_git_status() -> GitStatusResponse: @router.get("/mirrors", response_model=AvailableMirrorsResponse) -async def get_available_mirrors(authorization: Optional[str] = Header(None)) -> AvailableMirrorsResponse: +async def get_available_mirrors( + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> AvailableMirrorsResponse: """ 获取所有可用的镜像源配置 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -236,12 +425,14 @@ async def get_available_mirrors(authorization: Optional[str] = Header(None)) -> @router.post("/mirrors", response_model=MirrorConfigResponse) -async def add_mirror(request: AddMirrorRequest, authorization: Optional[str] = Header(None)) -> MirrorConfigResponse: +async def add_mirror( + request: AddMirrorRequest, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> MirrorConfigResponse: """ 添加新的镜像源 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -276,13 +467,16 @@ async def add_mirror(request: AddMirrorRequest, authorization: Optional[str] = H @router.put("/mirrors/{mirror_id}", response_model=MirrorConfigResponse) async def update_mirror( - mirror_id: str, request: UpdateMirrorRequest, authorization: Optional[str] = Header(None) + mirror_id: str, + request: UpdateMirrorRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), ) -> MirrorConfigResponse: """ 更新镜像源配置 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -319,12 +513,14 @@ async def update_mirror( @router.delete("/mirrors/{mirror_id}") -async def delete_mirror(mirror_id: str, authorization: Optional[str] = Header(None)) -> Dict[str, Any]: +async def delete_mirror( + mirror_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> Dict[str, Any]: """ 删除镜像源 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -342,26 +538,24 @@ async def delete_mirror(mirror_id: str, authorization: Optional[str] = Header(No @router.post("/fetch-raw", response_model=FetchRawFileResponse) async def fetch_raw_file( - request: FetchRawFileRequest, authorization: Optional[str] = Header(None) + request: FetchRawFileRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), ) -> FetchRawFileResponse: """ 获取 GitHub 仓库的 Raw 文件内容 支持多镜像源自动切换和错误重试 - 注意:此接口可公开访问,用于获取插件仓库等公开资源 + 需要认证才能访问,防止被滥用作为 SSRF 跳板 """ - # Token 验证(可选,用于日志记录) - token = authorization.replace("Bearer ", "") if authorization else None + # Token 验证(强制) + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() - is_authenticated = token and token_manager.verify_token(token) + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") - # 对于公开仓库的访问,不强制要求认证 - # 只在日志中记录是否认证 - logger.info( - f"收到获取 Raw 文件请求 (认证: {is_authenticated}): " - f"{request.owner}/{request.repo}/{request.branch}/{request.file_path}" - ) + logger.info(f"收到获取 Raw 文件请求: {request.owner}/{request.repo}/{request.branch}/{request.file_path}") # 发送开始加载进度 await update_progress( @@ -427,7 +621,9 @@ async def fetch_raw_file( @router.post("/clone", response_model=CloneRepositoryResponse) async def clone_repository( - request: CloneRepositoryRequest, authorization: Optional[str] = Header(None) + request: CloneRepositoryRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), ) -> CloneRepositoryResponse: """ 克隆 GitHub 仓库到本地 @@ -435,7 +631,7 @@ async def clone_repository( 支持多镜像源自动切换和错误重试 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -443,10 +639,10 @@ async def clone_repository( logger.info(f"收到克隆仓库请求: {request.owner}/{request.repo} -> {request.target_path}") try: - # TODO: 验证 target_path 的安全性,防止路径遍历攻击 - # TODO: 确定实际的插件目录基路径 - base_plugin_path = Path("./plugins") # 临时路径 - target_path = base_plugin_path / request.target_path + # 验证 target_path 的安全性,防止路径遍历攻击 + base_plugin_path = Path("./plugins").resolve() + base_plugin_path.mkdir(exist_ok=True) + target_path = validate_safe_path(request.target_path, base_plugin_path) service = get_git_mirror_service() result = await service.clone_repository( @@ -467,14 +663,18 @@ async def clone_repository( @router.post("/install") -async def install_plugin(request: InstallPluginRequest, authorization: Optional[str] = Header(None)) -> Dict[str, Any]: +async def install_plugin( + request: InstallPluginRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> Dict[str, Any]: """ 安装插件 从 Git 仓库克隆插件到本地插件目录 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -482,13 +682,16 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ logger.info(f"收到安装插件请求: {request.plugin_id}") try: + # 验证插件 ID 格式安全性 + plugin_id = validate_plugin_id(request.plugin_id) + # 推送进度:开始安装 await update_progress( stage="loading", progress=5, - message=f"开始安装插件: {request.plugin_id}", + message=f"开始安装插件: {plugin_id}", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) # 1. 解析仓库 URL @@ -509,23 +712,28 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=10, message=f"解析仓库信息: {owner}/{repo}", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) # 2. 确定插件安装路径 - plugins_dir = Path("plugins") + plugins_dir = Path("plugins").resolve() plugins_dir.mkdir(exist_ok=True) - target_path = plugins_dir / request.plugin_id + # 将插件 ID 中的点替换为下划线作为文件夹名称(避免文件系统问题) + # 例如: SengokuCola.Mute-Plugin -> SengokuCola_Mute-Plugin + folder_name = plugin_id.replace(".", "_") + # 使用安全路径验证,防止路径遍历 + target_path = validate_safe_path(folder_name, plugins_dir) - # 检查插件是否已安装 - if target_path.exists(): + # 检查插件是否已安装(需要检查两种格式:新格式下划线和旧格式点) + old_format_path = plugins_dir / plugin_id + if target_path.exists() or old_format_path.exists(): await update_progress( stage="error", progress=0, message="插件已存在", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error="插件已安装,请先卸载", ) raise HTTPException(status_code=400, detail="插件已安装") @@ -535,7 +743,7 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=15, message=f"准备克隆到: {target_path}", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) # 3. 克隆仓库(这里会自动推送 20%-80% 的进度) @@ -564,14 +772,14 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=0, message="克隆仓库失败", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error=error_msg, ) raise HTTPException(status_code=500, detail=error_msg) # 4. 验证插件完整性 await update_progress( - stage="loading", progress=85, message="验证插件文件...", operation="install", plugin_id=request.plugin_id + stage="loading", progress=85, message="验证插件文件...", operation="install", plugin_id=plugin_id ) manifest_path = target_path / "_manifest.json" @@ -586,14 +794,14 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=0, message="插件缺少 _manifest.json", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error="无效的插件格式", ) raise HTTPException(status_code=400, detail="无效的插件:缺少 _manifest.json") # 5. 读取并验证 manifest await update_progress( - stage="loading", progress=90, message="读取插件配置...", operation="install", plugin_id=request.plugin_id + stage="loading", progress=90, message="读取插件配置...", operation="install", plugin_id=plugin_id ) try: @@ -608,6 +816,12 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ if field not in manifest: raise ValueError(f"缺少必需字段: {field}") + # 将插件 ID 写入 manifest(用于后续准确识别) + # 这样即使文件夹名称改变,也能通过 manifest 准确识别插件 + manifest["id"] = plugin_id + with open(manifest_path, "w", encoding="utf-8") as f: + json_module.dump(manifest, f, ensure_ascii=False, indent=2) + except Exception as e: # 清理失败的安装 import shutil @@ -619,7 +833,7 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=0, message="_manifest.json 无效", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error=str(e), ) raise HTTPException(status_code=400, detail=f"无效的 _manifest.json: {e}") from e @@ -630,13 +844,13 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=100, message=f"成功安装插件: {manifest['name']} v{manifest['version']}", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) return { "success": True, "message": "插件安装成功", - "plugin_id": request.plugin_id, + "plugin_id": plugin_id, "plugin_name": manifest["name"], "version": manifest["version"], "path": str(target_path), @@ -652,7 +866,7 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ progress=0, message="安装失败", operation="install", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error=str(e), ) @@ -661,7 +875,9 @@ async def install_plugin(request: InstallPluginRequest, authorization: Optional[ @router.post("/uninstall") async def uninstall_plugin( - request: UninstallPluginRequest, authorization: Optional[str] = Header(None) + request: UninstallPluginRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), ) -> Dict[str, Any]: """ 卸载插件 @@ -669,7 +885,7 @@ async def uninstall_plugin( 删除插件目录及其所有文件 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -677,41 +893,53 @@ async def uninstall_plugin( logger.info(f"收到卸载插件请求: {request.plugin_id}") try: + # 验证插件 ID 格式安全性 + plugin_id = validate_plugin_id(request.plugin_id) + # 推送进度:开始卸载 await update_progress( stage="loading", progress=10, - message=f"开始卸载插件: {request.plugin_id}", + message=f"开始卸载插件: {plugin_id}", operation="uninstall", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) - # 1. 检查插件是否存在 - plugins_dir = Path("plugins") - plugin_path = plugins_dir / request.plugin_id + # 1. 检查插件是否存在(支持新旧两种格式) + plugins_dir = Path("plugins").resolve() + # 新格式:下划线 + folder_name = plugin_id.replace(".", "_") + # 使用安全路径验证 + plugin_path = validate_safe_path(folder_name, plugins_dir) + # 旧格式:点 + old_format_path = validate_safe_path(plugin_id, plugins_dir) + # 优先使用新格式,如果不存在则尝试旧格式 if not plugin_path.exists(): - await update_progress( - stage="error", - progress=0, - message="插件不存在", - operation="uninstall", - plugin_id=request.plugin_id, - error="插件未安装或已被删除", - ) - raise HTTPException(status_code=404, detail="插件未安装") + if old_format_path.exists(): + plugin_path = old_format_path + else: + await update_progress( + stage="error", + progress=0, + message="插件不存在", + operation="uninstall", + plugin_id=plugin_id, + error="插件未安装或已被删除", + ) + raise HTTPException(status_code=404, detail="插件未安装") await update_progress( stage="loading", progress=30, message=f"正在删除插件文件: {plugin_path}", operation="uninstall", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) # 2. 读取插件信息(用于日志) manifest_path = plugin_path / "_manifest.json" - plugin_name = request.plugin_id + plugin_name = plugin_id if manifest_path.exists(): try: @@ -719,7 +947,7 @@ async def uninstall_plugin( with open(manifest_path, "r", encoding="utf-8") as f: manifest = json_module.load(f) - plugin_name = manifest.get("name", request.plugin_id) + plugin_name = manifest.get("name", plugin_id) except Exception: pass # 如果读取失败,使用插件 ID 作为名称 @@ -728,7 +956,7 @@ async def uninstall_plugin( progress=50, message=f"正在删除 {plugin_name}...", operation="uninstall", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) # 3. 删除插件目录 @@ -744,7 +972,7 @@ async def uninstall_plugin( shutil.rmtree(plugin_path, onerror=remove_readonly) - logger.info(f"成功卸载插件: {request.plugin_id} ({plugin_name})") + logger.info(f"成功卸载插件: {plugin_id} ({plugin_name})") # 4. 推送成功状态 await update_progress( @@ -752,10 +980,10 @@ async def uninstall_plugin( progress=100, message=f"成功卸载插件: {plugin_name}", operation="uninstall", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) - return {"success": True, "message": "插件卸载成功", "plugin_id": request.plugin_id, "plugin_name": plugin_name} + return {"success": True, "message": "插件卸载成功", "plugin_id": plugin_id, "plugin_name": plugin_name} except HTTPException: raise @@ -767,7 +995,7 @@ async def uninstall_plugin( progress=0, message="卸载失败", operation="uninstall", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error="权限不足,无法删除插件文件", ) @@ -780,7 +1008,7 @@ async def uninstall_plugin( progress=0, message="卸载失败", operation="uninstall", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error=str(e), ) @@ -788,14 +1016,18 @@ async def uninstall_plugin( @router.post("/update") -async def update_plugin(request: UpdatePluginRequest, authorization: Optional[str] = Header(None)) -> Dict[str, Any]: +async def update_plugin( + request: UpdatePluginRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> Dict[str, Any]: """ 更新插件 删除旧版本,重新克隆新版本 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -803,34 +1035,45 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st logger.info(f"收到更新插件请求: {request.plugin_id}") try: + # 验证插件 ID 格式安全性 + plugin_id = validate_plugin_id(request.plugin_id) + # 推送进度:开始更新 await update_progress( stage="loading", progress=5, - message=f"开始更新插件: {request.plugin_id}", + message=f"开始更新插件: {plugin_id}", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) - # 1. 检查插件是否已安装 - plugins_dir = Path("plugins") - plugin_path = plugins_dir / request.plugin_id + # 1. 检查插件是否已安装(支持新旧两种格式) + plugins_dir = Path("plugins").resolve() + # 新格式:下划线 + folder_name = plugin_id.replace(".", "_") + # 使用安全路径验证 + plugin_path = validate_safe_path(folder_name, plugins_dir) + # 旧格式:点 + old_format_path = validate_safe_path(plugin_id, plugins_dir) + # 优先使用新格式,如果不存在则尝试旧格式 if not plugin_path.exists(): - await update_progress( - stage="error", - progress=0, - message="插件不存在", - operation="update", - plugin_id=request.plugin_id, - error="插件未安装,请先安装", - ) - raise HTTPException(status_code=404, detail="插件未安装") + if old_format_path.exists(): + plugin_path = old_format_path + else: + await update_progress( + stage="error", + progress=0, + message="插件不存在", + operation="update", + plugin_id=plugin_id, + error="插件未安装,请先安装", + ) + raise HTTPException(status_code=404, detail="插件未安装") # 2. 读取旧版本信息 manifest_path = plugin_path / "_manifest.json" old_version = "unknown" - plugin_name = request.plugin_id if manifest_path.exists(): try: @@ -839,7 +1082,6 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st with open(manifest_path, "r", encoding="utf-8") as f: manifest = json_module.load(f) old_version = manifest.get("version", "unknown") - _plugin_name = manifest.get("name", request.plugin_id) except Exception: pass @@ -848,12 +1090,12 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st progress=10, message=f"当前版本: {old_version},准备更新...", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) # 3. 删除旧版本 await update_progress( - stage="loading", progress=20, message="正在删除旧版本...", operation="update", plugin_id=request.plugin_id + stage="loading", progress=20, message="正在删除旧版本...", operation="update", plugin_id=plugin_id ) import shutil @@ -868,7 +1110,7 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st shutil.rmtree(plugin_path, onerror=remove_readonly) - logger.info(f"已删除旧版本: {request.plugin_id} v{old_version}") + logger.info(f"已删除旧版本: {plugin_id} v{old_version}") # 4. 解析仓库 URL await update_progress( @@ -876,7 +1118,7 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st progress=30, message="正在准备下载新版本...", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) repo_url = request.repository_url.rstrip("/") @@ -914,14 +1156,14 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st progress=0, message="下载新版本失败", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error=error_msg, ) raise HTTPException(status_code=500, detail=error_msg) # 6. 验证新版本 await update_progress( - stage="loading", progress=90, message="验证新版本...", operation="update", plugin_id=request.plugin_id + stage="loading", progress=90, message="验证新版本...", operation="update", plugin_id=plugin_id ) new_manifest_path = plugin_path / "_manifest.json" @@ -941,7 +1183,7 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st progress=0, message="新版本缺少 _manifest.json", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error="无效的插件格式", ) raise HTTPException(status_code=400, detail="无效的插件:缺少 _manifest.json") @@ -952,9 +1194,9 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st new_manifest = json_module.load(f) new_version = new_manifest.get("version", "unknown") - new_name = new_manifest.get("name", request.plugin_id) + new_name = new_manifest.get("name", plugin_id) - logger.info(f"成功更新插件: {request.plugin_id} {old_version} → {new_version}") + logger.info(f"成功更新插件: {plugin_id} {old_version} → {new_version}") # 8. 推送成功状态 await update_progress( @@ -962,13 +1204,13 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st progress=100, message=f"成功更新 {new_name}: {old_version} → {new_version}", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, ) return { "success": True, "message": "插件更新成功", - "plugin_id": request.plugin_id, + "plugin_id": plugin_id, "plugin_name": new_name, "old_version": old_version, "new_version": new_version, @@ -983,7 +1225,7 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st progress=0, message="_manifest.json 无效", operation="update", - plugin_id=request.plugin_id, + plugin_id=plugin_id, error=str(e), ) raise HTTPException(status_code=400, detail=f"无效的 _manifest.json: {e}") from e @@ -994,21 +1236,23 @@ async def update_plugin(request: UpdatePluginRequest, authorization: Optional[st logger.error(f"更新插件失败: {e}", exc_info=True) await update_progress( - stage="error", progress=0, message="更新失败", operation="update", plugin_id=request.plugin_id, error=str(e) + stage="error", progress=0, message="更新失败", operation="update", plugin_id=plugin_id, error=str(e) ) raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e @router.get("/installed") -async def get_installed_plugins(authorization: Optional[str] = Header(None)) -> Dict[str, Any]: +async def get_installed_plugins( + maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> Dict[str, Any]: """ 获取已安装的插件列表 扫描 plugins 目录,返回所有已安装插件的 ID 和基本信息 """ # Token 验证 - token = authorization.replace("Bearer ", "") if authorization else None + token = get_token_from_cookie_or_header(maibot_session, authorization) token_manager = get_token_manager() if not token or not token_manager.verify_token(token): raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") @@ -1032,18 +1276,18 @@ async def get_installed_plugins(authorization: Optional[str] = Header(None)) -> if not plugin_path.is_dir(): continue - # 目录名即为插件 ID - plugin_id = plugin_path.name + # 目录名(可能是下划线格式、点格式或其他格式) + folder_name = plugin_path.name # 跳过隐藏目录和特殊目录 - if plugin_id.startswith(".") or plugin_id.startswith("__"): + if folder_name.startswith(".") or folder_name.startswith("__"): continue # 读取 _manifest.json manifest_path = plugin_path / "_manifest.json" if not manifest_path.exists(): - logger.warning(f"插件 {plugin_id} 缺少 _manifest.json,跳过") + logger.warning(f"插件文件夹 {folder_name} 缺少 _manifest.json,跳过") continue try: @@ -1054,9 +1298,58 @@ async def get_installed_plugins(authorization: Optional[str] = Header(None)) -> # 基本验证 if "name" not in manifest or "version" not in manifest: - logger.warning(f"插件 {plugin_id} 的 _manifest.json 格式无效,跳过") + logger.warning(f"插件文件夹 {folder_name} 的 _manifest.json 格式无效,跳过") continue + # 获取插件 ID(优先从 manifest,否则从文件夹名推断) + if "id" in manifest: + # 优先使用 manifest 中的 id(最准确) + plugin_id = manifest["id"] + else: + # 从 manifest 信息构建 ID + # 尝试从 author.name 和 repository_url 构建标准 ID + author_name = None + repo_name = None + + # 获取作者名 + if "author" in manifest: + if isinstance(manifest["author"], dict) and "name" in manifest["author"]: + author_name = manifest["author"]["name"] + elif isinstance(manifest["author"], str): + author_name = manifest["author"] + + # 从 repository_url 获取仓库名 + if "repository_url" in manifest: + repo_url = manifest["repository_url"].rstrip("/") + if repo_url.endswith(".git"): + repo_url = repo_url[:-4] + repo_name = repo_url.split("/")[-1] + + # 构建 ID + if author_name and repo_name: + # 标准格式: Author.RepoName + plugin_id = f"{author_name}.{repo_name}" + elif author_name: + # 如果只有作者,使用 Author.FolderName + plugin_id = f"{author_name}.{folder_name}" + else: + # 从文件夹名推断 + if "_" in folder_name and "." not in folder_name: + # 假设格式为 Author_PluginName,转换为 Author.PluginName + plugin_id = folder_name.replace("_", ".", 1) + else: + # 直接使用文件夹名 + plugin_id = folder_name + + # 将推断的 ID 写入 manifest(方便下次识别) + logger.info(f"为插件 {folder_name} 自动生成 ID: {plugin_id}") + manifest["id"] = plugin_id + try: + with open(manifest_path, "w", encoding="utf-8") as f: + json_module.dump(manifest, f, ensure_ascii=False, indent=2) + except Exception as write_error: + logger.warning(f"无法写入 ID 到 manifest: {write_error}") + # 添加到已安装列表(返回完整的 manifest 信息) installed_plugins.append( { @@ -1067,16 +1360,628 @@ async def get_installed_plugins(authorization: Optional[str] = Header(None)) -> ) except json.JSONDecodeError as e: - logger.warning(f"插件 {plugin_id} 的 _manifest.json 解析失败: {e}") + logger.warning(f"插件 {folder_name} 的 _manifest.json 解析失败: {e}") continue except Exception as e: - logger.error(f"读取插件 {plugin_id} 信息时出错: {e}") + logger.error(f"读取插件 {folder_name} 信息时出错: {e}") continue - logger.info(f"找到 {len(installed_plugins)} 个已安装插件") + # 去重:如果有重复的 plugin_id,只保留第一个(按路径) + seen_ids = {} # 记录 ID -> 路径的映射 + unique_plugins = [] + duplicates = [] + + for plugin in installed_plugins: + plugin_id = plugin["id"] + plugin_path = plugin["path"] + + if plugin_id not in seen_ids: + seen_ids[plugin_id] = plugin_path + unique_plugins.append(plugin) + else: + duplicates.append(plugin) + first_path = seen_ids[plugin_id] + logger.warning( + f"重复插件 {plugin_id}: 保留 {first_path}, 跳过 {plugin_path}" + ) + + if duplicates: + logger.warning(f"共检测到 {len(duplicates)} 个重复插件已去重") - return {"success": True, "plugins": installed_plugins, "total": len(installed_plugins)} + logger.info(f"找到 {len(unique_plugins)} 个已安装插件") + + return {"success": True, "plugins": unique_plugins, "total": len(unique_plugins)} except Exception as e: logger.error(f"获取已安装插件列表失败: {e}", exc_info=True) raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +# ============ 插件配置管理 API ============ + + +class UpdatePluginConfigRequest(BaseModel): + """更新插件配置请求""" + + config: Dict[str, Any] = Field(..., description="配置数据") + + +@router.get("/config/{plugin_id}/schema") +async def get_plugin_config_schema( + plugin_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> Dict[str, Any]: + """ + 获取插件配置 Schema + + 返回插件的完整配置 schema,包含所有 section、字段定义和布局信息。 + 用于前端动态生成配置表单。 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"获取插件配置 Schema: {plugin_id}") + + try: + # 尝试从已加载的插件中获取 + from src.plugin_system.core.plugin_manager import plugin_manager + + # 查找插件实例 + plugin_instance = None + + # 遍历所有已加载的插件 + for loaded_plugin_name in plugin_manager.list_loaded_plugins(): + instance = plugin_manager.get_plugin_instance(loaded_plugin_name) + if instance: + # 匹配 plugin_name 或 manifest 中的 id + if instance.plugin_name == plugin_id: + plugin_instance = instance + break + # 也尝试匹配 manifest 中的 id + manifest_id = instance.get_manifest_info("id", "") + if manifest_id == plugin_id: + plugin_instance = instance + break + + if plugin_instance and hasattr(plugin_instance, "get_webui_config_schema"): + # 从插件实例获取 schema + schema = plugin_instance.get_webui_config_schema() + return {"success": True, "schema": schema} + + # 如果插件未加载,尝试从文件系统读取 + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + # 读取配置文件获取当前配置 + config_path = plugin_path / "config.toml" + current_config = {} + if config_path.exists(): + import tomlkit + + with open(config_path, "r", encoding="utf-8") as f: + current_config = tomlkit.load(f) + + # 构建基础 schema(无法获取完整的 ConfigField 信息) + schema = { + "plugin_id": plugin_id, + "plugin_info": { + "name": plugin_id, + "version": "", + "description": "", + "author": "", + }, + "sections": {}, + "layout": {"type": "auto", "tabs": []}, + "_note": "插件未加载,仅返回当前配置结构", + } + + # 从当前配置推断 schema + for section_name, section_data in current_config.items(): + if isinstance(section_data, dict): + schema["sections"][section_name] = { + "name": section_name, + "title": section_name, + "description": None, + "icon": None, + "collapsed": False, + "order": 0, + "fields": {}, + } + for field_name, field_value in section_data.items(): + # 推断字段类型 + field_type = type(field_value).__name__ + ui_type = "text" + item_type = None + item_fields = None + + if isinstance(field_value, bool): + ui_type = "switch" + elif isinstance(field_value, (int, float)): + ui_type = "number" + elif isinstance(field_value, list): + ui_type = "list" + # 推断数组元素类型 + if field_value: + first_item = field_value[0] + if isinstance(first_item, dict): + item_type = "object" + # 从第一个元素推断字段结构 + item_fields = {} + for k, v in first_item.items(): + item_fields[k] = { + "type": "number" if isinstance(v, (int, float)) else "string", + "label": k, + "default": "" if isinstance(v, str) else 0, + } + elif isinstance(first_item, (int, float)): + item_type = "number" + else: + item_type = "string" + else: + item_type = "string" + elif isinstance(field_value, dict): + ui_type = "json" + + schema["sections"][section_name]["fields"][field_name] = { + "name": field_name, + "type": field_type, + "default": field_value, + "description": field_name, + "label": field_name, + "ui_type": ui_type, + "required": False, + "hidden": False, + "disabled": False, + "order": 0, + "item_type": item_type, + "item_fields": item_fields, + "min_items": None, + "max_items": None, + # 补充缺失的字段 + "placeholder": None, + "hint": None, + "icon": None, + "example": None, + "choices": None, + "min": None, + "max": None, + "step": None, + "pattern": None, + "max_length": None, + "input_type": None, + "rows": 3, + "group": None, + "depends_on": None, + "depends_value": None, + } + + return {"success": True, "schema": schema} + + except HTTPException: + raise + except Exception as e: + logger.error(f"获取插件配置 Schema 失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +@router.get("/config/{plugin_id}/raw") +async def get_plugin_config_raw( + plugin_id: str, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> Dict[str, Any]: + """ + 获取插件原始 TOML 配置文件内容 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"获取插件原始配置: {plugin_id}") + + try: + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + # 读取配置文件 + config_path = plugin_path / "config.toml" + if not config_path.exists(): + return {"success": True, "config": "", "message": "配置文件不存在"} + + with open(config_path, "r", encoding="utf-8") as f: + config_content = f.read() + + return {"success": True, "config": config_content} + + except HTTPException: + raise + except Exception as e: + logger.error(f"获取插件原始配置失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +@router.put("/config/{plugin_id}/raw") +async def update_plugin_config_raw( + plugin_id: str, + request: UpdatePluginConfigRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> Dict[str, Any]: + """ + 更新插件原始 TOML 配置文件 + + 直接保存 TOML 字符串到配置文件。 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"更新插件原始配置: {plugin_id}") + + try: + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + config_path = plugin_path / "config.toml" + + # 验证 TOML 格式 + import tomlkit + + if not isinstance(request.config, str): + raise HTTPException(status_code=400, detail="配置必须是字符串格式的 TOML 内容") + + try: + tomlkit.loads(request.config) + except Exception as e: + raise HTTPException(status_code=400, detail=f"TOML 格式错误: {str(e)}") + + # 备份旧配置 + import shutil + import datetime + + if config_path.exists(): + backup_name = f"config.toml.backup.{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}" + backup_path = plugin_path / backup_name + shutil.copy(config_path, backup_path) + logger.info(f"已备份配置文件: {backup_path}") + + # 写入新配置 + with open(config_path, "w", encoding="utf-8") as f: + f.write(request.config) + + logger.info(f"已更新插件原始配置: {plugin_id}") + + return {"success": True, "message": "配置已保存", "note": "配置更改将在插件重新加载后生效"} + + except HTTPException: + raise + except Exception as e: + logger.error(f"更新插件原始配置失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +@router.get("/config/{plugin_id}") +async def get_plugin_config( + plugin_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> Dict[str, Any]: + """ + 获取插件当前配置值 + + 返回插件的当前配置值。 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"获取插件配置: {plugin_id}") + + try: + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + # 读取配置文件 + config_path = plugin_path / "config.toml" + if not config_path.exists(): + return {"success": True, "config": {}, "message": "配置文件不存在"} + + import tomlkit + + with open(config_path, "r", encoding="utf-8") as f: + config = tomlkit.load(f) + + return {"success": True, "config": dict(config)} + + except HTTPException: + raise + except Exception as e: + logger.error(f"获取插件配置失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +@router.put("/config/{plugin_id}") +async def update_plugin_config( + plugin_id: str, + request: UpdatePluginConfigRequest, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> Dict[str, Any]: + """ + 更新插件配置 + + 保存新的配置值到插件的配置文件。 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"更新插件配置: {plugin_id}") + + try: + plugin_instance = find_plugin_instance(plugin_id) + + # 纠正 WebUI 提交的数据结构(扁平键与字符串列表) + if plugin_instance and isinstance(request.config, dict): + request.config = normalize_dotted_keys(request.config) + if isinstance(plugin_instance.config_schema, dict): + coerce_types(plugin_instance.config_schema, request.config) + + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + config_path = plugin_path / "config.toml" + + # 备份旧配置 + import shutil + import datetime + + if config_path.exists(): + backup_name = f"config.toml.backup.{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}" + backup_path = plugin_path / backup_name + shutil.copy(config_path, backup_path) + logger.info(f"已备份配置文件: {backup_path}") + + # 写入新配置(自动保留注释和格式) + save_toml_with_format(request.config, str(config_path)) + + logger.info(f"已更新插件配置: {plugin_id}") + + return {"success": True, "message": "配置已保存", "note": "配置更改将在插件重新加载后生效"} + + except HTTPException: + raise + except Exception as e: + logger.error(f"更新插件配置失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +@router.post("/config/{plugin_id}/reset") +async def reset_plugin_config( + plugin_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> Dict[str, Any]: + """ + 重置插件配置为默认值 + + 删除当前配置文件,下次加载插件时将使用默认配置。 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"重置插件配置: {plugin_id}") + + try: + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + config_path = plugin_path / "config.toml" + + if not config_path.exists(): + return {"success": True, "message": "配置文件不存在,无需重置"} + + # 备份并删除 + import shutil + import datetime + + backup_name = f"config.toml.reset.{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}" + backup_path = plugin_path / backup_name + shutil.move(config_path, backup_path) + + logger.info(f"已重置插件配置: {plugin_id},备份: {backup_path}") + + return {"success": True, "message": "配置已重置,下次加载插件时将使用默认配置", "backup": str(backup_path)} + + except HTTPException: + raise + except Exception as e: + logger.error(f"重置插件配置失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e + + +@router.post("/config/{plugin_id}/toggle") +async def toggle_plugin( + plugin_id: str, maibot_session: Optional[str] = Cookie(None), authorization: Optional[str] = Header(None) +) -> Dict[str, Any]: + """ + 切换插件启用状态 + + 切换插件配置中的 enabled 字段。 + """ + # Token 验证 + token = get_token_from_cookie_or_header(maibot_session, authorization) + token_manager = get_token_manager() + if not token or not token_manager.verify_token(token): + raise HTTPException(status_code=401, detail="未授权:无效的访问令牌") + + logger.info(f"切换插件状态: {plugin_id}") + + try: + # 查找插件目录 + plugins_dir = Path("plugins") + plugin_path = None + + for p in plugins_dir.iterdir(): + if p.is_dir(): + manifest_path = p / "_manifest.json" + if manifest_path.exists(): + try: + with open(manifest_path, "r", encoding="utf-8") as f: + manifest = json.load(f) + if manifest.get("id") == plugin_id or p.name == plugin_id: + plugin_path = p + break + except Exception: + continue + + if not plugin_path: + raise HTTPException(status_code=404, detail=f"未找到插件: {plugin_id}") + + config_path = plugin_path / "config.toml" + + import tomlkit + + # 读取当前配置(保留注释和格式) + config = tomlkit.document() + if config_path.exists(): + with open(config_path, "r", encoding="utf-8") as f: + config = tomlkit.load(f) + + # 切换 enabled 状态 + if "plugin" not in config: + config["plugin"] = tomlkit.table() + + current_enabled = config["plugin"].get("enabled", True) + new_enabled = not current_enabled + config["plugin"]["enabled"] = new_enabled + + # 写入配置(保留注释,格式化数组) + save_toml_with_format(config, str(config_path)) + + status = "启用" if new_enabled else "禁用" + logger.info(f"已{status}插件: {plugin_id}") + + return { + "success": True, + "enabled": new_enabled, + "message": f"插件已{status}", + "note": "状态更改将在下次加载插件时生效", + } + + except HTTPException: + raise + except Exception as e: + logger.error(f"切换插件状态失败: {e}", exc_info=True) + raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}") from e diff --git a/src/webui/rate_limiter.py b/src/webui/rate_limiter.py new file mode 100644 index 00000000..23cfc0f0 --- /dev/null +++ b/src/webui/rate_limiter.py @@ -0,0 +1,245 @@ +""" +WebUI 请求频率限制模块 +防止暴力破解和 API 滥用 +""" + +import time +from collections import defaultdict +from typing import Dict, Tuple, Optional +from fastapi import Request, HTTPException +from src.common.logger import get_logger + +logger = get_logger("webui.rate_limiter") + + +class RateLimiter: + """ + 简单的内存请求频率限制器 + + 使用滑动窗口算法实现 + """ + + def __init__(self): + # 存储格式: {key: [(timestamp, count), ...]} + self._requests: Dict[str, list] = defaultdict(list) + # 被封禁的 IP: {ip: unblock_timestamp} + self._blocked: Dict[str, float] = {} + + def _get_client_ip(self, request: Request) -> str: + """获取客户端 IP 地址""" + # 检查代理头 + forwarded = request.headers.get("X-Forwarded-For") + if forwarded: + # 取第一个 IP(最原始的客户端) + return forwarded.split(",")[0].strip() + + real_ip = request.headers.get("X-Real-IP") + if real_ip: + return real_ip + + # 直接连接的客户端 + if request.client: + return request.client.host + + return "unknown" + + def _cleanup_old_requests(self, key: str, window_seconds: int): + """清理过期的请求记录""" + now = time.time() + cutoff = now - window_seconds + self._requests[key] = [(ts, count) for ts, count in self._requests[key] if ts > cutoff] + + def _cleanup_expired_blocks(self): + """清理过期的封禁""" + now = time.time() + expired = [ip for ip, unblock_time in self._blocked.items() if now > unblock_time] + for ip in expired: + del self._blocked[ip] + logger.info(f"🔓 IP {ip} 封禁已解除") + + def is_blocked(self, request: Request) -> Tuple[bool, Optional[int]]: + """ + 检查 IP 是否被封禁 + + Returns: + (是否被封禁, 剩余封禁秒数) + """ + self._cleanup_expired_blocks() + ip = self._get_client_ip(request) + + if ip in self._blocked: + remaining = int(self._blocked[ip] - time.time()) + return True, max(0, remaining) + + return False, None + + def check_rate_limit( + self, request: Request, max_requests: int, window_seconds: int, key_suffix: str = "" + ) -> Tuple[bool, int]: + """ + 检查请求是否超过频率限制 + + Args: + request: FastAPI Request 对象 + max_requests: 窗口期内允许的最大请求数 + window_seconds: 窗口时间(秒) + key_suffix: 键后缀,用于区分不同的限制规则 + + Returns: + (是否允许, 剩余请求数) + """ + ip = self._get_client_ip(request) + key = f"{ip}:{key_suffix}" if key_suffix else ip + + # 清理过期记录 + self._cleanup_old_requests(key, window_seconds) + + # 计算当前窗口内的请求数 + current_count = sum(count for _, count in self._requests[key]) + + if current_count >= max_requests: + return False, 0 + + # 记录新请求 + now = time.time() + self._requests[key].append((now, 1)) + + remaining = max_requests - current_count - 1 + return True, remaining + + def block_ip(self, request: Request, duration_seconds: int): + """ + 封禁 IP + + Args: + request: FastAPI Request 对象 + duration_seconds: 封禁时长(秒) + """ + ip = self._get_client_ip(request) + self._blocked[ip] = time.time() + duration_seconds + logger.warning(f"🔒 IP {ip} 已被封禁 {duration_seconds} 秒") + + def record_failed_attempt( + self, request: Request, max_failures: int = 5, window_seconds: int = 300, block_duration: int = 600 + ) -> Tuple[bool, int]: + """ + 记录失败尝试(如登录失败) + + 如果在窗口期内失败次数过多,自动封禁 IP + + Args: + request: FastAPI Request 对象 + max_failures: 允许的最大失败次数 + window_seconds: 统计窗口(秒) + block_duration: 封禁时长(秒) + + Returns: + (是否被封禁, 剩余尝试次数) + """ + ip = self._get_client_ip(request) + key = f"{ip}:auth_failures" + + # 清理过期记录 + self._cleanup_old_requests(key, window_seconds) + + # 计算当前失败次数 + current_failures = sum(count for _, count in self._requests[key]) + + # 记录本次失败 + now = time.time() + self._requests[key].append((now, 1)) + current_failures += 1 + + remaining = max_failures - current_failures + + # 检查是否需要封禁 + if current_failures >= max_failures: + self.block_ip(request, block_duration) + logger.warning(f"⚠️ IP {ip} 认证失败次数过多 ({current_failures}/{max_failures}),已封禁") + return True, 0 + + if current_failures >= max_failures - 2: + logger.warning(f"⚠️ IP {ip} 认证失败 {current_failures}/{max_failures} 次") + + return False, max(0, remaining) + + def reset_failures(self, request: Request): + """ + 重置失败计数(认证成功后调用) + """ + ip = self._get_client_ip(request) + key = f"{ip}:auth_failures" + if key in self._requests: + del self._requests[key] + + +# 全局单例 +_rate_limiter: Optional[RateLimiter] = None + + +def get_rate_limiter() -> RateLimiter: + """获取 RateLimiter 单例""" + global _rate_limiter + if _rate_limiter is None: + _rate_limiter = RateLimiter() + return _rate_limiter + + +async def check_auth_rate_limit(request: Request): + """ + 认证接口的频率限制依赖 + + 规则: + - 每个 IP 每分钟最多 10 次认证请求 + - 连续失败 5 次后封禁 10 分钟 + """ + limiter = get_rate_limiter() + + # 检查是否被封禁 + blocked, remaining_block = limiter.is_blocked(request) + if blocked: + raise HTTPException( + status_code=429, + detail=f"请求过于频繁,请在 {remaining_block} 秒后重试", + headers={"Retry-After": str(remaining_block)}, + ) + + # 检查频率限制 + allowed, remaining = limiter.check_rate_limit( + request, + max_requests=10, # 每分钟 10 次 + window_seconds=60, + key_suffix="auth", + ) + + if not allowed: + raise HTTPException(status_code=429, detail="认证请求过于频繁,请稍后重试", headers={"Retry-After": "60"}) + + +async def check_api_rate_limit(request: Request): + """ + 普通 API 的频率限制依赖 + + 规则:每个 IP 每分钟最多 100 次请求 + """ + limiter = get_rate_limiter() + + # 检查是否被封禁 + blocked, remaining_block = limiter.is_blocked(request) + if blocked: + raise HTTPException( + status_code=429, + detail=f"请求过于频繁,请在 {remaining_block} 秒后重试", + headers={"Retry-After": str(remaining_block)}, + ) + + # 检查频率限制 + allowed, _ = limiter.check_rate_limit( + request, + max_requests=100, # 每分钟 100 次 + window_seconds=60, + key_suffix="api", + ) + + if not allowed: + raise HTTPException(status_code=429, detail="请求过于频繁,请稍后重试", headers={"Retry-After": "60"}) diff --git a/src/webui/routers/system.py b/src/webui/routers/system.py index fb203f79..b1d3729a 100644 --- a/src/webui/routers/system.py +++ b/src/webui/routers/system.py @@ -5,19 +5,30 @@ """ import os -import sys import time from datetime import datetime -from fastapi import APIRouter, HTTPException +from typing import Optional +from fastapi import APIRouter, HTTPException, Depends, Cookie, Header from pydantic import BaseModel from src.config.config import MMC_VERSION +from src.common.logger import get_logger +from src.webui.auth import verify_auth_token_from_cookie_or_header router = APIRouter(prefix="/system", tags=["system"]) +logger = get_logger("webui_system") # 记录启动时间 _start_time = time.time() +def require_auth( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> bool: + """认证依赖:验证用户是否已登录""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) + + class RestartResponse(BaseModel): """重启响应""" @@ -35,33 +46,38 @@ class StatusResponse(BaseModel): @router.post("/restart", response_model=RestartResponse) -async def restart_maibot(): +async def restart_maibot(_auth: bool = Depends(require_auth)): """ 重启麦麦主程序 - 使用 os.execv 重启当前进程,配置更改将在重启后生效。 + 请求重启当前进程,配置更改将在重启后生效。 注意:此操作会使麦麦暂时离线。 """ + import asyncio + try: # 记录重启操作 - print(f"[{datetime.now()}] WebUI 触发重启操作") + logger.info("WebUI 触发重启操作") - # 使用 os.execv 重启当前进程 - # 这会替换当前进程,保持相同的 PID - python = sys.executable - args = [python] + sys.argv + # 定义延迟重启的异步任务 + async def delayed_restart(): + await asyncio.sleep(0.5) # 延迟0.5秒,确保响应已发送 + # 使用 os._exit(42) 退出当前进程,配合外部 runner 脚本进行重启 + # 42 是约定的重启状态码 + logger.info("WebUI 请求重启,退出代码 42") + os._exit(42) - # 返回成功响应(实际上这个响应可能不会发送,因为进程会立即重启) - # 但我们仍然返回它以保持 API 一致性 - os.execv(python, args) + # 创建后台任务执行重启 + asyncio.create_task(delayed_restart()) + # 立即返回成功响应 return RestartResponse(success=True, message="麦麦正在重启中...") except Exception as e: raise HTTPException(status_code=500, detail=f"重启失败: {str(e)}") from e @router.get("/status", response_model=StatusResponse) -async def get_maibot_status(): +async def get_maibot_status(_auth: bool = Depends(require_auth)): """ 获取麦麦运行状态 @@ -84,7 +100,7 @@ async def get_maibot_status(): @router.post("/reload-config") -async def reload_config(): +async def reload_config(_auth: bool = Depends(require_auth)): """ 热重载配置(不重启进程) diff --git a/src/webui/routes.py b/src/webui/routes.py index 3eb7e673..8f85490c 100644 --- a/src/webui/routes.py +++ b/src/webui/routes.py @@ -1,18 +1,23 @@ """WebUI API 路由""" -from fastapi import APIRouter, HTTPException, Header +from fastapi import APIRouter, HTTPException, Header, Response, Request, Cookie, Depends from pydantic import BaseModel, Field from typing import Optional from src.common.logger import get_logger from .token_manager import get_token_manager +from .auth import set_auth_cookie, clear_auth_cookie +from .rate_limiter import get_rate_limiter, check_auth_rate_limit from .config_routes import router as config_router from .statistics_routes import router as statistics_router from .person_routes import router as person_router from .expression_routes import router as expression_router +from .jargon_routes import router as jargon_router from .emoji_routes import router as emoji_router from .plugin_routes import router as plugin_router from .plugin_progress_ws import get_progress_router from .routers.system import router as system_router +from .model_routes import router as model_router +from .ws_auth import router as ws_auth_router logger = get_logger("webui.api") @@ -27,6 +32,8 @@ router.include_router(statistics_router) router.include_router(person_router) # 注册表达方式管理路由 router.include_router(expression_router) +# 注册黑话管理路由 +router.include_router(jargon_router) # 注册表情包管理路由 router.include_router(emoji_router) # 注册插件管理路由 @@ -35,6 +42,10 @@ router.include_router(plugin_router) router.include_router(get_progress_router()) # 注册系统控制路由 router.include_router(system_router) +# 注册模型列表获取路由 +router.include_router(model_router) +# 注册 WebSocket 认证路由 +router.include_router(ws_auth_router) class TokenVerifyRequest(BaseModel): @@ -48,6 +59,7 @@ class TokenVerifyResponse(BaseModel): valid: bool = Field(..., description="Token 是否有效") message: str = Field(..., description="验证结果消息") + is_first_setup: bool = Field(False, description="是否为首次设置") class TokenUpdateRequest(BaseModel): @@ -99,47 +111,151 @@ async def health_check(): @router.post("/auth/verify", response_model=TokenVerifyResponse) -async def verify_token(request: TokenVerifyRequest): +async def verify_token( + request_body: TokenVerifyRequest, + request: Request, + response: Response, + _rate_limit: None = Depends(check_auth_rate_limit), +): """ - 验证访问令牌 + 验证访问令牌,验证成功后设置 HttpOnly Cookie Args: - request: 包含 token 的验证请求 + request_body: 包含 token 的验证请求 + request: FastAPI Request 对象(用于获取客户端 IP) + response: FastAPI Response 对象 Returns: - 验证结果 + 验证结果(包含首次配置状态) """ try: token_manager = get_token_manager() - is_valid = token_manager.verify_token(request.token) + rate_limiter = get_rate_limiter() + + is_valid = token_manager.verify_token(request_body.token) if is_valid: - return TokenVerifyResponse(valid=True, message="Token 验证成功") + # 认证成功,重置失败计数 + rate_limiter.reset_failures(request) + # 设置 HttpOnly Cookie(传入 request 以检测协议) + set_auth_cookie(response, request_body.token, request) + # 同时返回首次配置状态,避免额外请求 + is_first_setup = token_manager.is_first_setup() + return TokenVerifyResponse(valid=True, message="Token 验证成功", is_first_setup=is_first_setup) else: - return TokenVerifyResponse(valid=False, message="Token 无效或已过期") + # 记录失败尝试 + blocked, remaining = rate_limiter.record_failed_attempt( + request, + max_failures=5, # 5 次失败 + window_seconds=300, # 5 分钟窗口 + block_duration=600, # 封禁 10 分钟 + ) + + if blocked: + raise HTTPException(status_code=429, detail="认证失败次数过多,您的 IP 已被临时封禁 10 分钟") + + message = "Token 无效或已过期" + if remaining <= 2: + message += f"(剩余 {remaining} 次尝试机会)" + + return TokenVerifyResponse(valid=False, message=message) + except HTTPException: + raise except Exception as e: logger.error(f"Token 验证失败: {e}") raise HTTPException(status_code=500, detail="Token 验证失败") from e +@router.post("/auth/logout") +async def logout(response: Response): + """ + 登出并清除认证 Cookie + + Args: + response: FastAPI Response 对象 + + Returns: + 登出结果 + """ + clear_auth_cookie(response) + return {"success": True, "message": "已成功登出"} + + +@router.get("/auth/check") +async def check_auth_status( + request: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 检查当前认证状态(用于前端判断是否已登录) + + Returns: + 认证状态 + """ + try: + token = None + + # 记录请求信息用于调试 + logger.debug(f"检查认证状态 - Cookie: {maibot_session[:20] if maibot_session else 'None'}..., Authorization: {'Present' if authorization else 'None'}") + + # 优先从 Cookie 获取 + if maibot_session: + token = maibot_session + logger.debug("使用 Cookie 中的 token") + # 其次从 Header 获取 + elif authorization and authorization.startswith("Bearer "): + token = authorization.replace("Bearer ", "") + logger.debug("使用 Header 中的 token") + + if not token: + logger.debug("未找到 token,返回未认证") + return {"authenticated": False} + + token_manager = get_token_manager() + is_valid = token_manager.verify_token(token) + logger.debug(f"Token 验证结果: {is_valid}") + + if is_valid: + return {"authenticated": True} + else: + return {"authenticated": False} + except Exception as e: + logger.error(f"认证检查失败: {e}", exc_info=True) + return {"authenticated": False} + + @router.post("/auth/update", response_model=TokenUpdateResponse) -async def update_token(request: TokenUpdateRequest, authorization: Optional[str] = Header(None)): +async def update_token( + request: TokenUpdateRequest, + response: Response, + req: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 更新访问令牌(需要当前有效的 token) Args: request: 包含新 token 的更新请求 + response: FastAPI Response 对象 + maibot_session: Cookie 中的 token authorization: Authorization header (Bearer token) Returns: 更新结果 """ try: - # 验证当前 token - if not authorization or not authorization.startswith("Bearer "): + # 验证当前 token(优先 Cookie,其次 Header) + current_token = None + if maibot_session: + current_token = maibot_session + elif authorization and authorization.startswith("Bearer "): + current_token = authorization.replace("Bearer ", "") + + if not current_token: raise HTTPException(status_code=401, detail="未提供有效的认证信息") - current_token = authorization.replace("Bearer ", "") token_manager = get_token_manager() if not token_manager.verify_token(current_token): @@ -148,6 +264,10 @@ async def update_token(request: TokenUpdateRequest, authorization: Optional[str] # 更新 token success, message = token_manager.update_token(request.new_token) + # 如果更新成功,清除 Cookie,要求用户重新登录 + if success: + clear_auth_cookie(response) + return TokenUpdateResponse(success=success, message=message) except HTTPException: raise @@ -157,22 +277,34 @@ async def update_token(request: TokenUpdateRequest, authorization: Optional[str] @router.post("/auth/regenerate", response_model=TokenRegenerateResponse) -async def regenerate_token(authorization: Optional[str] = Header(None)): +async def regenerate_token( + response: Response, + request: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 重新生成访问令牌(需要当前有效的 token) Args: + response: FastAPI Response 对象 + maibot_session: Cookie 中的 token authorization: Authorization header (Bearer token) Returns: 新生成的 token """ try: - # 验证当前 token - if not authorization or not authorization.startswith("Bearer "): + # 验证当前 token(优先 Cookie,其次 Header) + current_token = None + if maibot_session: + current_token = maibot_session + elif authorization and authorization.startswith("Bearer "): + current_token = authorization.replace("Bearer ", "") + + if not current_token: raise HTTPException(status_code=401, detail="未提供有效的认证信息") - current_token = authorization.replace("Bearer ", "") token_manager = get_token_manager() if not token_manager.verify_token(current_token): @@ -181,6 +313,9 @@ async def regenerate_token(authorization: Optional[str] = Header(None)): # 重新生成 token new_token = token_manager.regenerate_token() + # 清除 Cookie,要求用户重新登录 + clear_auth_cookie(response) + return TokenRegenerateResponse(success=True, token=new_token, message="Token 已重新生成") except HTTPException: raise @@ -190,22 +325,32 @@ async def regenerate_token(authorization: Optional[str] = Header(None)): @router.get("/setup/status", response_model=FirstSetupStatusResponse) -async def get_setup_status(authorization: Optional[str] = Header(None)): +async def get_setup_status( + request: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 获取首次配置状态 Args: + maibot_session: Cookie 中的 token authorization: Authorization header (Bearer token) Returns: 首次配置状态 """ try: - # 验证 token - if not authorization or not authorization.startswith("Bearer "): + # 验证 token(优先 Cookie,其次 Header) + current_token = None + if maibot_session: + current_token = maibot_session + elif authorization and authorization.startswith("Bearer "): + current_token = authorization.replace("Bearer ", "") + + if not current_token: raise HTTPException(status_code=401, detail="未提供有效的认证信息") - current_token = authorization.replace("Bearer ", "") token_manager = get_token_manager() if not token_manager.verify_token(current_token): @@ -223,22 +368,32 @@ async def get_setup_status(authorization: Optional[str] = Header(None)): @router.post("/setup/complete", response_model=CompleteSetupResponse) -async def complete_setup(authorization: Optional[str] = Header(None)): +async def complete_setup( + request: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 标记首次配置完成 Args: + maibot_session: Cookie 中的 token authorization: Authorization header (Bearer token) Returns: 完成结果 """ try: - # 验证 token - if not authorization or not authorization.startswith("Bearer "): + # 验证 token(优先 Cookie,其次 Header) + current_token = None + if maibot_session: + current_token = maibot_session + elif authorization and authorization.startswith("Bearer "): + current_token = authorization.replace("Bearer ", "") + + if not current_token: raise HTTPException(status_code=401, detail="未提供有效的认证信息") - current_token = authorization.replace("Bearer ", "") token_manager = get_token_manager() if not token_manager.verify_token(current_token): @@ -256,22 +411,32 @@ async def complete_setup(authorization: Optional[str] = Header(None)): @router.post("/setup/reset", response_model=ResetSetupResponse) -async def reset_setup(authorization: Optional[str] = Header(None)): +async def reset_setup( + request: Request, + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): """ 重置首次配置状态,允许重新进入配置向导 Args: + maibot_session: Cookie 中的 token authorization: Authorization header (Bearer token) Returns: 重置结果 """ try: - # 验证 token - if not authorization or not authorization.startswith("Bearer "): + # 验证 token(优先 Cookie,其次 Header) + current_token = None + if maibot_session: + current_token = maibot_session + elif authorization and authorization.startswith("Bearer "): + current_token = authorization.replace("Bearer ", "") + + if not current_token: raise HTTPException(status_code=401, detail="未提供有效的认证信息") - current_token = authorization.replace("Bearer ", "") token_manager = get_token_manager() if not token_manager.verify_token(current_token): diff --git a/src/webui/statistics_routes.py b/src/webui/statistics_routes.py index b0a3664c..e5628538 100644 --- a/src/webui/statistics_routes.py +++ b/src/webui/statistics_routes.py @@ -1,19 +1,28 @@ """统计数据 API 路由""" -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Depends, Cookie, Header from pydantic import BaseModel, Field -from typing import Dict, Any, List +from typing import Dict, Any, List, Optional from datetime import datetime, timedelta from peewee import fn from src.common.logger import get_logger from src.common.database.database_model import LLMUsage, OnlineTime, Messages +from src.webui.auth import verify_auth_token_from_cookie_or_header logger = get_logger("webui.statistics") router = APIRouter(prefix="/statistics", tags=["statistics"]) +def require_auth( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +) -> bool: + """认证依赖:验证用户是否已登录""" + return verify_auth_token_from_cookie_or_header(maibot_session, authorization) + + class StatisticsSummary(BaseModel): """统计数据摘要""" @@ -58,7 +67,7 @@ class DashboardData(BaseModel): @router.get("/dashboard", response_model=DashboardData) -async def get_dashboard_data(hours: int = 24): +async def get_dashboard_data(hours: int = 24, _auth: bool = Depends(require_auth)): """ 获取仪表盘统计数据 @@ -275,7 +284,7 @@ async def _get_recent_activity(limit: int = 10) -> List[Dict[str, Any]]: @router.get("/summary") -async def get_summary(hours: int = 24): +async def get_summary(hours: int = 24, _auth: bool = Depends(require_auth)): """ 获取统计摘要 @@ -293,7 +302,7 @@ async def get_summary(hours: int = 24): @router.get("/models") -async def get_model_stats(hours: int = 24): +async def get_model_stats(hours: int = 24, _auth: bool = Depends(require_auth)): """ 获取模型统计 diff --git a/src/webui/token_manager.py b/src/webui/token_manager.py index 69abf1d8..bd1e5fbb 100644 --- a/src/webui/token_manager.py +++ b/src/webui/token_manager.py @@ -160,13 +160,29 @@ class TokenManager: def regenerate_token(self) -> str: """ - 重新生成 token + 重新生成 token(保留 first_setup_completed 状态) Returns: str: 新生成的 token """ logger.info("正在重新生成 WebUI Token...") - return self._create_new_token() + + # 生成新的 64 位十六进制字符串 + new_token = secrets.token_hex(32) + + # 加载现有配置,保留 first_setup_completed 状态 + config = self._load_config() + old_token = config.get("access_token", "")[:8] if config.get("access_token") else "无" + first_setup_completed = config.get("first_setup_completed", True) # 默认为 True,表示已完成配置 + + config["access_token"] = new_token + config["updated_at"] = self._get_current_timestamp() + config["first_setup_completed"] = first_setup_completed # 保留原来的状态 + + self._save_config(config) + logger.info(f"WebUI Token 已重新生成: {old_token}... -> {new_token[:8]}...") + + return new_token def _validate_token_format(self, token: str) -> bool: """ diff --git a/src/webui/webui_server.py b/src/webui/webui_server.py index 61d279e2..da5732d0 100644 --- a/src/webui/webui_server.py +++ b/src/webui/webui_server.py @@ -1,10 +1,10 @@ -"""独立的 WebUI 服务器 - 运行在 0.0.0.0:8001""" +"""独立的 WebUI 服务器 - 默认运行在 127.0.0.1:8001""" -import os import asyncio import mimetypes from pathlib import Path from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from uvicorn import Config, Server as UvicornServer from src.common.logger import get_logger @@ -15,24 +15,59 @@ logger = get_logger("webui_server") class WebUIServer: """独立的 WebUI 服务器""" - def __init__(self, host: str = "0.0.0.0", port: int = 8001): + def __init__(self, host: str = "127.0.0.1", port: int = 8001): self.host = host self.port = port self.app = FastAPI(title="MaiBot WebUI") self._server = None - + + # 配置防爬虫中间件(需要在CORS之前注册) + self._setup_anti_crawler() + + # 配置 CORS(支持开发环境跨域请求) + self._setup_cors() + # 显示 Access Token self._show_access_token() - + # 重要:先注册 API 路由,再设置静态文件 self._register_api_routes() self._setup_static_files() + # 注册robots.txt路由 + self._setup_robots_txt() + + def _setup_cors(self): + """配置 CORS 中间件""" + # 开发环境需要允许前端开发服务器的跨域请求 + self.app.add_middleware( + CORSMiddleware, + allow_origins=[ + "http://localhost:5173", # Vite 开发服务器 + "http://127.0.0.1:5173", + "http://localhost:7999", # 前端开发服务器备用端口 + "http://127.0.0.1:7999", + "http://localhost:8001", # 生产环境 + "http://127.0.0.1:8001", + ], + allow_credentials=True, # 允许携带 Cookie + allow_methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"], # 明确指定允许的方法 + allow_headers=[ + "Content-Type", + "Authorization", + "Accept", + "Origin", + "X-Requested-With", + ], # 明确指定允许的头 + expose_headers=["Content-Length", "Content-Type"], # 允许前端读取的响应头 + ) + logger.debug("✅ CORS 中间件已配置") + def _show_access_token(self): """显示 WebUI Access Token""" try: from src.webui.token_manager import get_token_manager - + token_manager = get_token_manager() current_token = token_manager.get_token() logger.info(f"🔑 WebUI Access Token: {current_token}") @@ -68,37 +103,94 @@ class WebUIServer: """服务单页应用 - 只处理非 API 请求""" # 如果是根路径,直接返回 index.html if not full_path or full_path == "/": - return FileResponse(static_path / "index.html", media_type="text/html") - + response = FileResponse(static_path / "index.html", media_type="text/html") + response.headers["X-Robots-Tag"] = "noindex, nofollow, noarchive" + return response + # 检查是否是静态文件 file_path = static_path / full_path if file_path.is_file() and file_path.exists(): # 自动检测 MIME 类型 media_type = mimetypes.guess_type(str(file_path))[0] - return FileResponse(file_path, media_type=media_type) + response = FileResponse(file_path, media_type=media_type) + # HTML 文件添加防索引头 + if str(file_path).endswith(".html"): + response.headers["X-Robots-Tag"] = "noindex, nofollow, noarchive" + return response # 其他路径返回 index.html(SPA 路由) - return FileResponse(static_path / "index.html", media_type="text/html") + response = FileResponse(static_path / "index.html", media_type="text/html") + response.headers["X-Robots-Tag"] = "noindex, nofollow, noarchive" + return response logger.info(f"✅ WebUI 静态文件服务已配置: {static_path}") + def _setup_anti_crawler(self): + """配置防爬虫中间件""" + try: + from src.webui.anti_crawler import AntiCrawlerMiddleware + from src.config.config import global_config + + # 从配置读取防爬虫模式 + anti_crawler_mode = global_config.webui.anti_crawler_mode + + # 注意:中间件按注册顺序反向执行,所以先注册的中间件后执行 + # 我们需要在CORS之前注册,这样防爬虫检查会在CORS之前执行 + self.app.add_middleware(AntiCrawlerMiddleware, mode=anti_crawler_mode) + + mode_descriptions = {"false": "已禁用", "strict": "严格模式", "loose": "宽松模式", "basic": "基础模式"} + mode_desc = mode_descriptions.get(anti_crawler_mode, "基础模式") + logger.info(f"🛡️ 防爬虫中间件已配置: {mode_desc}") + except Exception as e: + logger.error(f"❌ 配置防爬虫中间件失败: {e}", exc_info=True) + + def _setup_robots_txt(self): + """设置robots.txt路由""" + try: + from src.webui.anti_crawler import create_robots_txt_response + + @self.app.get("/robots.txt", include_in_schema=False) + async def robots_txt(): + """返回robots.txt,禁止所有爬虫""" + return create_robots_txt_response() + + logger.debug("✅ robots.txt 路由已注册") + except Exception as e: + logger.error(f"❌ 注册robots.txt路由失败: {e}", exc_info=True) + def _register_api_routes(self): """注册所有 WebUI API 路由""" try: # 导入所有 WebUI 路由 from src.webui.routes import router as webui_router from src.webui.logs_ws import router as logs_router + from src.webui.knowledge_routes import router as knowledge_router + + # 导入本地聊天室路由 + from src.webui.chat_routes import router as chat_router # 注册路由 self.app.include_router(webui_router) self.app.include_router(logs_router) + self.app.include_router(knowledge_router) + self.app.include_router(chat_router) logger.info("✅ WebUI API 路由已注册") except Exception as e: - logger.error(f"❌ 注册 WebUI API 路由失败: {e}") + logger.error(f"❌ 注册 WebUI API 路由失败: {e}", exc_info=True) async def start(self): """启动服务器""" + # 预先检查端口是否可用 + if not self._check_port_available(): + error_msg = f"❌ WebUI 服务器启动失败: 端口 {self.port} 已被占用" + logger.error(error_msg) + logger.error(f"💡 请检查是否有其他程序正在使用端口 {self.port}") + logger.error("💡 可以在 .env 文件中修改 WEBUI_PORT 来更改 WebUI 端口") + logger.error(f"💡 Windows 用户可以运行: netstat -ano | findstr :{self.port}") + logger.error(f"💡 Linux/Mac 用户可以运行: lsof -i :{self.port}") + raise OSError(f"端口 {self.port} 已被占用,无法启动 WebUI 服务器") + config = Config( app=self.app, host=self.host, @@ -109,13 +201,59 @@ class WebUIServer: self._server = UvicornServer(config=config) logger.info("🌐 WebUI 服务器启动中...") - logger.info(f"🌐 访问地址: http://{self.host}:{self.port}") + + # 根据地址类型显示正确的访问地址 + if ':' in self.host: + # IPv6 地址需要用方括号包裹 + logger.info(f"🌐 访问地址: http://[{self.host}]:{self.port}") + if self.host == "::": + logger.info(f"💡 IPv6 本机访问: http://[::1]:{self.port}") + logger.info(f"💡 IPv4 本机访问: http://127.0.0.1:{self.port}") + elif self.host == "::1": + logger.info("💡 仅支持 IPv6 本地访问") + else: + # IPv4 地址 + logger.info(f"🌐 访问地址: http://{self.host}:{self.port}") + if self.host == "0.0.0.0": + logger.info(f"💡 本机访问: http://localhost:{self.port} 或 http://127.0.0.1:{self.port}") try: await self._server.serve() - except Exception as e: - logger.error(f"❌ WebUI 服务器运行错误: {e}") + except OSError as e: + # 处理端口绑定相关的错误 + if "address already in use" in str(e).lower() or e.errno in (98, 10048): # 98: Linux, 10048: Windows + logger.error(f"❌ WebUI 服务器启动失败: 端口 {self.port} 已被占用") + logger.error(f"💡 请检查是否有其他程序正在使用端口 {self.port}") + logger.error("💡 可以在 .env 文件中修改 WEBUI_PORT 来更改 WebUI 端口") + else: + logger.error(f"❌ WebUI 服务器启动失败 (网络错误): {e}") raise + except Exception as e: + logger.error(f"❌ WebUI 服务器运行错误: {e}", exc_info=True) + raise + + def _check_port_available(self) -> bool: + """检查端口是否可用(支持 IPv4 和 IPv6)""" + import socket + + # 判断使用 IPv4 还是 IPv6 + if ':' in self.host: + # IPv6 地址 + family = socket.AF_INET6 + test_host = self.host if self.host != "::" else "::1" + else: + # IPv4 地址 + family = socket.AF_INET + test_host = self.host if self.host != "0.0.0.0" else "127.0.0.1" + + try: + with socket.socket(family, socket.SOCK_STREAM) as s: + s.settimeout(1) + # 尝试绑定端口 + s.bind((test_host, self.port)) + return True + except OSError: + return False async def shutdown(self): """关闭服务器""" @@ -141,8 +279,9 @@ def get_webui_server() -> WebUIServer: """获取全局 WebUI 服务器实例""" global _webui_server if _webui_server is None: - # 从环境变量读取配置 - host = os.getenv("WEBUI_HOST", "0.0.0.0") + # 从环境变量读取 + import os + host = os.getenv("WEBUI_HOST", "127.0.0.1") port = int(os.getenv("WEBUI_PORT", "8001")) _webui_server = WebUIServer(host=host, port=port) return _webui_server diff --git a/src/webui/ws_auth.py b/src/webui/ws_auth.py new file mode 100644 index 00000000..e6bb00e7 --- /dev/null +++ b/src/webui/ws_auth.py @@ -0,0 +1,114 @@ +"""WebSocket 认证模块 + +提供所有 WebSocket 端点统一使用的临时 token 认证机制。 +临时 token 有效期 60 秒,且只能使用一次,用于解决 WebSocket 握手时 Cookie 不可用的问题。 +""" + +from fastapi import APIRouter, Cookie, Header +from typing import Optional +import secrets +import time +from src.common.logger import get_logger +from src.webui.token_manager import get_token_manager + +logger = get_logger("webui.ws_auth") +router = APIRouter() + +# WebSocket 临时 token 存储 {token: (expire_time, session_token)} +# 临时 token 有效期 60 秒,仅用于 WebSocket 握手 +_ws_temp_tokens: dict[str, tuple[float, str]] = {} +_WS_TOKEN_EXPIRE_SECONDS = 60 + + +def _cleanup_expired_ws_tokens(): + """清理过期的临时 token""" + now = time.time() + expired = [t for t, (exp, _) in _ws_temp_tokens.items() if now > exp] + for t in expired: + del _ws_temp_tokens[t] + + +def generate_ws_token(session_token: str) -> str: + """生成 WebSocket 临时 token + + Args: + session_token: 原始的 session token + + Returns: + 临时 token 字符串 + """ + _cleanup_expired_ws_tokens() + temp_token = secrets.token_urlsafe(32) + _ws_temp_tokens[temp_token] = (time.time() + _WS_TOKEN_EXPIRE_SECONDS, session_token) + logger.debug(f"生成 WS 临时 token: {temp_token[:8]}... 有效期 {_WS_TOKEN_EXPIRE_SECONDS}s") + return temp_token + + +def verify_ws_token(temp_token: str) -> bool: + """验证并消费 WebSocket 临时 token(一次性使用) + + Args: + temp_token: 临时 token + + Returns: + 验证是否通过 + """ + _cleanup_expired_ws_tokens() + if temp_token not in _ws_temp_tokens: + logger.warning(f"WS token 不存在: {temp_token[:8]}...") + return False + expire_time, session_token = _ws_temp_tokens[temp_token] + if time.time() > expire_time: + del _ws_temp_tokens[temp_token] + logger.warning(f"WS token 已过期: {temp_token[:8]}...") + return False + # 验证原始 session token 仍然有效 + token_manager = get_token_manager() + if not token_manager.verify_token(session_token): + del _ws_temp_tokens[temp_token] + logger.warning(f"WS token 关联的 session 已失效: {temp_token[:8]}...") + return False + # 消费 token(一次性使用) + del _ws_temp_tokens[temp_token] + logger.debug(f"WS token 验证成功: {temp_token[:8]}...") + return True + + +@router.get("/ws-token") +async def get_ws_token( + maibot_session: Optional[str] = Cookie(None), + authorization: Optional[str] = Header(None), +): + """ + 获取 WebSocket 连接用的临时 token + + 此端点验证当前会话的 Cookie 或 Authorization header, + 然后返回一个临时 token 用于 WebSocket 握手认证。 + 临时 token 有效期 60 秒,且只能使用一次。 + + 注意:在未认证时返回 200 状态码但 success=False,避免前端因 401 刷新页面。 + """ + # 获取当前 session token + session_token = None + if maibot_session: + session_token = maibot_session + elif authorization and authorization.startswith("Bearer "): + session_token = authorization.replace("Bearer ", "") + + if not session_token: + # 返回 200 但 success=False,避免前端因 401 刷新页面 + # 这在登录页面是正常情况,不应该触发错误处理 + logger.debug("ws-token 请求:未提供认证信息(可能在登录页面)") + return {"success": False, "message": "未提供认证信息,请先登录", "token": None, "expires_in": 0} + + # 验证 session token + token_manager = get_token_manager() + if not token_manager.verify_token(session_token): + # 同样返回 200 但 success=False,避免前端刷新 + logger.debug("ws-token 请求:认证已过期") + return {"success": False, "message": "认证已过期,请重新登录", "token": None, "expires_in": 0} + + # 生成临时 WebSocket token + ws_token = generate_ws_token(session_token) + + return {"success": True, "token": ws_token, "expires_in": _WS_TOKEN_EXPIRE_SECONDS} diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 2c1da1be..9b0544aa 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,9 +1,9 @@ [inner] -version = "6.21.8" +version = "7.2.5" #----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读---- -#如果你想要修改配置文件,请递增version的值 -#如果新增项目,请阅读src/config/official_configs.py中的说明 +# 如果你想要修改配置文件,请递增version的值 +# 如果新增项目,请阅读src/config/official_configs.py中的说明 # # 版本格式:主版本号.次版本号.修订号,版本号递增规则如下: # 主版本号:MMC版本更新 @@ -22,21 +22,31 @@ alias_names = ["麦叠", "牢麦"] # 麦麦的别名 [personality] # 建议120字以内,描述人格特质 和 身份特征 -personality = "是一个女大学生,现在在读大二,会刷贴吧。" -#アイデンティティがない 生まれないらららら -# 描述麦麦说话的表达风格,表达习惯,如要修改,可以酌情新增内容 -reply_style = "请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。" +personality = "是一个大二在读女大学生,现在正在上网和群友聊天,有时有点攻击性,有时比较温柔" +# アイデンティティがない 生まれないらららら +# 描述麦麦说话的表达风格,表达习惯,如要修改,可以酌情新增内容,建议1-2行 +reply_style = "请不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。" -# 麦麦的兴趣,会影响麦麦对什么话题进行回复 -interest = "对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题" +# 多种回复风格列表,可选配置:当 non-empty 且 multiple_probability>0 时,会按概率随机从中选择一个替换 reply_style +multiple_reply_style = [ + # "你的风格平淡但不失讽刺,很简短,很白话。可以参考贴吧,微博的回复风格。", + # "用1-2个字进行回复", + # "用1-2个符号进行回复", + # "言辭凝練古雅,穿插《論語》經句卻不晦澀,以文言短句為基,輔以淺白語意,持長者溫和風範,全用繁體字表達,具先秦儒者談吐韻致。", + # "带点翻译腔,但不要太长", +] + +# 替换概率:每次构建回复时,以该概率从 multiple_reply_style 中随机选择一个替换 reply_style(0.0-1.0) +multiple_probability = 0.3 # 麦麦的说话规则,行为风格: plan_style = """ 1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 2.如果相同的内容已经被执行,请不要重复执行 -3.请控制你的发言频率,不要太过频繁的发言 -4.如果有人对你感到厌烦,请减少回复 -5.如果有人对你进行攻击,或者情绪激动,请你以合适的方法应对""" +3.你对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题 +4.请控制你的发言频率,不要太过频繁的发言 +5.如果有人对你感到厌烦,请减少回复 +6.如果有人在追问你,或者话题没有说完,请你继续回复""" # 麦麦识图规则,不建议修改 visual_style = "请用中文描述这张图片的内容。如果有文字,请把文字描述概括出来,请留意其主题,直观感受,输出为一段平文本,最多30字,请注意不要分点,就输出一段文本" @@ -57,18 +67,19 @@ states = [ # 替换概率,每次构建人格时替换personality的概率(0.0-1.0) state_probability = 0.3 + + [expression] # 表达学习配置 learning_list = [ # 表达学习配置列表,支持按聊天流配置 - ["", "enable", "enable", "1.0"], # 全局配置:使用表达,启用学习,学习强度1.0 - ["qq:1919810:group", "enable", "enable", "1.5"], # 特定群聊配置:使用表达,启用学习,学习强度1.5 - ["qq:114514:private", "enable", "disable", "0.5"], # 特定私聊配置:使用表达,禁用学习,学习强度0.5 + ["", "enable", "enable", "enable"], # 全局配置:使用表达,启用学习,启用jargon学习 + ["qq:1919810:group", "enable", "enable", "enable"], # 特定群聊配置:使用表达,启用学习,启用jargon学习 + ["qq:114514:private", "enable", "disable", "disable"], # 特定私聊配置:使用表达,禁用学习,禁用jargon学习 # 格式说明: # 第一位: chat_stream_id,空字符串表示全局配置 # 第二位: 是否使用学到的表达 ("enable"/"disable") # 第三位: 是否学习表达 ("enable"/"disable") - # 第四位: 学习强度(浮点数),影响学习频率,最短学习时间间隔 = 300/学习强度(秒) - # 学习强度越高,学习越频繁;学习强度越低,学习越少 + # 第四位: 是否启用jargon学习 ("enable"/"disable") ] expression_groups = [ @@ -80,12 +91,21 @@ expression_groups = [ # 注意:如果为群聊,则需要设置为group,如果设置为私聊,则需要设置为private ] +reflect = false # 是否启用表达反思(Bot主动向管理员询问表达方式是否合适) +reflect_operator_id = "" # 表达反思操作员ID,格式:platform:id:type (例如 "qq:123456:private" 或 "qq:654321:group") +allow_reflect = [] # 允许进行表达反思的聊天流ID列表,格式:["qq:123456:private", "qq:654321:group", ...],只有在此列表中的聊天流才会提出问题并跟踪。如果列表为空,则所有聊天流都可以进行表达反思(前提是 reflect = true) -[chat] #麦麦的聊天设置 -talk_value = 1 #聊天频率,越小越沉默,范围0-1 +all_global_jargon = true # 是否开启全局黑话模式,注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除 +enable_jargon_explanation = true # 是否在回复前尝试对上下文中的黑话进行解释(关闭可减少一次LLM调用,仅影响回复前的黑话匹配与解释,不影响黑话学习) +jargon_mode = "planner" # 黑话解释来源模式,可选: "context"(使用上下文自动匹配黑话) 或 "planner"(仅使用Planner在reply动作中给出的unknown_words列表) + + +[chat] # 麦麦的聊天设置 +talk_value = 1 # 聊天频率,越小越沉默,范围0-1 mentioned_bot_reply = true # 是否启用提及必回复 max_context_size = 30 # 上下文长度 -planner_smooth = 2 #规划器平滑,增大数值会减小planner负荷,略微降低反应速度,推荐1-5,0为关闭,必须大于等于0 +planner_smooth = 3 # 规划器平滑,增大数值会减小planner负荷,略微降低反应速度,推荐1-5,0为关闭,必须大于等于0 +think_mode = "dynamic" # 思考模式,可选:classic(默认浅度思考和回复)、deep(会进行比较长的,深度回复)、dynamic(动态选择两种模式) enable_talk_value_rules = true # 是否启用动态发言频率规则 @@ -93,7 +113,7 @@ enable_talk_value_rules = true # 是否启用动态发言频率规则 # 推荐格式(对象数组):{ target="platform:id:type" 或 "", time="HH:MM-HH:MM", value=0.5 } # 说明: # - target 为空字符串表示全局;type 为 group/private,例如:"qq:1919810:group" 或 "qq:114514:private"; -# - 支持跨夜区间,例如 "23:00-02:00";数值范围建议 0-1。 +# - 支持跨夜区间,例如 "23:00-02:00";数值范围建议 0-1,如果 value 设置为0会自动转换为0.0001以避免除以零错误。 talk_value_rules = [ { target = "", time = "00:00-08:59", value = 0.8 }, { target = "", time = "09:00-22:59", value = 1.0 }, @@ -101,22 +121,37 @@ talk_value_rules = [ { target = "qq:114514:private", time = "00:00-23:59", value = 0.3 }, ] -include_planner_reasoning = false # 是否将planner推理加入replyer,默认关闭(不加入) - [memory] -max_agent_iterations = 3 # 记忆思考深度(最低为1(不深入思考)) +max_agent_iterations = 3 # 记忆思考深度(最低为1) +agent_timeout_seconds = 45.0 # 最长回忆时间(秒) +enable_jargon_detection = true # 记忆检索过程中是否启用黑话识别 +global_memory = false # 是否允许记忆检索进行全局查询 -[jargon] -all_global = true # 是否开启全局黑话模式,注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除 +[dream] +interval_minutes = 60 # 做梦时间间隔(分钟),默认30分钟 +max_iterations = 20 # 做梦最大轮次,默认20轮 +first_delay_seconds = 1800 # 程序启动后首次做梦前的延迟时间(秒),默认60秒 + +# 做梦结果推送目标,格式为 "platform:user_id" +# 例如: "qq:123456" 表示在做梦结束后,将梦境文本额外发送给该QQ私聊用户。 +# 为空字符串时不推送。 +dream_send = "" + +# 做梦时间段配置,格式:["HH:MM-HH:MM", ...] +# 如果列表为空,则表示全天允许做梦。 +# 如果配置了时间段,则只有在这些时间段内才会实际执行做梦流程。 +# 时间段外,调度器仍会按间隔检查,但不会进入做梦流程。 +# 支持跨夜区间,例如 "23:00-02:00" 表示从23:00到次日02:00。 +# 示例: +dream_time_ranges = [ + # "09:00-22:00", # 白天允许做梦 + "23:00-10:00", # 跨夜时间段(23:00到次日10:00) +] +# dream_time_ranges = [] [tool] enable_tool = true # 是否启用工具 -[mood] -enable_mood = false # 是否启用情绪系统 -mood_update_threshold = 1 # 情绪更新阈值,越高,更新越慢 -# 情感特征,影响情绪的变化情况 -emotion_style = "情绪较为稳定,但遭遇特定事件的时候起伏较大" [emoji] emoji_chance = 0.4 # 麦麦激活表情包动作的概率 @@ -138,37 +173,38 @@ ban_words = [ ban_msgs_regex = [ # 需要过滤的消息(原始消息)匹配的正则表达式,匹配到的消息将被过滤,若不了解正则表达式请勿修改 - #"https?://[^\\s]+", # 匹配https链接 - #"\\d{4}-\\d{2}-\\d{2}", # 匹配日期 + # "https?://[^\\s]+", # 匹配https链接 + # "\\d{4}-\\d{2}-\\d{2}", # 匹配日期 ] [lpmm_knowledge] # lpmm知识库配置 enable = false # 是否启用lpmm知识库 lpmm_mode = "agent" -# 可选:classic经典模式,agent 模式,结合最新的记忆一同使用 -rag_synonym_search_top_k = 10 # 同义词搜索TopK -rag_synonym_threshold = 0.8 # 同义词阈值(相似度高于此阈值的词语会被认为是同义词) -info_extraction_workers = 3 # 实体提取同时执行线程数,非Pro模型不要设置超过5 -qa_relation_search_top_k = 10 # 关系搜索TopK -qa_relation_threshold = 0.5 # 关系阈值(相似度高于此阈值的关系会被认为是相关的关系) -qa_paragraph_search_top_k = 1000 # 段落搜索TopK(不能过小,可能影响搜索结果) +# 可选择classic传统模式/agent 模式,结合新的记忆一同使用 +rag_synonym_search_top_k = 10 # 同义检索TopK +rag_synonym_threshold = 0.8 # 同义阈值,相似度高于该值的关系会被当作同义词 +info_extraction_workers = 3 # 实体抽取同时执行线程数,非Pro模型不要设置超过5 +qa_relation_search_top_k = 10 # 关系检索TopK +qa_relation_threshold = 0.5 # 关系阈值,相似度高于该值的关系会被认为是相关关系 +qa_paragraph_search_top_k = 1000 # 段落检索TopK(不能过小,可能影响搜索结果) qa_paragraph_node_weight = 0.05 # 段落节点权重(在图搜索&PPR计算中的权重,当搜索仅使用DPR时,此参数不起作用) qa_ent_filter_top_k = 10 # 实体过滤TopK qa_ppr_damping = 0.8 # PPR阻尼系数 -qa_res_top_k = 3 # 最终提供的文段TopK -embedding_dimension = 1024 # 嵌入向量维度,应该与模型的输出维度一致 +qa_res_top_k = 3 # 最终提供段落TopK +embedding_dimension = 1024 # 嵌入向量维度,输出维度一致 +# 性能与降级参数(低配机器可下调) +# 低配机器参考:单/双核或内存≤4GB(如轻量云主机/云函数/开发板),建议先关闭PPR并降低并发 +max_embedding_workers = 3 # 嵌入/抽取并发线程数 +embedding_chunk_size = 4 # 每批嵌入的条数 +max_synonym_entities = 2000 # 同义边参与的实体数上限,超限则跳过 +enable_ppr = true # 是否启用PPR,低配机器可关闭 -# keyword_rules 用于设置关键词触发的额外回复知识 -# 添加新规则方法:在 keyword_rules 数组中增加一项,格式如下: -# { keywords = ["关键词1", "关键词2"], reaction = "触发这些关键词时的回复内容" } -# 例如,添加一个新规则:当检测到“你好”或“hello”时回复“你好,有什么可以帮你?” -# { keywords = ["你好", "hello"], reaction = "你好,有什么可以帮你?" } [keyword_reaction] keyword_rules = [ { keywords = ["人机", "bot", "机器", "入机", "robot", "机器人", "ai", "AI"], reaction = "有人说你是人机或者机器人,否定这一事实,攻击或反问他。注意,只有认为你是机器人才回复,否则不要否认" }, { keywords = ["测试关键词回复", "test"], reaction = "回答测试成功" }, - #{ keywords = ["你好", "hello"], reaction = "你好,有什么可以帮你?" } + # { keywords = ["你好", "hello"], reaction = "你好,有什么可以帮你?" } # 在此处添加更多规则,格式同上 ] @@ -216,19 +252,35 @@ show_planner_prompt = false # 是否显示planner的prompt和原始返回结果 show_lpmm_paragraph = false # 是否显示lpmm找到的相关文段日志 [maim_message] -auth_token = [] # 认证令牌,用于API验证,为空则不启用验证 -# 以下项目若要使用需要打开use_custom,并单独配置maim_message的服务器 -use_custom = false # 是否启用自定义的maim_message服务器,注意这需要设置新的端口,不能与.env重复 -host="127.0.0.1" -port=8090 -mode="ws" # 支持ws和tcp两种模式 -use_wss = false # 是否使用WSS安全连接,只支持ws模式 -cert_file = "" # SSL证书文件路径,仅在use_wss=true时有效 -key_file = "" # SSL密钥文件路径,仅在use_wss=true时有效 +auth_token = [] # 认证令牌,用于旧版API验证,为空则不启用验证 + +# 新版API Server配置(额外监听端口) +enable_api_server = false # 是否启用额外的新版API Server +api_server_host = "0.0.0.0" # 新版API Server主机地址 +api_server_port = 8090 # 新版API Server端口号 +api_server_use_wss = false # 新版API Server是否启用WSS +api_server_cert_file = "" # 新版API Server SSL证书文件路径 +api_server_key_file = "" # 新版API Server SSL密钥文件路径 +api_server_allowed_api_keys = [] # 新版API Server允许的API Key列表,为空则允许所有连接 [telemetry] #发送统计信息,主要是看全球有多少只麦麦 enable = true +[webui] # WebUI 独立服务器配置 +# 注意: WebUI 的监听地址(host)和端口(port)已移至 .env 文件中的 WEBUI_HOST 和 WEBUI_PORT +enabled = true # 是否启用WebUI +mode = "production" # 模式: development(开发) 或 production(生产) + +# 防爬虫配置 +anti_crawler_mode = "basic" # 防爬虫模式: false(禁用) / strict(严格) / loose(宽松) / basic(基础-只记录不阻止) +allowed_ips = "127.0.0.1" # IP白名单(逗号分隔,支持精确IP、CIDR格式和通配符) + # 示例: 127.0.0.1,192.168.1.0/24,172.17.0.0/16 +trusted_proxies = "" # 信任的代理IP列表(逗号分隔),只有来自这些IP的X-Forwarded-For才被信任 + # 示例: 127.0.0.1,192.168.1.1,172.17.0.1 +trust_xff = false # 是否启用X-Forwarded-For代理解析(默认false) + # 启用后,仍要求直连IP在trusted_proxies中才会信任XFF头 +secure_cookie = false # 是否启用安全Cookie(仅通过HTTPS传输,默认false) + [experimental] #实验性功能 # 为指定聊天添加额外的prompt配置 # 格式: ["platform:id:type:prompt内容", ...] @@ -241,7 +293,6 @@ enable = true chat_prompts = [] -#此系统暂时移除,无效配置 +# 此系统暂时移除,无效配置 [relationship] enable_relationship = true # 是否启用关系系统 - diff --git a/template/model_config_template.toml b/template/model_config_template.toml index 6d956ace..669488f6 100644 --- a/template/model_config_template.toml +++ b/template/model_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "1.7.8" +version = "1.9.1" # 配置文件版本号迭代规则同bot_config.toml @@ -46,7 +46,7 @@ name = "deepseek-v3" # 模型名称(可随意命名,在后面 api_provider = "DeepSeek" # API服务商名称(对应在api_providers中配置的服务商名称) price_in = 2.0 # 输入价格(用于API调用统计,单位:元/ M token)(可选,若无该字段,默认值为0) price_out = 8.0 # 输出价格(用于API调用统计,单位:元/ M token)(可选,若无该字段,默认值为0) -#force_stream_mode = true # 强制流式输出模式(若模型不支持非流式输出,请取消该注释,启用强制流式输出,若无该字段,默认值为false) +# force_stream_mode = true # 强制流式输出模式(若模型不支持非流式输出,请取消该注释,启用强制流式输出,若无该字段,默认值为false) [[models]] model_identifier = "deepseek-ai/DeepSeek-V3.2-Exp" @@ -54,17 +54,48 @@ name = "siliconflow-deepseek-v3.2" api_provider = "SiliconFlow" price_in = 2.0 price_out = 3.0 +# temperature = 0.5 # 可选:为该模型单独指定温度,会覆盖任务配置中的温度 +# max_tokens = 4096 # 可选:为该模型单独指定最大token数,会覆盖任务配置中的max_tokens [models.extra_params] # 可选的额外参数配置 enable_thinking = false # 不启用思考 + [[models]] model_identifier = "deepseek-ai/DeepSeek-V3.2-Exp" name = "siliconflow-deepseek-v3.2-think" api_provider = "SiliconFlow" price_in = 2.0 price_out = 3.0 +# temperature = 0.7 # 可选:为该模型单独指定温度,会覆盖任务配置中的温度 +# max_tokens = 4096 # 可选:为该模型单独指定最大token数,会覆盖任务配置中的max_tokens [models.extra_params] # 可选的额外参数配置 -enable_thinking = true # 不启用思考 +enable_thinking = true # 启用思考 + + +[[models]] +model_identifier = "Qwen/Qwen3-Next-80B-A3B-Instruct" +name = "qwen3-next-80b" +api_provider = "SiliconFlow" +price_in = 1.0 +price_out = 4.0 + +[[models]] +model_identifier = "zai-org/GLM-4.6" +name = "siliconflow-glm-4.6" +api_provider = "SiliconFlow" +price_in = 3.5 +price_out = 14.0 +[models.extra_params] # 可选的额外参数配置 +enable_thinking = false # 不启用思考 + +[[models]] +model_identifier = "zai-org/GLM-4.6" +name = "siliconflow-glm-4.6-think" +api_provider = "SiliconFlow" +price_in = 3.5 +price_out = 14.0 +[models.extra_params] # 可选的额外参数配置 +enable_thinking = true # 启用思考 [[models]] model_identifier = "deepseek-ai/DeepSeek-R1" @@ -107,52 +138,63 @@ price_out = 0 [model_task_config.utils] # 在麦麦的一些组件中使用的模型,例如表情包模块,取名模块,关系模块,麦麦的情绪变化等,是麦麦必须的模型 model_list = ["siliconflow-deepseek-v3.2"] # 使用的模型列表,每个子项对应上面的模型名称(name) temperature = 0.2 # 模型温度,新V3建议0.1-0.3 -max_tokens = 2048 # 最大输出token数 +max_tokens = 4096 # 最大输出token数 +slow_threshold = 15.0 # 慢请求阈值(秒),模型等待回复时间超过此值会输出警告日志 [model_task_config.utils_small] # 在麦麦的一些组件中使用的小模型,消耗量较大,建议使用速度较快的小模型 model_list = ["qwen3-30b","qwen3-next-80b"] temperature = 0.7 max_tokens = 2048 +slow_threshold = 10.0 [model_task_config.tool_use] #工具调用模型,需要使用支持工具调用的模型 model_list = ["qwen3-30b","qwen3-next-80b"] temperature = 0.7 max_tokens = 800 +slow_threshold = 10.0 [model_task_config.replyer] # 首要回复模型,还用于表达器和表达方式学习 -model_list = ["siliconflow-deepseek-v3.2-think","siliconflow-glm-4.6-think","siliconflow-glm-4.6"] +model_list = ["siliconflow-deepseek-v3.2","siliconflow-deepseek-v3.2-think","siliconflow-glm-4.6","siliconflow-glm-4.6-think"] temperature = 0.3 # 模型温度,新V3建议0.1-0.3 max_tokens = 2048 +slow_threshold = 25.0 [model_task_config.planner] #决策:负责决定麦麦该什么时候回复的模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.3 max_tokens = 800 +slow_threshold = 12.0 [model_task_config.vlm] # 图像识别模型 model_list = ["qwen3-vl-30"] max_tokens = 256 +slow_threshold = 15.0 [model_task_config.voice] # 语音识别模型 model_list = ["sensevoice-small"] +slow_threshold = 12.0 -#嵌入模型 +# 嵌入模型 [model_task_config.embedding] model_list = ["bge-m3"] +slow_threshold = 5.0 -#------------LPMM知识库模型------------ +# ------------LPMM知识库模型------------ [model_task_config.lpmm_entity_extract] # 实体提取模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.2 max_tokens = 800 +slow_threshold = 20.0 [model_task_config.lpmm_rdf_build] # RDF构建模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.2 max_tokens = 800 +slow_threshold = 20.0 [model_task_config.lpmm_qa] # 问答模型 model_list = ["siliconflow-deepseek-v3.2"] temperature = 0.7 max_tokens = 800 +slow_threshold = 20.0 diff --git a/template/template.env b/template/template.env index b6dd0e5c..23143a71 100644 --- a/template/template.env +++ b/template/template.env @@ -2,8 +2,6 @@ HOST=127.0.0.1 PORT=8000 -# WebUI 独立服务器配置 -WEBUI_ENABLED=true -WEBUI_MODE=production # 模式: development(开发) 或 production(生产) -WEBUI_HOST=0.0.0.0 # WebUI 服务器监听地址 -WEBUI_PORT=8001 # WebUI 服务器端口 \ No newline at end of file +# WebUI 服务器配置 +WEBUI_HOST=127.0.0.1 +WEBUI_PORT=8001 \ No newline at end of file diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..788844f4 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2824 @@ +version = 1 +revision = 2 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", + "python_full_version < '3.11'", +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload_time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload_time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload_time = "2025-10-28T20:59:39.937Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/34/939730e66b716b76046dedfe0842995842fa906ccc4964bba414ff69e429/aiohttp-3.13.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2372b15a5f62ed37789a6b383ff7344fc5b9f243999b0cd9b629d8bc5f5b4155", size = 736471, upload_time = "2025-10-28T20:55:27.924Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/cf/dcbdf2df7f6ca72b0bb4c0b4509701f2d8942cf54e29ca197389c214c07f/aiohttp-3.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7f8659a48995edee7229522984bd1009c1213929c769c2daa80b40fe49a180c", size = 493985, upload_time = "2025-10-28T20:55:29.456Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9d/87/71c8867e0a1d0882dcbc94af767784c3cb381c1c4db0943ab4aae4fed65e/aiohttp-3.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:939ced4a7add92296b0ad38892ce62b98c619288a081170695c6babe4f50e636", size = 489274, upload_time = "2025-10-28T20:55:31.134Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/0f/46c24e8dae237295eaadd113edd56dee96ef6462adf19b88592d44891dc5/aiohttp-3.13.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6315fb6977f1d0dd41a107c527fee2ed5ab0550b7d885bc15fee20ccb17891da", size = 1668171, upload_time = "2025-10-28T20:55:36.065Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/c6/4cdfb4440d0e28483681a48f69841fa5e39366347d66ef808cbdadddb20e/aiohttp-3.13.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6e7352512f763f760baaed2637055c49134fd1d35b37c2dedfac35bfe5cf8725", size = 1636036, upload_time = "2025-10-28T20:55:37.576Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/37/8708cf678628216fb678ab327a4e1711c576d6673998f4f43e86e9ae90dd/aiohttp-3.13.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e09a0a06348a2dd73e7213353c90d709502d9786219f69b731f6caa0efeb46f5", size = 1727975, upload_time = "2025-10-28T20:55:39.457Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/2e/3ebfe12fdcb9b5f66e8a0a42dffcd7636844c8a018f261efb2419f68220b/aiohttp-3.13.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a09a6d073fb5789456545bdee2474d14395792faa0527887f2f4ec1a486a59d3", size = 1815823, upload_time = "2025-10-28T20:55:40.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/4f/ca2ef819488cbb41844c6cf92ca6dd15b9441e6207c58e5ae0e0fc8d70ad/aiohttp-3.13.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b59d13c443f8e049d9e94099c7e412e34610f1f49be0f230ec656a10692a5802", size = 1669374, upload_time = "2025-10-28T20:55:42.745Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/fe/1fe2e1179a0d91ce09c99069684aab619bf2ccde9b20bd6ca44f8837203e/aiohttp-3.13.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20db2d67985d71ca033443a1ba2001c4b5693fe09b0e29f6d9358a99d4d62a8a", size = 1555315, upload_time = "2025-10-28T20:55:44.264Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/2b/f3781899b81c45d7cbc7140cddb8a3481c195e7cbff8e36374759d2ab5a5/aiohttp-3.13.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:960c2fc686ba27b535f9fd2b52d87ecd7e4fd1cf877f6a5cba8afb5b4a8bd204", size = 1639140, upload_time = "2025-10-28T20:55:46.626Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/27/c37e85cd3ece6f6c772e549bd5a253d0c122557b25855fb274224811e4f2/aiohttp-3.13.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6c00dbcf5f0d88796151e264a8eab23de2997c9303dd7c0bf622e23b24d3ce22", size = 1645496, upload_time = "2025-10-28T20:55:48.933Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/20/3af1ab663151bd3780b123e907761cdb86ec2c4e44b2d9b195ebc91fbe37/aiohttp-3.13.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fed38a5edb7945f4d1bcabe2fcd05db4f6ec7e0e82560088b754f7e08d93772d", size = 1697625, upload_time = "2025-10-28T20:55:50.377Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/eb/ae5cab15efa365e13d56b31b0d085a62600298bf398a7986f8388f73b598/aiohttp-3.13.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:b395bbca716c38bef3c764f187860e88c724b342c26275bc03e906142fc5964f", size = 1542025, upload_time = "2025-10-28T20:55:51.861Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/2d/1683e8d67ec72d911397fe4e575688d2a9b8f6a6e03c8fdc9f3fd3d4c03f/aiohttp-3.13.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:204ffff2426c25dfda401ba08da85f9c59525cdc42bda26660463dd1cbcfec6f", size = 1714918, upload_time = "2025-10-28T20:55:53.515Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/a2/ffe8e0e1c57c5e542d47ffa1fcf95ef2b3ea573bf7c4d2ee877252431efc/aiohttp-3.13.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:05c4dd3c48fb5f15db31f57eb35374cb0c09afdde532e7fb70a75aede0ed30f6", size = 1656113, upload_time = "2025-10-28T20:55:55.438Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/42/d511aff5c3a2b06c09d7d214f508a4ad8ac7799817f7c3d23e7336b5e896/aiohttp-3.13.2-cp310-cp310-win32.whl", hash = "sha256:e574a7d61cf10351d734bcddabbe15ede0eaa8a02070d85446875dc11189a251", size = 432290, upload_time = "2025-10-28T20:55:56.96Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/ea/1c2eb7098b5bad4532994f2b7a8228d27674035c9b3234fe02c37469ef14/aiohttp-3.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:364f55663085d658b8462a1c3f17b2b84a5c2e1ba858e1b79bff7b2e24ad1514", size = 455075, upload_time = "2025-10-28T20:55:58.373Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/74/b321e7d7ca762638cdf8cdeceb39755d9c745aff7a64c8789be96ddf6e96/aiohttp-3.13.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4647d02df098f6434bafd7f32ad14942f05a9caa06c7016fdcc816f343997dd0", size = 743409, upload_time = "2025-10-28T20:56:00.354Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/3d/91524b905ec473beaf35158d17f82ef5a38033e5809fe8742e3657cdbb97/aiohttp-3.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e3403f24bcb9c3b29113611c3c16a2a447c3953ecf86b79775e7be06f7ae7ccb", size = 497006, upload_time = "2025-10-28T20:56:01.85Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/d3/7f68bc02a67716fe80f063e19adbd80a642e30682ce74071269e17d2dba1/aiohttp-3.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:43dff14e35aba17e3d6d5ba628858fb8cb51e30f44724a2d2f0c75be492c55e9", size = 493195, upload_time = "2025-10-28T20:56:03.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/31/913f774a4708775433b7375c4f867d58ba58ead833af96c8af3621a0d243/aiohttp-3.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2a9ea08e8c58bb17655630198833109227dea914cd20be660f52215f6de5613", size = 1747759, upload_time = "2025-10-28T20:56:04.904Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/63/04efe156f4326f31c7c4a97144f82132c3bb21859b7bb84748d452ccc17c/aiohttp-3.13.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53b07472f235eb80e826ad038c9d106c2f653584753f3ddab907c83f49eedead", size = 1704456, upload_time = "2025-10-28T20:56:06.986Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/02/4e16154d8e0a9cf4ae76f692941fd52543bbb148f02f098ca73cab9b1c1b/aiohttp-3.13.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e736c93e9c274fce6419af4aac199984d866e55f8a4cec9114671d0ea9688780", size = 1807572, upload_time = "2025-10-28T20:56:08.558Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/58/b0583defb38689e7f06798f0285b1ffb3a6fb371f38363ce5fd772112724/aiohttp-3.13.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ff5e771f5dcbc81c64898c597a434f7682f2259e0cd666932a913d53d1341d1a", size = 1895954, upload_time = "2025-10-28T20:56:10.545Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/f3/083907ee3437425b4e376aa58b2c915eb1a33703ec0dc30040f7ae3368c6/aiohttp-3.13.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3b6fb0c207cc661fa0bf8c66d8d9b657331ccc814f4719468af61034b478592", size = 1747092, upload_time = "2025-10-28T20:56:12.118Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/61/98a47319b4e425cc134e05e5f3fc512bf9a04bf65aafd9fdcda5d57ec693/aiohttp-3.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:97a0895a8e840ab3520e2288db7cace3a1981300d48babeb50e7425609e2e0ab", size = 1606815, upload_time = "2025-10-28T20:56:14.191Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/4b/e78b854d82f66bb974189135d31fce265dee0f5344f64dd0d345158a5973/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e8f8afb552297aca127c90cb840e9a1d4bfd6a10d7d8f2d9176e1acc69bad30", size = 1723789, upload_time = "2025-10-28T20:56:16.101Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/fc/9d2ccc794fc9b9acd1379d625c3a8c64a45508b5091c546dea273a41929e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed2f9c7216e53c3df02264f25d824b079cc5914f9e2deba94155190ef648ee40", size = 1718104, upload_time = "2025-10-28T20:56:17.655Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/65/34564b8765ea5c7d79d23c9113135d1dd3609173da13084830f1507d56cf/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:99c5280a329d5fa18ef30fd10c793a190d996567667908bef8a7f81f8202b948", size = 1785584, upload_time = "2025-10-28T20:56:19.238Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/be/f6a7a426e02fc82781afd62016417b3948e2207426d90a0e478790d1c8a4/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ca6ffef405fc9c09a746cb5d019c1672cd7f402542e379afc66b370833170cf", size = 1595126, upload_time = "2025-10-28T20:56:20.836Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/c7/8e22d5d28f94f67d2af496f14a83b3c155d915d1fe53d94b66d425ec5b42/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:47f438b1a28e926c37632bff3c44df7d27c9b57aaf4e34b1def3c07111fdb782", size = 1800665, upload_time = "2025-10-28T20:56:22.922Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/11/91133c8b68b1da9fc16555706aa7276fdf781ae2bb0876c838dd86b8116e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8", size = 1739532, upload_time = "2025-10-28T20:56:25.924Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/6b/3747644d26a998774b21a616016620293ddefa4d63af6286f389aedac844/aiohttp-3.13.2-cp311-cp311-win32.whl", hash = "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec", size = 431876, upload_time = "2025-10-28T20:56:27.524Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/63/688462108c1a00eb9f05765331c107f95ae86f6b197b865d29e930b7e462/aiohttp-3.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c", size = 456205, upload_time = "2025-10-28T20:56:29.062Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload_time = "2025-10-28T20:56:30.797Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664, upload_time = "2025-10-28T20:56:32.708Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808, upload_time = "2025-10-28T20:56:34.57Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863, upload_time = "2025-10-28T20:56:36.377Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586, upload_time = "2025-10-28T20:56:38.034Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625, upload_time = "2025-10-28T20:56:39.75Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281, upload_time = "2025-10-28T20:56:41.471Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431, upload_time = "2025-10-28T20:56:43.162Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846, upload_time = "2025-10-28T20:56:44.85Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606, upload_time = "2025-10-28T20:56:46.519Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663, upload_time = "2025-10-28T20:56:48.528Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939, upload_time = "2025-10-28T20:56:50.77Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132, upload_time = "2025-10-28T20:56:52.568Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802, upload_time = "2025-10-28T20:56:54.292Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload_time = "2025-10-28T20:56:56.428Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload_time = "2025-10-28T20:56:58.736Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload_time = "2025-10-28T20:57:00.795Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload_time = "2025-10-28T20:57:02.455Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload_time = "2025-10-28T20:57:04.784Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload_time = "2025-10-28T20:57:06.894Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload_time = "2025-10-28T20:57:08.685Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload_time = "2025-10-28T20:57:10.693Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload_time = "2025-10-28T20:57:12.563Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload_time = "2025-10-28T20:57:14.623Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload_time = "2025-10-28T20:57:16.399Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload_time = "2025-10-28T20:57:18.288Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload_time = "2025-10-28T20:57:20.241Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload_time = "2025-10-28T20:57:22.253Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload_time = "2025-10-28T20:57:24.37Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload_time = "2025-10-28T20:57:26.257Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload_time = "2025-10-28T20:57:28.349Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload_time = "2025-10-28T20:57:30.233Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload_time = "2025-10-28T20:57:32.105Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload_time = "2025-10-28T20:57:34.166Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload_time = "2025-10-28T20:57:36.415Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload_time = "2025-10-28T20:57:38.205Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload_time = "2025-10-28T20:57:40.122Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload_time = "2025-10-28T20:57:42.28Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload_time = "2025-10-28T20:57:44.869Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload_time = "2025-10-28T20:57:47.216Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload_time = "2025-10-28T20:57:49.337Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload_time = "2025-10-28T20:57:51.327Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload_time = "2025-10-28T20:57:53.554Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload_time = "2025-10-28T20:57:55.617Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload_time = "2025-10-28T20:57:57.59Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload_time = "2025-10-28T20:57:59.525Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload_time = "2025-10-28T20:58:01.914Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload_time = "2025-10-28T20:58:03.972Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload_time = "2025-10-28T20:58:06.189Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload_time = "2025-10-28T20:58:08.636Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload_time = "2025-10-28T20:58:11Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload_time = "2025-10-28T20:58:13.358Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload_time = "2025-10-28T20:58:15.339Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload_time = "2025-10-28T20:58:17.693Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload_time = "2025-10-28T20:58:20.113Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload_time = "2025-10-28T20:58:22.583Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload_time = "2025-10-28T20:58:24.672Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload_time = "2025-10-28T20:58:26.758Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload_time = "2025-10-28T20:58:29.787Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload_time = "2025-10-28T20:58:32.529Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload_time = "2025-10-28T20:58:34.618Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload_time = "2025-10-28T20:58:38.835Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload_time = "2025-10-28T20:58:41.507Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload_time = "2025-10-28T20:58:43.674Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload_time = "2025-10-28T20:58:45.787Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload_time = "2025-10-28T20:58:47.936Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload_time = "2025-10-28T20:58:50.642Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload_time = "2025-10-28T20:58:52.782Z" }, +] + +[[package]] +name = "aiohttp-cors" +version = "0.8.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "aiohttp" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/6d/d89e846a5444b3d5eb8985a6ddb0daef3774928e1bfbce8e84ec97b0ffa7/aiohttp_cors-0.8.1.tar.gz", hash = "sha256:ccacf9cb84b64939ea15f859a146af1f662a6b1d68175754a07315e305fb1403", size = 38626, upload_time = "2025-03-31T14:16:20.048Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/3b/40a68de458904bcc143622015fff2352b6461cd92fd66d3527bf1c6f5716/aiohttp_cors-0.8.1-py3-none-any.whl", hash = "sha256:3180cf304c5c712d626b9162b195b1db7ddf976a2a25172b35bb2448b890a80d", size = 25231, upload_time = "2025-03-31T14:16:18.478Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload_time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload_time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload_time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload_time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload_time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload_time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.12.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload_time = "2025-11-28T23:37:38.911Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload_time = "2025-11-28T23:36:57.897Z" }, +] + +[[package]] +name = "async-timeout" +version = "5.0.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload_time = "2024-11-06T16:41:39.6Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload_time = "2024-11-06T16:41:37.9Z" }, +] + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload_time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload_time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "cachetools" +version = "6.2.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/44/ca1675be2a83aeee1886ab745b28cda92093066590233cc501890eb8417a/cachetools-6.2.2.tar.gz", hash = "sha256:8e6d266b25e539df852251cfd6f990b4bc3a141db73b939058d809ebd2590fc6", size = 31571, upload_time = "2025-11-13T17:42:51.465Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/46/eb6eca305c77a4489affe1c5d8f4cae82f285d9addd8de4ec084a7184221/cachetools-6.2.2-py3-none-any.whl", hash = "sha256:6c09c98183bf58560c97b2abfcedcbaf6a896a490f534b031b661d3723b45ace", size = 11503, upload_time = "2025-11-13T17:42:50.232Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload_time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload_time = "2025-11-12T02:54:49.735Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload_time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload_time = "2025-09-08T23:22:08.01Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload_time = "2025-09-08T23:22:10.637Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload_time = "2025-09-08T23:22:12.267Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload_time = "2025-09-08T23:22:13.455Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload_time = "2025-09-08T23:22:14.596Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload_time = "2025-09-08T23:22:15.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload_time = "2025-09-08T23:22:17.427Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload_time = "2025-09-08T23:22:19.069Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload_time = "2025-09-08T23:22:20.588Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload_time = "2025-09-08T23:22:22.143Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload_time = "2025-09-08T23:22:23.328Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload_time = "2025-09-08T23:22:24.752Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload_time = "2025-09-08T23:22:26.456Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload_time = "2025-09-08T23:22:28.197Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload_time = "2025-09-08T23:22:29.475Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload_time = "2025-09-08T23:22:31.063Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload_time = "2025-09-08T23:22:32.507Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload_time = "2025-09-08T23:22:34.132Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload_time = "2025-09-08T23:22:35.443Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload_time = "2025-09-08T23:22:36.805Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload_time = "2025-09-08T23:22:38.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload_time = "2025-09-08T23:22:39.776Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload_time = "2025-09-08T23:22:40.95Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload_time = "2025-09-08T23:22:42.463Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload_time = "2025-09-08T23:22:43.623Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload_time = "2025-09-08T23:22:44.795Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload_time = "2025-09-08T23:22:45.938Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload_time = "2025-09-08T23:22:47.349Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload_time = "2025-09-08T23:22:48.677Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload_time = "2025-09-08T23:22:50.06Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload_time = "2025-09-08T23:22:51.364Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload_time = "2025-09-08T23:22:52.902Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload_time = "2025-09-08T23:22:54.518Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload_time = "2025-09-08T23:22:55.867Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload_time = "2025-09-08T23:22:57.188Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload_time = "2025-09-08T23:22:58.351Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload_time = "2025-09-08T23:22:59.668Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload_time = "2025-09-08T23:23:00.879Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload_time = "2025-09-08T23:23:02.231Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload_time = "2025-09-08T23:23:03.472Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload_time = "2025-09-08T23:23:04.792Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload_time = "2025-09-08T23:23:06.127Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload_time = "2025-09-08T23:23:07.753Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload_time = "2025-09-08T23:23:09.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload_time = "2025-09-08T23:23:10.928Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload_time = "2025-09-08T23:23:12.42Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload_time = "2025-09-08T23:23:14.32Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload_time = "2025-09-08T23:23:15.535Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload_time = "2025-09-08T23:23:16.761Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload_time = "2025-09-08T23:23:18.087Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload_time = "2025-09-08T23:23:19.622Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload_time = "2025-09-08T23:23:20.853Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload_time = "2025-09-08T23:23:22.08Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload_time = "2025-09-08T23:23:23.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload_time = "2025-09-08T23:23:24.541Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload_time = "2025-09-08T23:23:26.143Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload_time = "2025-09-08T23:23:27.873Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload_time = "2025-09-08T23:23:44.61Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload_time = "2025-09-08T23:23:45.848Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload_time = "2025-09-08T23:23:47.105Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload_time = "2025-09-08T23:23:29.347Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload_time = "2025-09-08T23:23:30.63Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload_time = "2025-09-08T23:23:31.91Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload_time = "2025-09-08T23:23:33.214Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload_time = "2025-09-08T23:23:34.495Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload_time = "2025-09-08T23:23:36.096Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload_time = "2025-09-08T23:23:37.328Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload_time = "2025-09-08T23:23:38.945Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload_time = "2025-09-08T23:23:40.423Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload_time = "2025-09-08T23:23:41.742Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload_time = "2025-09-08T23:23:43.004Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload_time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", size = 209709, upload_time = "2025-10-14T04:40:11.385Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/af/1f9d7f7faafe2ddfb6f72a2e07a548a629c61ad510fe60f9630309908fef/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", size = 148814, upload_time = "2025-10-14T04:40:13.135Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/3d/f2e3ac2bbc056ca0c204298ea4e3d9db9b4afe437812638759db2c976b5f/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", size = 144467, upload_time = "2025-10-14T04:40:14.728Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/85/1bf997003815e60d57de7bd972c57dc6950446a3e4ccac43bc3070721856/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", size = 162280, upload_time = "2025-10-14T04:40:16.14Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/8e/6aa1952f56b192f54921c436b87f2aaf7c7a7c3d0d1a765547d64fd83c13/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", size = 159454, upload_time = "2025-10-14T04:40:17.567Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", size = 153609, upload_time = "2025-10-14T04:40:19.08Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/91/6a13396948b8fd3c4b4fd5bc74d045f5637d78c9675585e8e9fbe5636554/charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", size = 151849, upload_time = "2025-10-14T04:40:20.607Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/7a/59482e28b9981d105691e968c544cc0df3b7d6133152fb3dcdc8f135da7a/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", size = 151586, upload_time = "2025-10-14T04:40:21.719Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/59/f64ef6a1c4bdd2baf892b04cd78792ed8684fbc48d4c2afe467d96b4df57/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", size = 145290, upload_time = "2025-10-14T04:40:23.069Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/63/3bf9f279ddfa641ffa1962b0db6a57a9c294361cc2f5fcac997049a00e9c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", size = 163663, upload_time = "2025-10-14T04:40:24.17Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/09/c9e38fc8fa9e0849b172b581fd9803bdf6e694041127933934184e19f8c3/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", size = 151964, upload_time = "2025-10-14T04:40:25.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/d1/d28b747e512d0da79d8b6a1ac18b7ab2ecfd81b2944c4c710e166d8dd09c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", size = 161064, upload_time = "2025-10-14T04:40:26.806Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/9a/31d62b611d901c3b9e5500c36aab0ff5eb442043fb3a1c254200d3d397d9/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", size = 155015, upload_time = "2025-10-14T04:40:28.284Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/f3/107e008fa2bff0c8b9319584174418e5e5285fef32f79d8ee6a430d0039c/charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", size = 99792, upload_time = "2025-10-14T04:40:29.613Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/66/e396e8a408843337d7315bab30dbf106c38966f1819f123257f5520f8a96/charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", size = 107198, upload_time = "2025-10-14T04:40:30.644Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/58/01b4f815bf0312704c267f2ccb6e5d42bcc7752340cd487bc9f8c3710597/charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", size = 100262, upload_time = "2025-10-14T04:40:32.108Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload_time = "2025-10-14T04:40:33.79Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload_time = "2025-10-14T04:40:34.961Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload_time = "2025-10-14T04:40:36.105Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload_time = "2025-10-14T04:40:37.188Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload_time = "2025-10-14T04:40:38.435Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload_time = "2025-10-14T04:40:40.053Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload_time = "2025-10-14T04:40:41.163Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload_time = "2025-10-14T04:40:42.276Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload_time = "2025-10-14T04:40:43.439Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload_time = "2025-10-14T04:40:44.547Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload_time = "2025-10-14T04:40:46.018Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload_time = "2025-10-14T04:40:47.081Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload_time = "2025-10-14T04:40:48.246Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload_time = "2025-10-14T04:40:49.376Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload_time = "2025-10-14T04:40:50.844Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload_time = "2025-10-14T04:40:52.272Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload_time = "2025-10-14T04:40:53.353Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload_time = "2025-10-14T04:40:54.558Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload_time = "2025-10-14T04:40:55.677Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload_time = "2025-10-14T04:40:57.217Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload_time = "2025-10-14T04:40:58.358Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload_time = "2025-10-14T04:40:59.468Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload_time = "2025-10-14T04:41:00.623Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload_time = "2025-10-14T04:41:01.754Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload_time = "2025-10-14T04:41:03.231Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload_time = "2025-10-14T04:41:04.715Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload_time = "2025-10-14T04:41:05.827Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload_time = "2025-10-14T04:41:06.938Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload_time = "2025-10-14T04:41:08.101Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload_time = "2025-10-14T04:41:09.23Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload_time = "2025-10-14T04:41:10.467Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload_time = "2025-10-14T04:41:11.915Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload_time = "2025-10-14T04:41:13.346Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload_time = "2025-10-14T04:41:14.461Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload_time = "2025-10-14T04:41:15.588Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload_time = "2025-10-14T04:41:16.738Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload_time = "2025-10-14T04:41:17.923Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload_time = "2025-10-14T04:41:19.106Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload_time = "2025-10-14T04:41:20.245Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload_time = "2025-10-14T04:41:21.398Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload_time = "2025-10-14T04:41:22.583Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload_time = "2025-10-14T04:41:23.754Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload_time = "2025-10-14T04:41:25.27Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload_time = "2025-10-14T04:41:26.725Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload_time = "2025-10-14T04:41:28.322Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload_time = "2025-10-14T04:41:29.95Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload_time = "2025-10-14T04:41:31.188Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload_time = "2025-10-14T04:41:32.624Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload_time = "2025-10-14T04:41:33.773Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload_time = "2025-10-14T04:41:34.897Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload_time = "2025-10-14T04:41:36.116Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload_time = "2025-10-14T04:41:37.229Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload_time = "2025-10-14T04:41:38.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload_time = "2025-10-14T04:41:39.862Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload_time = "2025-10-14T04:41:41.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload_time = "2025-10-14T04:41:42.539Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload_time = "2025-10-14T04:41:43.661Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload_time = "2025-10-14T04:41:44.821Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload_time = "2025-10-14T04:41:46.442Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload_time = "2025-10-14T04:41:47.631Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload_time = "2025-10-14T04:41:48.81Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload_time = "2025-10-14T04:41:49.946Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload_time = "2025-10-14T04:41:51.051Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload_time = "2025-10-14T04:41:52.122Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload_time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload_time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload_time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload_time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload_time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload_time = "2025-04-15T17:47:53.79Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/a3/da4153ec8fe25d263aa48c1a4cbde7f49b59af86f0b6f7862788c60da737/contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934", size = 268551, upload_time = "2025-04-15T17:34:46.581Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2f/6c/330de89ae1087eb622bfca0177d32a7ece50c3ef07b28002de4757d9d875/contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989", size = 253399, upload_time = "2025-04-15T17:34:51.427Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/bd/20c6726b1b7f81a8bee5271bed5c165f0a8e1f572578a9d27e2ccb763cb2/contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d", size = 312061, upload_time = "2025-04-15T17:34:55.961Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/fc/a9665c88f8a2473f823cf1ec601de9e5375050f1958cbb356cdf06ef1ab6/contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9", size = 351956, upload_time = "2025-04-15T17:35:00.992Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/eb/9f0a0238f305ad8fb7ef42481020d6e20cf15e46be99a1fcf939546a177e/contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512", size = 320872, upload_time = "2025-04-15T17:35:06.177Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/5c/1ee32d1c7956923202f00cf8d2a14a62ed7517bdc0ee1e55301227fc273c/contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631", size = 325027, upload_time = "2025-04-15T17:35:11.244Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/bf/9baed89785ba743ef329c2b07fd0611d12bfecbedbdd3eeecf929d8d3b52/contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f", size = 1306641, upload_time = "2025-04-15T17:35:26.701Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/cc/74e5e83d1e35de2d28bd97033426b450bc4fd96e092a1f7a63dc7369b55d/contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2", size = 1374075, upload_time = "2025-04-15T17:35:43.204Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/42/17f3b798fd5e033b46a16f8d9fcb39f1aba051307f5ebf441bad1ecf78f8/contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0", size = 177534, upload_time = "2025-04-15T17:35:46.554Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/ec/5162b8582f2c994721018d0c9ece9dc6ff769d298a8ac6b6a652c307e7df/contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a", size = 221188, upload_time = "2025-04-15T17:35:50.064Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/b9/ede788a0b56fc5b071639d06c33cb893f68b1178938f3425debebe2dab78/contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445", size = 269636, upload_time = "2025-04-15T17:35:54.473Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/75/3469f011d64b8bbfa04f709bfc23e1dd71be54d05b1b083be9f5b22750d1/contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773", size = 254636, upload_time = "2025-04-15T17:35:58.283Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/2f/95adb8dae08ce0ebca4fd8e7ad653159565d9739128b2d5977806656fcd2/contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1", size = 313053, upload_time = "2025-04-15T17:36:03.235Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/a6/8ccf97a50f31adfa36917707fe39c9a0cbc24b3bbb58185577f119736cc9/contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43", size = 352985, upload_time = "2025-04-15T17:36:08.275Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/b6/7925ab9b77386143f39d9c3243fdd101621b4532eb126743201160ffa7e6/contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab", size = 323750, upload_time = "2025-04-15T17:36:13.29Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/f3/20c5d1ef4f4748e52d60771b8560cf00b69d5c6368b5c2e9311bcfa2a08b/contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7", size = 326246, upload_time = "2025-04-15T17:36:18.329Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/e5/9dae809e7e0b2d9d70c52b3d24cba134dd3dad979eb3e5e71f5df22ed1f5/contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83", size = 1308728, upload_time = "2025-04-15T17:36:33.878Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/4a/0058ba34aeea35c0b442ae61a4f4d4ca84d6df8f91309bc2d43bb8dd248f/contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd", size = 1375762, upload_time = "2025-04-15T17:36:51.295Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/33/7174bdfc8b7767ef2c08ed81244762d93d5c579336fc0b51ca57b33d1b80/contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f", size = 178196, upload_time = "2025-04-15T17:36:55.002Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5e/fe/4029038b4e1c4485cef18e480b0e2cd2d755448bb071eb9977caac80b77b/contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878", size = 222017, upload_time = "2025-04-15T17:36:58.576Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/f7/44785876384eff370c251d58fd65f6ad7f39adce4a093c934d4a67a7c6b6/contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2", size = 271580, upload_time = "2025-04-15T17:37:03.105Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/3b/0004767622a9826ea3d95f0e9d98cd8729015768075d61f9fea8eeca42a8/contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15", size = 255530, upload_time = "2025-04-15T17:37:07.026Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/bb/7bd49e1f4fa805772d9fd130e0d375554ebc771ed7172f48dfcd4ca61549/contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92", size = 307688, upload_time = "2025-04-15T17:37:11.481Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/97/e1d5dbbfa170725ef78357a9a0edc996b09ae4af170927ba8ce977e60a5f/contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87", size = 347331, upload_time = "2025-04-15T17:37:18.212Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/66/e69e6e904f5ecf6901be3dd16e7e54d41b6ec6ae3405a535286d4418ffb4/contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415", size = 318963, upload_time = "2025-04-15T17:37:22.76Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/32/b8a1c8965e4f72482ff2d1ac2cd670ce0b542f203c8e1d34e7c3e6925da7/contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe", size = 323681, upload_time = "2025-04-15T17:37:33.001Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/c6/12a7e6811d08757c7162a541ca4c5c6a34c0f4e98ef2b338791093518e40/contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441", size = 1308674, upload_time = "2025-04-15T17:37:48.64Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/8a/bebe5a3f68b484d3a2b8ffaf84704b3e343ef1addea528132ef148e22b3b/contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e", size = 1380480, upload_time = "2025-04-15T17:38:06.7Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/db/fcd325f19b5978fb509a7d55e06d99f5f856294c1991097534360b307cf1/contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912", size = 178489, upload_time = "2025-04-15T17:38:10.338Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/c8/fadd0b92ffa7b5eb5949bf340a63a4a496a6930a6c37a7ba0f12acb076d6/contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73", size = 223042, upload_time = "2025-04-15T17:38:14.239Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/61/5673f7e364b31e4e7ef6f61a4b5121c5f170f941895912f773d95270f3a2/contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb", size = 271630, upload_time = "2025-04-15T17:38:19.142Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/66/a40badddd1223822c95798c55292844b7e871e50f6bfd9f158cb25e0bd39/contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08", size = 255670, upload_time = "2025-04-15T17:38:23.688Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/c7/cf9fdee8200805c9bc3b148f49cb9482a4e3ea2719e772602a425c9b09f8/contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c", size = 306694, upload_time = "2025-04-15T17:38:28.238Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dd/e7/ccb9bec80e1ba121efbffad7f38021021cda5be87532ec16fd96533bb2e0/contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f", size = 345986, upload_time = "2025-04-15T17:38:33.502Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/49/ca13bb2da90391fa4219fdb23b078d6065ada886658ac7818e5441448b78/contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85", size = 318060, upload_time = "2025-04-15T17:38:38.672Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/65/5245ce8c548a8422236c13ffcdcdada6a2a812c361e9e0c70548bb40b661/contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841", size = 322747, upload_time = "2025-04-15T17:38:43.712Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/30/669b8eb48e0a01c660ead3752a25b44fdb2e5ebc13a55782f639170772f9/contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422", size = 1308895, upload_time = "2025-04-15T17:39:00.224Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/5a/b569f4250decee6e8d54498be7bdf29021a4c256e77fe8138c8319ef8eb3/contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef", size = 1379098, upload_time = "2025-04-15T17:43:29.649Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/19/ba/b227c3886d120e60e41b28740ac3617b2f2b971b9f601c835661194579f1/contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f", size = 178535, upload_time = "2025-04-15T17:44:44.532Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/6e/2fed56cd47ca739b43e892707ae9a13790a486a3173be063681ca67d2262/contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9", size = 223096, upload_time = "2025-04-15T17:44:48.194Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/4c/e76fe2a03014a7c767d79ea35c86a747e9325537a8b7627e0e5b3ba266b4/contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f", size = 285090, upload_time = "2025-04-15T17:43:34.084Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/e2/5aba47debd55d668e00baf9651b721e7733975dc9fc27264a62b0dd26eb8/contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739", size = 268643, upload_time = "2025-04-15T17:43:38.626Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/37/cd45f1f051fe6230f751cc5cdd2728bb3a203f5619510ef11e732109593c/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823", size = 310443, upload_time = "2025-04-15T17:43:44.522Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/a2/36ea6140c306c9ff6dd38e3bcec80b3b018474ef4d17eb68ceecd26675f4/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5", size = 349865, upload_time = "2025-04-15T17:43:49.545Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/b7/2fc76bc539693180488f7b6cc518da7acbbb9e3b931fd9280504128bf956/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532", size = 321162, upload_time = "2025-04-15T17:43:54.203Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/10/76d4f778458b0aa83f96e59d65ece72a060bacb20cfbee46cf6cd5ceba41/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b", size = 327355, upload_time = "2025-04-15T17:44:01.025Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/a3/10cf483ea683f9f8ab096c24bad3cce20e0d1dd9a4baa0e2093c1c962d9d/contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52", size = 1307935, upload_time = "2025-04-15T17:44:17.322Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/73/69dd9a024444489e22d86108e7b913f3528f56cfc312b5c5727a44188471/contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd", size = 1372168, upload_time = "2025-04-15T17:44:33.43Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/1b/96d586ccf1b1a9d2004dd519b25fbf104a11589abfd05484ff12199cca21/contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1", size = 189550, upload_time = "2025-04-15T17:44:37.092Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/e6/6000d0094e8a5e32ad62591c8609e269febb6e4db83a1c75ff8868b42731/contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69", size = 238214, upload_time = "2025-04-15T17:44:40.827Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/05/b26e3c6ecc05f349ee0013f0bb850a761016d89cec528a98193a48c34033/contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c", size = 265681, upload_time = "2025-04-15T17:44:59.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/25/ac07d6ad12affa7d1ffed11b77417d0a6308170f44ff20fa1d5aa6333f03/contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16", size = 315101, upload_time = "2025-04-15T17:45:04.165Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/4d/5bb3192bbe9d3f27e3061a6a8e7733c9120e203cb8515767d30973f71030/contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad", size = 220599, upload_time = "2025-04-15T17:45:08.456Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/c0/91f1215d0d9f9f343e4773ba6c9b89e8c0cc7a64a6263f21139da639d848/contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0", size = 266807, upload_time = "2025-04-15T17:45:15.535Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/79/6be7e90c955c0487e7712660d6cead01fa17bff98e0ea275737cc2bc8e71/contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5", size = 318729, upload_time = "2025-04-15T17:45:20.166Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/68/7f46fb537958e87427d98a4074bcde4b67a70b04900cfc5ce29bc2f556c1/contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5", size = 221791, upload_time = "2025-04-15T17:45:24.794Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload_time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload_time = "2025-07-26T12:01:02.277Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload_time = "2025-07-26T12:01:04.072Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload_time = "2025-07-26T12:01:05.688Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload_time = "2025-07-26T12:01:07.054Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload_time = "2025-07-26T12:01:08.801Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload_time = "2025-07-26T12:01:10.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload_time = "2025-07-26T12:01:12.659Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload_time = "2025-07-26T12:01:15.533Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload_time = "2025-07-26T12:01:17.088Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload_time = "2025-07-26T12:01:18.256Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload_time = "2025-07-26T12:01:19.848Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload_time = "2025-07-26T12:01:21.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload_time = "2025-07-26T12:01:22.448Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload_time = "2025-07-26T12:01:24.155Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload_time = "2025-07-26T12:01:25.91Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload_time = "2025-07-26T12:01:27.152Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload_time = "2025-07-26T12:01:28.808Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload_time = "2025-07-26T12:01:31.198Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload_time = "2025-07-26T12:01:33.947Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload_time = "2025-07-26T12:01:35.64Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload_time = "2025-07-26T12:01:36.804Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload_time = "2025-07-26T12:01:37.999Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload_time = "2025-07-26T12:01:39.367Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload_time = "2025-07-26T12:01:40.645Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload_time = "2025-07-26T12:01:41.942Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload_time = "2025-07-26T12:01:43.499Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload_time = "2025-07-26T12:01:45.219Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload_time = "2025-07-26T12:01:46.519Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload_time = "2025-07-26T12:01:48.964Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload_time = "2025-07-26T12:01:51.979Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload_time = "2025-07-26T12:01:53.245Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload_time = "2025-07-26T12:01:54.422Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload_time = "2025-07-26T12:01:55.73Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload_time = "2025-07-26T12:01:57.051Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload_time = "2025-07-26T12:01:58.663Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload_time = "2025-07-26T12:02:00.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload_time = "2025-07-26T12:02:02.128Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload_time = "2025-07-26T12:02:03.615Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload_time = "2025-07-26T12:02:05.165Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload_time = "2025-07-26T12:02:07.379Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload_time = "2025-07-26T12:02:10.171Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload_time = "2025-07-26T12:02:11.488Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload_time = "2025-07-26T12:02:12.754Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload_time = "2025-07-26T12:02:14.4Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload_time = "2025-07-26T12:02:16.095Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload_time = "2025-07-26T12:02:17.524Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload_time = "2025-07-26T12:02:18.9Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload_time = "2025-07-26T12:02:20.418Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload_time = "2025-07-26T12:02:21.916Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload_time = "2025-07-26T12:02:23.759Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload_time = "2025-07-26T12:02:26.181Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload_time = "2025-07-26T12:02:28.782Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload_time = "2025-07-26T12:02:30.128Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload_time = "2025-07-26T12:02:31.395Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload_time = "2025-07-26T12:02:32.956Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload_time = "2025-07-26T12:02:34.2Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload_time = "2025-07-26T12:02:35.807Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload_time = "2025-07-26T12:02:37.193Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload_time = "2025-07-26T12:02:38.894Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload_time = "2025-07-26T12:02:40.642Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload_time = "2025-07-26T12:02:42.25Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload_time = "2025-07-26T12:02:44.668Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload_time = "2025-07-26T12:02:47.09Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload_time = "2025-07-26T12:02:48.691Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload_time = "2025-07-26T12:02:50.137Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload_time = "2025-07-26T12:02:51.449Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload_time = "2025-07-26T12:02:52.74Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload_time = "2025-07-26T12:02:54.037Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload_time = "2025-07-26T12:02:55.947Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload_time = "2025-07-26T12:02:57.468Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload_time = "2025-07-26T12:02:58.801Z" }, +] + +[[package]] +name = "cryptography" +version = "46.0.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload_time = "2025-10-15T23:18:31.74Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload_time = "2025-10-15T23:16:52.239Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload_time = "2025-10-15T23:16:54.369Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload_time = "2025-10-15T23:16:56.414Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload_time = "2025-10-15T23:16:58.442Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload_time = "2025-10-15T23:17:00.378Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload_time = "2025-10-15T23:17:01.98Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload_time = "2025-10-15T23:17:04.078Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload_time = "2025-10-15T23:17:05.483Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload_time = "2025-10-15T23:17:07.425Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload_time = "2025-10-15T23:17:09.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload_time = "2025-10-15T23:17:11.22Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload_time = "2025-10-15T23:17:12.829Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload_time = "2025-10-15T23:17:14.65Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload_time = "2025-10-15T23:17:16.142Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload_time = "2025-10-15T23:17:18.04Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload_time = "2025-10-15T23:17:19.982Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload_time = "2025-10-15T23:17:21.527Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload_time = "2025-10-15T23:17:23.042Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload_time = "2025-10-15T23:17:24.885Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload_time = "2025-10-15T23:17:26.449Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload_time = "2025-10-15T23:17:28.06Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload_time = "2025-10-15T23:17:29.665Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload_time = "2025-10-15T23:17:31.686Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload_time = "2025-10-15T23:17:33.478Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload_time = "2025-10-15T23:17:35.158Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload_time = "2025-10-15T23:17:37.188Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload_time = "2025-10-15T23:17:39.236Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload_time = "2025-10-15T23:17:40.888Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload_time = "2025-10-15T23:17:42.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload_time = "2025-10-15T23:17:44.468Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload_time = "2025-10-15T23:17:46.294Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload_time = "2025-10-15T23:17:48.269Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload_time = "2025-10-15T23:17:49.837Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload_time = "2025-10-15T23:17:51.357Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload_time = "2025-10-15T23:17:52.964Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload_time = "2025-10-15T23:17:54.965Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload_time = "2025-10-15T23:17:56.754Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload_time = "2025-10-15T23:17:58.588Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload_time = "2025-10-15T23:18:00.897Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload_time = "2025-10-15T23:18:02.749Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload_time = "2025-10-15T23:18:04.85Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload_time = "2025-10-15T23:18:06.908Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload_time = "2025-10-15T23:18:08.672Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload_time = "2025-10-15T23:18:10.632Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload_time = "2025-10-15T23:18:12.277Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/cd/1a8633802d766a0fa46f382a77e096d7e209e0817892929655fe0586ae32/cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32", size = 3689163, upload_time = "2025-10-15T23:18:13.821Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/59/6b26512964ace6480c3e54681a9859c974172fb141c38df11eadd8416947/cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c", size = 3429474, upload_time = "2025-10-15T23:18:15.477Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/8a/e60e46adab4362a682cf142c7dcb5bf79b782ab2199b0dcb81f55970807f/cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea", size = 3698132, upload_time = "2025-10-15T23:18:17.056Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/38/f59940ec4ee91e93d3311f7532671a5cef5570eb04a144bf203b58552d11/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b", size = 4243992, upload_time = "2025-10-15T23:18:18.695Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/0c/35b3d92ddebfdfda76bb485738306545817253d0a3ded0bfe80ef8e67aa5/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb", size = 4409944, upload_time = "2025-10-15T23:18:20.597Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/55/181022996c4063fc0e7666a47049a1ca705abb9c8a13830f074edb347495/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717", size = 4242957, upload_time = "2025-10-15T23:18:22.18Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/af/72cd6ef29f9c5f731251acadaeb821559fe25f10852f44a63374c9ca08c1/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9", size = 4409447, upload_time = "2025-10-15T23:18:24.209Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/c3/e90f4a4feae6410f914f8ebac129b9ae7a8c92eb60a638012dde42030a9d/cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c", size = 3438528, upload_time = "2025-10-15T23:18:26.227Z" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload_time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload_time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload_time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload_time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "faiss-cpu" +version = "1.13.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/92/c4f30580aee11fda3f424f8509d9b5ad96b9f44409f52a7ceb6b42880e50/faiss_cpu-1.13.1-cp310-abi3-macosx_14_0_arm64.whl", hash = "sha256:2967def7aa2da8efbf6a5da81138780aa17a9970ca666417cb632a00a593423d", size = 3418004, upload_time = "2025-12-05T01:01:51.955Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/1f/30803e63affa8bbdfd549f83ed5d39ccf900c030b6da8010d0b95f7ae1d1/faiss_cpu-1.13.1-cp310-abi3-macosx_14_0_x86_64.whl", hash = "sha256:30c179891656a988f5223e586c696432aacc5f4e763d85e165be30ef57ac2bbf", size = 7806468, upload_time = "2025-12-05T01:01:54.096Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/ae/40f66b640664af319ff8be87a9b0cc2c9ec025a2cf82b27cc27964fcf3c0/faiss_cpu-1.13.1-cp310-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff5bdbf392081659e6b0f98f03b602bf08d1b5a790e28aa1185ae925decff6b2", size = 11410471, upload_time = "2025-12-05T01:01:56.038Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/f8/b8f0862ec6af8a71c6410a61baa35571161f7dba616aed696e91cb464630/faiss_cpu-1.13.1-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3de25edb0e69c1b95eeda923b2e23da01f472b2cc3f4817e63b25a56847d6ea7", size = 23719213, upload_time = "2025-12-05T01:01:58.545Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/ee/01e07e4e780b0b739a3299ca8e5b4751970629b0f2c51f5ec464718e9f9e/faiss_cpu-1.13.1-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0b2f0e6cd30511b9fe320a2309389269269d3e363cc88c3a0380095a8c08ae27", size = 13400767, upload_time = "2025-12-05T01:02:00.742Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/27/0c4e249fe50f87f1f038c80deebcdd28b23617bb42e3e5708b34c86fdae7/faiss_cpu-1.13.1-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8ad542573ad05af6c508f4cf5268ba2aad06f0c8d4e780a0eeba7fe6fd274922", size = 24960102, upload_time = "2025-12-05T01:02:04.56Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/51/eddbd8468b27328d739128559155b3b36dc427e63355b5d3fb5c5c181198/faiss_cpu-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:30e9c129e0beb9da699982d9068322e3808e0d0faab4652cabf2c08900ab7892", size = 18801122, upload_time = "2025-12-05T01:02:07.274Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/c1/93983f2be41d0ab24cefd8926d1246e744671b4dc0b577ad576eb1205bfa/faiss_cpu-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:dbcf54daf14068b23c3d4116aa087eff6cf7cb43457c572318dfc2cbd944607a", size = 18802476, upload_time = "2025-12-05T01:02:10.09Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/a1/007e547cc7e8731346387a42001a06ee53394663616c84f3de247094158e/faiss_cpu-1.13.1-cp311-cp311-win_arm64.whl", hash = "sha256:9860949a70d1b25ff11ac9600aeda796db6710bf667b1f5508b44a63e6170b30", size = 8505159, upload_time = "2025-12-05T01:02:12.578Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/bc/ce942b00958ef52caca71666c06fa801fcd99dc61a9873ab067932dd3d5e/faiss_cpu-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:0fece5b63e8d014f8db4abfe0b4c9a82e6508e64f450fce700e5cb4b47041f1a", size = 18812863, upload_time = "2025-12-05T01:02:14.982Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/ab/7b91c9cb328d960466e23cd9ca02f44d554ac5761d41262b74daa1715da1/faiss_cpu-1.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:168986e3f152a7568257c5ac50f3cf1a1aaa34fb41e1ba7259799bcb8ffe687f", size = 8507940, upload_time = "2025-12-05T01:02:18.078Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/75/0fb845be2e674531ce7f89207d7f932ffbc8fc50f866dba5569512305cc9/faiss_cpu-1.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5f71c8840794c39c1e1cdd92c2ef4d3f77b3e650f614f296e31c2545ad2bab51", size = 18812964, upload_time = "2025-12-05T01:02:20.505Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/2c/c13c816546ffc5b0b7f8ca64811b24b17d73ff6382464f1ab0eed87b7753/faiss_cpu-1.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:24cb2d6ce2459c94e15a6cecfed15ff8d9f997aed7bae4037c0f045022030cb3", size = 8508631, upload_time = "2025-12-05T01:02:22.751Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/6f/adf064c644a80c0ebd499144ccbab672c9946361132617ceafcc48819771/faiss_cpu-1.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:5195ab9149c563cafe4da8ab4cc0b84b177cbb1f8aa897a8c199e11ef4f37e16", size = 18816994, upload_time = "2025-12-05T01:02:25.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/53/042f863a6a1202af8eec94604dc8b192319253faabb8ee6070297a24c091/faiss_cpu-1.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:ffc58173e24026ee4dc08c50dd3506ad553d4b2103892500b0d4ae9344027d57", size = 8511280, upload_time = "2025-12-05T01:02:27.163Z" }, +] + +[[package]] +name = "fastapi" +version = "0.124.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/9c/11969bd3e3bc4aa3a711f83dd3720239d3565a934929c74fc32f6c9f3638/fastapi-0.124.0.tar.gz", hash = "sha256:260cd178ad75e6d259991f2fd9b0fee924b224850079df576a3ba604ce58f4e6", size = 357623, upload_time = "2025-12-06T13:11:35.692Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/29/9e1e82e16e9a1763d3b55bfbe9b2fa39d7175a1fd97685c482fa402e111d/fastapi-0.124.0-py3-none-any.whl", hash = "sha256:91596bdc6dde303c318f06e8d2bc75eafb341fc793a0c9c92c0bc1db1ac52480", size = 112505, upload_time = "2025-12-06T13:11:34.392Z" }, +] + +[[package]] +name = "fonttools" +version = "4.61.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/f9/0e84d593c0e12244150280a630999835a64f2852276161b62a0f98318de0/fonttools-4.61.0.tar.gz", hash = "sha256:ec520a1f0c7758d7a858a00f090c1745f6cde6a7c5e76fb70ea4044a15f712e7", size = 3561884, upload_time = "2025-11-28T17:05:49.491Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/f3/91bba2721fb173fc68e09d15b6ccf3ad4f83d127fbff579be7e5984888a6/fonttools-4.61.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dc25a4a9c1225653e4431a9413d0381b1c62317b0f543bdcec24e1991f612f33", size = 2850151, upload_time = "2025-11-28T17:04:14.214Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/8c/a1691dec01038ac7e7bb3ab83300dcc5087b11d8f48640928c02a873eb92/fonttools-4.61.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b493c32d2555e9944ec1b911ea649ff8f01a649ad9cba6c118d6798e932b3f0", size = 2389769, upload_time = "2025-11-28T17:04:16.443Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/dd/5bb369a44319d92ba25612511eb8ed2a6fa75239979e0388907525626902/fonttools-4.61.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad751319dc532a79bdf628b8439af167181b4210a0cd28a8935ca615d9fdd727", size = 4893189, upload_time = "2025-11-28T17:04:18.398Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5e/02/51373fa8846bd22bb54e5efb30a824b417b058083f775a194a432f21a45f/fonttools-4.61.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2de14557d113faa5fb519f7f29c3abe4d69c17fe6a5a2595cc8cda7338029219", size = 4854415, upload_time = "2025-11-28T17:04:20.421Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/64/9cdbbb804577a7e6191448851c57e6a36eb02aa4bf6a9668b528c968e44e/fonttools-4.61.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:59587bbe455dbdf75354a9dbca1697a35a8903e01fab4248d6b98a17032cee52", size = 4870927, upload_time = "2025-11-28T17:04:22.625Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/68/e40b22919dc96dc30a70b58fec609ab85112de950bdecfadf8dd478c5a88/fonttools-4.61.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:46cb3d9279f758ac0cf671dc3482da877104b65682679f01b246515db03dbb72", size = 4988674, upload_time = "2025-11-28T17:04:24.675Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9b/5c/e857349ce8aedb2451b9448282e86544b2b7f1c8b10ea0fe49b7cb369b72/fonttools-4.61.0-cp310-cp310-win32.whl", hash = "sha256:58b4f1b78dfbfe855bb8a6801b31b8cdcca0e2847ec769ad8e0b0b692832dd3b", size = 1497663, upload_time = "2025-11-28T17:04:26.598Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/0c/62961d5fe6f764d6cbc387ef2c001f5f610808c7aded837409836c0b3e7c/fonttools-4.61.0-cp310-cp310-win_amd64.whl", hash = "sha256:68704a8bbe0b61976262b255e90cde593dc0fe3676542d9b4d846bad2a890a76", size = 1546143, upload_time = "2025-11-28T17:04:28.432Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/be/5aa89cdddf2863d8afbdc19eb8ec5d8d35d40eeeb8e6cf52c5ff1c2dbd33/fonttools-4.61.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a32a16951cbf113d38f1dd8551b277b6e06e0f6f776fece0f99f746d739e1be3", size = 2847553, upload_time = "2025-11-28T17:04:30.539Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/3e/6ff643b07cead1236a534f51291ae2981721cf419135af5b740c002a66dd/fonttools-4.61.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:328a9c227984bebaf69f3ac9062265f8f6acc7ddf2e4e344c63358579af0aa3d", size = 2388298, upload_time = "2025-11-28T17:04:32.161Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/15/fca8dfbe7b482e6f240b1aad0ed7c6e2e75e7a28efa3d3a03b570617b5e5/fonttools-4.61.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f0bafc8a3b3749c69cc610e5aa3da832d39c2a37a68f03d18ec9a02ecaac04a", size = 5054133, upload_time = "2025-11-28T17:04:34.035Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/a2/821c61c691b21fd09e07528a9a499cc2b075ac83ddb644aa16c9875a64bc/fonttools-4.61.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b5ca59b7417d149cf24e4c1933c9f44b2957424fc03536f132346d5242e0ebe5", size = 5031410, upload_time = "2025-11-28T17:04:36.141Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/f6/8b16339e93d03c732c8a23edefe3061b17a5f9107ddc47a3215ecd054cac/fonttools-4.61.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:df8cbce85cf482eb01f4551edca978c719f099c623277bda8332e5dbe7dba09d", size = 5030005, upload_time = "2025-11-28T17:04:38.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/eb/d4e150427bdaa147755239c931bbce829a88149ade5bfd8a327afe565567/fonttools-4.61.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7fb5b84f48a6a733ca3d7f41aa9551908ccabe8669ffe79586560abcc00a9cfd", size = 5154026, upload_time = "2025-11-28T17:04:40.34Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/5f/3dd00ce0dba6759943c707b1830af8c0bcf6f8f1a9fe46cb82e7ac2aaa74/fonttools-4.61.0-cp311-cp311-win32.whl", hash = "sha256:787ef9dfd1ea9fe49573c272412ae5f479d78e671981819538143bec65863865", size = 2276035, upload_time = "2025-11-28T17:04:42.59Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/44/798c472f096ddf12955eddb98f4f7c906e7497695d04ce073ddf7161d134/fonttools-4.61.0-cp311-cp311-win_amd64.whl", hash = "sha256:14fafda386377b6131d9e448af42d0926bad47e038de0e5ba1d58c25d621f028", size = 2327290, upload_time = "2025-11-28T17:04:44.57Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/5d/19e5939f773c7cb05480fe2e881d63870b63ee2b4bdb9a77d55b1d36c7b9/fonttools-4.61.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e24a1565c4e57111ec7f4915f8981ecbb61adf66a55f378fdc00e206059fcfef", size = 2846930, upload_time = "2025-11-28T17:04:46.639Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/b2/0658faf66f705293bd7e739a4f038302d188d424926be9c59bdad945664b/fonttools-4.61.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2bfacb5351303cae9f072ccf3fc6ecb437a6f359c0606bae4b1ab6715201d87", size = 2383016, upload_time = "2025-11-28T17:04:48.525Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/a3/1fa90b95b690f0d7541f48850adc40e9019374d896c1b8148d15012b2458/fonttools-4.61.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0bdcf2e29d65c26299cc3d502f4612365e8b90a939f46cd92d037b6cb7bb544a", size = 4949425, upload_time = "2025-11-28T17:04:50.482Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/00/acf18c00f6c501bd6e05ee930f926186f8a8e268265407065688820f1c94/fonttools-4.61.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6cd0d9051b8ddaf7385f99dd82ec2a058e2b46cf1f1961e68e1ff20fcbb61af", size = 4999632, upload_time = "2025-11-28T17:04:52.508Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/e0/19a2b86e54109b1d2ee8743c96a1d297238ae03243897bc5345c0365f34d/fonttools-4.61.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e074bc07c31406f45c418e17c1722e83560f181d122c412fa9e815df0ff74810", size = 4939438, upload_time = "2025-11-28T17:04:54.437Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/35/7b57a5f57d46286360355eff8d6b88c64ab6331107f37a273a71c803798d/fonttools-4.61.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a9b78da5d5faa17e63b2404b77feeae105c1b7e75f26020ab7a27b76e02039f", size = 5088960, upload_time = "2025-11-28T17:04:56.348Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/0e/6c5023eb2e0fe5d1ababc7e221e44acd3ff668781489cc1937a6f83d620a/fonttools-4.61.0-cp312-cp312-win32.whl", hash = "sha256:9821ed77bb676736b88fa87a737c97b6af06e8109667e625a4f00158540ce044", size = 2264404, upload_time = "2025-11-28T17:04:58.149Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/0b/63273128c7c5df19b1e4cd92e0a1e6ea5bb74a400c4905054c96ad60a675/fonttools-4.61.0-cp312-cp312-win_amd64.whl", hash = "sha256:0011d640afa61053bc6590f9a3394bd222de7cfde19346588beabac374e9d8ac", size = 2314427, upload_time = "2025-11-28T17:04:59.812Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/45/334f0d7f181e5473cfb757e1b60f4e60e7fc64f28d406e5d364a952718c0/fonttools-4.61.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba774b8cbd8754f54b8eb58124e8bd45f736b2743325ab1a5229698942b9b433", size = 2841801, upload_time = "2025-11-28T17:05:01.621Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/63/97b9c78e1f79bc741d4efe6e51f13872d8edb2b36e1b9fb2bab0d4491bb7/fonttools-4.61.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c84b430616ed73ce46e9cafd0bf0800e366a3e02fb7e1ad7c1e214dbe3862b1f", size = 2379024, upload_time = "2025-11-28T17:05:03.668Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/80/c87bc524a90dbeb2a390eea23eae448286983da59b7e02c67fa0ca96a8c5/fonttools-4.61.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b2b734d8391afe3c682320840c8191de9bd24e7eb85768dd4dc06ed1b63dbb1b", size = 4923706, upload_time = "2025-11-28T17:05:05.494Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/f6/a3b0374811a1de8c3f9207ec88f61ad1bb96f938ed89babae26c065c2e46/fonttools-4.61.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5c5fff72bf31b0e558ed085e4fd7ed96eb85881404ecc39ed2a779e7cf724eb", size = 4979751, upload_time = "2025-11-28T17:05:07.665Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/3b/30f63b4308b449091573285f9d27619563a84f399946bca3eadc9554afbe/fonttools-4.61.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:14a290c5c93fcab76b7f451e6a4b7721b712d90b3b5ed6908f1abcf794e90d6d", size = 4921113, upload_time = "2025-11-28T17:05:09.551Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/6c/58e6e9b7d9d8bf2d7010bd7bb493060b39b02a12d1cda64a8bfb116ce760/fonttools-4.61.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:13e3e20a5463bfeb77b3557d04b30bd6a96a6bb5c15c7b2e7908903e69d437a0", size = 5063183, upload_time = "2025-11-28T17:05:11.677Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/e3/52c790ab2b07492df059947a1fd7778e105aac5848c0473029a4d20481a2/fonttools-4.61.0-cp313-cp313-win32.whl", hash = "sha256:6781e7a4bb010be1cd69a29927b0305c86b843395f2613bdabe115f7d6ea7f34", size = 2263159, upload_time = "2025-11-28T17:05:13.292Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/1f/116013b200fbeba871046554d5d2a45fefa69a05c40e9cdfd0d4fff53edc/fonttools-4.61.0-cp313-cp313-win_amd64.whl", hash = "sha256:c53b47834ae41e8e4829171cc44fec0fdf125545a15f6da41776b926b9645a9a", size = 2313530, upload_time = "2025-11-28T17:05:14.848Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/99/59b1e25987787cb714aa9457cee4c9301b7c2153f0b673e2b8679d37669d/fonttools-4.61.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:96dfc9bc1f2302224e48e6ee37e656eddbab810b724b52e9d9c13a57a6abad01", size = 2841429, upload_time = "2025-11-28T17:05:16.671Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/b2/4c1911d4332c8a144bb3b44416e274ccca0e297157c971ea1b3fbb855590/fonttools-4.61.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3b2065d94e5d63aafc2591c8b6ccbdb511001d9619f1bca8ad39b745ebeb5efa", size = 2378987, upload_time = "2025-11-28T17:05:18.69Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/b0/f442e90fde5d2af2ae0cb54008ab6411edc557ee33b824e13e1d04925ac9/fonttools-4.61.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e0d87e81e4d869549585ba0beb3f033718501c1095004f5e6aef598d13ebc216", size = 4873270, upload_time = "2025-11-28T17:05:20.625Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/04/f5d5990e33053c8a59b90b1d7e10ad9b97a73f42c745304da0e709635fab/fonttools-4.61.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1cfa2eb9bae650e58f0e8ad53c49d19a844d6034d6b259f30f197238abc1ccee", size = 4968270, upload_time = "2025-11-28T17:05:22.515Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/9f/2091402e0d27c9c8c4bab5de0e5cd146d9609a2d7d1c666bbb75c0011c1a/fonttools-4.61.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4238120002e68296d55e091411c09eab94e111c8ce64716d17df53fd0eb3bb3d", size = 4919799, upload_time = "2025-11-28T17:05:24.437Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/72/86adab22fde710b829f8ffbc8f264df01928e5b7a8f6177fa29979ebf256/fonttools-4.61.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b6ceac262cc62bec01b3bb59abccf41b24ef6580869e306a4e88b7e56bb4bdda", size = 5030966, upload_time = "2025-11-28T17:05:26.115Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/a7/7c8e31b003349e845b853f5e0a67b95ff6b052fa4f5224f8b72624f5ac69/fonttools-4.61.0-cp314-cp314-win32.whl", hash = "sha256:adbb4ecee1a779469a77377bbe490565effe8fce6fb2e6f95f064de58f8bac85", size = 2267243, upload_time = "2025-11-28T17:05:27.807Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/ee/f434fe7749360497c52b7dcbcfdbccdaab0a71c59f19d572576066717122/fonttools-4.61.0-cp314-cp314-win_amd64.whl", hash = "sha256:02bdf8e04d1a70476564b8640380f04bb4ac74edc1fc71f1bacb840b3e398ee9", size = 2318822, upload_time = "2025-11-28T17:05:29.882Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/b3/c16255320255e5c1863ca2b2599bb61a46e2f566db0bbb9948615a8fe692/fonttools-4.61.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:627216062d90ab0d98215176d8b9562c4dd5b61271d35f130bcd30f6a8aaa33a", size = 2924917, upload_time = "2025-11-28T17:05:31.46Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/b8/08067ae21de705a817777c02ef36ab0b953cbe91d8adf134f9c2da75ed6d/fonttools-4.61.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7b446623c9cd5f14a59493818eaa80255eec2468c27d2c01b56e05357c263195", size = 2413576, upload_time = "2025-11-28T17:05:33.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/f1/96ff43f92addce2356780fdc203f2966206f3d22ea20e242c27826fd7442/fonttools-4.61.0-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:70e2a0c0182ee75e493ef33061bfebf140ea57e035481d2f95aa03b66c7a0e05", size = 4877447, upload_time = "2025-11-28T17:05:35.278Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/1e/a3d8e51ed9ccfd7385e239ae374b78d258a0fb82d82cab99160a014a45d1/fonttools-4.61.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9064b0f55b947e929ac669af5311ab1f26f750214db6dd9a0c97e091e918f486", size = 5095681, upload_time = "2025-11-28T17:05:37.142Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/f6/d256bd6c1065c146a0bdddf1c62f542e08ae5b3405dbf3fcc52be272f674/fonttools-4.61.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2cb5e45a824ce14b90510024d0d39dae51bd4fbb54c42a9334ea8c8cf4d95cbe", size = 4974140, upload_time = "2025-11-28T17:05:39.5Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/0c/96633eb4b26f138cc48561c6e0c44b4ea48acea56b20b507d6b14f8e80ce/fonttools-4.61.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e5ca8c62efdec7972dfdfd454415c4db49b89aeaefaaacada432f3b7eea9866", size = 5001741, upload_time = "2025-11-28T17:05:41.424Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/9a/3b536bad3be4f26186f296e749ff17bad3e6d57232c104d752d24b2e265b/fonttools-4.61.0-cp314-cp314t-win32.whl", hash = "sha256:63c7125d31abe3e61d7bb917329b5543c5b3448db95f24081a13aaf064360fc8", size = 2330707, upload_time = "2025-11-28T17:05:43.548Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/ea/e6b9ac610451ee9f04477c311ad126de971f6112cb579fa391d2a8edb00b/fonttools-4.61.0-cp314-cp314t-win_amd64.whl", hash = "sha256:67d841aa272be5500de7f447c40d1d8452783af33b4c3599899319f6ef9ad3c1", size = 2395950, upload_time = "2025-11-28T17:05:45.638Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/14/634f7daea5ffe6a5f7a0322ba8e1a0e23c9257b80aa91458107896d1dfc7/fonttools-4.61.0-py3-none-any.whl", hash = "sha256:276f14c560e6f98d24ef7f5f44438e55ff5a67f78fa85236b218462c9f5d0635", size = 1144485, upload_time = "2025-11-28T17:05:47.573Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload_time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/4a/557715d5047da48d54e659203b9335be7bfaafda2c3f627b7c47e0b3aaf3/frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011", size = 86230, upload_time = "2025-10-06T05:35:23.699Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/fb/c85f9fed3ea8fe8740e5b46a59cc141c23b842eca617da8876cfce5f760e/frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565", size = 49621, upload_time = "2025-10-06T05:35:25.341Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/70/26ca3f06aace16f2352796b08704338d74b6d1a24ca38f2771afbb7ed915/frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad", size = 49889, upload_time = "2025-10-06T05:35:26.797Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/ed/c7895fd2fde7f3ee70d248175f9b6cdf792fb741ab92dc59cd9ef3bd241b/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2", size = 219464, upload_time = "2025-10-06T05:35:28.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/83/4d587dccbfca74cb8b810472392ad62bfa100bf8108c7223eb4c4fa2f7b3/frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186", size = 221649, upload_time = "2025-10-06T05:35:29.454Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/c6/fd3b9cd046ec5fff9dab66831083bc2077006a874a2d3d9247dea93ddf7e/frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e", size = 219188, upload_time = "2025-10-06T05:35:30.951Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ce/80/6693f55eb2e085fc8afb28cf611448fb5b90e98e068fa1d1b8d8e66e5c7d/frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450", size = 231748, upload_time = "2025-10-06T05:35:32.101Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/d6/e9459f7c5183854abd989ba384fe0cc1a0fb795a83c033f0571ec5933ca4/frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef", size = 236351, upload_time = "2025-10-06T05:35:33.834Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/92/24e97474b65c0262e9ecd076e826bfd1d3074adcc165a256e42e7b8a7249/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4", size = 218767, upload_time = "2025-10-06T05:35:35.205Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/bf/dc394a097508f15abff383c5108cb8ad880d1f64a725ed3b90d5c2fbf0bb/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff", size = 235887, upload_time = "2025-10-06T05:35:36.354Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/90/25b201b9c015dbc999a5baf475a257010471a1fa8c200c843fd4abbee725/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c", size = 228785, upload_time = "2025-10-06T05:35:37.949Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/f4/b5bc148df03082f05d2dd30c089e269acdbe251ac9a9cf4e727b2dbb8a3d/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f", size = 230312, upload_time = "2025-10-06T05:35:39.178Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/4b/87e95b5d15097c302430e647136b7d7ab2398a702390cf4c8601975709e7/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7", size = 217650, upload_time = "2025-10-06T05:35:40.377Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/70/78a0315d1fea97120591a83e0acd644da638c872f142fd72a6cebee825f3/frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a", size = 39659, upload_time = "2025-10-06T05:35:41.863Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/aa/3f04523fb189a00e147e60c5b2205126118f216b0aa908035c45336e27e4/frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6", size = 43837, upload_time = "2025-10-06T05:35:43.205Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/75/1135feecdd7c336938bd55b4dc3b0dfc46d85b9be12ef2628574b28de776/frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e", size = 39989, upload_time = "2025-10-06T05:35:44.596Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912, upload_time = "2025-10-06T05:35:45.98Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046, upload_time = "2025-10-06T05:35:47.009Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119, upload_time = "2025-10-06T05:35:48.38Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067, upload_time = "2025-10-06T05:35:49.97Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160, upload_time = "2025-10-06T05:35:51.729Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544, upload_time = "2025-10-06T05:35:53.246Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797, upload_time = "2025-10-06T05:35:54.497Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923, upload_time = "2025-10-06T05:35:55.861Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886, upload_time = "2025-10-06T05:35:57.399Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731, upload_time = "2025-10-06T05:35:58.563Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544, upload_time = "2025-10-06T05:35:59.719Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806, upload_time = "2025-10-06T05:36:00.959Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382, upload_time = "2025-10-06T05:36:02.22Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload_time = "2025-10-06T05:36:03.409Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload_time = "2025-10-06T05:36:04.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload_time = "2025-10-06T05:36:05.669Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload_time = "2025-10-06T05:36:06.649Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload_time = "2025-10-06T05:36:07.69Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload_time = "2025-10-06T05:36:08.78Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload_time = "2025-10-06T05:36:09.801Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload_time = "2025-10-06T05:36:11.394Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload_time = "2025-10-06T05:36:12.598Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload_time = "2025-10-06T05:36:14.065Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload_time = "2025-10-06T05:36:15.39Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload_time = "2025-10-06T05:36:16.558Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload_time = "2025-10-06T05:36:17.821Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload_time = "2025-10-06T05:36:19.046Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload_time = "2025-10-06T05:36:20.763Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload_time = "2025-10-06T05:36:22.129Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload_time = "2025-10-06T05:36:23.661Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload_time = "2025-10-06T05:36:24.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload_time = "2025-10-06T05:36:26.333Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload_time = "2025-10-06T05:36:27.341Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload_time = "2025-10-06T05:36:28.855Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload_time = "2025-10-06T05:36:29.877Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload_time = "2025-10-06T05:36:31.301Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload_time = "2025-10-06T05:36:32.531Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload_time = "2025-10-06T05:36:33.706Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload_time = "2025-10-06T05:36:34.947Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload_time = "2025-10-06T05:36:36.534Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload_time = "2025-10-06T05:36:38.582Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload_time = "2025-10-06T05:36:40.152Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload_time = "2025-10-06T05:36:41.355Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload_time = "2025-10-06T05:36:42.716Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload_time = "2025-10-06T05:36:44.251Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload_time = "2025-10-06T05:36:45.423Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload_time = "2025-10-06T05:36:46.796Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload_time = "2025-10-06T05:36:47.8Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload_time = "2025-10-06T05:36:48.78Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload_time = "2025-10-06T05:36:49.837Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload_time = "2025-10-06T05:36:50.851Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload_time = "2025-10-06T05:36:51.898Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload_time = "2025-10-06T05:36:53.101Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload_time = "2025-10-06T05:36:54.309Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload_time = "2025-10-06T05:36:55.566Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload_time = "2025-10-06T05:36:56.758Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload_time = "2025-10-06T05:36:57.965Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload_time = "2025-10-06T05:36:59.237Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload_time = "2025-10-06T05:37:00.811Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload_time = "2025-10-06T05:37:02.115Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload_time = "2025-10-06T05:37:03.711Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload_time = "2025-10-06T05:37:04.915Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload_time = "2025-10-06T05:37:06.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload_time = "2025-10-06T05:37:07.431Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload_time = "2025-10-06T05:37:08.438Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload_time = "2025-10-06T05:37:09.48Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload_time = "2025-10-06T05:37:10.569Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload_time = "2025-10-06T05:37:11.993Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload_time = "2025-10-06T05:37:13.194Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload_time = "2025-10-06T05:37:14.577Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload_time = "2025-10-06T05:37:15.781Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload_time = "2025-10-06T05:37:17.037Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload_time = "2025-10-06T05:37:18.221Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload_time = "2025-10-06T05:37:19.771Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload_time = "2025-10-06T05:37:20.969Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload_time = "2025-10-06T05:37:22.252Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload_time = "2025-10-06T05:37:23.5Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload_time = "2025-10-06T05:37:25.581Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload_time = "2025-10-06T05:37:26.928Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload_time = "2025-10-06T05:37:28.075Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload_time = "2025-10-06T05:37:29.373Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload_time = "2025-10-06T05:37:30.792Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload_time = "2025-10-06T05:37:32.127Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload_time = "2025-10-06T05:37:33.21Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload_time = "2025-10-06T05:37:36.107Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload_time = "2025-10-06T05:37:37.663Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload_time = "2025-10-06T05:37:39.261Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload_time = "2025-10-06T05:37:43.213Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload_time = "2025-10-06T05:37:45.337Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload_time = "2025-10-06T05:37:46.657Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload_time = "2025-10-06T05:37:47.946Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload_time = "2025-10-06T05:37:49.499Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload_time = "2025-10-06T05:37:50.745Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload_time = "2025-10-06T05:37:52.222Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload_time = "2025-10-06T05:37:53.425Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload_time = "2025-10-06T05:37:54.513Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload_time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "google-auth" +version = "2.43.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "pyasn1-modules" }, + { name = "rsa" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/ef/66d14cf0e01b08d2d51ffc3c20410c4e134a1548fc246a6081eae585a4fe/google_auth-2.43.0.tar.gz", hash = "sha256:88228eee5fc21b62a1b5fe773ca15e67778cb07dc8363adcb4a8827b52d81483", size = 296359, upload_time = "2025-11-06T00:13:36.587Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/d1/385110a9ae86d91cc14c5282c61fe9f4dc41c0b9f7d423c6ad77038c4448/google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16", size = 223114, upload_time = "2025-11-06T00:13:35.209Z" }, +] + +[package.optional-dependencies] +requests = [ + { name = "requests" }, +] + +[[package]] +name = "google-genai" +version = "1.53.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "anyio" }, + { name = "google-auth", extra = ["requests"] }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/de/b3/36fbfde2e21e6d3bc67780b61da33632f495ab1be08076cf0a16af74098f/google_genai-1.53.0.tar.gz", hash = "sha256:938a26d22f3fd32c6eeeb4276ef204ef82884e63af9842ce3eac05ceb39cbd8d", size = 260102, upload_time = "2025-12-03T17:21:23.233Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/f2/97fefdd1ad1f3428321bac819ae7a83ccc59f6439616054736b7819fa56c/google_genai-1.53.0-py3-none-any.whl", hash = "sha256:65a3f99e5c03c372d872cda7419f5940e723374bb12a2f3ffd5e3e56e8eb2094", size = 262015, upload_time = "2025-12-03T17:21:21.934Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload_time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload_time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload_time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload_time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload_time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload_time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload_time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload_time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "jieba" +version = "0.42.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/cb/18eeb235f833b726522d7ebed54f2278ce28ba9438e3135ab0278d9792a2/jieba-0.42.1.tar.gz", hash = "sha256:055ca12f62674fafed09427f176506079bc135638a14e23e25be909131928db2", size = 19214172, upload_time = "2020-01-20T14:27:23.5Z" } + +[[package]] +name = "jiter" +version = "0.12.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/9d/e0660989c1370e25848bb4c52d061c71837239738ad937e83edca174c273/jiter-0.12.0.tar.gz", hash = "sha256:64dfcd7d5c168b38d3f9f8bba7fc639edb3418abcc74f22fdbe6b8938293f30b", size = 168294, upload_time = "2025-11-09T20:49:23.302Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3b/91/13cb9505f7be74a933f37da3af22e029f6ba64f5669416cb8b2774bc9682/jiter-0.12.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e7acbaba9703d5de82a2c98ae6a0f59ab9770ab5af5fa35e43a303aee962cf65", size = 316652, upload_time = "2025-11-09T20:46:41.021Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/76/4e9185e5d9bb4e482cf6dec6410d5f78dfeb374cfcecbbe9888d07c52daa/jiter-0.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:364f1a7294c91281260364222f535bc427f56d4de1d8ffd718162d21fbbd602e", size = 319829, upload_time = "2025-11-09T20:46:43.281Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/af/727de50995d3a153138139f259baae2379d8cb0522c0c00419957bc478a6/jiter-0.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85ee4d25805d4fb23f0a5167a962ef8e002dbfb29c0989378488e32cf2744b62", size = 350568, upload_time = "2025-11-09T20:46:45.075Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/c1/d6e9f4b7a3d5ac63bcbdfddeb50b2dcfbdc512c86cffc008584fdc350233/jiter-0.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:796f466b7942107eb889c08433b6e31b9a7ed31daceaecf8af1be26fb26c0ca8", size = 369052, upload_time = "2025-11-09T20:46:46.818Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/be/00824cd530f30ed73fa8a4f9f3890a705519e31ccb9e929f1e22062e7c76/jiter-0.12.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35506cb71f47dba416694e67af996bbdefb8e3608f1f78799c2e1f9058b01ceb", size = 481585, upload_time = "2025-11-09T20:46:48.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/b6/2ad7990dff9504d4b5052eef64aa9574bd03d722dc7edced97aad0d47be7/jiter-0.12.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:726c764a90c9218ec9e4f99a33d6bf5ec169163f2ca0fc21b654e88c2abc0abc", size = 380541, upload_time = "2025-11-09T20:46:49.643Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/c7/f3c26ecbc1adbf1db0d6bba99192143d8fe8504729d9594542ecc4445784/jiter-0.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa47810c5565274810b726b0dc86d18dce5fd17b190ebdc3890851d7b2a0e74", size = 364423, upload_time = "2025-11-09T20:46:51.731Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/51/eac547bf3a2d7f7e556927278e14c56a0604b8cddae75815d5739f65f81d/jiter-0.12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8ec0259d3f26c62aed4d73b198c53e316ae11f0f69c8fbe6682c6dcfa0fcce2", size = 389958, upload_time = "2025-11-09T20:46:53.432Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/1f/9ca592e67175f2db156cff035e0d817d6004e293ee0c1d73692d38fcb596/jiter-0.12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:79307d74ea83465b0152fa23e5e297149506435535282f979f18b9033c0bb025", size = 522084, upload_time = "2025-11-09T20:46:54.848Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/ff/597d9cdc3028f28224f53e1a9d063628e28b7a5601433e3196edda578cdd/jiter-0.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cf6e6dd18927121fec86739f1a8906944703941d000f0639f3eb6281cc601dca", size = 513054, upload_time = "2025-11-09T20:46:56.487Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/6d/1970bce1351bd02e3afcc5f49e4f7ef3dabd7fb688f42be7e8091a5b809a/jiter-0.12.0-cp310-cp310-win32.whl", hash = "sha256:b6ae2aec8217327d872cbfb2c1694489057b9433afce447955763e6ab015b4c4", size = 206368, upload_time = "2025-11-09T20:46:58.638Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/6b/eb1eb505b2d86709b59ec06681a2b14a94d0941db091f044b9f0e16badc0/jiter-0.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:c7f49ce90a71e44f7e1aa9e7ec415b9686bbc6a5961e57eab511015e6759bc11", size = 204847, upload_time = "2025-11-09T20:47:00.295Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/f9/eaca4633486b527ebe7e681c431f529b63fe2709e7c5242fc0f43f77ce63/jiter-0.12.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8f8a7e317190b2c2d60eb2e8aa835270b008139562d70fe732e1c0020ec53c9", size = 316435, upload_time = "2025-11-09T20:47:02.087Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/c1/40c9f7c22f5e6ff715f28113ebaba27ab85f9af2660ad6e1dd6425d14c19/jiter-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2218228a077e784c6c8f1a8e5d6b8cb1dea62ce25811c356364848554b2056cd", size = 320548, upload_time = "2025-11-09T20:47:03.409Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/1b/efbb68fe87e7711b00d2cfd1f26bb4bfc25a10539aefeaa7727329ffb9cb/jiter-0.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9354ccaa2982bf2188fd5f57f79f800ef622ec67beb8329903abf6b10da7d423", size = 351915, upload_time = "2025-11-09T20:47:05.171Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/2d/c06e659888c128ad1e838123d0638f0efad90cc30860cb5f74dd3f2fc0b3/jiter-0.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2607185ea89b4af9a604d4c7ec40e45d3ad03ee66998b031134bc510232bb7", size = 368966, upload_time = "2025-11-09T20:47:06.508Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/20/058db4ae5fb07cf6a4ab2e9b9294416f606d8e467fb74c2184b2a1eeacba/jiter-0.12.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a585a5e42d25f2e71db5f10b171f5e5ea641d3aa44f7df745aa965606111cc2", size = 482047, upload_time = "2025-11-09T20:47:08.382Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/bb/dc2b1c122275e1de2eb12905015d61e8316b2f888bdaac34221c301495d6/jiter-0.12.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd9e21d34edff5a663c631f850edcb786719c960ce887a5661e9c828a53a95d9", size = 380835, upload_time = "2025-11-09T20:47:09.81Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/7d/38f9cd337575349de16da575ee57ddb2d5a64d425c9367f5ef9e4612e32e/jiter-0.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a612534770470686cd5431478dc5a1b660eceb410abade6b1b74e320ca98de6", size = 364587, upload_time = "2025-11-09T20:47:11.529Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/a3/b13e8e61e70f0bb06085099c4e2462647f53cc2ca97614f7fedcaa2bb9f3/jiter-0.12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3985aea37d40a908f887b34d05111e0aae822943796ebf8338877fee2ab67725", size = 390492, upload_time = "2025-11-09T20:47:12.993Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/71/e0d11422ed027e21422f7bc1883c61deba2d9752b720538430c1deadfbca/jiter-0.12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b1207af186495f48f72529f8d86671903c8c10127cac6381b11dddc4aaa52df6", size = 522046, upload_time = "2025-11-09T20:47:14.6Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/59/b968a9aa7102a8375dbbdfbd2aeebe563c7e5dddf0f47c9ef1588a97e224/jiter-0.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef2fb241de583934c9915a33120ecc06d94aa3381a134570f59eed784e87001e", size = 513392, upload_time = "2025-11-09T20:47:16.011Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/e4/7df62002499080dbd61b505c5cb351aa09e9959d176cac2aa8da6f93b13b/jiter-0.12.0-cp311-cp311-win32.whl", hash = "sha256:453b6035672fecce8007465896a25b28a6b59cfe8fbc974b2563a92f5a92a67c", size = 206096, upload_time = "2025-11-09T20:47:17.344Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/60/1032b30ae0572196b0de0e87dce3b6c26a1eff71aad5fe43dee3082d32e0/jiter-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:ca264b9603973c2ad9435c71a8ec8b49f8f715ab5ba421c85a51cde9887e421f", size = 204899, upload_time = "2025-11-09T20:47:19.365Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/d5/c145e526fccdb834063fb45c071df78b0cc426bbaf6de38b0781f45d956f/jiter-0.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:cb00ef392e7d684f2754598c02c409f376ddcef857aae796d559e6cacc2d78a5", size = 188070, upload_time = "2025-11-09T20:47:20.75Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/c9/5b9f7b4983f1b542c64e84165075335e8a236fa9e2ea03a0c79780062be8/jiter-0.12.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:305e061fa82f4680607a775b2e8e0bcb071cd2205ac38e6ef48c8dd5ebe1cf37", size = 314449, upload_time = "2025-11-09T20:47:22.999Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/6e/e8efa0e78de00db0aee82c0cf9e8b3f2027efd7f8a71f859d8f4be8e98ef/jiter-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c1860627048e302a528333c9307c818c547f214d8659b0705d2195e1a94b274", size = 319855, upload_time = "2025-11-09T20:47:24.779Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/26/894cd88e60b5d58af53bec5c6759d1292bd0b37a8b5f60f07abf7a63ae5f/jiter-0.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df37577a4f8408f7e0ec3205d2a8f87672af8f17008358063a4d6425b6081ce3", size = 350171, upload_time = "2025-11-09T20:47:26.469Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/27/a7b818b9979ac31b3763d25f3653ec3a954044d5e9f5d87f2f247d679fd1/jiter-0.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fdd787356c1c13a4f40b43c2156276ef7a71eb487d98472476476d803fb2cf", size = 365590, upload_time = "2025-11-09T20:47:27.918Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/7e/e46195801a97673a83746170b17984aa8ac4a455746354516d02ca5541b4/jiter-0.12.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1eb5db8d9c65b112aacf14fcd0faae9913d07a8afea5ed06ccdd12b724e966a1", size = 479462, upload_time = "2025-11-09T20:47:29.654Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/75/f833bfb009ab4bd11b1c9406d333e3b4357709ed0570bb48c7c06d78c7dd/jiter-0.12.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73c568cc27c473f82480abc15d1301adf333a7ea4f2e813d6a2c7d8b6ba8d0df", size = 378983, upload_time = "2025-11-09T20:47:31.026Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/b3/7a69d77943cc837d30165643db753471aff5df39692d598da880a6e51c24/jiter-0.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4321e8a3d868919bcb1abb1db550d41f2b5b326f72df29e53b2df8b006eb9403", size = 361328, upload_time = "2025-11-09T20:47:33.286Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/ac/a78f90caf48d65ba70d8c6efc6f23150bc39dc3389d65bbec2a95c7bc628/jiter-0.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a51bad79f8cc9cac2b4b705039f814049142e0050f30d91695a2d9a6611f126", size = 386740, upload_time = "2025-11-09T20:47:34.703Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/b6/5d31c2cc8e1b6a6bcf3c5721e4ca0a3633d1ab4754b09bc7084f6c4f5327/jiter-0.12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2a67b678f6a5f1dd6c36d642d7db83e456bc8b104788262aaefc11a22339f5a9", size = 520875, upload_time = "2025-11-09T20:47:36.058Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/b5/4df540fae4e9f68c54b8dab004bd8c943a752f0b00efd6e7d64aa3850339/jiter-0.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efe1a211fe1fd14762adea941e3cfd6c611a136e28da6c39272dbb7a1bbe6a86", size = 511457, upload_time = "2025-11-09T20:47:37.932Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/65/86b74010e450a1a77b2c1aabb91d4a91dd3cd5afce99f34d75fd1ac64b19/jiter-0.12.0-cp312-cp312-win32.whl", hash = "sha256:d779d97c834b4278276ec703dc3fc1735fca50af63eb7262f05bdb4e62203d44", size = 204546, upload_time = "2025-11-09T20:47:40.47Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/c7/6659f537f9562d963488e3e55573498a442503ced01f7e169e96a6110383/jiter-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e8269062060212b373316fe69236096aaf4c49022d267c6736eebd66bbbc60bb", size = 205196, upload_time = "2025-11-09T20:47:41.794Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/f4/935304f5169edadfec7f9c01eacbce4c90bb9a82035ac1de1f3bd2d40be6/jiter-0.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:06cb970936c65de926d648af0ed3d21857f026b1cf5525cb2947aa5e01e05789", size = 186100, upload_time = "2025-11-09T20:47:43.007Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/a6/97209693b177716e22576ee1161674d1d58029eb178e01866a0422b69224/jiter-0.12.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6cc49d5130a14b732e0612bc76ae8db3b49898732223ef8b7599aa8d9810683e", size = 313658, upload_time = "2025-11-09T20:47:44.424Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/4d/125c5c1537c7d8ee73ad3d530a442d6c619714b95027143f1b61c0b4dfe0/jiter-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37f27a32ce36364d2fa4f7fdc507279db604d27d239ea2e044c8f148410defe1", size = 318605, upload_time = "2025-11-09T20:47:45.973Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/bf/a840b89847885064c41a5f52de6e312e91fa84a520848ee56c97e4fa0205/jiter-0.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc0944aa3d4b4773e348cda635252824a78f4ba44328e042ef1ff3f6080d1cf", size = 349803, upload_time = "2025-11-09T20:47:47.535Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/88/e63441c28e0db50e305ae23e19c1d8fae012d78ed55365da392c1f34b09c/jiter-0.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da25c62d4ee1ffbacb97fac6dfe4dcd6759ebdc9015991e92a6eae5816287f44", size = 365120, upload_time = "2025-11-09T20:47:49.284Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/7c/49b02714af4343970eb8aca63396bc1c82fa01197dbb1e9b0d274b550d4e/jiter-0.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:048485c654b838140b007390b8182ba9774621103bd4d77c9c3f6f117474ba45", size = 479918, upload_time = "2025-11-09T20:47:50.807Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/ba/0a809817fdd5a1db80490b9150645f3aae16afad166960bcd562be194f3b/jiter-0.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:635e737fbb7315bef0037c19b88b799143d2d7d3507e61a76751025226b3ac87", size = 379008, upload_time = "2025-11-09T20:47:52.211Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/c3/c9fc0232e736c8877d9e6d83d6eeb0ba4e90c6c073835cc2e8f73fdeef51/jiter-0.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e017c417b1ebda911bd13b1e40612704b1f5420e30695112efdbed8a4b389ed", size = 361785, upload_time = "2025-11-09T20:47:53.512Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/61/61f69b7e442e97ca6cd53086ddc1cf59fb830549bc72c0a293713a60c525/jiter-0.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:89b0bfb8b2bf2351fba36bb211ef8bfceba73ef58e7f0c68fb67b5a2795ca2f9", size = 386108, upload_time = "2025-11-09T20:47:54.893Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/2e/76bb3332f28550c8f1eba3bf6e5efe211efda0ddbbaf24976bc7078d42a5/jiter-0.12.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f5aa5427a629a824a543672778c9ce0c5e556550d1569bb6ea28a85015287626", size = 519937, upload_time = "2025-11-09T20:47:56.253Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/d6/fa96efa87dc8bff2094fb947f51f66368fa56d8d4fc9e77b25d7fbb23375/jiter-0.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed53b3d6acbcb0fd0b90f20c7cb3b24c357fe82a3518934d4edfa8c6898e498c", size = 510853, upload_time = "2025-11-09T20:47:58.32Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/28/93f67fdb4d5904a708119a6ab58a8f1ec226ff10a94a282e0215402a8462/jiter-0.12.0-cp313-cp313-win32.whl", hash = "sha256:4747de73d6b8c78f2e253a2787930f4fffc68da7fa319739f57437f95963c4de", size = 204699, upload_time = "2025-11-09T20:47:59.686Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/1f/30b0eb087045a0abe2a5c9c0c0c8da110875a1d3be83afd4a9a4e548be3c/jiter-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e25012eb0c456fcc13354255d0338cd5397cce26c77b2832b3c4e2e255ea5d9a", size = 204258, upload_time = "2025-11-09T20:48:01.01Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/f4/2b4daf99b96bce6fc47971890b14b2a36aef88d7beb9f057fafa032c6141/jiter-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:c97b92c54fe6110138c872add030a1f99aea2401ddcdaa21edf74705a646dd60", size = 185503, upload_time = "2025-11-09T20:48:02.35Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/ca/67bb15a7061d6fe20b9b2a2fd783e296a1e0f93468252c093481a2f00efa/jiter-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53839b35a38f56b8be26a7851a48b89bc47e5d88e900929df10ed93b95fea3d6", size = 317965, upload_time = "2025-11-09T20:48:03.783Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/af/1788031cd22e29c3b14bc6ca80b16a39a0b10e611367ffd480c06a259831/jiter-0.12.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94f669548e55c91ab47fef8bddd9c954dab1938644e715ea49d7e117015110a4", size = 345831, upload_time = "2025-11-09T20:48:05.55Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload_time = "2025-11-09T20:48:06.951Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload_time = "2025-11-09T20:48:08.328Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload_time = "2025-11-09T20:48:09.572Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload_time = "2025-11-09T20:48:10.898Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload_time = "2025-11-09T20:48:12.266Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload_time = "2025-11-09T20:48:13.673Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload_time = "2025-11-09T20:48:15.083Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload_time = "2025-11-09T20:48:16.706Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload_time = "2025-11-09T20:48:18.614Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload_time = "2025-11-09T20:48:20.117Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload_time = "2025-11-09T20:48:21.543Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload_time = "2025-11-09T20:48:22.964Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload_time = "2025-11-09T20:48:24.483Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload_time = "2025-11-09T20:48:25.749Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload_time = "2025-11-09T20:48:27.415Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload_time = "2025-11-09T20:48:29.125Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload_time = "2025-11-09T20:48:30.87Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload_time = "2025-11-09T20:48:32.658Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload_time = "2025-11-09T20:48:34.093Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload_time = "2025-11-09T20:48:35.507Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload_time = "2025-11-09T20:48:40.014Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload_time = "2025-11-09T20:48:41.462Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload_time = "2025-11-09T20:48:42.921Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload_time = "2025-11-09T20:48:44.278Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload_time = "2025-11-09T20:48:45.726Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload_time = "2025-11-09T20:48:47.033Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload_time = "2025-11-09T20:48:49.076Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload_time = "2025-11-09T20:48:50.376Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/54/5339ef1ecaa881c6948669956567a64d2670941925f245c434f494ffb0e5/jiter-0.12.0-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:4739a4657179ebf08f85914ce50332495811004cc1747852e8b2041ed2aab9b8", size = 311144, upload_time = "2025-11-09T20:49:10.503Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/74/3446c652bffbd5e81ab354e388b1b5fc1d20daac34ee0ed11ff096b1b01a/jiter-0.12.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:41da8def934bf7bec16cb24bd33c0ca62126d2d45d81d17b864bd5ad721393c3", size = 305877, upload_time = "2025-11-09T20:49:12.269Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/f4/ed76ef9043450f57aac2d4fbeb27175aa0eb9c38f833be6ef6379b3b9a86/jiter-0.12.0-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c44ee814f499c082e69872d426b624987dbc5943ab06e9bbaa4f81989fdb79e", size = 340419, upload_time = "2025-11-09T20:49:13.803Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/01/857d4608f5edb0664aa791a3d45702e1a5bcfff9934da74035e7b9803846/jiter-0.12.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd2097de91cf03eaa27b3cbdb969addf83f0179c6afc41bbc4513705e013c65d", size = 347212, upload_time = "2025-11-09T20:49:15.643Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/f5/12efb8ada5f5c9edc1d4555fe383c1fb2eac05ac5859258a72d61981d999/jiter-0.12.0-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:e8547883d7b96ef2e5fe22b88f8a4c8725a56e7f4abafff20fd5272d634c7ecb", size = 309974, upload_time = "2025-11-09T20:49:17.187Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/15/d6eb3b770f6a0d332675141ab3962fd4a7c270ede3515d9f3583e1d28276/jiter-0.12.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:89163163c0934854a668ed783a2546a0617f71706a2551a4a0666d91ab365d6b", size = 304233, upload_time = "2025-11-09T20:49:18.734Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/3e/e7e06743294eea2cf02ced6aa0ff2ad237367394e37a0e2b4a1108c67a36/jiter-0.12.0-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d96b264ab7d34bbb2312dedc47ce07cd53f06835eacbc16dde3761f47c3a9e7f", size = 338537, upload_time = "2025-11-09T20:49:20.317Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2f/9c/6753e6522b8d0ef07d3a3d239426669e984fb0eba15a315cdbc1253904e4/jiter-0.12.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24e864cb30ab82311c6425655b0cdab0a98c5d973b065c66a3f020740c2324c", size = 346110, upload_time = "2025-11-09T20:49:21.817Z" }, +] + +[[package]] +name = "json-repair" +version = "0.54.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/05/9fbcd5ffab9c41455e7d80af65a90876718b8ea2fb4525e187ab11836dd4/json_repair-0.54.2.tar.gz", hash = "sha256:4b6b62ce17f1a505b220fa4aadba1fc37dc9c221544f158471efe3775620bad6", size = 38575, upload_time = "2025-11-25T19:31:22.768Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/53/3a/1b4df9adcd69fee9c9e4b439c13e8c866f2fae520054aede7030b2278be9/json_repair-0.54.2-py3-none-any.whl", hash = "sha256:be51cce5dca97e0c24ebdf61a1ede2449a8a7666012de99467bb7b0afb35179b", size = 29322, upload_time = "2025-11-25T19:31:21.492Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.4.9" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload_time = "2025-08-10T21:27:49.279Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/5d/8ce64e36d4e3aac5ca96996457dcf33e34e6051492399a3f1fec5657f30b/kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b", size = 124159, upload_time = "2025-08-10T21:25:35.472Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/1e/22f63ec454874378175a5f435d6ea1363dd33fb2af832c6643e4ccea0dc8/kiwisolver-1.4.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fb3b8132019ea572f4611d770991000d7f58127560c4889729248eb5852a102f", size = 66578, upload_time = "2025-08-10T21:25:36.73Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/4c/1925dcfff47a02d465121967b95151c82d11027d5ec5242771e580e731bd/kiwisolver-1.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84fd60810829c27ae375114cd379da1fa65e6918e1da405f356a775d49a62bcf", size = 65312, upload_time = "2025-08-10T21:25:37.658Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/42/0f333164e6307a0687d1eb9ad256215aae2f4bd5d28f4653d6cd319a3ba3/kiwisolver-1.4.9-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b78efa4c6e804ecdf727e580dbb9cba85624d2e1c6b5cb059c66290063bd99a9", size = 1628458, upload_time = "2025-08-10T21:25:39.067Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/b6/2dccb977d651943995a90bfe3495c2ab2ba5cd77093d9f2318a20c9a6f59/kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4efec7bcf21671db6a3294ff301d2fc861c31faa3c8740d1a94689234d1b415", size = 1225640, upload_time = "2025-08-10T21:25:40.489Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/2b/362ebd3eec46c850ccf2bfe3e30f2fc4c008750011f38a850f088c56a1c6/kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90f47e70293fc3688b71271100a1a5453aa9944a81d27ff779c108372cf5567b", size = 1244074, upload_time = "2025-08-10T21:25:42.221Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/bb/f09a1e66dab8984773d13184a10a29fe67125337649d26bdef547024ed6b/kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fdca1def57a2e88ef339de1737a1449d6dbf5fab184c54a1fca01d541317154", size = 1293036, upload_time = "2025-08-10T21:25:43.801Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/01/11ecf892f201cafda0f68fa59212edaea93e96c37884b747c181303fccd1/kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cf554f21be770f5111a1690d42313e140355e687e05cf82cb23d0a721a64a48", size = 2175310, upload_time = "2025-08-10T21:25:45.045Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/5f/bfe11d5b934f500cc004314819ea92427e6e5462706a498c1d4fc052e08f/kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1795ac5cd0510207482c3d1d3ed781143383b8cfd36f5c645f3897ce066220", size = 2270943, upload_time = "2025-08-10T21:25:46.393Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/de/259f786bf71f1e03e73d87e2db1a9a3bcab64d7b4fd780167123161630ad/kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ccd09f20ccdbbd341b21a67ab50a119b64a403b09288c27481575105283c1586", size = 2440488, upload_time = "2025-08-10T21:25:48.074Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1b/76/c989c278faf037c4d3421ec07a5c452cd3e09545d6dae7f87c15f54e4edf/kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:540c7c72324d864406a009d72f5d6856f49693db95d1fbb46cf86febef873634", size = 2246787, upload_time = "2025-08-10T21:25:49.442Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/55/c2898d84ca440852e560ca9f2a0d28e6e931ac0849b896d77231929900e7/kiwisolver-1.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:ede8c6d533bc6601a47ad4046080d36b8fc99f81e6f1c17b0ac3c2dc91ac7611", size = 73730, upload_time = "2025-08-10T21:25:51.102Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/09/486d6ac523dd33b80b368247f238125d027964cfacb45c654841e88fb2ae/kiwisolver-1.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:7b4da0d01ac866a57dd61ac258c5607b4cd677f63abaec7b148354d2b2cdd536", size = 65036, upload_time = "2025-08-10T21:25:52.063Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/ab/c80b0d5a9d8a1a65f4f815f2afff9798b12c3b9f31f1d304dd233dd920e2/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16", size = 124167, upload_time = "2025-08-10T21:25:53.403Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089", size = 66579, upload_time = "2025-08-10T21:25:54.79Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543", size = 65309, upload_time = "2025-08-10T21:25:55.76Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61", size = 1435596, upload_time = "2025-08-10T21:25:56.861Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/1e/51b73c7347f9aabdc7215aa79e8b15299097dc2f8e67dee2b095faca9cb0/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1", size = 1246548, upload_time = "2025-08-10T21:25:58.246Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/aa/72a1c5d1e430294f2d32adb9542719cfb441b5da368d09d268c7757af46c/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872", size = 1263618, upload_time = "2025-08-10T21:25:59.857Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/af/db1509a9e79dbf4c260ce0cfa3903ea8945f6240e9e59d1e4deb731b1a40/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26", size = 1317437, upload_time = "2025-08-10T21:26:01.105Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/f2/3ea5ee5d52abacdd12013a94130436e19969fa183faa1e7c7fbc89e9a42f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028", size = 2195742, upload_time = "2025-08-10T21:26:02.675Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/9b/1efdd3013c2d9a2566aa6a337e9923a00590c516add9a1e89a768a3eb2fc/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771", size = 2290810, upload_time = "2025-08-10T21:26:04.009Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/e5/cfdc36109ae4e67361f9bc5b41323648cb24a01b9ade18784657e022e65f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a", size = 2461579, upload_time = "2025-08-10T21:26:05.317Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/86/b589e5e86c7610842213994cdea5add00960076bef4ae290c5fa68589cac/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464", size = 2268071, upload_time = "2025-08-10T21:26:06.686Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2", size = 73840, upload_time = "2025-08-10T21:26:07.94Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/2d/16e0581daafd147bc11ac53f032a2b45eabac897f42a338d0a13c1e5c436/kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7", size = 65159, upload_time = "2025-08-10T21:26:09.048Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload_time = "2025-08-10T21:26:10.034Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload_time = "2025-08-10T21:26:11.083Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload_time = "2025-08-10T21:26:12.058Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload_time = "2025-08-10T21:26:13.096Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload_time = "2025-08-10T21:26:14.457Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload_time = "2025-08-10T21:26:15.73Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload_time = "2025-08-10T21:26:17.045Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload_time = "2025-08-10T21:26:18.737Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload_time = "2025-08-10T21:26:20.11Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload_time = "2025-08-10T21:26:21.49Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload_time = "2025-08-10T21:26:22.812Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload_time = "2025-08-10T21:26:24.37Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload_time = "2025-08-10T21:26:25.732Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/c1/c2686cda909742ab66c7388e9a1a8521a59eb89f8bcfbee28fc980d07e24/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8", size = 123681, upload_time = "2025-08-10T21:26:26.725Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2", size = 66464, upload_time = "2025-08-10T21:26:27.733Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f", size = 64961, upload_time = "2025-08-10T21:26:28.729Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098", size = 1474607, upload_time = "2025-08-10T21:26:29.798Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/28/aac26d4c882f14de59041636292bc838db8961373825df23b8eeb807e198/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed", size = 1276546, upload_time = "2025-08-10T21:26:31.401Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/ad/8bfc1c93d4cc565e5069162f610ba2f48ff39b7de4b5b8d93f69f30c4bed/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525", size = 1294482, upload_time = "2025-08-10T21:26:32.721Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/f1/6aca55ff798901d8ce403206d00e033191f63d82dd708a186e0ed2067e9c/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78", size = 1343720, upload_time = "2025-08-10T21:26:34.032Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/91/eed031876c595c81d90d0f6fc681ece250e14bf6998c3d7c419466b523b7/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b", size = 2224907, upload_time = "2025-08-10T21:26:35.824Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/ec/4d1925f2e49617b9cca9c34bfa11adefad49d00db038e692a559454dfb2e/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799", size = 2321334, upload_time = "2025-08-10T21:26:37.534Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/cb/450cd4499356f68802750c6ddc18647b8ea01ffa28f50d20598e0befe6e9/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3", size = 2488313, upload_time = "2025-08-10T21:26:39.191Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/67/fc76242bd99f885651128a5d4fa6083e5524694b7c88b489b1b55fdc491d/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c", size = 2291970, upload_time = "2025-08-10T21:26:40.828Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d", size = 73894, upload_time = "2025-08-10T21:26:42.33Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/38/dce480814d25b99a391abbddadc78f7c117c6da34be68ca8b02d5848b424/kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2", size = 64995, upload_time = "2025-08-10T21:26:43.889Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/37/7d218ce5d92dadc5ebdd9070d903e0c7cf7edfe03f179433ac4d13ce659c/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1", size = 126510, upload_time = "2025-08-10T21:26:44.915Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/b0/e85a2b48233daef4b648fb657ebbb6f8367696a2d9548a00b4ee0eb67803/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1", size = 67903, upload_time = "2025-08-10T21:26:45.934Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/98/f2425bc0113ad7de24da6bb4dae1343476e95e1d738be7c04d31a5d037fd/kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11", size = 66402, upload_time = "2025-08-10T21:26:47.101Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/d8/594657886df9f34c4177cc353cc28ca7e6e5eb562d37ccc233bff43bbe2a/kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c", size = 1582135, upload_time = "2025-08-10T21:26:48.665Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/c6/38a115b7170f8b306fc929e166340c24958347308ea3012c2b44e7e295db/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197", size = 1389409, upload_time = "2025-08-10T21:26:50.335Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/3b/e04883dace81f24a568bcee6eb3001da4ba05114afa622ec9b6fafdc1f5e/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c", size = 1401763, upload_time = "2025-08-10T21:26:51.867Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/80/20ace48e33408947af49d7d15c341eaee69e4e0304aab4b7660e234d6288/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185", size = 1453643, upload_time = "2025-08-10T21:26:53.592Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/31/6ce4380a4cd1f515bdda976a1e90e547ccd47b67a1546d63884463c92ca9/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748", size = 2330818, upload_time = "2025-08-10T21:26:55.051Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/e9/3f3fcba3bcc7432c795b82646306e822f3fd74df0ee81f0fa067a1f95668/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64", size = 2419963, upload_time = "2025-08-10T21:26:56.421Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/43/7320c50e4133575c66e9f7dadead35ab22d7c012a3b09bb35647792b2a6d/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff", size = 2594639, upload_time = "2025-08-10T21:26:57.882Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/d6/17ae4a270d4a987ef8a385b906d2bdfc9fce502d6dc0d3aea865b47f548c/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07", size = 2391741, upload_time = "2025-08-10T21:26:59.237Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/8f/8f6f491d595a9e5912971f3f863d81baddccc8a4d0c3749d6a0dd9ffc9df/kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c", size = 68646, upload_time = "2025-08-10T21:27:00.52Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/32/6cc0fbc9c54d06c2969faa9c1d29f5751a2e51809dd55c69055e62d9b426/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386", size = 123806, upload_time = "2025-08-10T21:27:01.537Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/dd/2bfb1d4a4823d92e8cbb420fe024b8d2167f72079b3bb941207c42570bdf/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552", size = 66605, upload_time = "2025-08-10T21:27:03.335Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f7/69/00aafdb4e4509c2ca6064646cba9cd4b37933898f426756adb2cb92ebbed/kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3", size = 64925, upload_time = "2025-08-10T21:27:04.339Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/dc/51acc6791aa14e5cb6d8a2e28cefb0dc2886d8862795449d021334c0df20/kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58", size = 1472414, upload_time = "2025-08-10T21:27:05.437Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/bb/93fa64a81db304ac8a246f834d5094fae4b13baf53c839d6bb6e81177129/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4", size = 1281272, upload_time = "2025-08-10T21:27:07.063Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/e6/6df102916960fb8d05069d4bd92d6d9a8202d5a3e2444494e7cd50f65b7a/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df", size = 1298578, upload_time = "2025-08-10T21:27:08.452Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/47/e142aaa612f5343736b087864dbaebc53ea8831453fb47e7521fa8658f30/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6", size = 1345607, upload_time = "2025-08-10T21:27:10.125Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/89/d641a746194a0f4d1a3670fb900d0dbaa786fb98341056814bc3f058fa52/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5", size = 2230150, upload_time = "2025-08-10T21:27:11.484Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/6b/5ee1207198febdf16ac11f78c5ae40861b809cbe0e6d2a8d5b0b3044b199/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf", size = 2325979, upload_time = "2025-08-10T21:27:12.917Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/ff/b269eefd90f4ae14dcc74973d5a0f6d28d3b9bb1afd8c0340513afe6b39a/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5", size = 2491456, upload_time = "2025-08-10T21:27:14.353Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/d4/10303190bd4d30de547534601e259a4fbf014eed94aae3e5521129215086/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce", size = 2294621, upload_time = "2025-08-10T21:27:15.808Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/28/e0/a9a90416fce5c0be25742729c2ea52105d62eda6c4be4d803c2a7be1fa50/kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7", size = 75417, upload_time = "2025-08-10T21:27:17.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/10/6949958215b7a9a264299a7db195564e87900f709db9245e4ebdd3c70779/kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c", size = 66582, upload_time = "2025-08-10T21:27:18.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/79/60e53067903d3bc5469b369fe0dfc6b3482e2133e85dae9daa9527535991/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548", size = 126514, upload_time = "2025-08-10T21:27:19.465Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/d1/4843d3e8d46b072c12a38c97c57fab4608d36e13fe47d47ee96b4d61ba6f/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d", size = 67905, upload_time = "2025-08-10T21:27:20.51Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/ae/29ffcbd239aea8b93108de1278271ae764dfc0d803a5693914975f200596/kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c", size = 66399, upload_time = "2025-08-10T21:27:21.496Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/ae/d7ba902aa604152c2ceba5d352d7b62106bedbccc8e95c3934d94472bfa3/kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122", size = 1582197, upload_time = "2025-08-10T21:27:22.604Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/41/27c70d427eddb8bc7e4f16420a20fefc6f480312122a59a959fdfe0445ad/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64", size = 1390125, upload_time = "2025-08-10T21:27:24.036Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/42/b3799a12bafc76d962ad69083f8b43b12bf4fe78b097b12e105d75c9b8f1/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134", size = 1402612, upload_time = "2025-08-10T21:27:25.773Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/b5/a210ea073ea1cfaca1bb5c55a62307d8252f531beb364e18aa1e0888b5a0/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370", size = 1453990, upload_time = "2025-08-10T21:27:27.089Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/ce/a829eb8c033e977d7ea03ed32fb3c1781b4fa0433fbadfff29e39c676f32/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21", size = 2331601, upload_time = "2025-08-10T21:27:29.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/4b/b5e97eb142eb9cd0072dacfcdcd31b1c66dc7352b0f7c7255d339c0edf00/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a", size = 2422041, upload_time = "2025-08-10T21:27:30.754Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/be/8eb4cd53e1b85ba4edc3a9321666f12b83113a178845593307a3e7891f44/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f", size = 2594897, upload_time = "2025-08-10T21:27:32.803Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/dd/841e9a66c4715477ea0abc78da039832fbb09dac5c35c58dc4c41a407b8a/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369", size = 2391835, upload_time = "2025-08-10T21:27:34.23Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/28/4b2e5c47a0da96896fdfdb006340ade064afa1e63675d01ea5ac222b6d52/kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891", size = 79988, upload_time = "2025-08-10T21:27:35.587Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload_time = "2025-08-10T21:27:36.606Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/63/fde392691690f55b38d5dd7b3710f5353bf7a8e52de93a22968801ab8978/kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d1d9e582ad4d63062d34077a9a1e9f3c34088a2ec5135b1f7190c07cf366527", size = 60183, upload_time = "2025-08-10T21:27:37.669Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/b1/6aad34edfdb7cced27f371866f211332bba215bfd918ad3322a58f480d8b/kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:deed0c7258ceb4c44ad5ec7d9918f9f14fd05b2be86378d86cf50e63d1e7b771", size = 58675, upload_time = "2025-08-10T21:27:39.031Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9d/1a/23d855a702bb35a76faed5ae2ba3de57d323f48b1f6b17ee2176c4849463/kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a590506f303f512dff6b7f75fd2fd18e16943efee932008fe7140e5fa91d80e", size = 80277, upload_time = "2025-08-10T21:27:40.129Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/5b/5239e3c2b8fb5afa1e8508f721bb77325f740ab6994d963e61b2b7abcc1e/kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e09c2279a4d01f099f52d5c4b3d9e208e91edcbd1a175c9662a8b16e000fece9", size = 77994, upload_time = "2025-08-10T21:27:41.181Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/1c/5d4d468fb16f8410e596ed0eac02d2c68752aa7dc92997fe9d60a7147665/kiwisolver-1.4.9-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c9e7cdf45d594ee04d5be1b24dd9d49f3d1590959b2271fb30b5ca2b262c00fb", size = 73744, upload_time = "2025-08-10T21:27:42.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/0f/36d89194b5a32c054ce93e586d4049b6c2c22887b0eb229c61c68afd3078/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5", size = 60104, upload_time = "2025-08-10T21:27:43.287Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/52/ba/4ed75f59e4658fd21fe7dde1fee0ac397c678ec3befba3fe6482d987af87/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa", size = 58592, upload_time = "2025-08-10T21:27:44.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/01/a8ea7c5ea32a9b45ceeaee051a04c8ed4320f5add3c51bfa20879b765b70/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2", size = 80281, upload_time = "2025-08-10T21:27:45.369Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/e3/dbd2ecdce306f1d07a1aaf324817ee993aab7aee9db47ceac757deabafbe/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f", size = 78009, upload_time = "2025-08-10T21:27:46.376Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload_time = "2025-08-10T21:27:48.236Z" }, +] + +[[package]] +name = "maibot" +version = "0.11.6" +source = { virtual = "." } +dependencies = [ + { name = "aiohttp" }, + { name = "aiohttp-cors" }, + { name = "colorama" }, + { name = "faiss-cpu" }, + { name = "fastapi" }, + { name = "google-genai" }, + { name = "jieba" }, + { name = "json-repair" }, + { name = "maim-message" }, + { name = "matplotlib" }, + { name = "msgpack" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "openai" }, + { name = "pandas" }, + { name = "peewee" }, + { name = "pillow" }, + { name = "pyarrow" }, + { name = "pydantic" }, + { name = "pypinyin" }, + { name = "python-dotenv" }, + { name = "python-multipart" }, + { name = "quick-algo" }, + { name = "rich" }, + { name = "ruff" }, + { name = "setuptools" }, + { name = "structlog" }, + { name = "toml" }, + { name = "tomlkit" }, + { name = "urllib3" }, + { name = "uvicorn" }, + { name = "zstandard" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", specifier = ">=3.12.14" }, + { name = "aiohttp-cors", specifier = ">=0.8.1" }, + { name = "colorama", specifier = ">=0.4.6" }, + { name = "faiss-cpu", specifier = ">=1.11.0" }, + { name = "fastapi", specifier = ">=0.116.0" }, + { name = "google-genai", specifier = ">=1.39.1" }, + { name = "jieba", specifier = ">=0.42.1" }, + { name = "json-repair", specifier = ">=0.47.6" }, + { name = "maim-message" }, + { name = "matplotlib", specifier = ">=3.10.3" }, + { name = "msgpack", specifier = ">=1.1.2" }, + { name = "numpy", specifier = ">=2.2.6" }, + { name = "openai", specifier = ">=1.95.0" }, + { name = "pandas", specifier = ">=2.3.1" }, + { name = "peewee", specifier = ">=3.18.2" }, + { name = "pillow", specifier = ">=11.3.0" }, + { name = "pyarrow", specifier = ">=20.0.0" }, + { name = "pydantic", specifier = ">=2.11.7" }, + { name = "pypinyin", specifier = ">=0.54.0" }, + { name = "python-dotenv", specifier = ">=1.1.1" }, + { name = "python-multipart", specifier = ">=0.0.20" }, + { name = "quick-algo", specifier = ">=0.1.3" }, + { name = "rich", specifier = ">=14.0.0" }, + { name = "ruff", specifier = ">=0.12.2" }, + { name = "setuptools", specifier = ">=80.9.0" }, + { name = "structlog", specifier = ">=25.4.0" }, + { name = "toml", specifier = ">=0.10.2" }, + { name = "tomlkit", specifier = ">=0.13.3" }, + { name = "urllib3", specifier = ">=2.5.0" }, + { name = "uvicorn", specifier = ">=0.35.0" }, + { name = "zstandard", specifier = ">=0.25.0" }, +] + +[[package]] +name = "maim-message" +version = "0.5.7" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "cryptography" }, + { name = "fastapi" }, + { name = "pydantic" }, + { name = "uvicorn" }, + { name = "websockets" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/79/5255680b5831cafbf5e99ceb3cecdd229ebc25f6087cb719e136633dd52b/maim_message-0.5.7.tar.gz", hash = "sha256:aaf21aeff890409a53445041c6c77bbfa038672d616556eda8bf981f133f535a", size = 612184, upload_time = "2025-11-03T13:53:03.542Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/a2/9b26e4d708b77423b42c65a6db6d538a6dfb4f6e3bd4162efde0bcac7180/maim_message-0.5.7-py3-none-any.whl", hash = "sha256:3ac69ba26d68da128feaa9fff4f7d0da1b691a7bf0a7fd98c97e9fd5faac4717", size = 27808, upload_time = "2025-11-03T13:53:01.024Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload_time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload_time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.10.7" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "contourpy", version = "1.3.2", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.11'" }, + { name = "contourpy", version = "1.3.3", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/e2/d2d5295be2f44c678ebaf3544ba32d20c1f9ef08c49fe47f496180e1db15/matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7", size = 34804865, upload_time = "2025-10-09T00:28:00.669Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/87/3932d5778ab4c025db22710b61f49ccaed3956c5cf46ffb2ffa7492b06d9/matplotlib-3.10.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ac81eee3b7c266dd92cee1cd658407b16c57eed08c7421fa354ed68234de380", size = 8247141, upload_time = "2025-10-09T00:26:06.023Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/a8/bfed45339160102bce21a44e38a358a1134a5f84c26166de03fb4a53208f/matplotlib-3.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:667ecd5d8d37813a845053d8f5bf110b534c3c9f30e69ebd25d4701385935a6d", size = 8107995, upload_time = "2025-10-09T00:26:08.669Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/3c/5692a2d9a5ba848fda3f48d2b607037df96460b941a59ef236404b39776b/matplotlib-3.10.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc1c51b846aca49a5a8b44fbba6a92d583a35c64590ad9e1e950dc88940a4297", size = 8680503, upload_time = "2025-10-09T00:26:10.607Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/a0/86ace53c48b05d0e6e9c127b2ace097434901f3e7b93f050791c8243201a/matplotlib-3.10.7-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a11c2e9e72e7de09b7b72e62f3df23317c888299c875e2b778abf1eda8c0a42", size = 9514982, upload_time = "2025-10-09T00:26:12.594Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/81/ead71e2824da8f72640a64166d10e62300df4ae4db01a0bac56c5b39fa51/matplotlib-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f19410b486fdd139885ace124e57f938c1e6a3210ea13dd29cab58f5d4bc12c7", size = 9566429, upload_time = "2025-10-09T00:26:14.758Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/7d/954b3067120456f472cce8fdcacaf4a5fcd522478db0c37bb243c7cb59dd/matplotlib-3.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:b498e9e4022f93de2d5a37615200ca01297ceebbb56fe4c833f46862a490f9e3", size = 8108174, upload_time = "2025-10-09T00:26:17.015Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/bc/0fb489005669127ec13f51be0c6adc074d7cf191075dab1da9fe3b7a3cfc/matplotlib-3.10.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:53b492410a6cd66c7a471de6c924f6ede976e963c0f3097a3b7abfadddc67d0a", size = 8257507, upload_time = "2025-10-09T00:26:19.073Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/6a/d42588ad895279ff6708924645b5d2ed54a7fb2dc045c8a804e955aeace1/matplotlib-3.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9749313deb729f08207718d29c86246beb2ea3fdba753595b55901dee5d2fd6", size = 8119565, upload_time = "2025-10-09T00:26:21.023Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/b7/4aa196155b4d846bd749cf82aa5a4c300cf55a8b5e0dfa5b722a63c0f8a0/matplotlib-3.10.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2222c7ba2cbde7fe63032769f6eb7e83ab3227f47d997a8453377709b7fe3a5a", size = 8692668, upload_time = "2025-10-09T00:26:22.967Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/e7/664d2b97016f46683a02d854d730cfcf54ff92c1dafa424beebef50f831d/matplotlib-3.10.7-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e91f61a064c92c307c5a9dc8c05dc9f8a68f0a3be199d9a002a0622e13f874a1", size = 9521051, upload_time = "2025-10-09T00:26:25.041Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/a3/37aef1404efa615f49b5758a5e0261c16dd88f389bc1861e722620e4a754/matplotlib-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f1851eab59ca082c95df5a500106bad73672645625e04538b3ad0f69471ffcc", size = 9576878, upload_time = "2025-10-09T00:26:27.478Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/cd/b145f9797126f3f809d177ca378de57c45413c5099c5990de2658760594a/matplotlib-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:6516ce375109c60ceec579e699524e9d504cd7578506f01150f7a6bc174a775e", size = 8115142, upload_time = "2025-10-09T00:26:29.774Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/39/63bca9d2b78455ed497fcf51a9c71df200a11048f48249038f06447fa947/matplotlib-3.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:b172db79759f5f9bc13ef1c3ef8b9ee7b37b0247f987fbbbdaa15e4f87fd46a9", size = 7992439, upload_time = "2025-10-09T00:26:40.32Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/be/b3/09eb0f7796932826ec20c25b517d568627754f6c6462fca19e12c02f2e12/matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748", size = 8272389, upload_time = "2025-10-09T00:26:42.474Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/0b/1ae80ddafb8652fd8046cb5c8460ecc8d4afccb89e2c6d6bec61e04e1eaf/matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f", size = 8128247, upload_time = "2025-10-09T00:26:44.77Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/18/95ae2e242d4a5c98bd6e90e36e128d71cf1c7e39b0874feaed3ef782e789/matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0", size = 8696996, upload_time = "2025-10-09T00:26:46.792Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/3d/5b559efc800bd05cb2033aa85f7e13af51958136a48327f7c261801ff90a/matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695", size = 9530153, upload_time = "2025-10-09T00:26:49.07Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/57/eab4a719fd110312d3c220595d63a3c85ec2a39723f0f4e7fa7e6e3f74ba/matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65", size = 9593093, upload_time = "2025-10-09T00:26:51.067Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/3c/80816f027b3a4a28cd2a0a6ef7f89a2db22310e945cd886ec25bfb399221/matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee", size = 8122771, upload_time = "2025-10-09T00:26:53.296Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/de/77/ef1fc78bfe99999b2675435cc52120887191c566b25017d78beaabef7f2d/matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8", size = 7992812, upload_time = "2025-10-09T00:26:54.882Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f", size = 8273212, upload_time = "2025-10-09T00:26:56.752Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c", size = 8128713, upload_time = "2025-10-09T00:26:59.001Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1", size = 8698527, upload_time = "2025-10-09T00:27:00.69Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/7f/ccdca06f4c2e6c7989270ed7829b8679466682f4cfc0f8c9986241c023b6/matplotlib-3.10.7-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22df30ffaa89f6643206cf13877191c63a50e8f800b038bc39bee9d2d4957632", size = 9529690, upload_time = "2025-10-09T00:27:02.664Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/95/b80fc2c1f269f21ff3d193ca697358e24408c33ce2b106a7438a45407b63/matplotlib-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b69676845a0a66f9da30e87f48be36734d6748024b525ec4710be40194282c84", size = 9593732, upload_time = "2025-10-09T00:27:04.653Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815", size = 8122727, upload_time = "2025-10-09T00:27:06.814Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/a6/2faaf48133b82cf3607759027f82b5c702aa99cdfcefb7f93d6ccf26a424/matplotlib-3.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:fba2974df0bf8ce3c995fa84b79cde38326e0f7b5409e7a3a481c1141340bcf7", size = 7992958, upload_time = "2025-10-09T00:27:08.567Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/f0/b018fed0b599bd48d84c08794cb242227fe3341952da102ee9d9682db574/matplotlib-3.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:932c55d1fa7af4423422cb6a492a31cbcbdbe68fd1a9a3f545aa5e7a143b5355", size = 8316849, upload_time = "2025-10-09T00:27:10.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/b7/bb4f23856197659f275e11a2a164e36e65e9b48ea3e93c4ec25b4f163198/matplotlib-3.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e38c2d581d62ee729a6e144c47a71b3f42fb4187508dbbf4fe71d5612c3433b", size = 8178225, upload_time = "2025-10-09T00:27:12.241Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/56/0600609893ff277e6f3ab3c0cef4eafa6e61006c058e84286c467223d4d5/matplotlib-3.10.7-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:786656bb13c237bbcebcd402f65f44dd61ead60ee3deb045af429d889c8dbc67", size = 8711708, upload_time = "2025-10-09T00:27:13.879Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/1a/6bfecb0cafe94d6658f2f1af22c43b76cf7a1c2f0dc34ef84cbb6809617e/matplotlib-3.10.7-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d7945a70ea43bf9248f4b6582734c2fe726723204a76eca233f24cffc7ef67", size = 9541409, upload_time = "2025-10-09T00:27:15.684Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/50/95122a407d7f2e446fd865e2388a232a23f2b81934960ea802f3171518e4/matplotlib-3.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0b181e9fa8daf1d9f2d4c547527b167cb8838fc587deabca7b5c01f97199e84", size = 9594054, upload_time = "2025-10-09T00:27:17.547Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/76/75b194a43b81583478a81e78a07da8d9ca6ddf50dd0a2ccabf258059481d/matplotlib-3.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:31963603041634ce1a96053047b40961f7a29eb8f9a62e80cc2c0427aa1d22a2", size = 8200100, upload_time = "2025-10-09T00:27:20.039Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/9e/6aefebdc9f8235c12bdeeda44cc0383d89c1e41da2c400caf3ee2073a3ce/matplotlib-3.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:aebed7b50aa6ac698c90f60f854b47e48cd2252b30510e7a1feddaf5a3f72cbf", size = 8042131, upload_time = "2025-10-09T00:27:21.608Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/4b/e5bc2c321b6a7e3a75638d937d19ea267c34bd5a90e12bee76c4d7c7a0d9/matplotlib-3.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d883460c43e8c6b173fef244a2341f7f7c0e9725c7fe68306e8e44ed9c8fb100", size = 8273787, upload_time = "2025-10-09T00:27:23.27Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/ad/6efae459c56c2fbc404da154e13e3a6039129f3c942b0152624f1c621f05/matplotlib-3.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07124afcf7a6504eafcb8ce94091c5898bbdd351519a1beb5c45f7a38c67e77f", size = 8131348, upload_time = "2025-10-09T00:27:24.926Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/5a/a4284d2958dee4116359cc05d7e19c057e64ece1b4ac986ab0f2f4d52d5a/matplotlib-3.10.7-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c17398b709a6cce3d9fdb1595c33e356d91c098cd9486cb2cc21ea2ea418e715", size = 9533949, upload_time = "2025-10-09T00:27:26.704Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/de/ff/f3781b5057fa3786623ad8976fc9f7b0d02b2f28534751fd5a44240de4cf/matplotlib-3.10.7-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7146d64f561498764561e9cd0ed64fcf582e570fc519e6f521e2d0cfd43365e1", size = 9804247, upload_time = "2025-10-09T00:27:28.514Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/5a/993a59facb8444efb0e197bf55f545ee449902dcee86a4dfc580c3b61314/matplotlib-3.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90ad854c0a435da3104c01e2c6f0028d7e719b690998a2333d7218db80950722", size = 9595497, upload_time = "2025-10-09T00:27:30.418Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/a5/77c95aaa9bb32c345cbb49626ad8eb15550cba2e6d4c88081a6c2ac7b08d/matplotlib-3.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:4645fc5d9d20ffa3a39361fcdbcec731382763b623b72627806bf251b6388866", size = 8252732, upload_time = "2025-10-09T00:27:32.332Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/04/45d269b4268d222390d7817dae77b159651909669a34ee9fdee336db5883/matplotlib-3.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:9257be2f2a03415f9105c486d304a321168e61ad450f6153d77c69504ad764bb", size = 8124240, upload_time = "2025-10-09T00:27:33.94Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/c7/ca01c607bb827158b439208c153d6f14ddb9fb640768f06f7ca3488ae67b/matplotlib-3.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1e4bbad66c177a8fdfa53972e5ef8be72a5f27e6a607cec0d8579abd0f3102b1", size = 8316938, upload_time = "2025-10-09T00:27:35.534Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/d2/5539e66e9f56d2fdec94bb8436f5e449683b4e199bcc897c44fbe3c99e28/matplotlib-3.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8eb7194b084b12feb19142262165832fc6ee879b945491d1c3d4660748020c4", size = 8178245, upload_time = "2025-10-09T00:27:37.334Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/77/b5/e6ca22901fd3e4fe433a82e583436dd872f6c966fca7e63cf806b40356f8/matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d41379b05528091f00e1728004f9a8d7191260f3862178b88e8fd770206318", size = 9541411, upload_time = "2025-10-09T00:27:39.387Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/99/a4524db57cad8fee54b7237239a8f8360bfcfa3170d37c9e71c090c0f409/matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a74f79fafb2e177f240579bc83f0b60f82cc47d2f1d260f422a0627207008ca", size = 9803664, upload_time = "2025-10-09T00:27:41.492Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/a5/85e2edf76ea0ad4288d174926d9454ea85f3ce5390cc4e6fab196cbf250b/matplotlib-3.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:702590829c30aada1e8cef0568ddbffa77ca747b4d6e36c6d173f66e301f89cc", size = 9594066, upload_time = "2025-10-09T00:27:43.694Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/69/9684368a314f6d83fe5c5ad2a4121a3a8e03723d2e5c8ea17b66c1bad0e7/matplotlib-3.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:f79d5de970fc90cd5591f60053aecfce1fcd736e0303d9f0bf86be649fa68fb8", size = 8342832, upload_time = "2025-10-09T00:27:45.543Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/5f/e22e08da14bc1a0894184640d47819d2338b792732e20d292bf86e5ab785/matplotlib-3.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:cb783436e47fcf82064baca52ce748af71725d0352e1d31564cbe9c95df92b9c", size = 8172585, upload_time = "2025-10-09T00:27:47.185Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/6c/a9bcf03e9afb2a873e0a5855f79bce476d1023f26f8212969f2b7504756c/matplotlib-3.10.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5c09cf8f2793f81368f49f118b6f9f937456362bee282eac575cca7f84cda537", size = 8241204, upload_time = "2025-10-09T00:27:48.806Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/fd/0e6f5aa762ed689d9fa8750b08f1932628ffa7ed30e76423c399d19407d2/matplotlib-3.10.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:de66744b2bb88d5cd27e80dfc2ec9f0517d0a46d204ff98fe9e5f2864eb67657", size = 8104607, upload_time = "2025-10-09T00:27:50.876Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/a9/21c9439d698fac5f0de8fc68b2405b738ed1f00e1279c76f2d9aa5521ead/matplotlib-3.10.7-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53cc80662dd197ece414dd5b66e07370201515a3eaf52e7c518c68c16814773b", size = 8682257, upload_time = "2025-10-09T00:27:52.597Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/8f/76d5dc21ac64a49e5498d7f0472c0781dae442dd266a67458baec38288ec/matplotlib-3.10.7-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:15112bcbaef211bd663fa935ec33313b948e214454d949b723998a43357b17b0", size = 8252283, upload_time = "2025-10-09T00:27:54.739Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/0d/9c5d4c2317feb31d819e38c9f947c942f42ebd4eb935fc6fd3518a11eaa7/matplotlib-3.10.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d2a959c640cdeecdd2ec3136e8ea0441da59bcaf58d67e9c590740addba2cb68", size = 8116733, upload_time = "2025-10-09T00:27:56.406Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/cc/3fe688ff1355010937713164caacf9ed443675ac48a997bab6ed23b3f7c0/matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91", size = 8693919, upload_time = "2025-10-09T00:27:58.41Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload_time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload_time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "msgpack" +version = "1.1.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e", size = 173581, upload_time = "2025-10-08T09:15:56.596Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/a2/3b68a9e769db68668b25c6108444a35f9bd163bb848c0650d516761a59c0/msgpack-1.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2", size = 81318, upload_time = "2025-10-08T09:14:38.722Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/e1/2b720cc341325c00be44e1ed59e7cfeae2678329fbf5aa68f5bda57fe728/msgpack-1.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87", size = 83786, upload_time = "2025-10-08T09:14:40.082Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/e5/c2241de64bfceac456b140737812a2ab310b10538a7b34a1d393b748e095/msgpack-1.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251", size = 398240, upload_time = "2025-10-08T09:14:41.151Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/09/2a06956383c0fdebaef5aa9246e2356776f12ea6f2a44bd1368abf0e46c4/msgpack-1.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a", size = 406070, upload_time = "2025-10-08T09:14:42.821Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/74/2957703f0e1ef20637d6aead4fbb314330c26f39aa046b348c7edcf6ca6b/msgpack-1.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f", size = 393403, upload_time = "2025-10-08T09:14:44.38Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/09/3bfc12aa90f77b37322fc33e7a8a7c29ba7c8edeadfa27664451801b9860/msgpack-1.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f", size = 398947, upload_time = "2025-10-08T09:14:45.56Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/4f/05fcebd3b4977cb3d840f7ef6b77c51f8582086de5e642f3fefee35c86fc/msgpack-1.1.2-cp310-cp310-win32.whl", hash = "sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9", size = 64769, upload_time = "2025-10-08T09:14:47.334Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/3e/b4547e3a34210956382eed1c85935fff7e0f9b98be3106b3745d7dec9c5e/msgpack-1.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa", size = 71293, upload_time = "2025-10-08T09:14:48.665Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c", size = 82271, upload_time = "2025-10-08T09:14:49.967Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0", size = 84914, upload_time = "2025-10-08T09:14:50.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/46/b817349db6886d79e57a966346cf0902a426375aadc1e8e7a86a75e22f19/msgpack-1.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296", size = 416962, upload_time = "2025-10-08T09:14:51.997Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef", size = 426183, upload_time = "2025-10-08T09:14:53.477Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/98/6a19f030b3d2ea906696cedd1eb251708e50a5891d0978b012cb6107234c/msgpack-1.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c", size = 411454, upload_time = "2025-10-08T09:14:54.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/cd/9098fcb6adb32187a70b7ecaabf6339da50553351558f37600e53a4a2a23/msgpack-1.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e", size = 422341, upload_time = "2025-10-08T09:14:56.328Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/ae/270cecbcf36c1dc85ec086b33a51a4d7d08fc4f404bdbc15b582255d05ff/msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e", size = 64747, upload_time = "2025-10-08T09:14:57.882Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68", size = 71633, upload_time = "2025-10-08T09:14:59.177Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/4d/7c4e2b3d9b1106cd0aa6cb56cc57c6267f59fa8bfab7d91df5adc802c847/msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406", size = 64755, upload_time = "2025-10-08T09:15:00.48Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ad/bd/8b0d01c756203fbab65d265859749860682ccd2a59594609aeec3a144efa/msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa", size = 81939, upload_time = "2025-10-08T09:15:01.472Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/68/ba4f155f793a74c1483d4bdef136e1023f7bcba557f0db4ef3db3c665cf1/msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb", size = 85064, upload_time = "2025-10-08T09:15:03.764Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/60/a064b0345fc36c4c3d2c743c82d9100c40388d77f0b48b2f04d6041dbec1/msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f", size = 417131, upload_time = "2025-10-08T09:15:05.136Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/92/a5100f7185a800a5d29f8d14041f61475b9de465ffcc0f3b9fba606e4505/msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42", size = 427556, upload_time = "2025-10-08T09:15:06.837Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/87/ffe21d1bf7d9991354ad93949286f643b2bb6ddbeab66373922b44c3b8cc/msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9", size = 404920, upload_time = "2025-10-08T09:15:08.179Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/41/8543ed2b8604f7c0d89ce066f42007faac1eaa7d79a81555f206a5cdb889/msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620", size = 415013, upload_time = "2025-10-08T09:15:09.83Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/0d/2ddfaa8b7e1cee6c490d46cb0a39742b19e2481600a7a0e96537e9c22f43/msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029", size = 65096, upload_time = "2025-10-08T09:15:11.11Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/ec/d431eb7941fb55a31dd6ca3404d41fbb52d99172df2e7707754488390910/msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b", size = 72708, upload_time = "2025-10-08T09:15:12.554Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/31/5b1a1f70eb0e87d1678e9624908f86317787b536060641d6798e3cf70ace/msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69", size = 64119, upload_time = "2025-10-08T09:15:13.589Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf", size = 81212, upload_time = "2025-10-08T09:15:14.552Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7", size = 84315, upload_time = "2025-10-08T09:15:15.543Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/68/93180dce57f684a61a88a45ed13047558ded2be46f03acb8dec6d7c513af/msgpack-1.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999", size = 412721, upload_time = "2025-10-08T09:15:16.567Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e", size = 424657, upload_time = "2025-10-08T09:15:17.825Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/f8/4398c46863b093252fe67368b44edc6c13b17f4e6b0e4929dbf0bdb13f23/msgpack-1.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162", size = 402668, upload_time = "2025-10-08T09:15:19.003Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/28/ce/698c1eff75626e4124b4d78e21cca0b4cc90043afb80a507626ea354ab52/msgpack-1.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794", size = 419040, upload_time = "2025-10-08T09:15:20.183Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/32/f3cd1667028424fa7001d82e10ee35386eea1408b93d399b09fb0aa7875f/msgpack-1.1.2-cp313-cp313-win32.whl", hash = "sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c", size = 65037, upload_time = "2025-10-08T09:15:21.416Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9", size = 72631, upload_time = "2025-10-08T09:15:22.431Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/db/0314e4e2db56ebcf450f277904ffd84a7988b9e5da8d0d61ab2d057df2b6/msgpack-1.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84", size = 64118, upload_time = "2025-10-08T09:15:23.402Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00", size = 81127, upload_time = "2025-10-08T09:15:24.408Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939", size = 84981, upload_time = "2025-10-08T09:15:25.812Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/a9/3536e385167b88c2cc8f4424c49e28d49a6fc35206d4a8060f136e71f94c/msgpack-1.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e", size = 411885, upload_time = "2025-10-08T09:15:27.22Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931", size = 419658, upload_time = "2025-10-08T09:15:28.4Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3b/ef/2b92e286366500a09a67e03496ee8b8ba00562797a52f3c117aa2b29514b/msgpack-1.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014", size = 403290, upload_time = "2025-10-08T09:15:29.764Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/90/e0ea7990abea5764e4655b8177aa7c63cdfa89945b6e7641055800f6c16b/msgpack-1.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2", size = 415234, upload_time = "2025-10-08T09:15:31.022Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/4e/9390aed5db983a2310818cd7d3ec0aecad45e1f7007e0cda79c79507bb0d/msgpack-1.1.2-cp314-cp314-win32.whl", hash = "sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717", size = 66391, upload_time = "2025-10-08T09:15:32.265Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/f1/abd09c2ae91228c5f3998dbd7f41353def9eac64253de3c8105efa2082f7/msgpack-1.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b", size = 73787, upload_time = "2025-10-08T09:15:33.219Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/b0/9d9f667ab48b16ad4115c1935d94023b82b3198064cb84a123e97f7466c1/msgpack-1.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af", size = 66453, upload_time = "2025-10-08T09:15:34.225Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/67/93f80545eb1792b61a217fa7f06d5e5cb9e0055bed867f43e2b8e012e137/msgpack-1.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a", size = 85264, upload_time = "2025-10-08T09:15:35.61Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/1c/33c8a24959cf193966ef11a6f6a2995a65eb066bd681fd085afd519a57ce/msgpack-1.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b", size = 89076, upload_time = "2025-10-08T09:15:36.619Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/6b/62e85ff7193663fbea5c0254ef32f0c77134b4059f8da89b958beb7696f3/msgpack-1.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245", size = 435242, upload_time = "2025-10-08T09:15:37.647Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/47/5c74ecb4cc277cf09f64e913947871682ffa82b3b93c8dad68083112f412/msgpack-1.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90", size = 432509, upload_time = "2025-10-08T09:15:38.794Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/a4/e98ccdb56dc4e98c929a3f150de1799831c0a800583cde9fa022fa90602d/msgpack-1.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20", size = 415957, upload_time = "2025-10-08T09:15:40.238Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/28/6951f7fb67bc0a4e184a6b38ab71a92d9ba58080b27a77d3e2fb0be5998f/msgpack-1.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27", size = 422910, upload_time = "2025-10-08T09:15:41.505Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/03/42106dcded51f0a0b5284d3ce30a671e7bd3f7318d122b2ead66ad289fed/msgpack-1.1.2-cp314-cp314t-win32.whl", hash = "sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b", size = 75197, upload_time = "2025-10-08T09:15:42.954Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/86/d0071e94987f8db59d4eeb386ddc64d0bb9b10820a8d82bcd3e53eeb2da6/msgpack-1.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff", size = 85772, upload_time = "2025-10-08T09:15:43.954Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/81/f2/08ace4142eb281c12701fc3b93a10795e4d4dc7f753911d836675050f886/msgpack-1.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46", size = 70868, upload_time = "2025-10-08T09:15:44.959Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload_time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/63/7bdd4adc330abcca54c85728db2327130e49e52e8c3ce685cec44e0f2e9f/multidict-6.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349", size = 77153, upload_time = "2025-10-06T14:48:26.409Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/bb/b6c35ff175ed1a3142222b78455ee31be71a8396ed3ab5280fbe3ebe4e85/multidict-6.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e", size = 44993, upload_time = "2025-10-06T14:48:28.4Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/1f/064c77877c5fa6df6d346e68075c0f6998547afe952d6471b4c5f6a7345d/multidict-6.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3", size = 44607, upload_time = "2025-10-06T14:48:29.581Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/7a/bf6aa92065dd47f287690000b3d7d332edfccb2277634cadf6a810463c6a/multidict-6.7.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046", size = 241847, upload_time = "2025-10-06T14:48:32.107Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/39/297a8de920f76eda343e4ce05f3b489f0ab3f9504f2576dfb37b7c08ca08/multidict-6.7.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32", size = 242616, upload_time = "2025-10-06T14:48:34.054Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/3a/d0eee2898cfd9d654aea6cb8c4addc2f9756e9a7e09391cfe55541f917f7/multidict-6.7.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73", size = 222333, upload_time = "2025-10-06T14:48:35.9Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/48/3b328851193c7a4240815b71eea165b49248867bbb6153a0aee227a0bb47/multidict-6.7.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc", size = 253239, upload_time = "2025-10-06T14:48:37.302Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/ca/0706a98c8d126a89245413225ca4a3fefc8435014de309cf8b30acb68841/multidict-6.7.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62", size = 251618, upload_time = "2025-10-06T14:48:38.963Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5e/4f/9c7992f245554d8b173f6f0a048ad24b3e645d883f096857ec2c0822b8bd/multidict-6.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84", size = 241655, upload_time = "2025-10-06T14:48:40.312Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/79/26a85991ae67efd1c0b1fc2e0c275b8a6aceeb155a68861f63f87a798f16/multidict-6.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0", size = 239245, upload_time = "2025-10-06T14:48:41.848Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/1e/75fa96394478930b79d0302eaf9a6c69f34005a1a5251ac8b9c336486ec9/multidict-6.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e", size = 233523, upload_time = "2025-10-06T14:48:43.749Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/5e/085544cb9f9c4ad2b5d97467c15f856df8d9bac410cffd5c43991a5d878b/multidict-6.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4", size = 243129, upload_time = "2025-10-06T14:48:45.225Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/c3/e9d9e2f20c9474e7a8fcef28f863c5cbd29bb5adce6b70cebe8bdad0039d/multidict-6.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648", size = 248999, upload_time = "2025-10-06T14:48:46.703Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/3f/df171b6efa3239ae33b97b887e42671cd1d94d460614bfb2c30ffdab3b95/multidict-6.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111", size = 243711, upload_time = "2025-10-06T14:48:48.146Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/2f/9b5564888c4e14b9af64c54acf149263721a283aaf4aa0ae89b091d5d8c1/multidict-6.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36", size = 237504, upload_time = "2025-10-06T14:48:49.447Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/3a/0bd6ca0f7d96d790542d591c8c3354c1e1b6bfd2024d4d92dc3d87485ec7/multidict-6.7.0-cp310-cp310-win32.whl", hash = "sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85", size = 41422, upload_time = "2025-10-06T14:48:50.789Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/35/f6a637ea2c75f0d3b7c7d41b1189189acff0d9deeb8b8f35536bb30f5e33/multidict-6.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7", size = 46050, upload_time = "2025-10-06T14:48:51.938Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/b8/f7bf8329b39893d02d9d95cf610c75885d12fc0f402b1c894e1c8e01c916/multidict-6.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0", size = 43153, upload_time = "2025-10-06T14:48:53.146Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/9e/5c727587644d67b2ed479041e4b1c58e30afc011e3d45d25bbe35781217c/multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc", size = 76604, upload_time = "2025-10-06T14:48:54.277Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/e4/67b5c27bd17c085a5ea8f1ec05b8a3e5cba0ca734bfcad5560fb129e70ca/multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721", size = 44715, upload_time = "2025-10-06T14:48:55.445Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/e1/866a5d77be6ea435711bef2a4291eed11032679b6b28b56b4776ab06ba3e/multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6", size = 44332, upload_time = "2025-10-06T14:48:56.706Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/61/0c2d50241ada71ff61a79518db85ada85fdabfcf395d5968dae1cbda04e5/multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c", size = 245212, upload_time = "2025-10-06T14:48:58.042Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/e0/919666a4e4b57fff1b57f279be1c9316e6cdc5de8a8b525d76f6598fefc7/multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7", size = 246671, upload_time = "2025-10-06T14:49:00.004Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/cc/d027d9c5a520f3321b65adea289b965e7bcbd2c34402663f482648c716ce/multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7", size = 225491, upload_time = "2025-10-06T14:49:01.393Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/c4/bbd633980ce6155a28ff04e6a6492dd3335858394d7bb752d8b108708558/multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9", size = 257322, upload_time = "2025-10-06T14:49:02.745Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/6d/d622322d344f1f053eae47e033b0b3f965af01212de21b10bcf91be991fb/multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8", size = 254694, upload_time = "2025-10-06T14:49:04.15Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/9f/78f8761c2705d4c6d7516faed63c0ebdac569f6db1bef95e0d5218fdc146/multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd", size = 246715, upload_time = "2025-10-06T14:49:05.967Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/59/950818e04f91b9c2b95aab3d923d9eabd01689d0dcd889563988e9ea0fd8/multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb", size = 243189, upload_time = "2025-10-06T14:49:07.37Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/3d/77c79e1934cad2ee74991840f8a0110966d9599b3af95964c0cd79bb905b/multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6", size = 237845, upload_time = "2025-10-06T14:49:08.759Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/1b/834ce32a0a97a3b70f86437f685f880136677ac00d8bce0027e9fd9c2db7/multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2", size = 246374, upload_time = "2025-10-06T14:49:10.574Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/ef/43d1c3ba205b5dec93dc97f3fba179dfa47910fc73aaaea4f7ceb41cec2a/multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff", size = 253345, upload_time = "2025-10-06T14:49:12.331Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/03/eaf95bcc2d19ead522001f6a650ef32811aa9e3624ff0ad37c445c7a588c/multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b", size = 246940, upload_time = "2025-10-06T14:49:13.821Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/df/ec8a5fd66ea6cd6f525b1fcbb23511b033c3e9bc42b81384834ffa484a62/multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34", size = 242229, upload_time = "2025-10-06T14:49:15.603Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/a2/59b405d59fd39ec86d1142630e9049243015a5f5291ba49cadf3c090c541/multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff", size = 41308, upload_time = "2025-10-06T14:49:16.871Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/0f/13228f26f8b882c34da36efa776c3b7348455ec383bab4a66390e42963ae/multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81", size = 46037, upload_time = "2025-10-06T14:49:18.457Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/1f/68588e31b000535a3207fd3c909ebeec4fb36b52c442107499c18a896a2a/multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912", size = 43023, upload_time = "2025-10-06T14:49:19.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload_time = "2025-10-06T14:49:20.884Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload_time = "2025-10-06T14:49:22.054Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload_time = "2025-10-06T14:49:23.566Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload_time = "2025-10-06T14:49:24.882Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload_time = "2025-10-06T14:49:26.778Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload_time = "2025-10-06T14:49:28.562Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload_time = "2025-10-06T14:49:29.96Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload_time = "2025-10-06T14:49:31.404Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload_time = "2025-10-06T14:49:32.974Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload_time = "2025-10-06T14:49:34.52Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload_time = "2025-10-06T14:49:35.956Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload_time = "2025-10-06T14:49:37.631Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload_time = "2025-10-06T14:49:39.502Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload_time = "2025-10-06T14:49:41.32Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload_time = "2025-10-06T14:49:46.021Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload_time = "2025-10-06T14:49:48.718Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload_time = "2025-10-06T14:49:50.28Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload_time = "2025-10-06T14:49:52.304Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload_time = "2025-10-06T14:49:54.26Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload_time = "2025-10-06T14:49:55.82Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload_time = "2025-10-06T14:49:57.048Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload_time = "2025-10-06T14:49:58.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload_time = "2025-10-06T14:49:59.89Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload_time = "2025-10-06T14:50:01.485Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload_time = "2025-10-06T14:50:02.955Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload_time = "2025-10-06T14:50:04.446Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload_time = "2025-10-06T14:50:05.98Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload_time = "2025-10-06T14:50:07.511Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload_time = "2025-10-06T14:50:09.074Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload_time = "2025-10-06T14:50:10.714Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload_time = "2025-10-06T14:50:12.28Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload_time = "2025-10-06T14:50:14.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload_time = "2025-10-06T14:50:15.639Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload_time = "2025-10-06T14:50:17.066Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload_time = "2025-10-06T14:50:18.264Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload_time = "2025-10-06T14:50:19.853Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload_time = "2025-10-06T14:50:21.223Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload_time = "2025-10-06T14:50:22.871Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload_time = "2025-10-06T14:50:24.258Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload_time = "2025-10-06T14:50:25.716Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload_time = "2025-10-06T14:50:28.192Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload_time = "2025-10-06T14:50:29.82Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload_time = "2025-10-06T14:50:31.731Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload_time = "2025-10-06T14:50:33.26Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload_time = "2025-10-06T14:50:34.808Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload_time = "2025-10-06T14:50:36.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload_time = "2025-10-06T14:50:37.953Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload_time = "2025-10-06T14:50:39.574Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload_time = "2025-10-06T14:50:41.612Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload_time = "2025-10-06T14:50:43.972Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload_time = "2025-10-06T14:50:45.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload_time = "2025-10-06T14:50:47.154Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload_time = "2025-10-06T14:50:48.851Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload_time = "2025-10-06T14:50:50.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload_time = "2025-10-06T14:50:51.92Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload_time = "2025-10-06T14:50:53.275Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload_time = "2025-10-06T14:50:54.911Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload_time = "2025-10-06T14:50:56.369Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload_time = "2025-10-06T14:50:57.991Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload_time = "2025-10-06T14:50:59.589Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload_time = "2025-10-06T14:51:01.183Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload_time = "2025-10-06T14:51:02.794Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload_time = "2025-10-06T14:51:04.724Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload_time = "2025-10-06T14:51:06.306Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload_time = "2025-10-06T14:51:08.091Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload_time = "2025-10-06T14:51:10.365Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload_time = "2025-10-06T14:51:12.466Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload_time = "2025-10-06T14:51:14.48Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload_time = "2025-10-06T14:51:16.072Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload_time = "2025-10-06T14:51:17.544Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload_time = "2025-10-06T14:51:18.875Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload_time = "2025-10-06T14:51:20.225Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload_time = "2025-10-06T14:51:21.588Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload_time = "2025-10-06T14:51:22.93Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload_time = "2025-10-06T14:51:24.352Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload_time = "2025-10-06T14:51:25.822Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload_time = "2025-10-06T14:51:27.604Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload_time = "2025-10-06T14:51:29.664Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload_time = "2025-10-06T14:51:31.684Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload_time = "2025-10-06T14:51:33.699Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload_time = "2025-10-06T14:51:36.189Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload_time = "2025-10-06T14:51:41.291Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload_time = "2025-10-06T14:51:43.55Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload_time = "2025-10-06T14:51:45.265Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload_time = "2025-10-06T14:51:46.836Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload_time = "2025-10-06T14:51:48.541Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload_time = "2025-10-06T14:51:50.355Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload_time = "2025-10-06T14:51:51.883Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload_time = "2025-10-06T14:51:53.672Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload_time = "2025-10-06T14:51:55.415Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload_time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload_time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload_time = "2025-05-17T21:27:58.555Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload_time = "2025-05-17T21:28:21.406Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload_time = "2025-05-17T21:28:30.931Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload_time = "2025-05-17T21:28:41.613Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload_time = "2025-05-17T21:29:02.78Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload_time = "2025-05-17T21:29:27.675Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload_time = "2025-05-17T21:29:51.102Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload_time = "2025-05-17T21:30:18.703Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload_time = "2025-05-17T21:30:29.788Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload_time = "2025-05-17T21:30:48.994Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload_time = "2025-05-17T21:31:19.36Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload_time = "2025-05-17T21:31:41.087Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload_time = "2025-05-17T21:31:50.072Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload_time = "2025-05-17T21:32:01.712Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload_time = "2025-05-17T21:32:23.332Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload_time = "2025-05-17T21:32:47.991Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload_time = "2025-05-17T21:33:11.728Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload_time = "2025-05-17T21:33:39.139Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload_time = "2025-05-17T21:33:50.273Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload_time = "2025-05-17T21:34:09.135Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload_time = "2025-05-17T21:34:39.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload_time = "2025-05-17T21:35:01.241Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload_time = "2025-05-17T21:35:10.622Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload_time = "2025-05-17T21:35:21.414Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload_time = "2025-05-17T21:35:42.174Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload_time = "2025-05-17T21:36:06.711Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload_time = "2025-05-17T21:36:29.965Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload_time = "2025-05-17T21:36:56.883Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload_time = "2025-05-17T21:37:07.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload_time = "2025-05-17T21:37:26.213Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload_time = "2025-05-17T21:37:56.699Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload_time = "2025-05-17T21:38:18.291Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload_time = "2025-05-17T21:38:27.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload_time = "2025-05-17T21:38:38.141Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload_time = "2025-05-17T21:38:58.433Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload_time = "2025-05-17T21:39:22.638Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload_time = "2025-05-17T21:39:45.865Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload_time = "2025-05-17T21:40:13.331Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload_time = "2025-05-17T21:43:46.099Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload_time = "2025-05-17T21:44:05.145Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload_time = "2025-05-17T21:40:44Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload_time = "2025-05-17T21:41:05.695Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload_time = "2025-05-17T21:41:15.903Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload_time = "2025-05-17T21:41:27.321Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload_time = "2025-05-17T21:41:49.738Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload_time = "2025-05-17T21:42:14.046Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload_time = "2025-05-17T21:42:37.464Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload_time = "2025-05-17T21:43:05.189Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload_time = "2025-05-17T21:43:16.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload_time = "2025-05-17T21:43:35.479Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload_time = "2025-05-17T21:44:35.948Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload_time = "2025-05-17T21:44:47.446Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload_time = "2025-05-17T21:45:11.871Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload_time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload_time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/77/84dd1d2e34d7e2792a236ba180b5e8fcc1e3e414e761ce0253f63d7f572e/numpy-2.3.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:de5672f4a7b200c15a4127042170a694d4df43c992948f5e1af57f0174beed10", size = 17034641, upload_time = "2025-11-16T22:49:19.336Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/ea/25e26fa5837106cde46ae7d0b667e20f69cbbc0efd64cba8221411ab26ae/numpy-2.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:acfd89508504a19ed06ef963ad544ec6664518c863436306153e13e94605c218", size = 12528324, upload_time = "2025-11-16T22:49:22.582Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/1a/e85f0eea4cf03d6a0228f5c0256b53f2df4bc794706e7df019fc622e47f1/numpy-2.3.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:ffe22d2b05504f786c867c8395de703937f934272eb67586817b46188b4ded6d", size = 5356872, upload_time = "2025-11-16T22:49:25.408Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/bb/35ef04afd567f4c989c2060cde39211e4ac5357155c1833bcd1166055c61/numpy-2.3.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:872a5cf366aec6bb1147336480fef14c9164b154aeb6542327de4970282cd2f5", size = 6893148, upload_time = "2025-11-16T22:49:27.549Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/2b/05bbeb06e2dff5eab512dfc678b1cc5ee94d8ac5956a0885c64b6b26252b/numpy-2.3.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3095bdb8dd297e5920b010e96134ed91d852d81d490e787beca7e35ae1d89cf7", size = 14557282, upload_time = "2025-11-16T22:49:30.964Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/fb/2b23769462b34398d9326081fad5655198fcf18966fcb1f1e49db44fbf31/numpy-2.3.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cba086a43d54ca804ce711b2a940b16e452807acebe7852ff327f1ecd49b0d4", size = 16897903, upload_time = "2025-11-16T22:49:34.191Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/14/085f4cf05fc3f1e8aa95e85404e984ffca9b2275a5dc2b1aae18a67538b8/numpy-2.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6cf9b429b21df6b99f4dee7a1218b8b7ffbbe7df8764dc0bd60ce8a0708fed1e", size = 16341672, upload_time = "2025-11-16T22:49:37.2Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/3b/1f73994904142b2aa290449b3bb99772477b5fd94d787093e4f24f5af763/numpy-2.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:396084a36abdb603546b119d96528c2f6263921c50df3c8fd7cb28873a237748", size = 18838896, upload_time = "2025-11-16T22:49:39.727Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/b9/cf6649b2124f288309ffc353070792caf42ad69047dcc60da85ee85fea58/numpy-2.3.5-cp311-cp311-win32.whl", hash = "sha256:b0c7088a73aef3d687c4deef8452a3ac7c1be4e29ed8bf3b366c8111128ac60c", size = 6563608, upload_time = "2025-11-16T22:49:42.079Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/44/9fe81ae1dcc29c531843852e2874080dc441338574ccc4306b39e2ff6e59/numpy-2.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:a414504bef8945eae5f2d7cb7be2d4af77c5d1cb5e20b296c2c25b61dff2900c", size = 13078442, upload_time = "2025-11-16T22:49:43.99Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/a7/f99a41553d2da82a20a2f22e93c94f928e4490bb447c9ff3c4ff230581d3/numpy-2.3.5-cp311-cp311-win_arm64.whl", hash = "sha256:0cd00b7b36e35398fa2d16af7b907b65304ef8bb4817a550e06e5012929830fa", size = 10458555, upload_time = "2025-11-16T22:49:47.092Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload_time = "2025-11-16T22:49:49.84Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload_time = "2025-11-16T22:49:52.863Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload_time = "2025-11-16T22:49:55.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload_time = "2025-11-16T22:49:57.371Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload_time = "2025-11-16T22:49:59.632Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload_time = "2025-11-16T22:50:02.127Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload_time = "2025-11-16T22:50:04.536Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload_time = "2025-11-16T22:50:07.557Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload_time = "2025-11-16T22:50:10.746Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload_time = "2025-11-16T22:50:12.811Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload_time = "2025-11-16T22:50:16.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload_time = "2025-11-16T22:50:19.013Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload_time = "2025-11-16T22:50:21.487Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload_time = "2025-11-16T22:50:24.562Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload_time = "2025-11-16T22:50:26.47Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload_time = "2025-11-16T22:50:28.861Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload_time = "2025-11-16T22:50:31.56Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload_time = "2025-11-16T22:50:34.242Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload_time = "2025-11-16T22:50:37.651Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload_time = "2025-11-16T22:50:40.11Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload_time = "2025-11-16T22:50:42.503Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload_time = "2025-11-16T22:50:44.971Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload_time = "2025-11-16T22:50:47.715Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload_time = "2025-11-16T22:50:51.327Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload_time = "2025-11-16T22:50:54.542Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload_time = "2025-11-16T22:50:56.794Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload_time = "2025-11-16T22:50:59.208Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload_time = "2025-11-16T22:51:01.991Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload_time = "2025-11-16T22:51:05.291Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload_time = "2025-11-16T22:51:08.585Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload_time = "2025-11-16T22:51:11.541Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload_time = "2025-11-16T22:51:14.312Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload_time = "2025-11-16T22:51:16.846Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload_time = "2025-11-16T22:51:19.558Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload_time = "2025-11-16T22:51:22.492Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload_time = "2025-11-16T22:51:25.171Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload_time = "2025-11-16T22:51:27Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload_time = "2025-11-16T22:51:29.402Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload_time = "2025-11-16T22:51:32.167Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload_time = "2025-11-16T22:51:35.403Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload_time = "2025-11-16T22:51:39.698Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload_time = "2025-11-16T22:51:42.476Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload_time = "2025-11-16T22:51:45.275Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload_time = "2025-11-16T22:51:47.749Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload_time = "2025-11-16T22:51:50.443Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload_time = "2025-11-16T22:51:53.609Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload_time = "2025-11-16T22:51:56.213Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload_time = "2025-11-16T22:51:58.584Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload_time = "2025-11-16T22:52:01.698Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload_time = "2025-11-16T22:52:04.267Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload_time = "2025-11-16T22:52:08.651Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload_time = "2025-11-16T22:52:11.453Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload_time = "2025-11-16T22:52:14.641Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload_time = "2025-11-16T22:52:17.975Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload_time = "2025-11-16T22:52:20.55Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/65/f9dea8e109371ade9c782b4e4756a82edf9d3366bca495d84d79859a0b79/numpy-2.3.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f0963b55cdd70fad460fa4c1341f12f976bb26cb66021a5580329bd498988310", size = 16910689, upload_time = "2025-11-16T22:52:23.247Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/4f/edb00032a8fb92ec0a679d3830368355da91a69cab6f3e9c21b64d0bb986/numpy-2.3.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f4255143f5160d0de972d28c8f9665d882b5f61309d8362fdd3e103cf7bf010c", size = 12457053, upload_time = "2025-11-16T22:52:26.367Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/a4/e8a53b5abd500a63836a29ebe145fc1ab1f2eefe1cfe59276020373ae0aa/numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:a4b9159734b326535f4dd01d947f919c6eefd2d9827466a696c44ced82dfbc18", size = 5285635, upload_time = "2025-11-16T22:52:29.266Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/2f/37eeb9014d9c8b3e9c55bc599c68263ca44fdbc12a93e45a21d1d56df737/numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2feae0d2c91d46e59fcd62784a3a83b3fb677fead592ce51b5a6fbb4f95965ff", size = 6801770, upload_time = "2025-11-16T22:52:31.421Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/e4/68d2f474df2cb671b2b6c2986a02e520671295647dad82484cde80ca427b/numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffac52f28a7849ad7576293c0cb7b9f08304e8f7d738a8cb8a90ec4c55a998eb", size = 14391768, upload_time = "2025-11-16T22:52:33.593Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/50/94ccd8a2b141cb50651fddd4f6a48874acb3c91c8f0842b08a6afc4b0b21/numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63c0e9e7eea69588479ebf4a8a270d5ac22763cc5854e9a7eae952a3908103f7", size = 16729263, upload_time = "2025-11-16T22:52:36.369Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/ee/346fa473e666fe14c52fcdd19ec2424157290a032d4c41f98127bfb31ac7/numpy-2.3.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f16417ec91f12f814b10bafe79ef77e70113a2f5f7018640e7425ff979253425", size = 12967213, upload_time = "2025-11-16T22:52:39.38Z" }, +] + +[[package]] +name = "openai" +version = "2.9.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/48/516290f38745cc1e72856f50e8afed4a7f9ac396a5a18f39e892ab89dfc2/openai-2.9.0.tar.gz", hash = "sha256:b52ec65727fc8f1eed2fbc86c8eac0998900c7ef63aa2eb5c24b69717c56fa5f", size = 608202, upload_time = "2025-12-04T18:15:09.01Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/fd/ae2da789cd923dd033c99b8d544071a827c92046b150db01cfa5cea5b3fd/openai-2.9.0-py3-none-any.whl", hash = "sha256:0d168a490fbb45630ad508a6f3022013c155a68fd708069b6a1a01a5e8f0ffad", size = 1030836, upload_time = "2025-12-04T18:15:07.063Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload_time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload_time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload_time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763, upload_time = "2025-09-29T23:16:53.287Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217, upload_time = "2025-09-29T23:17:04.522Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791, upload_time = "2025-09-29T23:17:18.444Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373, upload_time = "2025-09-29T23:17:35.846Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444, upload_time = "2025-09-29T23:17:49.341Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459, upload_time = "2025-09-29T23:18:03.722Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086, upload_time = "2025-09-29T23:18:18.505Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload_time = "2025-09-29T23:18:30.065Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload_time = "2025-09-29T23:38:56.071Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload_time = "2025-09-29T23:18:41.627Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload_time = "2025-09-29T23:18:56.834Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload_time = "2025-09-29T23:19:09.247Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload_time = "2025-09-29T23:19:25.342Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload_time = "2025-09-29T23:19:38.296Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload_time = "2025-09-29T23:19:48.856Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload_time = "2025-09-29T23:39:08.659Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload_time = "2025-09-29T23:19:59.765Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload_time = "2025-09-29T23:20:14.098Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload_time = "2025-09-29T23:20:26.76Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload_time = "2025-09-29T23:20:41.344Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload_time = "2025-09-29T23:20:54.139Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload_time = "2025-09-29T23:21:05.024Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload_time = "2025-09-29T23:21:15.979Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload_time = "2025-09-29T23:21:27.165Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload_time = "2025-09-29T23:21:40.532Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload_time = "2025-09-29T23:21:55.77Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload_time = "2025-09-29T23:22:10.109Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload_time = "2025-09-29T23:25:04.889Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload_time = "2025-09-29T23:22:24.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload_time = "2025-09-29T23:22:37.762Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload_time = "2025-09-29T23:22:51.688Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload_time = "2025-09-29T23:23:05.042Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload_time = "2025-09-29T23:23:28.57Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload_time = "2025-09-29T23:24:24.876Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload_time = "2025-09-29T23:25:52.486Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload_time = "2025-09-29T23:26:33.204Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload_time = "2025-09-29T23:27:15.384Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload_time = "2025-09-29T23:27:51.625Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload_time = "2025-09-29T23:28:21.289Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload_time = "2025-09-29T23:28:58.261Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload_time = "2025-09-29T23:32:27.484Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload_time = "2025-09-29T23:29:31.47Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload_time = "2025-09-29T23:29:54.591Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload_time = "2025-09-29T23:30:21.003Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload_time = "2025-09-29T23:30:43.391Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload_time = "2025-09-29T23:31:10.009Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload_time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "peewee" +version = "3.18.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/60/58e7a307a24044e0e982b99042fcd5a58d0cd928d9c01829574d7553ee8d/peewee-3.18.3.tar.gz", hash = "sha256:62c3d93315b1a909360c4b43c3a573b47557a1ec7a4583a71286df2a28d4b72e", size = 3026296, upload_time = "2025-11-03T16:43:46.678Z" } + +[[package]] +name = "pillow" +version = "12.0.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload_time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/08/26e68b6b5da219c2a2cb7b563af008b53bb8e6b6fcb3fa40715fcdb2523a/pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b", size = 5289809, upload_time = "2025-10-15T18:21:27.791Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/e9/4e58fb097fb74c7b4758a680aacd558810a417d1edaa7000142976ef9d2f/pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1", size = 4650606, upload_time = "2025-10-15T18:21:29.823Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/e0/1fa492aa9f77b3bc6d471c468e62bfea1823056bf7e5e4f1914d7ab2565e/pillow-12.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363", size = 6221023, upload_time = "2025-10-15T18:21:31.415Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/09/4de7cd03e33734ccd0c876f0251401f1314e819cbfd89a0fcb6e77927cc6/pillow-12.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca", size = 8024937, upload_time = "2025-10-15T18:21:33.453Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/69/0688e7c1390666592876d9d474f5e135abb4acb39dcb583c4dc5490f1aff/pillow-12.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e", size = 6334139, upload_time = "2025-10-15T18:21:35.395Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/1c/880921e98f525b9b44ce747ad1ea8f73fd7e992bafe3ca5e5644bf433dea/pillow-12.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782", size = 7026074, upload_time = "2025-10-15T18:21:37.219Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/28/03/96f718331b19b355610ef4ebdbbde3557c726513030665071fd025745671/pillow-12.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10", size = 6448852, upload_time = "2025-10-15T18:21:39.168Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/a0/6a193b3f0cc9437b122978d2c5cbce59510ccf9a5b48825096ed7472da2f/pillow-12.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa", size = 7117058, upload_time = "2025-10-15T18:21:40.997Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/c4/043192375eaa4463254e8e61f0e2ec9a846b983929a8d0a7122e0a6d6fff/pillow-12.0.0-cp310-cp310-win32.whl", hash = "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275", size = 6295431, upload_time = "2025-10-15T18:21:42.518Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/c6/c2f2fc7e56301c21827e689bb8b0b465f1b52878b57471a070678c0c33cd/pillow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d", size = 7000412, upload_time = "2025-10-15T18:21:44.404Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/d2/5f675067ba82da7a1c238a73b32e3fd78d67f9d9f80fbadd33a40b9c0481/pillow-12.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7", size = 2435903, upload_time = "2025-10-15T18:21:46.29Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/5a/a2f6773b64edb921a756eb0729068acad9fc5208a53f4a349396e9436721/pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc", size = 5289798, upload_time = "2025-10-15T18:21:47.763Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/05/069b1f8a2e4b5a37493da6c5868531c3f77b85e716ad7a590ef87d58730d/pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257", size = 4650589, upload_time = "2025-10-15T18:21:49.515Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/e3/2c820d6e9a36432503ead175ae294f96861b07600a7156154a086ba7111a/pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642", size = 6230472, upload_time = "2025-10-15T18:21:51.052Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/89/63427f51c64209c5e23d4d52071c8d0f21024d3a8a487737caaf614a5795/pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3", size = 8033887, upload_time = "2025-10-15T18:21:52.604Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/1b/c9711318d4901093c15840f268ad649459cd81984c9ec9887756cca049a5/pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c", size = 6343964, upload_time = "2025-10-15T18:21:54.619Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/1e/db9470f2d030b4995083044cd8738cdd1bf773106819f6d8ba12597d5352/pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227", size = 7034756, upload_time = "2025-10-15T18:21:56.151Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/b0/6177a8bdd5ee4ed87cba2de5a3cc1db55ffbbec6176784ce5bb75aa96798/pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b", size = 6458075, upload_time = "2025-10-15T18:21:57.759Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/5e/61537aa6fa977922c6a03253a0e727e6e4a72381a80d63ad8eec350684f2/pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e", size = 7125955, upload_time = "2025-10-15T18:21:59.372Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/3d/d5033539344ee3cbd9a4d69e12e63ca3a44a739eb2d4c8da350a3d38edd7/pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", size = 6298440, upload_time = "2025-10-15T18:22:00.982Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/42/aaca386de5cc8bd8a0254516957c1f265e3521c91515b16e286c662854c4/pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", size = 6999256, upload_time = "2025-10-15T18:22:02.617Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/f1/9197c9c2d5708b785f631a6dfbfa8eb3fb9672837cb92ae9af812c13b4ed/pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", size = 2436025, upload_time = "2025-10-15T18:22:04.598Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload_time = "2025-10-15T18:22:05.993Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload_time = "2025-10-15T18:22:07.718Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload_time = "2025-10-15T18:22:09.287Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload_time = "2025-10-15T18:22:10.872Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload_time = "2025-10-15T18:22:12.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload_time = "2025-10-15T18:22:14.813Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload_time = "2025-10-15T18:22:16.375Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload_time = "2025-10-15T18:22:17.996Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload_time = "2025-10-15T18:22:19.923Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload_time = "2025-10-15T18:22:21.644Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload_time = "2025-10-15T18:22:23.621Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload_time = "2025-10-15T18:22:25.758Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload_time = "2025-10-15T18:22:27.286Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload_time = "2025-10-15T18:22:28.751Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload_time = "2025-10-15T18:22:30.641Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload_time = "2025-10-15T18:22:32.73Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload_time = "2025-10-15T18:22:34.337Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload_time = "2025-10-15T18:22:36.402Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload_time = "2025-10-15T18:22:38.066Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload_time = "2025-10-15T18:22:39.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload_time = "2025-10-15T18:22:41.437Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload_time = "2025-10-15T18:22:43.152Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload_time = "2025-10-15T18:22:44.753Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload_time = "2025-10-15T18:22:46.838Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload_time = "2025-10-15T18:22:48.399Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload_time = "2025-10-15T18:22:49.905Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload_time = "2025-10-15T18:22:51.587Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload_time = "2025-10-15T18:22:53.215Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload_time = "2025-10-15T18:22:54.933Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload_time = "2025-10-15T18:22:56.605Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload_time = "2025-10-15T18:22:58.53Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload_time = "2025-10-15T18:23:00.582Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload_time = "2025-10-15T18:23:02.627Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload_time = "2025-10-15T18:23:04.709Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload_time = "2025-10-15T18:23:06.46Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload_time = "2025-10-15T18:23:08.194Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload_time = "2025-10-15T18:23:10.121Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload_time = "2025-10-15T18:23:12.14Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload_time = "2025-10-15T18:23:13.962Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload_time = "2025-10-15T18:23:15.562Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload_time = "2025-10-15T18:23:17.379Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload_time = "2025-10-15T18:23:18.971Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload_time = "2025-10-15T18:23:20.909Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload_time = "2025-10-15T18:23:23.077Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload_time = "2025-10-15T18:23:25.005Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload_time = "2025-10-15T18:23:27.009Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload_time = "2025-10-15T18:23:29.752Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload_time = "2025-10-15T18:23:32.06Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload_time = "2025-10-15T18:23:34.71Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload_time = "2025-10-15T18:23:36.967Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload_time = "2025-10-15T18:23:38.573Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload_time = "2025-10-15T18:23:40.238Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload_time = "2025-10-15T18:23:42.434Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload_time = "2025-10-15T18:23:44.29Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload_time = "2025-10-15T18:23:46.065Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload_time = "2025-10-15T18:23:47.898Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload_time = "2025-10-15T18:23:49.607Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload_time = "2025-10-15T18:23:51.351Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload_time = "2025-10-15T18:23:53.177Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload_time = "2025-10-15T18:23:55.316Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload_time = "2025-10-15T18:23:57.149Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/b3/582327e6c9f86d037b63beebe981425d6811104cb443e8193824ef1a2f27/pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", size = 5215068, upload_time = "2025-10-15T18:23:59.594Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/d6/67748211d119f3b6540baf90f92fae73ae51d5217b171b0e8b5f7e5d558f/pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", size = 4614994, upload_time = "2025-10-15T18:24:01.669Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/e1/f8281e5d844c41872b273b9f2c34a4bf64ca08905668c8ae730eedc7c9fa/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", size = 5246639, upload_time = "2025-10-15T18:24:03.403Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/5a/0d8ab8ffe8a102ff5df60d0de5af309015163bf710c7bb3e8311dd3b3ad0/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c", size = 6986839, upload_time = "2025-10-15T18:24:05.344Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/2e/3434380e8110b76cd9eb00a363c484b050f949b4bbe84ba770bb8508a02c/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e", size = 5313505, upload_time = "2025-10-15T18:24:07.137Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/ca/5a9d38900d9d74785141d6580950fe705de68af735ff6e727cb911b64740/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76", size = 5963654, upload_time = "2025-10-15T18:24:09.579Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/7e/f896623c3c635a90537ac093c6a618ebe1a90d87206e42309cb5d98a1b9e/pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", size = 6997850, upload_time = "2025-10-15T18:24:11.495Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload_time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/0e/934b541323035566a9af292dba85a195f7b78179114f2c6ebb24551118a9/propcache-0.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db", size = 79534, upload_time = "2025-10-08T19:46:02.083Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/6b/db0d03d96726d995dc7171286c6ba9d8d14251f37433890f88368951a44e/propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8", size = 45526, upload_time = "2025-10-08T19:46:03.884Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/c3/82728404aea669e1600f304f2609cde9e665c18df5a11cdd57ed73c1dceb/propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925", size = 47263, upload_time = "2025-10-08T19:46:05.405Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/1b/39313ddad2bf9187a1432654c38249bab4562ef535ef07f5eb6eb04d0b1b/propcache-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21", size = 201012, upload_time = "2025-10-08T19:46:07.165Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/01/f1d0b57d136f294a142acf97f4ed58c8e5b974c21e543000968357115011/propcache-0.4.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5", size = 209491, upload_time = "2025-10-08T19:46:08.909Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/c8/038d909c61c5bb039070b3fb02ad5cccdb1dde0d714792e251cdb17c9c05/propcache-0.4.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db", size = 215319, upload_time = "2025-10-08T19:46:10.7Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/57/8c87e93142b2c1fa2408e45695205a7ba05fb5db458c0bf5c06ba0e09ea6/propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7", size = 196856, upload_time = "2025-10-08T19:46:12.003Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/df/5615fec76aa561987a534759b3686008a288e73107faa49a8ae5795a9f7a/propcache-0.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4", size = 193241, upload_time = "2025-10-08T19:46:13.495Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/21/62949eb3a7a54afe8327011c90aca7e03547787a88fb8bd9726806482fea/propcache-0.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60", size = 190552, upload_time = "2025-10-08T19:46:14.938Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/ee/ab4d727dd70806e5b4de96a798ae7ac6e4d42516f030ee60522474b6b332/propcache-0.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f", size = 200113, upload_time = "2025-10-08T19:46:16.695Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/0b/38b46208e6711b016aa8966a3ac793eee0d05c7159d8342aa27fc0bc365e/propcache-0.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900", size = 200778, upload_time = "2025-10-08T19:46:18.023Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/81/5abec54355ed344476bee711e9f04815d4b00a311ab0535599204eecc257/propcache-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c", size = 193047, upload_time = "2025-10-08T19:46:19.449Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/b6/1f237c04e32063cb034acd5f6ef34ef3a394f75502e72703545631ab1ef6/propcache-0.4.1-cp310-cp310-win32.whl", hash = "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb", size = 38093, upload_time = "2025-10-08T19:46:20.643Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/67/354aac4e0603a15f76439caf0427781bcd6797f370377f75a642133bc954/propcache-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37", size = 41638, upload_time = "2025-10-08T19:46:21.935Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/e1/74e55b9fd1a4c209ff1a9a824bf6c8b3d1fc5a1ac3eabe23462637466785/propcache-0.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581", size = 38229, upload_time = "2025-10-08T19:46:23.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208, upload_time = "2025-10-08T19:46:24.597Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777, upload_time = "2025-10-08T19:46:25.733Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647, upload_time = "2025-10-08T19:46:27.304Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929, upload_time = "2025-10-08T19:46:28.62Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778, upload_time = "2025-10-08T19:46:30.358Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144, upload_time = "2025-10-08T19:46:32.607Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030, upload_time = "2025-10-08T19:46:33.969Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252, upload_time = "2025-10-08T19:46:35.309Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064, upload_time = "2025-10-08T19:46:36.993Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429, upload_time = "2025-10-08T19:46:38.398Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727, upload_time = "2025-10-08T19:46:39.732Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097, upload_time = "2025-10-08T19:46:41.025Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload_time = "2025-10-08T19:46:42.693Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload_time = "2025-10-08T19:46:43.778Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload_time = "2025-10-08T19:46:44.872Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload_time = "2025-10-08T19:46:46.075Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload_time = "2025-10-08T19:46:47.23Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload_time = "2025-10-08T19:46:48.384Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload_time = "2025-10-08T19:46:50.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload_time = "2025-10-08T19:46:51.815Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload_time = "2025-10-08T19:46:53.208Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload_time = "2025-10-08T19:46:54.511Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload_time = "2025-10-08T19:46:56.212Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload_time = "2025-10-08T19:46:57.595Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload_time = "2025-10-08T19:46:59.067Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload_time = "2025-10-08T19:47:00.544Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload_time = "2025-10-08T19:47:01.968Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload_time = "2025-10-08T19:47:03.503Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload_time = "2025-10-08T19:47:04.973Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload_time = "2025-10-08T19:47:06.077Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload_time = "2025-10-08T19:47:07.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload_time = "2025-10-08T19:47:08.851Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload_time = "2025-10-08T19:47:09.982Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload_time = "2025-10-08T19:47:11.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload_time = "2025-10-08T19:47:13.146Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload_time = "2025-10-08T19:47:14.913Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload_time = "2025-10-08T19:47:16.277Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload_time = "2025-10-08T19:47:17.962Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload_time = "2025-10-08T19:47:19.355Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload_time = "2025-10-08T19:47:21.338Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload_time = "2025-10-08T19:47:23.059Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload_time = "2025-10-08T19:47:24.445Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload_time = "2025-10-08T19:47:25.736Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload_time = "2025-10-08T19:47:26.847Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload_time = "2025-10-08T19:47:27.961Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload_time = "2025-10-08T19:47:29.445Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload_time = "2025-10-08T19:47:30.579Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload_time = "2025-10-08T19:47:31.79Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload_time = "2025-10-08T19:47:33.481Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload_time = "2025-10-08T19:47:34.906Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload_time = "2025-10-08T19:47:36.338Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload_time = "2025-10-08T19:47:37.692Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload_time = "2025-10-08T19:47:39.659Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload_time = "2025-10-08T19:47:41.084Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload_time = "2025-10-08T19:47:42.51Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload_time = "2025-10-08T19:47:43.927Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload_time = "2025-10-08T19:47:45.448Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload_time = "2025-10-08T19:47:47.202Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload_time = "2025-10-08T19:47:48.336Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload_time = "2025-10-08T19:47:49.876Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload_time = "2025-10-08T19:47:51.051Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload_time = "2025-10-08T19:47:52.594Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload_time = "2025-10-08T19:47:54.073Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload_time = "2025-10-08T19:47:55.715Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload_time = "2025-10-08T19:47:57.499Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload_time = "2025-10-08T19:47:59.317Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload_time = "2025-10-08T19:48:00.67Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload_time = "2025-10-08T19:48:02.604Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload_time = "2025-10-08T19:48:04.499Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload_time = "2025-10-08T19:48:06.213Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload_time = "2025-10-08T19:48:08.432Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload_time = "2025-10-08T19:48:09.968Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload_time = "2025-10-08T19:48:11.232Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload_time = "2025-10-08T19:48:12.707Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload_time = "2025-10-08T19:48:13.923Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload_time = "2025-10-08T19:48:15.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload_time = "2025-10-08T19:48:16.424Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload_time = "2025-10-08T19:48:17.577Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload_time = "2025-10-08T19:48:18.901Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload_time = "2025-10-08T19:48:20.762Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload_time = "2025-10-08T19:48:22.592Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload_time = "2025-10-08T19:48:23.947Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload_time = "2025-10-08T19:48:25.656Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload_time = "2025-10-08T19:48:27.207Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload_time = "2025-10-08T19:48:28.65Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload_time = "2025-10-08T19:48:30.133Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload_time = "2025-10-08T19:48:31.567Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload_time = "2025-10-08T19:48:32.872Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload_time = "2025-10-08T19:48:34.226Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload_time = "2025-10-08T19:48:35.441Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload_time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "pyarrow" +version = "22.0.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload_time = "2025-10-24T12:30:00.762Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/9b/cb3f7e0a345353def531ca879053e9ef6b9f38ed91aebcf68b09ba54dec0/pyarrow-22.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:77718810bd3066158db1e95a63c160ad7ce08c6b0710bc656055033e39cdad88", size = 34223968, upload_time = "2025-10-24T10:03:31.21Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/41/3184b8192a120306270c5307f105b70320fdaa592c99843c5ef78aaefdcf/pyarrow-22.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:44d2d26cda26d18f7af7db71453b7b783788322d756e81730acb98f24eb90ace", size = 35942085, upload_time = "2025-10-24T10:03:38.146Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/3d/a1eab2f6f08001f9fb714b8ed5cfb045e2fe3e3e3c0c221f2c9ed1e6d67d/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b9d71701ce97c95480fecb0039ec5bb889e75f110da72005743451339262f4ce", size = 44964613, upload_time = "2025-10-24T10:03:46.516Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/46/a1d9c24baf21cfd9ce994ac820a24608decf2710521b29223d4334985127/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:710624ab925dc2b05a6229d47f6f0dac1c1155e6ed559be7109f684eba048a48", size = 47627059, upload_time = "2025-10-24T10:03:55.353Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/4c/f711acb13075c1391fd54bc17e078587672c575f8de2a6e62509af026dcf/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f963ba8c3b0199f9d6b794c90ec77545e05eadc83973897a4523c9e8d84e9340", size = 47947043, upload_time = "2025-10-24T10:04:05.408Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/70/1f3180dd7c2eab35c2aca2b29ace6c519f827dcd4cfeb8e0dca41612cf7a/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd0d42297ace400d8febe55f13fdf46e86754842b860c978dfec16f081e5c653", size = 50206505, upload_time = "2025-10-24T10:04:15.786Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/07/fea6578112c8c60ffde55883a571e4c4c6bc7049f119d6b09333b5cc6f73/pyarrow-22.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:00626d9dc0f5ef3a75fe63fd68b9c7c8302d2b5bbc7f74ecaedba83447a24f84", size = 28101641, upload_time = "2025-10-24T10:04:22.57Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/b7/18f611a8cdc43417f9394a3ccd3eace2f32183c08b9eddc3d17681819f37/pyarrow-22.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:3e294c5eadfb93d78b0763e859a0c16d4051fc1c5231ae8956d61cb0b5666f5a", size = 34272022, upload_time = "2025-10-24T10:04:28.973Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/5c/f259e2526c67eb4b9e511741b19870a02363a47a35edbebc55c3178db22d/pyarrow-22.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:69763ab2445f632d90b504a815a2a033f74332997052b721002298ed6de40f2e", size = 35995834, upload_time = "2025-10-24T10:04:35.467Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/8d/281f0f9b9376d4b7f146913b26fac0aa2829cd1ee7e997f53a27411bbb92/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b41f37cabfe2463232684de44bad753d6be08a7a072f6a83447eeaf0e4d2a215", size = 45030348, upload_time = "2025-10-24T10:04:43.366Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/e5/53c0a1c428f0976bf22f513d79c73000926cb00b9c138d8e02daf2102e18/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35ad0f0378c9359b3f297299c3309778bb03b8612f987399a0333a560b43862d", size = 47699480, upload_time = "2025-10-24T10:04:51.486Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/e1/9dbe4c465c3365959d183e6345d0a8d1dc5b02ca3f8db4760b3bc834cf25/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8382ad21458075c2e66a82a29d650f963ce51c7708c7c0ff313a8c206c4fd5e8", size = 48011148, upload_time = "2025-10-24T10:04:59.585Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/b4/7caf5d21930061444c3cf4fa7535c82faf5263e22ce43af7c2759ceb5b8b/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a812a5b727bc09c3d7ea072c4eebf657c2f7066155506ba31ebf4792f88f016", size = 50276964, upload_time = "2025-10-24T10:05:08.175Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/f3/cec89bd99fa3abf826f14d4e53d3d11340ce6f6af4d14bdcd54cd83b6576/pyarrow-22.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ec5d40dd494882704fb876c16fa7261a69791e784ae34e6b5992e977bd2e238c", size = 28106517, upload_time = "2025-10-24T10:05:14.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload_time = "2025-10-24T10:05:21.583Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload_time = "2025-10-24T10:05:29.485Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload_time = "2025-10-24T10:05:38.274Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload_time = "2025-10-24T10:05:47.314Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload_time = "2025-10-24T10:05:58.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload_time = "2025-10-24T10:06:08.08Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload_time = "2025-10-24T10:06:14.204Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/d6/d0fac16a2963002fc22c8fa75180a838737203d558f0ed3b564c4a54eef5/pyarrow-22.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6e95176209257803a8b3d0394f21604e796dadb643d2f7ca21b66c9c0b30c9a", size = 34204629, upload_time = "2025-10-24T10:06:20.274Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/9c/1d6357347fbae062ad3f17082f9ebc29cc733321e892c0d2085f42a2212b/pyarrow-22.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:001ea83a58024818826a9e3f89bf9310a114f7e26dfe404a4c32686f97bd7901", size = 35985783, upload_time = "2025-10-24T10:06:27.301Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/c0/782344c2ce58afbea010150df07e3a2f5fdad299cd631697ae7bd3bac6e3/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ce20fe000754f477c8a9125543f1936ea5b8867c5406757c224d745ed033e691", size = 45020999, upload_time = "2025-10-24T10:06:35.387Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1b/8b/5362443737a5307a7b67c1017c42cd104213189b4970bf607e05faf9c525/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e0a15757fccb38c410947df156f9749ae4a3c89b2393741a50521f39a8cf202a", size = 47724601, upload_time = "2025-10-24T10:06:43.551Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/4d/76e567a4fc2e190ee6072967cb4672b7d9249ac59ae65af2d7e3047afa3b/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cedb9dd9358e4ea1d9bce3665ce0797f6adf97ff142c8e25b46ba9cdd508e9b6", size = 48001050, upload_time = "2025-10-24T10:06:52.284Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/5e/5653f0535d2a1aef8223cee9d92944cb6bccfee5cf1cd3f462d7cb022790/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:252be4a05f9d9185bb8c18e83764ebcfea7185076c07a7a662253af3a8c07941", size = 50307877, upload_time = "2025-10-24T10:07:02.405Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/f8/1d0bd75bf9328a3b826e24a16e5517cd7f9fbf8d34a3184a4566ef5a7f29/pyarrow-22.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:a4893d31e5ef780b6edcaf63122df0f8d321088bb0dee4c8c06eccb1ca28d145", size = 27977099, upload_time = "2025-10-24T10:08:07.259Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/90/81/db56870c997805bf2b0f6eeeb2d68458bf4654652dccdcf1bf7a42d80903/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:f7fe3dbe871294ba70d789be16b6e7e52b418311e166e0e3cba9522f0f437fb1", size = 34336685, upload_time = "2025-10-24T10:07:11.47Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/98/0727947f199aba8a120f47dfc229eeb05df15bcd7a6f1b669e9f882afc58/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:ba95112d15fd4f1105fb2402c4eab9068f0554435e9b7085924bcfaac2cc306f", size = 36032158, upload_time = "2025-10-24T10:07:18.626Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/b4/9babdef9c01720a0785945c7cf550e4acd0ebcd7bdd2e6f0aa7981fa85e2/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c064e28361c05d72eed8e744c9605cbd6d2bb7481a511c74071fd9b24bc65d7d", size = 44892060, upload_time = "2025-10-24T10:07:26.002Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/ca/2f8804edd6279f78a37062d813de3f16f29183874447ef6d1aadbb4efa0f/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6f9762274496c244d951c819348afbcf212714902742225f649cf02823a6a10f", size = 47504395, upload_time = "2025-10-24T10:07:34.09Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload_time = "2025-10-24T10:07:43.528Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload_time = "2025-10-24T10:07:53.519Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload_time = "2025-10-24T10:08:00.932Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062, upload_time = "2025-10-24T10:08:14.101Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057, upload_time = "2025-10-24T10:08:21.842Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002, upload_time = "2025-10-24T10:08:29.034Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765, upload_time = "2025-10-24T10:08:38.559Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139, upload_time = "2025-10-24T10:08:46.784Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244, upload_time = "2025-10-24T10:08:55.771Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501, upload_time = "2025-10-24T10:09:59.891Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506, upload_time = "2025-10-24T10:09:02.953Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312, upload_time = "2025-10-24T10:09:10.334Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609, upload_time = "2025-10-24T10:09:18.61Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663, upload_time = "2025-10-24T10:09:27.369Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543, upload_time = "2025-10-24T10:09:34.908Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838, upload_time = "2025-10-24T10:09:44.394Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload_time = "2025-10-24T10:09:53.111Z" }, +] + +[[package]] +name = "pyasn1" +version = "0.6.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload_time = "2024-09-10T22:41:42.55Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload_time = "2024-09-11T16:00:36.122Z" }, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload_time = "2025-03-28T02:41:22.17Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload_time = "2025-03-28T02:41:19.028Z" }, +] + +[[package]] +name = "pycparser" +version = "2.23" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload_time = "2025-09-09T13:23:47.91Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload_time = "2025-09-09T13:23:46.651Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload_time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload_time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload_time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298, upload_time = "2025-11-04T13:39:04.116Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475, upload_time = "2025-11-04T13:39:06.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815, upload_time = "2025-11-04T13:39:10.41Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567, upload_time = "2025-11-04T13:39:12.244Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442, upload_time = "2025-11-04T13:39:13.962Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956, upload_time = "2025-11-04T13:39:15.889Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253, upload_time = "2025-11-04T13:39:17.403Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050, upload_time = "2025-11-04T13:39:19.351Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178, upload_time = "2025-11-04T13:39:21Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833, upload_time = "2025-11-04T13:39:22.606Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156, upload_time = "2025-11-04T13:39:25.843Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378, upload_time = "2025-11-04T13:39:27.92Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622, upload_time = "2025-11-04T13:39:29.848Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload_time = "2025-11-04T13:39:31.373Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload_time = "2025-11-04T13:39:32.897Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload_time = "2025-11-04T13:39:34.469Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload_time = "2025-11-04T13:39:36.053Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload_time = "2025-11-04T13:39:37.753Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload_time = "2025-11-04T13:39:40.94Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload_time = "2025-11-04T13:39:42.523Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload_time = "2025-11-04T13:39:44.553Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload_time = "2025-11-04T13:39:46.238Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload_time = "2025-11-04T13:39:48.002Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload_time = "2025-11-04T13:39:49.705Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload_time = "2025-11-04T13:39:51.842Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload_time = "2025-11-04T13:39:53.485Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload_time = "2025-11-04T13:39:56.488Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload_time = "2025-11-04T13:39:58.079Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload_time = "2025-11-04T13:39:59.956Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload_time = "2025-11-04T13:40:02.241Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload_time = "2025-11-04T13:40:04.401Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload_time = "2025-11-04T13:40:06.072Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload_time = "2025-11-04T13:40:07.835Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload_time = "2025-11-04T13:40:09.804Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload_time = "2025-11-04T13:40:12.004Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload_time = "2025-11-04T13:40:13.868Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload_time = "2025-11-04T13:40:15.672Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload_time = "2025-11-04T13:40:17.532Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload_time = "2025-11-04T13:40:19.309Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload_time = "2025-11-04T13:40:21.548Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload_time = "2025-11-04T13:40:23.393Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload_time = "2025-11-04T13:40:25.248Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload_time = "2025-11-04T13:40:27.099Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload_time = "2025-11-04T13:40:29.806Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload_time = "2025-11-04T13:40:33.544Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload_time = "2025-11-04T13:40:35.479Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload_time = "2025-11-04T13:40:37.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload_time = "2025-11-04T13:40:40.289Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload_time = "2025-11-04T13:40:42.809Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload_time = "2025-11-04T13:40:44.752Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload_time = "2025-11-04T13:40:46.66Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload_time = "2025-11-04T13:40:48.575Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload_time = "2025-11-04T13:40:50.619Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload_time = "2025-11-04T13:40:52.631Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload_time = "2025-11-04T13:40:54.734Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload_time = "2025-11-04T13:40:56.68Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload_time = "2025-11-04T13:40:58.807Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload_time = "2025-11-04T13:41:00.853Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload_time = "2025-11-04T13:41:03.504Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload_time = "2025-11-04T13:41:05.804Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload_time = "2025-11-04T13:41:07.809Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload_time = "2025-11-04T13:41:09.827Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload_time = "2025-11-04T13:41:12.379Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload_time = "2025-11-04T13:41:14.627Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload_time = "2025-11-04T13:41:16.868Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload_time = "2025-11-04T13:41:18.934Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload_time = "2025-11-04T13:41:21.418Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload_time = "2025-11-04T13:41:24.076Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload_time = "2025-11-04T13:41:26.33Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload_time = "2025-11-04T13:41:28.569Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload_time = "2025-11-04T13:41:31.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload_time = "2025-11-04T13:41:33.21Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload_time = "2025-11-04T13:41:35.508Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload_time = "2025-11-04T13:41:37.732Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload_time = "2025-11-04T13:41:40Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload_time = "2025-11-04T13:41:42.323Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload_time = "2025-11-04T13:41:45.221Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload_time = "2025-11-04T13:41:47.474Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload_time = "2025-11-04T13:41:49.992Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload_time = "2025-11-04T13:41:54.079Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload_time = "2025-11-04T13:41:56.606Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload_time = "2025-11-04T13:41:58.889Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload_time = "2025-11-04T13:42:01.186Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload_time = "2025-11-04T13:42:39.557Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload_time = "2025-11-04T13:42:42.169Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload_time = "2025-11-04T13:42:44.564Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload_time = "2025-11-04T13:42:47.156Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload_time = "2025-11-04T13:42:49.689Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload_time = "2025-11-04T13:42:52.215Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload_time = "2025-11-04T13:42:56.483Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload_time = "2025-11-04T13:42:59.471Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351, upload_time = "2025-11-04T13:43:02.058Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363, upload_time = "2025-11-04T13:43:05.159Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615, upload_time = "2025-11-04T13:43:08.116Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369, upload_time = "2025-11-04T13:43:12.49Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218, upload_time = "2025-11-04T13:43:15.431Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951, upload_time = "2025-11-04T13:43:18.062Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428, upload_time = "2025-11-04T13:43:20.679Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009, upload_time = "2025-11-04T13:43:23.286Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload_time = "2025-11-04T13:43:25.97Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload_time = "2025-11-04T13:43:28.763Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload_time = "2025-11-04T13:43:31.71Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload_time = "2025-11-04T13:43:34.744Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload_time = "2025-11-04T13:43:37.701Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload_time = "2025-11-04T13:43:40.406Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload_time = "2025-11-04T13:43:43.602Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload_time = "2025-11-04T13:43:46.64Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload_time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload_time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.2.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload_time = "2025-09-21T04:11:06.277Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload_time = "2025-09-21T04:11:04.117Z" }, +] + +[[package]] +name = "pypinyin" +version = "0.55.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/a4/784cf98c09e0dc22776b0d7d8a4a5b761218bcae4608c2416ce1e167c8af/pypinyin-0.55.0.tar.gz", hash = "sha256:b5711b3a0c6f76e67408ec6b2e3c4987a3a806b7c528076e7c7b86fcf0eaa66b", size = 839836, upload_time = "2025-07-20T12:01:50.657Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/7b/4cabc76fcc21c3c7d5c671d8783984d30ac9d3bb387c4ba784fca3cdfa3a/pypinyin-0.55.0-py2.py3-none-any.whl", hash = "sha256:d53b1e8ad2cdb815fb2cb604ed3123372f5a28c6f447571244aca36fc62a286f", size = 840203, upload_time = "2025-07-20T12:01:48.535Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload_time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload_time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload_time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload_time = "2025-10-26T15:12:09.109Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.20" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload_time = "2024-12-16T19:45:46.972Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload_time = "2024-12-16T19:45:44.423Z" }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload_time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload_time = "2025-03-25T02:24:58.468Z" }, +] + +[[package]] +name = "quick-algo" +version = "0.1.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/5e/9a8aa66f6a9da26253bb1fb87c573fb5ced9da19aea306787542bb4abc2f/quick_algo-0.1.3.tar.gz", hash = "sha256:83bc6a991a30222019b38dcccabe0aa703d4a14ef6d8a41d801f6c51f2b6beec", size = 201656, upload_time = "2025-04-24T08:39:56.854Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/8e/779063325ba04c0a44e61c9ebf5fedecb427de377c081986bcc59dba6312/quick_algo-0.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:901b365e5ada781332bf38103b7a03f52a5bd4a81e01391d1271f710be1a4092", size = 320533, upload_time = "2025-04-24T08:39:49.485Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/0d/9dcf1ed1f1a89a4b307408fe980b853bdaabd5d72d625b30bcbb0c972750/quick_algo-0.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:68b121726cabb4da03bd6b644df2a0d7be9accf8388f2cd34cb2cc9318d96f0a", size = 320943, upload_time = "2025-04-24T08:39:51.911Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5e/3d/c75e6c509fde672c19e63cf22389da60f5bbe9273bc91865726b24f88689/quick_algo-0.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1d73297c6f0135ca6acd1a3c036a8d4280f005744abdbb5a30428fabb8f095fe", size = 318958, upload_time = "2025-04-24T08:39:53.491Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/2f/9a9a77d4aafe9f290b5db1a63a1c3c2c105eb9dbdc573cc0a20fd5299b96/quick_algo-0.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:8ddc2ec38a04e757b9b5861e73001c4e0d8f66d5cd9a45b00f878f396d50a2b1", size = 317673, upload_time = "2025-04-24T08:39:55.119Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload_time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload_time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload_time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload_time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "rsa" +version = "4.9.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload_time = "2025-04-16T09:51:18.218Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload_time = "2025-04-16T09:51:17.142Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.8" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/d9/f7a0c4b3a2bf2556cd5d99b05372c29980249ef71e8e32669ba77428c82c/ruff-0.14.8.tar.gz", hash = "sha256:774ed0dd87d6ce925e3b8496feb3a00ac564bea52b9feb551ecd17e0a23d1eed", size = 5765385, upload_time = "2025-12-04T15:06:17.669Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/b8/9537b52010134b1d2b72870cc3f92d5fb759394094741b09ceccae183fbe/ruff-0.14.8-py3-none-linux_armv6l.whl", hash = "sha256:ec071e9c82eca417f6111fd39f7043acb53cd3fde9b1f95bbed745962e345afb", size = 13441540, upload_time = "2025-12-04T15:06:14.896Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/00/99031684efb025829713682012b6dd37279b1f695ed1b01725f85fd94b38/ruff-0.14.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8cdb162a7159f4ca36ce980a18c43d8f036966e7f73f866ac8f493b75e0c27e9", size = 13669384, upload_time = "2025-12-04T15:06:51.809Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/64/3eb5949169fc19c50c04f28ece2c189d3b6edd57e5b533649dae6ca484fe/ruff-0.14.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e2fcbefe91f9fad0916850edf0854530c15bd1926b6b779de47e9ab619ea38f", size = 12806917, upload_time = "2025-12-04T15:06:08.925Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/08/5250babb0b1b11910f470370ec0cbc67470231f7cdc033cee57d4976f941/ruff-0.14.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d70721066a296f45786ec31916dc287b44040f553da21564de0ab4d45a869b", size = 13256112, upload_time = "2025-12-04T15:06:23.498Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/4c/6c588e97a8e8c2d4b522c31a579e1df2b4d003eddfbe23d1f262b1a431ff/ruff-0.14.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c87e09b3cd9d126fc67a9ecd3b5b1d3ded2b9c7fce3f16e315346b9d05cfb52", size = 13227559, upload_time = "2025-12-04T15:06:33.432Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/ce/5f78cea13eda8eceac71b5f6fa6e9223df9b87bb2c1891c166d1f0dce9f1/ruff-0.14.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d62cb310c4fbcb9ee4ac023fe17f984ae1e12b8a4a02e3d21489f9a2a5f730c", size = 13896379, upload_time = "2025-12-04T15:06:02.687Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/79/13de4517c4dadce9218a20035b21212a4c180e009507731f0d3b3f5df85a/ruff-0.14.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1af35c2d62633d4da0521178e8a2641c636d2a7153da0bac1b30cfd4ccd91344", size = 15372786, upload_time = "2025-12-04T15:06:29.828Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/06/33df72b3bb42be8a1c3815fd4fae83fa2945fc725a25d87ba3e42d1cc108/ruff-0.14.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25add4575ffecc53d60eed3f24b1e934493631b48ebbc6ebaf9d8517924aca4b", size = 14990029, upload_time = "2025-12-04T15:06:36.812Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/61/0f34927bd90925880394de0e081ce1afab66d7b3525336f5771dcf0cb46c/ruff-0.14.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c943d847b7f02f7db4201a0600ea7d244d8a404fbb639b439e987edcf2baf9a", size = 14407037, upload_time = "2025-12-04T15:06:39.979Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/bc/058fe0aefc0fbf0d19614cb6d1a3e2c048f7dc77ca64957f33b12cfdc5ef/ruff-0.14.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb6e8bf7b4f627548daa1b69283dac5a296bfe9ce856703b03130732e20ddfe2", size = 14102390, upload_time = "2025-12-04T15:06:46.372Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/a4/e4f77b02b804546f4c17e8b37a524c27012dd6ff05855d2243b49a7d3cb9/ruff-0.14.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:7aaf2974f378e6b01d1e257c6948207aec6a9b5ba53fab23d0182efb887a0e4a", size = 14230793, upload_time = "2025-12-04T15:06:20.497Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/52/bb8c02373f79552e8d087cedaffad76b8892033d2876c2498a2582f09dcf/ruff-0.14.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e5758ca513c43ad8a4ef13f0f081f80f08008f410790f3611a21a92421ab045b", size = 13160039, upload_time = "2025-12-04T15:06:49.06Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/ad/b69d6962e477842e25c0b11622548df746290cc6d76f9e0f4ed7456c2c31/ruff-0.14.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f74f7ba163b6e85a8d81a590363bf71618847e5078d90827749bfda1d88c9cdf", size = 13205158, upload_time = "2025-12-04T15:06:54.574Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/63/54f23da1315c0b3dfc1bc03fbc34e10378918a20c0b0f086418734e57e74/ruff-0.14.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eed28f6fafcc9591994c42254f5a5c5ca40e69a30721d2ab18bb0bb3baac3ab6", size = 13469550, upload_time = "2025-12-04T15:05:59.209Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/7d/a4d7b1961e4903bc37fffb7ddcfaa7beb250f67d97cfd1ee1d5cddb1ec90/ruff-0.14.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:21d48fa744c9d1cb8d71eb0a740c4dd02751a5de9db9a730a8ef75ca34cf138e", size = 14211332, upload_time = "2025-12-04T15:06:06.027Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/93/2a5063341fa17054e5c86582136e9895db773e3c2ffb770dde50a09f35f0/ruff-0.14.8-py3-none-win32.whl", hash = "sha256:15f04cb45c051159baebb0f0037f404f1dc2f15a927418f29730f411a79bc4e7", size = 13151890, upload_time = "2025-12-04T15:06:11.668Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/1c/65c61a0859c0add13a3e1cbb6024b42de587456a43006ca2d4fd3d1618fe/ruff-0.14.8-py3-none-win_amd64.whl", hash = "sha256:9eeb0b24242b5bbff3011409a739929f497f3fb5fe3b5698aba5e77e8c833097", size = 14537826, upload_time = "2025-12-04T15:06:26.409Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/63/8b41cea3afd7f58eb64ac9251668ee0073789a3bc9ac6f816c8c6fef986d/ruff-0.14.8-py3-none-win_arm64.whl", hash = "sha256:965a582c93c63fe715fd3e3f8aa37c4b776777203d8e1d8aa3cc0c14424a4b99", size = 13634522, upload_time = "2025-12-04T15:06:43.212Z" }, +] + +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload_time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload_time = "2025-05-27T00:56:49.664Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload_time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload_time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload_time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload_time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "starlette" +version = "0.50.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload_time = "2025-11-01T15:25:27.516Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload_time = "2025-11-01T15:25:25.461Z" }, +] + +[[package]] +name = "structlog" +version = "25.5.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/52/9ba0f43b686e7f3ddfeaa78ac3af750292662284b3661e91ad5494f21dbc/structlog-25.5.0.tar.gz", hash = "sha256:098522a3bebed9153d4570c6d0288abf80a031dfdb2048d59a49e9dc2190fc98", size = 1460830, upload_time = "2025-10-27T08:28:23.028Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/45/a132b9074aa18e799b891b91ad72133c98d8042c70f6240e4c5f9dabee2f/structlog-25.5.0-py3-none-any.whl", hash = "sha256:a8453e9b9e636ec59bd9e79bbd4a72f025981b3ba0f5837aebf48f02f37a7f9f", size = 72510, upload_time = "2025-10-27T08:28:21.535Z" }, +] + +[[package]] +name = "tenacity" +version = "9.1.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload_time = "2025-04-02T08:25:09.966Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload_time = "2025-04-02T08:25:07.678Z" }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload_time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload_time = "2020-11-01T01:40:20.672Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.13.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload_time = "2025-06-05T07:13:44.947Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload_time = "2025-06-05T07:13:43.546Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload_time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload_time = "2024-11-24T20:12:19.698Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload_time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload_time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload_time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload_time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload_time = "2025-03-23T13:54:43.652Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload_time = "2025-03-23T13:54:41.845Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/43/554c2569b62f49350597348fc3ac70f786e3c32e7f19d266e19817812dd3/urllib3-2.6.0.tar.gz", hash = "sha256:cb9bcef5a4b345d5da5d145dc3e30834f58e8018828cbc724d30b4cb7d4d49f1", size = 432585, upload_time = "2025-12-05T15:08:47.885Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl", hash = "sha256:c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f", size = 131083, upload_time = "2025-12-05T15:08:45.983Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.38.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload_time = "2025-10-18T13:46:44.63Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload_time = "2025-10-18T13:46:42.958Z" }, +] + +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload_time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload_time = "2025-03-05T20:01:35.363Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload_time = "2025-03-05T20:01:37.304Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload_time = "2025-03-05T20:01:39.668Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload_time = "2025-03-05T20:01:41.815Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload_time = "2025-03-05T20:01:43.967Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload_time = "2025-03-05T20:01:46.104Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload_time = "2025-03-05T20:01:47.603Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload_time = "2025-03-05T20:01:48.949Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload_time = "2025-03-05T20:01:50.938Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload_time = "2025-03-05T20:01:52.213Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload_time = "2025-03-05T20:01:53.922Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload_time = "2025-03-05T20:01:56.276Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload_time = "2025-03-05T20:01:57.563Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload_time = "2025-03-05T20:01:59.063Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload_time = "2025-03-05T20:02:00.305Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload_time = "2025-03-05T20:02:03.148Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload_time = "2025-03-05T20:02:05.29Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload_time = "2025-03-05T20:02:07.458Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload_time = "2025-03-05T20:02:09.842Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload_time = "2025-03-05T20:02:11.968Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload_time = "2025-03-05T20:02:13.32Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload_time = "2025-03-05T20:02:14.585Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload_time = "2025-03-05T20:02:16.706Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload_time = "2025-03-05T20:02:18.832Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload_time = "2025-03-05T20:02:20.187Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload_time = "2025-03-05T20:02:22.286Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload_time = "2025-03-05T20:02:24.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload_time = "2025-03-05T20:02:25.669Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload_time = "2025-03-05T20:02:26.99Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload_time = "2025-03-05T20:02:30.291Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload_time = "2025-03-05T20:02:31.634Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload_time = "2025-03-05T20:02:33.017Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload_time = "2025-03-05T20:02:34.498Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload_time = "2025-03-05T20:02:36.695Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload_time = "2025-03-05T20:02:37.985Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload_time = "2025-03-05T20:02:39.298Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload_time = "2025-03-05T20:02:40.595Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload_time = "2025-03-05T20:02:41.926Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload_time = "2025-03-05T20:02:43.304Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload_time = "2025-03-05T20:02:48.812Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload_time = "2025-03-05T20:02:50.14Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload_time = "2025-03-05T20:02:51.561Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload_time = "2025-03-05T20:02:53.814Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload_time = "2025-03-05T20:02:55.237Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload_time = "2025-03-05T20:03:17.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload_time = "2025-03-05T20:03:19.094Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload_time = "2025-03-05T20:03:21.1Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload_time = "2025-03-05T20:03:23.221Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload_time = "2025-03-05T20:03:25.321Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload_time = "2025-03-05T20:03:27.934Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload_time = "2025-03-05T20:03:39.41Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload_time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/43/a2204825342f37c337f5edb6637040fa14e365b2fcc2346960201d457579/yarl-1.22.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e", size = 140517, upload_time = "2025-10-06T14:08:42.494Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/6f/674f3e6f02266428c56f704cd2501c22f78e8b2eeb23f153117cc86fb28a/yarl-1.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f", size = 93495, upload_time = "2025-10-06T14:08:46.2Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/12/5b274d8a0f30c07b91b2f02cba69152600b47830fcfb465c108880fcee9c/yarl-1.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf", size = 94400, upload_time = "2025-10-06T14:08:47.855Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/7f/df1b6949b1fa1aa9ff6de6e2631876ad4b73c4437822026e85d8acb56bb1/yarl-1.22.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a", size = 347545, upload_time = "2025-10-06T14:08:49.683Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/09/f92ed93bd6cd77872ab6c3462df45ca45cd058d8f1d0c9b4f54c1704429f/yarl-1.22.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c", size = 319598, upload_time = "2025-10-06T14:08:51.215Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/97/ac3f3feae7d522cf7ccec3d340bb0b2b61c56cb9767923df62a135092c6b/yarl-1.22.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147", size = 363893, upload_time = "2025-10-06T14:08:53.144Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/49/f3219097403b9c84a4d079b1d7bda62dd9b86d0d6e4428c02d46ab2c77fc/yarl-1.22.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb", size = 371240, upload_time = "2025-10-06T14:08:55.036Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/9f/06b765d45c0e44e8ecf0fe15c9eacbbde342bb5b7561c46944f107bfb6c3/yarl-1.22.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6", size = 346965, upload_time = "2025-10-06T14:08:56.722Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/69/599e7cea8d0fcb1694323b0db0dda317fa3162f7b90166faddecf532166f/yarl-1.22.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0", size = 342026, upload_time = "2025-10-06T14:08:58.563Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/6f/9dfd12c8bc90fea9eab39832ee32ea48f8e53d1256252a77b710c065c89f/yarl-1.22.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda", size = 335637, upload_time = "2025-10-06T14:09:00.506Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/2e/34c5b4eb9b07e16e873db5b182c71e5f06f9b5af388cdaa97736d79dd9a6/yarl-1.22.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc", size = 359082, upload_time = "2025-10-06T14:09:01.936Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/71/fa7e10fb772d273aa1f096ecb8ab8594117822f683bab7d2c5a89914c92a/yarl-1.22.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737", size = 357811, upload_time = "2025-10-06T14:09:03.445Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/da/11374c04e8e1184a6a03cf9c8f5688d3e5cec83ed6f31ad3481b3207f709/yarl-1.22.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467", size = 351223, upload_time = "2025-10-06T14:09:05.401Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/8f/e2d01f161b0c034a30410e375e191a5d27608c1f8693bab1a08b089ca096/yarl-1.22.0-cp310-cp310-win32.whl", hash = "sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea", size = 82118, upload_time = "2025-10-06T14:09:11.148Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/46/94c76196642dbeae634c7a61ba3da88cd77bed875bf6e4a8bed037505aa6/yarl-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca", size = 86852, upload_time = "2025-10-06T14:09:12.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/af/7df4f179d3b1a6dcb9a4bd2ffbc67642746fcafdb62580e66876ce83fff4/yarl-1.22.0-cp310-cp310-win_arm64.whl", hash = "sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b", size = 82012, upload_time = "2025-10-06T14:09:14.664Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/27/5ab13fc84c76a0250afd3d26d5936349a35be56ce5785447d6c423b26d92/yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511", size = 141607, upload_time = "2025-10-06T14:09:16.298Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/a1/d065d51d02dc02ce81501d476b9ed2229d9a990818332242a882d5d60340/yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6", size = 94027, upload_time = "2025-10-06T14:09:17.786Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/da/8da9f6a53f67b5106ffe902c6fa0164e10398d4e150d85838b82f424072a/yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028", size = 94963, upload_time = "2025-10-06T14:09:19.662Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/68/fe/2c1f674960c376e29cb0bec1249b117d11738db92a6ccc4a530b972648db/yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d", size = 368406, upload_time = "2025-10-06T14:09:21.402Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/26/812a540e1c3c6418fec60e9bbd38e871eaba9545e94fa5eff8f4a8e28e1e/yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503", size = 336581, upload_time = "2025-10-06T14:09:22.98Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0b/f5/5777b19e26fdf98563985e481f8be3d8a39f8734147a6ebf459d0dab5a6b/yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65", size = 388924, upload_time = "2025-10-06T14:09:24.655Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/08/24bd2477bd59c0bbd994fe1d93b126e0472e4e3df5a96a277b0a55309e89/yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e", size = 392890, upload_time = "2025-10-06T14:09:26.617Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/00/71b90ed48e895667ecfb1eaab27c1523ee2fa217433ed77a73b13205ca4b/yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d", size = 365819, upload_time = "2025-10-06T14:09:28.544Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/30/2d/f715501cae832651d3282387c6a9236cd26bd00d0ff1e404b3dc52447884/yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7", size = 363601, upload_time = "2025-10-06T14:09:30.568Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/f9/a678c992d78e394e7126ee0b0e4e71bd2775e4334d00a9278c06a6cce96a/yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967", size = 358072, upload_time = "2025-10-06T14:09:32.528Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/d1/b49454411a60edb6fefdcad4f8e6dbba7d8019e3a508a1c5836cba6d0781/yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed", size = 385311, upload_time = "2025-10-06T14:09:34.634Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/e5/40d7a94debb8448c7771a916d1861d6609dddf7958dc381117e7ba36d9e8/yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6", size = 381094, upload_time = "2025-10-06T14:09:36.268Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/d8/611cc282502381ad855448643e1ad0538957fc82ae83dfe7762c14069e14/yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e", size = 370944, upload_time = "2025-10-06T14:09:37.872Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/df/fadd00fb1c90e1a5a8bd731fa3d3de2e165e5a3666a095b04e31b04d9cb6/yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", size = 81804, upload_time = "2025-10-06T14:09:39.359Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/f7/149bb6f45f267cb5c074ac40c01c6b3ea6d8a620d34b337f6321928a1b4d/yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", size = 86858, upload_time = "2025-10-06T14:09:41.068Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/13/88b78b93ad3f2f0b78e13bfaaa24d11cbc746e93fe76d8c06bf139615646/yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", size = 81637, upload_time = "2025-10-06T14:09:42.712Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload_time = "2025-10-06T14:09:44.631Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload_time = "2025-10-06T14:09:46.372Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload_time = "2025-10-06T14:09:48.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload_time = "2025-10-06T14:09:50.089Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload_time = "2025-10-06T14:09:52.142Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload_time = "2025-10-06T14:09:54.128Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload_time = "2025-10-06T14:09:55.762Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload_time = "2025-10-06T14:09:57.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload_time = "2025-10-06T14:09:59.527Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload_time = "2025-10-06T14:10:01.139Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload_time = "2025-10-06T14:10:02.756Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload_time = "2025-10-06T14:10:04.552Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload_time = "2025-10-06T14:10:06.489Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload_time = "2025-10-06T14:10:09.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload_time = "2025-10-06T14:10:11.369Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload_time = "2025-10-06T14:10:13.112Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload_time = "2025-10-06T14:10:14.601Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload_time = "2025-10-06T14:10:16.115Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload_time = "2025-10-06T14:10:17.993Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload_time = "2025-10-06T14:10:19.44Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload_time = "2025-10-06T14:10:21.124Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload_time = "2025-10-06T14:10:22.902Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload_time = "2025-10-06T14:10:24.523Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload_time = "2025-10-06T14:10:26.406Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload_time = "2025-10-06T14:10:28.461Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload_time = "2025-10-06T14:10:30.541Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload_time = "2025-10-06T14:10:33.352Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload_time = "2025-10-06T14:10:35.034Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload_time = "2025-10-06T14:10:37.76Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload_time = "2025-10-06T14:10:39.649Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload_time = "2025-10-06T14:10:41.313Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload_time = "2025-10-06T14:10:43.167Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload_time = "2025-10-06T14:10:44.643Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload_time = "2025-10-06T14:10:46.554Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload_time = "2025-10-06T14:10:48.007Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload_time = "2025-10-06T14:10:49.997Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload_time = "2025-10-06T14:10:52.004Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload_time = "2025-10-06T14:10:54.078Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload_time = "2025-10-06T14:10:55.767Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload_time = "2025-10-06T14:10:57.985Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload_time = "2025-10-06T14:10:59.633Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload_time = "2025-10-06T14:11:01.454Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload_time = "2025-10-06T14:11:03.452Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload_time = "2025-10-06T14:11:05.115Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload_time = "2025-10-06T14:11:08.137Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload_time = "2025-10-06T14:11:10.284Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload_time = "2025-10-06T14:11:11.739Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload_time = "2025-10-06T14:11:13.586Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload_time = "2025-10-06T14:11:15.465Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload_time = "2025-10-06T14:11:17.106Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload_time = "2025-10-06T14:11:19.064Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload_time = "2025-10-06T14:11:20.996Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload_time = "2025-10-06T14:11:22.847Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload_time = "2025-10-06T14:11:24.889Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload_time = "2025-10-06T14:11:27.307Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload_time = "2025-10-06T14:11:29.387Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload_time = "2025-10-06T14:11:31.423Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload_time = "2025-10-06T14:11:33.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload_time = "2025-10-06T14:11:35.136Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload_time = "2025-10-06T14:11:37.094Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload_time = "2025-10-06T14:11:38.83Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload_time = "2025-10-06T14:11:40.624Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload_time = "2025-10-06T14:11:42.578Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload_time = "2025-10-06T14:11:44.863Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload_time = "2025-10-06T14:11:46.796Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload_time = "2025-10-06T14:11:48.845Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload_time = "2025-10-06T14:11:50.897Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload_time = "2025-10-06T14:11:52.549Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload_time = "2025-10-06T14:11:54.225Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload_time = "2025-10-06T14:11:56.069Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload_time = "2025-10-06T14:11:58.783Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload_time = "2025-10-06T14:12:00.686Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload_time = "2025-10-06T14:12:02.628Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload_time = "2025-10-06T14:12:04.871Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload_time = "2025-10-06T14:12:06.624Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload_time = "2025-10-06T14:12:08.362Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload_time = "2025-10-06T14:12:10.994Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload_time = "2025-10-06T14:12:13.317Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload_time = "2025-10-06T14:12:15.398Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload_time = "2025-10-06T14:12:16.935Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload_time = "2025-10-06T14:12:53.872Z" }, +] + +[[package]] +name = "zstandard" +version = "0.25.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload_time = "2025-09-14T22:15:54.002Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/56/7a/28efd1d371f1acd037ac64ed1c5e2b41514a6cc937dd6ab6a13ab9f0702f/zstandard-0.25.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e59fdc271772f6686e01e1b3b74537259800f57e24280be3f29c8a0deb1904dd", size = 795256, upload_time = "2025-09-14T22:15:56.415Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/34/ef34ef77f1ee38fc8e4f9775217a613b452916e633c4f1d98f31db52c4a5/zstandard-0.25.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4d441506e9b372386a5271c64125f72d5df6d2a8e8a2a45a0ae09b03cb781ef7", size = 640565, upload_time = "2025-09-14T22:15:58.177Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9d/1b/4fdb2c12eb58f31f28c4d28e8dc36611dd7205df8452e63f52fb6261d13e/zstandard-0.25.0-cp310-cp310-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:ab85470ab54c2cb96e176f40342d9ed41e58ca5733be6a893b730e7af9c40550", size = 5345306, upload_time = "2025-09-14T22:16:00.165Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/28/a44bdece01bca027b079f0e00be3b6bd89a4df180071da59a3dd7381665b/zstandard-0.25.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e05ab82ea7753354bb054b92e2f288afb750e6b439ff6ca78af52939ebbc476d", size = 5055561, upload_time = "2025-09-14T22:16:02.22Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/74/68341185a4f32b274e0fc3410d5ad0750497e1acc20bd0f5b5f64ce17785/zstandard-0.25.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:78228d8a6a1c177a96b94f7e2e8d012c55f9c760761980da16ae7546a15a8e9b", size = 5402214, upload_time = "2025-09-14T22:16:04.109Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/67/f92e64e748fd6aaffe01e2b75a083c0c4fd27abe1c8747fee4555fcee7dd/zstandard-0.25.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b6bd67528ee8b5c5f10255735abc21aa106931f0dbaf297c7be0c886353c3d0", size = 5449703, upload_time = "2025-09-14T22:16:06.312Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/e5/6d36f92a197c3c17729a2125e29c169f460538a7d939a27eaaa6dcfcba8e/zstandard-0.25.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4b6d83057e713ff235a12e73916b6d356e3084fd3d14ced499d84240f3eecee0", size = 5556583, upload_time = "2025-09-14T22:16:08.457Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/83/41939e60d8d7ebfe2b747be022d0806953799140a702b90ffe214d557638/zstandard-0.25.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9174f4ed06f790a6869b41cba05b43eeb9a35f8993c4422ab853b705e8112bbd", size = 5045332, upload_time = "2025-09-14T22:16:10.444Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/87/d3ee185e3d1aa0133399893697ae91f221fda79deb61adbe998a7235c43f/zstandard-0.25.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:25f8f3cd45087d089aef5ba3848cd9efe3ad41163d3400862fb42f81a3a46701", size = 5572283, upload_time = "2025-09-14T22:16:12.128Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0a/1d/58635ae6104df96671076ac7d4ae7816838ce7debd94aecf83e30b7121b0/zstandard-0.25.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3756b3e9da9b83da1796f8809dd57cb024f838b9eeafde28f3cb472012797ac1", size = 4959754, upload_time = "2025-09-14T22:16:14.225Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/d6/57e9cb0a9983e9a229dd8fd2e6e96593ef2aa82a3907188436f22b111ccd/zstandard-0.25.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:81dad8d145d8fd981b2962b686b2241d3a1ea07733e76a2f15435dfb7fb60150", size = 5266477, upload_time = "2025-09-14T22:16:16.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/a9/ee891e5edf33a6ebce0a028726f0bbd8567effe20fe3d5808c42323e8542/zstandard-0.25.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a5a419712cf88862a45a23def0ae063686db3d324cec7edbe40509d1a79a0aab", size = 5440914, upload_time = "2025-09-14T22:16:18.453Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/08/a8522c28c08031a9521f27abc6f78dbdee7312a7463dd2cfc658b813323b/zstandard-0.25.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e7360eae90809efd19b886e59a09dad07da4ca9ba096752e61a2e03c8aca188e", size = 5819847, upload_time = "2025-09-14T22:16:20.559Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/11/4c91411805c3f7b6f31c60e78ce347ca48f6f16d552fc659af6ec3b73202/zstandard-0.25.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:75ffc32a569fb049499e63ce68c743155477610532da1eb38e7f24bf7cd29e74", size = 5363131, upload_time = "2025-09-14T22:16:22.206Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/d6/8c4bd38a3b24c4c7676a7a3d8de85d6ee7a983602a734b9f9cdefb04a5d6/zstandard-0.25.0-cp310-cp310-win32.whl", hash = "sha256:106281ae350e494f4ac8a80470e66d1fe27e497052c8d9c3b95dc4cf1ade81aa", size = 436469, upload_time = "2025-09-14T22:16:25.002Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/93/90/96d50ad417a8ace5f841b3228e93d1bb13e6ad356737f42e2dde30d8bd68/zstandard-0.25.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea9d54cc3d8064260114a0bbf3479fc4a98b21dffc89b3459edd506b69262f6e", size = 506100, upload_time = "2025-09-14T22:16:23.569Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", size = 795254, upload_time = "2025-09-14T22:16:26.137Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", size = 640559, upload_time = "2025-09-14T22:16:27.973Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", size = 5348020, upload_time = "2025-09-14T22:16:29.523Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", size = 5058126, upload_time = "2025-09-14T22:16:31.811Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", size = 5405390, upload_time = "2025-09-14T22:16:33.486Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", size = 5452914, upload_time = "2025-09-14T22:16:35.277Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", size = 5559635, upload_time = "2025-09-14T22:16:37.141Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", size = 5048277, upload_time = "2025-09-14T22:16:38.807Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", size = 5574377, upload_time = "2025-09-14T22:16:40.523Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", size = 4961493, upload_time = "2025-09-14T22:16:43.3Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", size = 5269018, upload_time = "2025-09-14T22:16:45.292Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", size = 5443672, upload_time = "2025-09-14T22:16:47.076Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", size = 5822753, upload_time = "2025-09-14T22:16:49.316Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", size = 5366047, upload_time = "2025-09-14T22:16:51.328Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl", hash = "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", size = 436484, upload_time = "2025-09-14T22:16:55.005Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", size = 506183, upload_time = "2025-09-14T22:16:52.753Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", size = 462533, upload_time = "2025-09-14T22:16:53.878Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload_time = "2025-09-14T22:16:56.237Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload_time = "2025-09-14T22:16:57.774Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload_time = "2025-09-14T22:16:59.302Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload_time = "2025-09-14T22:17:01.156Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload_time = "2025-09-14T22:17:03.091Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload_time = "2025-09-14T22:17:04.979Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload_time = "2025-09-14T22:17:06.781Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload_time = "2025-09-14T22:17:08.415Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload_time = "2025-09-14T22:17:10.164Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload_time = "2025-09-14T22:17:11.857Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload_time = "2025-09-14T22:17:13.627Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload_time = "2025-09-14T22:17:16.103Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload_time = "2025-09-14T22:17:17.827Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload_time = "2025-09-14T22:17:19.954Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload_time = "2025-09-14T22:17:24.398Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload_time = "2025-09-14T22:17:21.429Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload_time = "2025-09-14T22:17:23.147Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload_time = "2025-09-14T22:17:26.042Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload_time = "2025-09-14T22:17:27.366Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload_time = "2025-09-14T22:17:28.896Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001, upload_time = "2025-09-14T22:17:31.044Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120, upload_time = "2025-09-14T22:17:32.711Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230, upload_time = "2025-09-14T22:17:34.41Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173, upload_time = "2025-09-14T22:17:36.084Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736, upload_time = "2025-09-14T22:17:37.891Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368, upload_time = "2025-09-14T22:17:40.206Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022, upload_time = "2025-09-14T22:17:41.879Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889, upload_time = "2025-09-14T22:17:43.577Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952, upload_time = "2025-09-14T22:17:45.271Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054, upload_time = "2025-09-14T22:17:47.08Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113, upload_time = "2025-09-14T22:17:48.893Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload_time = "2025-09-14T22:17:52.658Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload_time = "2025-09-14T22:17:50.402Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload_time = "2025-09-14T22:17:51.533Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload_time = "2025-09-14T22:17:54.198Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload_time = "2025-09-14T22:17:55.423Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload_time = "2025-09-14T22:17:57.372Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload_time = "2025-09-14T22:17:59.498Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload_time = "2025-09-14T22:18:01.618Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload_time = "2025-09-14T22:18:03.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload_time = "2025-09-14T22:18:05.954Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload_time = "2025-09-14T22:18:07.68Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload_time = "2025-09-14T22:18:09.753Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload_time = "2025-09-14T22:18:11.966Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload_time = "2025-09-14T22:18:13.907Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload_time = "2025-09-14T22:18:16.465Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload_time = "2025-09-14T22:18:20.61Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload_time = "2025-09-14T22:18:17.849Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload_time = "2025-09-14T22:18:19.088Z" }, +] diff --git a/webui/dist/assets/charts-B1JvyJzO.js b/webui/dist/assets/charts-B1JvyJzO.js deleted file mode 100644 index 7d2ae929..00000000 --- a/webui/dist/assets/charts-B1JvyJzO.js +++ /dev/null @@ -1,65 +0,0 @@ -import{r as N,R as S,i as Qt}from"./router-BWgTyY51.js";import{c as vi,g as oe}from"./react-vendor-Dtc2IqVY.js";function Ub(e){var t,r,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var i=e.length;for(t=0;t-1}return Ho=t,Ho}var Ko,Op;function TO(){if(Op)return Ko;Op=1;var e=ja();function t(r,n){var i=this.__data__,a=e(i,r);return a<0?(++this.size,i.push([r,n])):i[a][1]=n,this}return Ko=t,Ko}var Go,_p;function Ma(){if(_p)return Go;_p=1;var e=_O(),t=AO(),r=SO(),n=PO(),i=TO();function a(o){var u=-1,c=o==null?0:o.length;for(this.clear();++u0?1:-1},Gt=function(t){return er(t)&&t.indexOf("%")===t.length-1},q=function(t){return YO(t)&&!oi(t)},ZO=function(t){return Y(t)},Ae=function(t){return q(t)||er(t)},JO=0,Zr=function(t){var r=++JO;return"".concat(t||"").concat(r)},Ie=function(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(!q(t)&&!er(t))return n;var a;if(Gt(t)){var o=t.indexOf("%");a=r*parseFloat(t.slice(0,o))/100}else a=+t;return oi(a)&&(a=n),i&&a>r&&(a=r),a},Mt=function(t){if(!t)return null;var r=Object.keys(t);return r&&r.length?t[r[0]]:null},QO=function(t){if(!Array.isArray(t))return!1;for(var r=t.length,n={},i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function o_(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function ml(e){"@babel/helpers - typeof";return ml=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ml(e)}var Zp={click:"onClick",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseover:"onMouseOver",mousemove:"onMouseMove",mouseout:"onMouseOut",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",touchcancel:"onTouchCancel",touchend:"onTouchEnd",touchmove:"onTouchMove",touchstart:"onTouchStart",contextmenu:"onContextMenu",dblclick:"onDoubleClick"},bt=function(t){return typeof t=="string"?t:t?t.displayName||t.name||"Component":""},Jp=null,bu=null,Kf=function e(t){if(t===Jp&&Array.isArray(bu))return bu;var r=[];return N.Children.forEach(t,function(n){Y(n)||(KO.isFragment(n)?r=r.concat(e(n.props.children)):r.push(n))}),bu=r,Jp=t,r};function Ke(e,t){var r=[],n=[];return Array.isArray(t)?n=t.map(function(i){return bt(i)}):n=[bt(t)],Kf(e).forEach(function(i){var a=He(i,"type.displayName")||He(i,"type.name");n.indexOf(a)!==-1&&r.push(i)}),r}function We(e,t){var r=Ke(e,t);return r&&r[0]}var Qp=function(t){if(!t||!t.props)return!1;var r=t.props,n=r.width,i=r.height;return!(!q(n)||n<=0||!q(i)||i<=0)},u_=["a","altGlyph","altGlyphDef","altGlyphItem","animate","animateColor","animateMotion","animateTransform","circle","clipPath","color-profile","cursor","defs","desc","ellipse","feBlend","feColormatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","font","font-face","font-face-format","font-face-name","font-face-url","foreignObject","g","glyph","glyphRef","hkern","image","line","lineGradient","marker","mask","metadata","missing-glyph","mpath","path","pattern","polygon","polyline","radialGradient","rect","script","set","stop","style","svg","switch","symbol","text","textPath","title","tref","tspan","use","view","vkern"],c_=function(t){return t&&t.type&&er(t.type)&&u_.indexOf(t.type)>=0},s_=function(t){return t&&ml(t)==="object"&&"clipDot"in t},l_=function(t,r,n,i){var a,o=(a=gu?.[i])!==null&&a!==void 0?a:[];return r.startsWith("data-")||!X(t)&&(i&&o.includes(r)||r_.includes(r))||n&&Hf.includes(r)},H=function(t,r,n){if(!t||typeof t=="function"||typeof t=="boolean")return null;var i=t;if(N.isValidElement(t)&&(i=t.props),!Yr(i))return null;var a={};return Object.keys(i).forEach(function(o){var u;l_((u=i)===null||u===void 0?void 0:u[o],o,r,n)&&(a[o]=i[o])}),a},gl=function e(t,r){if(t===r)return!0;var n=N.Children.count(t);if(n!==N.Children.count(r))return!1;if(n===0)return!0;if(n===1)return ed(Array.isArray(t)?t[0]:t,Array.isArray(r)?r[0]:r);for(var i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function v_(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function xl(e){var t=e.children,r=e.width,n=e.height,i=e.viewBox,a=e.className,o=e.style,u=e.title,c=e.desc,s=d_(e,p_),f=i||{width:r,height:n,x:0,y:0},l=J("recharts-surface",a);return S.createElement("svg",bl({},H(s,!0,"svg"),{className:l,width:r,height:n,style:o,viewBox:"".concat(f.x," ").concat(f.y," ").concat(f.width," ").concat(f.height)}),S.createElement("title",null,u),S.createElement("desc",null,c),t)}var y_=["children","className"];function wl(){return wl=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function g_(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}var te=S.forwardRef(function(e,t){var r=e.children,n=e.className,i=m_(e,y_),a=J("recharts-layer",n);return S.createElement("g",wl({className:a},H(i,!0),{ref:t}),r)}),it=function(t,r){for(var n=arguments.length,i=new Array(n>2?n-2:0),a=2;aa?0:a+r),n=n>a?a:n,n<0&&(n+=a),a=r>n?0:n-r>>>0,r>>>=0;for(var o=Array(a);++i=a?r:e(r,n,i)}return wu=t,wu}var Ou,id;function Jb(){if(id)return Ou;id=1;var e="\\ud800-\\udfff",t="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",n="\\u20d0-\\u20ff",i=t+r+n,a="\\ufe0e\\ufe0f",o="\\u200d",u=RegExp("["+o+e+i+a+"]");function c(s){return u.test(s)}return Ou=c,Ou}var _u,ad;function w_(){if(ad)return _u;ad=1;function e(t){return t.split("")}return _u=e,_u}var Au,od;function O_(){if(od)return Au;od=1;var e="\\ud800-\\udfff",t="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",n="\\u20d0-\\u20ff",i=t+r+n,a="\\ufe0e\\ufe0f",o="["+e+"]",u="["+i+"]",c="\\ud83c[\\udffb-\\udfff]",s="(?:"+u+"|"+c+")",f="[^"+e+"]",l="(?:\\ud83c[\\udde6-\\uddff]){2}",h="[\\ud800-\\udbff][\\udc00-\\udfff]",d="\\u200d",y=s+"?",v="["+a+"]?",p="(?:"+d+"(?:"+[f,l,h].join("|")+")"+v+y+")*",g=v+y+p,x="(?:"+[f+u+"?",u,l,h,o].join("|")+")",w=RegExp(c+"(?="+c+")|"+x+g,"g");function O(m){return m.match(w)||[]}return Au=O,Au}var Su,ud;function __(){if(ud)return Su;ud=1;var e=w_(),t=Jb(),r=O_();function n(i){return t(i)?r(i):e(i)}return Su=n,Su}var Pu,cd;function A_(){if(cd)return Pu;cd=1;var e=x_(),t=Jb(),r=__(),n=Vb();function i(a){return function(o){o=n(o);var u=t(o)?r(o):void 0,c=u?u[0]:o.charAt(0),s=u?e(u,1).join(""):o.slice(1);return c[a]()+s}}return Pu=i,Pu}var Tu,sd;function S_(){if(sd)return Tu;sd=1;var e=A_(),t=e("toUpperCase");return Tu=t,Tu}var P_=S_();const Ia=oe(P_);function se(e){return function(){return e}}const Qb=Math.cos,Ci=Math.sin,at=Math.sqrt,Ii=Math.PI,ka=2*Ii,Ol=Math.PI,_l=2*Ol,Ut=1e-6,T_=_l-Ut;function e0(e){this._+=e[0];for(let t=1,r=e.length;t=0))throw new Error(`invalid digits: ${e}`);if(t>15)return e0;const r=10**t;return function(n){this._+=n[0];for(let i=1,a=n.length;iUt)if(!(Math.abs(l*c-s*f)>Ut)||!a)this._append`L${this._x1=t},${this._y1=r}`;else{let d=n-o,y=i-u,v=c*c+s*s,p=d*d+y*y,g=Math.sqrt(v),x=Math.sqrt(h),w=a*Math.tan((Ol-Math.acos((v+h-p)/(2*g*x)))/2),O=w/x,m=w/g;Math.abs(O-1)>Ut&&this._append`L${t+O*f},${r+O*l}`,this._append`A${a},${a},0,0,${+(l*d>f*y)},${this._x1=t+m*c},${this._y1=r+m*s}`}}arc(t,r,n,i,a,o){if(t=+t,r=+r,n=+n,o=!!o,n<0)throw new Error(`negative radius: ${n}`);let u=n*Math.cos(i),c=n*Math.sin(i),s=t+u,f=r+c,l=1^o,h=o?i-a:a-i;this._x1===null?this._append`M${s},${f}`:(Math.abs(this._x1-s)>Ut||Math.abs(this._y1-f)>Ut)&&this._append`L${s},${f}`,n&&(h<0&&(h=h%_l+_l),h>T_?this._append`A${n},${n},0,1,${l},${t-u},${r-c}A${n},${n},0,1,${l},${this._x1=s},${this._y1=f}`:h>Ut&&this._append`A${n},${n},0,${+(h>=Ol)},${l},${this._x1=t+n*Math.cos(a)},${this._y1=r+n*Math.sin(a)}`)}rect(t,r,n,i){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+r}h${n=+n}v${+i}h${-n}Z`}toString(){return this._}}function Gf(e){let t=3;return e.digits=function(r){if(!arguments.length)return t;if(r==null)t=null;else{const n=Math.floor(r);if(!(n>=0))throw new RangeError(`invalid digits: ${r}`);t=n}return e},()=>new j_(t)}function Vf(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function t0(e){this._context=e}t0.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t);break}}};function Ra(e){return new t0(e)}function r0(e){return e[0]}function n0(e){return e[1]}function i0(e,t){var r=se(!0),n=null,i=Ra,a=null,o=Gf(u);e=typeof e=="function"?e:e===void 0?r0:se(e),t=typeof t=="function"?t:t===void 0?n0:se(t);function u(c){var s,f=(c=Vf(c)).length,l,h=!1,d;for(n==null&&(a=i(d=o())),s=0;s<=f;++s)!(s=d;--y)u.point(w[y],O[y]);u.lineEnd(),u.areaEnd()}g&&(w[h]=+e(p,h,l),O[h]=+t(p,h,l),u.point(n?+n(p,h,l):w[h],r?+r(p,h,l):O[h]))}if(x)return u=null,x+""||null}function f(){return i0().defined(i).curve(o).context(a)}return s.x=function(l){return arguments.length?(e=typeof l=="function"?l:se(+l),n=null,s):e},s.x0=function(l){return arguments.length?(e=typeof l=="function"?l:se(+l),s):e},s.x1=function(l){return arguments.length?(n=l==null?null:typeof l=="function"?l:se(+l),s):n},s.y=function(l){return arguments.length?(t=typeof l=="function"?l:se(+l),r=null,s):t},s.y0=function(l){return arguments.length?(t=typeof l=="function"?l:se(+l),s):t},s.y1=function(l){return arguments.length?(r=l==null?null:typeof l=="function"?l:se(+l),s):r},s.lineX0=s.lineY0=function(){return f().x(e).y(t)},s.lineY1=function(){return f().x(e).y(r)},s.lineX1=function(){return f().x(n).y(t)},s.defined=function(l){return arguments.length?(i=typeof l=="function"?l:se(!!l),s):i},s.curve=function(l){return arguments.length?(o=l,a!=null&&(u=o(a)),s):o},s.context=function(l){return arguments.length?(l==null?a=u=null:u=o(a=l),s):a},s}class a0{constructor(t,r){this._context=t,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(t,r){switch(t=+t,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(t,r):this._context.moveTo(t,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,r,t,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,t,this._y0,t,r);break}}this._x0=t,this._y0=r}}function M_(e){return new a0(e,!0)}function $_(e){return new a0(e,!1)}const Xf={draw(e,t){const r=at(t/Ii);e.moveTo(r,0),e.arc(0,0,r,0,ka)}},C_={draw(e,t){const r=at(t/5)/2;e.moveTo(-3*r,-r),e.lineTo(-r,-r),e.lineTo(-r,-3*r),e.lineTo(r,-3*r),e.lineTo(r,-r),e.lineTo(3*r,-r),e.lineTo(3*r,r),e.lineTo(r,r),e.lineTo(r,3*r),e.lineTo(-r,3*r),e.lineTo(-r,r),e.lineTo(-3*r,r),e.closePath()}},o0=at(1/3),I_=o0*2,k_={draw(e,t){const r=at(t/I_),n=r*o0;e.moveTo(0,-r),e.lineTo(n,0),e.lineTo(0,r),e.lineTo(-n,0),e.closePath()}},R_={draw(e,t){const r=at(t),n=-r/2;e.rect(n,n,r,r)}},D_=.8908130915292852,u0=Ci(Ii/10)/Ci(7*Ii/10),N_=Ci(ka/10)*u0,q_=-Qb(ka/10)*u0,L_={draw(e,t){const r=at(t*D_),n=N_*r,i=q_*r;e.moveTo(0,-r),e.lineTo(n,i);for(let a=1;a<5;++a){const o=ka*a/5,u=Qb(o),c=Ci(o);e.lineTo(c*r,-u*r),e.lineTo(u*n-c*i,c*n+u*i)}e.closePath()}},Eu=at(3),B_={draw(e,t){const r=-at(t/(Eu*3));e.moveTo(0,r*2),e.lineTo(-Eu*r,-r),e.lineTo(Eu*r,-r),e.closePath()}},Ge=-.5,Ve=at(3)/2,Al=1/at(12),F_=(Al/2+1)*3,W_={draw(e,t){const r=at(t/F_),n=r/2,i=r*Al,a=n,o=r*Al+r,u=-a,c=o;e.moveTo(n,i),e.lineTo(a,o),e.lineTo(u,c),e.lineTo(Ge*n-Ve*i,Ve*n+Ge*i),e.lineTo(Ge*a-Ve*o,Ve*a+Ge*o),e.lineTo(Ge*u-Ve*c,Ve*u+Ge*c),e.lineTo(Ge*n+Ve*i,Ge*i-Ve*n),e.lineTo(Ge*a+Ve*o,Ge*o-Ve*a),e.lineTo(Ge*u+Ve*c,Ge*c-Ve*u),e.closePath()}};function z_(e,t){let r=null,n=Gf(i);e=typeof e=="function"?e:se(e||Xf),t=typeof t=="function"?t:se(t===void 0?64:+t);function i(){let a;if(r||(r=a=n()),e.apply(this,arguments).draw(r,+t.apply(this,arguments)),a)return r=null,a+""||null}return i.type=function(a){return arguments.length?(e=typeof a=="function"?a:se(a),i):e},i.size=function(a){return arguments.length?(t=typeof a=="function"?a:se(+a),i):t},i.context=function(a){return arguments.length?(r=a??null,i):r},i}function ki(){}function Ri(e,t,r){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+r)/6)}function c0(e){this._context=e}c0.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ri(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ri(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function U_(e){return new c0(e)}function s0(e){this._context=e}s0.prototype={areaStart:ki,areaEnd:ki,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Ri(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function H_(e){return new s0(e)}function l0(e){this._context=e}l0.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+e)/6,n=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:Ri(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function K_(e){return new l0(e)}function f0(e){this._context=e}f0.prototype={areaStart:ki,areaEnd:ki,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function G_(e){return new f0(e)}function ld(e){return e<0?-1:1}function fd(e,t,r){var n=e._x1-e._x0,i=t-e._x1,a=(e._y1-e._y0)/(n||i<0&&-0),o=(r-e._y1)/(i||n<0&&-0),u=(a*i+o*n)/(n+i);return(ld(a)+ld(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(u))||0}function hd(e,t){var r=e._x1-e._x0;return r?(3*(e._y1-e._y0)/r-t)/2:t}function ju(e,t,r){var n=e._x0,i=e._y0,a=e._x1,o=e._y1,u=(a-n)/3;e._context.bezierCurveTo(n+u,i+u*t,a-u,o-u*r,a,o)}function Di(e){this._context=e}Di.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:ju(this,this._t0,hd(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){var r=NaN;if(e=+e,t=+t,!(e===this._x1&&t===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,ju(this,hd(this,r=fd(this,e,t)),r);break;default:ju(this,this._t0,r=fd(this,e,t));break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t,this._t0=r}}};function h0(e){this._context=new p0(e)}(h0.prototype=Object.create(Di.prototype)).point=function(e,t){Di.prototype.point.call(this,t,e)};function p0(e){this._context=e}p0.prototype={moveTo:function(e,t){this._context.moveTo(t,e)},closePath:function(){this._context.closePath()},lineTo:function(e,t){this._context.lineTo(t,e)},bezierCurveTo:function(e,t,r,n,i,a){this._context.bezierCurveTo(t,e,n,r,a,i)}};function V_(e){return new Di(e)}function X_(e){return new h0(e)}function d0(e){this._context=e}d0.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var e=this._x,t=this._y,r=e.length;if(r)if(this._line?this._context.lineTo(e[0],t[0]):this._context.moveTo(e[0],t[0]),r===2)this._context.lineTo(e[1],t[1]);else for(var n=pd(e),i=pd(t),a=0,o=1;o=0;--t)i[t]=(o[t]-i[t+1])/a[t];for(a[r-1]=(e[r]+i[r-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var r=this._x*(1-this._t)+e*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,t)}break}}this._x=e,this._y=t}};function Z_(e){return new Da(e,.5)}function J_(e){return new Da(e,0)}function Q_(e){return new Da(e,1)}function Ar(e,t){if((o=e.length)>1)for(var r=1,n,i,a=e[t[0]],o,u=a.length;r=0;)r[t]=t;return r}function e1(e,t){return e[t]}function t1(e){const t=[];return t.key=e,t}function r1(){var e=se([]),t=Sl,r=Ar,n=e1;function i(a){var o=Array.from(e.apply(this,arguments),t1),u,c=o.length,s=-1,f;for(const l of a)for(u=0,++s;u0){for(var r,n,i=0,a=e[0].length,o;i0){for(var r=0,n=e[t[0]],i,a=n.length;r0)||!((a=(i=e[t[0]]).length)>0))){for(var r=0,n=1,i,a,o;n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function f1(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}var v0={symbolCircle:Xf,symbolCross:C_,symbolDiamond:k_,symbolSquare:R_,symbolStar:L_,symbolTriangle:B_,symbolWye:W_},h1=Math.PI/180,p1=function(t){var r="symbol".concat(Ia(t));return v0[r]||Xf},d1=function(t,r,n){if(r==="area")return t;switch(n){case"cross":return 5*t*t/9;case"diamond":return .5*t*t/Math.sqrt(3);case"square":return t*t;case"star":{var i=18*h1;return 1.25*t*t*(Math.tan(i)-Math.tan(i*2)*Math.pow(Math.tan(i),2))}case"triangle":return Math.sqrt(3)*t*t/4;case"wye":return(21-10*Math.sqrt(3))*t*t/8;default:return Math.PI*t*t/4}},v1=function(t,r){v0["symbol".concat(Ia(t))]=r},Yf=function(t){var r=t.type,n=r===void 0?"circle":r,i=t.size,a=i===void 0?64:i,o=t.sizeType,u=o===void 0?"area":o,c=l1(t,o1),s=vd(vd({},c),{},{type:n,size:a,sizeType:u}),f=function(){var p=p1(n),g=z_().type(p).size(d1(a,u,n));return g()},l=s.className,h=s.cx,d=s.cy,y=H(s,!0);return h===+h&&d===+d&&a===+a?S.createElement("path",Pl({},y,{className:J("recharts-symbols",l),transform:"translate(".concat(h,", ").concat(d,")"),d:f()})):null};Yf.registerSymbol=v1;function Sr(e){"@babel/helpers - typeof";return Sr=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Sr(e)}function Tl(){return Tl=Object.assign?Object.assign.bind():function(e){for(var t=1;t`);var x=d.inactive?s:d.color;return S.createElement("li",Tl({className:p,style:l,key:"legend-item-".concat(y)},tr(n.props,d,y)),S.createElement(xl,{width:o,height:o,viewBox:f,style:h},n.renderIcon(d)),S.createElement("span",{className:"recharts-legend-item-text",style:{color:x}},v?v(g,d,y):g))})}},{key:"render",value:function(){var n=this.props,i=n.payload,a=n.layout,o=n.align;if(!i||!i.length)return null;var u={padding:0,margin:0,textAlign:a==="horizontal"?o:"left"};return S.createElement("ul",{className:"recharts-default-legend",style:u},this.renderItems())}}])})(N.PureComponent);Sn(Zf,"displayName","Legend");Sn(Zf,"defaultProps",{iconSize:14,layout:"horizontal",align:"center",verticalAlign:"middle",inactiveColor:"#ccc"});var Mu,md;function S1(){if(md)return Mu;md=1;var e=Ma();function t(){this.__data__=new e,this.size=0}return Mu=t,Mu}var $u,gd;function P1(){if(gd)return $u;gd=1;function e(t){var r=this.__data__,n=r.delete(t);return this.size=r.size,n}return $u=e,$u}var Cu,bd;function T1(){if(bd)return Cu;bd=1;function e(t){return this.__data__.get(t)}return Cu=e,Cu}var Iu,xd;function E1(){if(xd)return Iu;xd=1;function e(t){return this.__data__.has(t)}return Iu=e,Iu}var ku,wd;function j1(){if(wd)return ku;wd=1;var e=Ma(),t=Ff(),r=Wf(),n=200;function i(a,o){var u=this.__data__;if(u instanceof e){var c=u.__data__;if(!t||c.lengthd))return!1;var v=l.get(o),p=l.get(u);if(v&&p)return v==u&&p==o;var g=-1,x=!0,w=c&i?new e:void 0;for(l.set(o,u),l.set(u,o);++g-1&&n%1==0&&n-1&&r%1==0&&r<=e}return rc=t,rc}var nc,Hd;function W1(){if(Hd)return nc;Hd=1;var e=St(),t=th(),r=Pt(),n="[object Arguments]",i="[object Array]",a="[object Boolean]",o="[object Date]",u="[object Error]",c="[object Function]",s="[object Map]",f="[object Number]",l="[object Object]",h="[object RegExp]",d="[object Set]",y="[object String]",v="[object WeakMap]",p="[object ArrayBuffer]",g="[object DataView]",x="[object Float32Array]",w="[object Float64Array]",O="[object Int8Array]",m="[object Int16Array]",b="[object Int32Array]",_="[object Uint8Array]",A="[object Uint8ClampedArray]",T="[object Uint16Array]",M="[object Uint32Array]",P={};P[x]=P[w]=P[O]=P[m]=P[b]=P[_]=P[A]=P[T]=P[M]=!0,P[n]=P[i]=P[p]=P[a]=P[g]=P[o]=P[u]=P[c]=P[s]=P[f]=P[l]=P[h]=P[d]=P[y]=P[v]=!1;function E(j){return r(j)&&t(j.length)&&!!P[e(j)]}return nc=E,nc}var ic,Kd;function S0(){if(Kd)return ic;Kd=1;function e(t){return function(r){return t(r)}}return ic=e,ic}var vn={exports:{}};vn.exports;var Gd;function z1(){return Gd||(Gd=1,(function(e,t){var r=Hb(),n=t&&!t.nodeType&&t,i=n&&!0&&e&&!e.nodeType&&e,a=i&&i.exports===n,o=a&&r.process,u=(function(){try{var c=i&&i.require&&i.require("util").types;return c||o&&o.binding&&o.binding("util")}catch{}})();e.exports=u})(vn,vn.exports)),vn.exports}var ac,Vd;function P0(){if(Vd)return ac;Vd=1;var e=W1(),t=S0(),r=z1(),n=r&&r.isTypedArray,i=n?t(n):e;return ac=i,ac}var oc,Xd;function U1(){if(Xd)return oc;Xd=1;var e=L1(),t=Qf(),r=qe(),n=A0(),i=eh(),a=P0(),o=Object.prototype,u=o.hasOwnProperty;function c(s,f){var l=r(s),h=!l&&t(s),d=!l&&!h&&n(s),y=!l&&!h&&!d&&a(s),v=l||h||d||y,p=v?e(s.length,String):[],g=p.length;for(var x in s)(f||u.call(s,x))&&!(v&&(x=="length"||d&&(x=="offset"||x=="parent")||y&&(x=="buffer"||x=="byteLength"||x=="byteOffset")||i(x,g)))&&p.push(x);return p}return oc=c,oc}var uc,Yd;function H1(){if(Yd)return uc;Yd=1;var e=Object.prototype;function t(r){var n=r&&r.constructor,i=typeof n=="function"&&n.prototype||e;return r===i}return uc=t,uc}var cc,Zd;function T0(){if(Zd)return cc;Zd=1;function e(t,r){return function(n){return t(r(n))}}return cc=e,cc}var sc,Jd;function K1(){if(Jd)return sc;Jd=1;var e=T0(),t=e(Object.keys,Object);return sc=t,sc}var lc,Qd;function G1(){if(Qd)return lc;Qd=1;var e=H1(),t=K1(),r=Object.prototype,n=r.hasOwnProperty;function i(a){if(!e(a))return t(a);var o=[];for(var u in Object(a))n.call(a,u)&&u!="constructor"&&o.push(u);return o}return lc=i,lc}var fc,ev;function ui(){if(ev)return fc;ev=1;var e=Lf(),t=th();function r(n){return n!=null&&t(n.length)&&!e(n)}return fc=r,fc}var hc,tv;function Na(){if(tv)return hc;tv=1;var e=U1(),t=G1(),r=ui();function n(i){return r(i)?e(i):t(i)}return hc=n,hc}var pc,rv;function V1(){if(rv)return pc;rv=1;var e=R1(),t=q1(),r=Na();function n(i){return e(i,r,t)}return pc=n,pc}var dc,nv;function X1(){if(nv)return dc;nv=1;var e=V1(),t=1,r=Object.prototype,n=r.hasOwnProperty;function i(a,o,u,c,s,f){var l=u&t,h=e(a),d=h.length,y=e(o),v=y.length;if(d!=v&&!l)return!1;for(var p=d;p--;){var g=h[p];if(!(l?g in o:n.call(o,g)))return!1}var x=f.get(a),w=f.get(o);if(x&&w)return x==o&&w==a;var O=!0;f.set(a,o),f.set(o,a);for(var m=l;++p-1}return Bc=t,Bc}var Fc,Mv;function vA(){if(Mv)return Fc;Mv=1;function e(t,r,n){for(var i=-1,a=t==null?0:t.length;++i=o){var g=s?null:i(c);if(g)return a(g);y=!1,h=n,p=new e}else p=s?[]:v;e:for(;++l=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function MA(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function $A(e){return e.value}function CA(e,t){if(S.isValidElement(e))return S.cloneElement(e,t);if(typeof e=="function")return S.createElement(e,t);t.ref;var r=jA(t,wA);return S.createElement(Zf,r)}var qv=1,wr=(function(e){function t(){var r;OA(this,t);for(var n=arguments.length,i=new Array(n),a=0;aqv||Math.abs(i.height-this.lastBoundingBox.height)>qv)&&(this.lastBoundingBox.width=i.width,this.lastBoundingBox.height=i.height,n&&n(i)):(this.lastBoundingBox.width!==-1||this.lastBoundingBox.height!==-1)&&(this.lastBoundingBox.width=-1,this.lastBoundingBox.height=-1,n&&n(null))}},{key:"getBBoxSnapshot",value:function(){return this.lastBoundingBox.width>=0&&this.lastBoundingBox.height>=0?pt({},this.lastBoundingBox):{width:0,height:0}}},{key:"getDefaultPosition",value:function(n){var i=this.props,a=i.layout,o=i.align,u=i.verticalAlign,c=i.margin,s=i.chartWidth,f=i.chartHeight,l,h;if(!n||(n.left===void 0||n.left===null)&&(n.right===void 0||n.right===null))if(o==="center"&&a==="vertical"){var d=this.getBBoxSnapshot();l={left:((s||0)-d.width)/2}}else l=o==="right"?{right:c&&c.right||0}:{left:c&&c.left||0};if(!n||(n.top===void 0||n.top===null)&&(n.bottom===void 0||n.bottom===null))if(u==="middle"){var y=this.getBBoxSnapshot();h={top:((f||0)-y.height)/2}}else h=u==="bottom"?{bottom:c&&c.bottom||0}:{top:c&&c.top||0};return pt(pt({},l),h)}},{key:"render",value:function(){var n=this,i=this.props,a=i.content,o=i.width,u=i.height,c=i.wrapperStyle,s=i.payloadUniqBy,f=i.payload,l=pt(pt({position:"absolute",width:o||"auto",height:u||"auto"},this.getDefaultPosition(c)),c);return S.createElement("div",{className:"recharts-legend-wrapper",style:l,ref:function(d){n.wrapperNode=d}},CA(a,pt(pt({},this.props),{},{payload:C0(f,s,$A)})))}}],[{key:"getWithHeight",value:function(n,i){var a=pt(pt({},this.defaultProps),n.props),o=a.layout;return o==="vertical"&&q(n.props.height)?{height:n.props.height}:o==="horizontal"?{width:n.props.width||i}:null}}])})(N.PureComponent);qa(wr,"displayName","Legend");qa(wr,"defaultProps",{iconSize:14,layout:"horizontal",align:"center",verticalAlign:"bottom"});var Kc,Lv;function IA(){if(Lv)return Kc;Lv=1;var e=ai(),t=Qf(),r=qe(),n=e?e.isConcatSpreadable:void 0;function i(a){return r(a)||t(a)||!!(n&&a&&a[n])}return Kc=i,Kc}var Gc,Bv;function R0(){if(Bv)return Gc;Bv=1;var e=_0(),t=IA();function r(n,i,a,o,u){var c=-1,s=n.length;for(a||(a=t),u||(u=[]);++c0&&a(f)?i>1?r(f,i-1,a,o,u):e(u,f):o||(u[u.length]=f)}return u}return Gc=r,Gc}var Vc,Fv;function kA(){if(Fv)return Vc;Fv=1;function e(t){return function(r,n,i){for(var a=-1,o=Object(r),u=i(r),c=u.length;c--;){var s=u[t?c:++a];if(n(o[s],s,o)===!1)break}return r}}return Vc=e,Vc}var Xc,Wv;function RA(){if(Wv)return Xc;Wv=1;var e=kA(),t=e();return Xc=t,Xc}var Yc,zv;function D0(){if(zv)return Yc;zv=1;var e=RA(),t=Na();function r(n,i){return n&&e(n,i,t)}return Yc=r,Yc}var Zc,Uv;function DA(){if(Uv)return Zc;Uv=1;var e=ui();function t(r,n){return function(i,a){if(i==null)return i;if(!e(i))return r(i,a);for(var o=i.length,u=n?o:-1,c=Object(i);(n?u--:++un||u&&c&&f&&!s&&!l||a&&c&&f||!i&&f||!o)return 1;if(!a&&!u&&!l&&r=s)return f;var l=i[a];return f*(l=="desc"?-1:1)}}return r.index-n.index}return rs=t,rs}var ns,Yv;function BA(){if(Yv)return ns;Yv=1;var e=zf(),t=Uf(),r=ht(),n=N0(),i=NA(),a=S0(),o=LA(),u=Jr(),c=qe();function s(f,l,h){l.length?l=e(l,function(v){return c(v)?function(p){return t(p,v.length===1?v[0]:v)}:v}):l=[u];var d=-1;l=e(l,a(r));var y=n(f,function(v,p,g){var x=e(l,function(w){return w(v)});return{criteria:x,index:++d,value:v}});return i(y,function(v,p){return o(v,p,h)})}return ns=s,ns}var is,Zv;function FA(){if(Zv)return is;Zv=1;function e(t,r,n){switch(n.length){case 0:return t.call(r);case 1:return t.call(r,n[0]);case 2:return t.call(r,n[0],n[1]);case 3:return t.call(r,n[0],n[1],n[2])}return t.apply(r,n)}return is=e,is}var as,Jv;function WA(){if(Jv)return as;Jv=1;var e=FA(),t=Math.max;function r(n,i,a){return i=t(i===void 0?n.length-1:i,0),function(){for(var o=arguments,u=-1,c=t(o.length-i,0),s=Array(c);++u0){if(++a>=e)return arguments[0]}else a=0;return i.apply(void 0,arguments)}}return ss=n,ss}var ls,ny;function KA(){if(ny)return ls;ny=1;var e=UA(),t=HA(),r=t(e);return ls=r,ls}var fs,iy;function GA(){if(iy)return fs;iy=1;var e=Jr(),t=WA(),r=KA();function n(i,a){return r(t(i,a,e),i+"")}return fs=n,fs}var hs,ay;function La(){if(ay)return hs;ay=1;var e=Bf(),t=ui(),r=eh(),n=It();function i(a,o,u){if(!n(u))return!1;var c=typeof o;return(c=="number"?t(u)&&r(o,u.length):c=="string"&&o in u)?e(u[o],a):!1}return hs=i,hs}var ps,oy;function VA(){if(oy)return ps;oy=1;var e=R0(),t=BA(),r=GA(),n=La(),i=r(function(a,o){if(a==null)return[];var u=o.length;return u>1&&n(a,o[0],o[1])?o=[]:u>2&&n(o[0],o[1],o[2])&&(o=[o[0]]),t(a,e(o,1),[])});return ps=i,ps}var XA=VA();const ih=oe(XA);function Pn(e){"@babel/helpers - typeof";return Pn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Pn(e)}function Ml(){return Ml=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=t.x),"".concat(an,"-left"),q(r)&&t&&q(t.x)&&r=t.y),"".concat(an,"-top"),q(n)&&t&&q(t.y)&&nv?Math.max(f,c[n]):Math.max(l,c[n])}function lS(e){var t=e.translateX,r=e.translateY,n=e.useTranslate3d;return{transform:n?"translate3d(".concat(t,"px, ").concat(r,"px, 0)"):"translate(".concat(t,"px, ").concat(r,"px)")}}function fS(e){var t=e.allowEscapeViewBox,r=e.coordinate,n=e.offsetTopLeft,i=e.position,a=e.reverseDirection,o=e.tooltipBox,u=e.useTranslate3d,c=e.viewBox,s,f,l;return o.height>0&&o.width>0&&r?(f=sy({allowEscapeViewBox:t,coordinate:r,key:"x",offsetTopLeft:n,position:i,reverseDirection:a,tooltipDimension:o.width,viewBox:c,viewBoxDimension:c.width}),l=sy({allowEscapeViewBox:t,coordinate:r,key:"y",offsetTopLeft:n,position:i,reverseDirection:a,tooltipDimension:o.height,viewBox:c,viewBoxDimension:c.height}),s=lS({translateX:f,translateY:l,useTranslate3d:u})):s=cS,{cssProperties:s,cssClasses:sS({translateX:f,translateY:l,coordinate:r})}}function Tr(e){"@babel/helpers - typeof";return Tr=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Tr(e)}function ly(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function fy(e){for(var t=1;thy||Math.abs(n.height-this.state.lastBoundingBox.height)>hy)&&this.setState({lastBoundingBox:{width:n.width,height:n.height}})}else(this.state.lastBoundingBox.width!==-1||this.state.lastBoundingBox.height!==-1)&&this.setState({lastBoundingBox:{width:-1,height:-1}})}},{key:"componentDidMount",value:function(){document.addEventListener("keydown",this.handleKeyDown),this.updateBBox()}},{key:"componentWillUnmount",value:function(){document.removeEventListener("keydown",this.handleKeyDown)}},{key:"componentDidUpdate",value:function(){var n,i;this.props.active&&this.updateBBox(),this.state.dismissed&&(((n=this.props.coordinate)===null||n===void 0?void 0:n.x)!==this.state.dismissedAtCoordinate.x||((i=this.props.coordinate)===null||i===void 0?void 0:i.y)!==this.state.dismissedAtCoordinate.y)&&(this.state.dismissed=!1)}},{key:"render",value:function(){var n=this,i=this.props,a=i.active,o=i.allowEscapeViewBox,u=i.animationDuration,c=i.animationEasing,s=i.children,f=i.coordinate,l=i.hasPayload,h=i.isAnimationActive,d=i.offset,y=i.position,v=i.reverseDirection,p=i.useTranslate3d,g=i.viewBox,x=i.wrapperStyle,w=fS({allowEscapeViewBox:o,coordinate:f,offsetTopLeft:d,position:y,reverseDirection:v,tooltipBox:this.state.lastBoundingBox,useTranslate3d:p,viewBox:g}),O=w.cssClasses,m=w.cssProperties,b=fy(fy({transition:h&&a?"transform ".concat(u,"ms ").concat(c):void 0},m),{},{pointerEvents:"none",visibility:!this.state.dismissed&&a&&l?"visible":"hidden",position:"absolute",top:0,left:0},x);return S.createElement("div",{tabIndex:-1,className:O,style:b,ref:function(A){n.wrapperNode=A}},s)}}])})(N.PureComponent),wS=function(){return!(typeof window<"u"&&window.document&&window.document.createElement&&window.setTimeout)},or={isSsr:wS()};function Er(e){"@babel/helpers - typeof";return Er=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Er(e)}function py(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function dy(e){for(var t=1;t0;return S.createElement(xS,{allowEscapeViewBox:o,animationDuration:u,animationEasing:c,isAnimationActive:h,active:a,coordinate:f,hasPayload:b,offset:d,position:p,reverseDirection:g,useTranslate3d:x,viewBox:w,wrapperStyle:O},$S(s,dy(dy({},this.props),{},{payload:m})))}}])})(N.PureComponent);ah(dt,"displayName","Tooltip");ah(dt,"defaultProps",{accessibilityLayer:!1,allowEscapeViewBox:{x:!1,y:!1},animationDuration:400,animationEasing:"ease",contentStyle:{},coordinate:{x:0,y:0},cursor:!0,cursorStyle:{},filterNull:!0,isAnimationActive:!or.isSsr,itemStyle:{},labelStyle:{},offset:10,reverseDirection:{x:!1,y:!1},separator:" : ",trigger:"hover",useTranslate3d:!1,viewBox:{x:0,y:0,height:0,width:0},wrapperStyle:{}});var vs,vy;function CS(){if(vy)return vs;vy=1;var e=ft(),t=function(){return e.Date.now()};return vs=t,vs}var ys,yy;function IS(){if(yy)return ys;yy=1;var e=/\s/;function t(r){for(var n=r.length;n--&&e.test(r.charAt(n)););return n}return ys=t,ys}var ms,my;function kS(){if(my)return ms;my=1;var e=IS(),t=/^\s+/;function r(n){return n&&n.slice(0,e(n)+1).replace(t,"")}return ms=r,ms}var gs,gy;function z0(){if(gy)return gs;gy=1;var e=kS(),t=It(),r=Xr(),n=NaN,i=/^[-+]0x[0-9a-f]+$/i,a=/^0b[01]+$/i,o=/^0o[0-7]+$/i,u=parseInt;function c(s){if(typeof s=="number")return s;if(r(s))return n;if(t(s)){var f=typeof s.valueOf=="function"?s.valueOf():s;s=t(f)?f+"":f}if(typeof s!="string")return s===0?s:+s;s=e(s);var l=a.test(s);return l||o.test(s)?u(s.slice(2),l?2:8):i.test(s)?n:+s}return gs=c,gs}var bs,by;function RS(){if(by)return bs;by=1;var e=It(),t=CS(),r=z0(),n="Expected a function",i=Math.max,a=Math.min;function o(u,c,s){var f,l,h,d,y,v,p=0,g=!1,x=!1,w=!0;if(typeof u!="function")throw new TypeError(n);c=r(c)||0,e(s)&&(g=!!s.leading,x="maxWait"in s,h=x?i(r(s.maxWait)||0,c):h,w="trailing"in s?!!s.trailing:w);function O(j){var C=f,$=l;return f=l=void 0,p=j,d=u.apply($,C),d}function m(j){return p=j,y=setTimeout(A,c),g?O(j):d}function b(j){var C=j-v,$=j-p,k=c-C;return x?a(k,h-$):k}function _(j){var C=j-v,$=j-p;return v===void 0||C>=c||C<0||x&&$>=h}function A(){var j=t();if(_(j))return T(j);y=setTimeout(A,b(j))}function T(j){return y=void 0,w&&f?O(j):(f=l=void 0,d)}function M(){y!==void 0&&clearTimeout(y),p=0,f=v=l=y=void 0}function P(){return y===void 0?d:T(t())}function E(){var j=t(),C=_(j);if(f=arguments,l=this,v=j,C){if(y===void 0)return m(v);if(x)return clearTimeout(y),y=setTimeout(A,c),O(v)}return y===void 0&&(y=setTimeout(A,c)),d}return E.cancel=M,E.flush=P,E}return bs=o,bs}var xs,xy;function DS(){if(xy)return xs;xy=1;var e=RS(),t=It(),r="Expected a function";function n(i,a,o){var u=!0,c=!0;if(typeof i!="function")throw new TypeError(r);return t(o)&&(u="leading"in o?!!o.leading:u,c="trailing"in o?!!o.trailing:c),e(i,a,{leading:u,maxWait:a,trailing:c})}return xs=n,xs}var NS=DS();const U0=oe(NS);function En(e){"@babel/helpers - typeof";return En=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},En(e)}function wy(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function gi(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r0&&(j=U0(j,v,{trailing:!0,leading:!1}));var C=new ResizeObserver(j),$=m.current.getBoundingClientRect(),k=$.width,R=$.height;return P(k,R),C.observe(m.current),function(){C.disconnect()}},[P,v]);var E=N.useMemo(function(){var j=T.containerWidth,C=T.containerHeight;if(j<0||C<0)return null;it(Gt(o)||Gt(c),`The width(%s) and height(%s) are both fixed numbers, - maybe you don't need to use a ResponsiveContainer.`,o,c),it(!r||r>0,"The aspect(%s) must be greater than zero.",r);var $=Gt(o)?j:o,k=Gt(c)?C:c;r&&r>0&&($?k=$/r:k&&($=k*r),h&&k>h&&(k=h)),it($>0||k>0,`The width(%s) and height(%s) of chart should be greater than 0, - please check the style of container, or the props width(%s) and height(%s), - or add a minWidth(%s) or minHeight(%s) or use aspect(%s) to control the - height and width.`,$,k,o,c,f,l,r);var R=!Array.isArray(d)&&bt(d.type).endsWith("Chart");return S.Children.map(d,function(L){return S.isValidElement(L)?N.cloneElement(L,gi({width:$,height:k},R?{style:gi({height:"100%",width:"100%",maxHeight:k,maxWidth:$},L.props.style)}:{})):L})},[r,d,c,h,l,f,T,o]);return S.createElement("div",{id:p?"".concat(p):void 0,className:J("recharts-responsive-container",g),style:gi(gi({},O),{},{width:o,height:c,minWidth:f,minHeight:l,maxHeight:h}),ref:m},E)}),oh=function(t){return null};oh.displayName="Cell";function jn(e){"@babel/helpers - typeof";return jn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},jn(e)}function _y(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function kl(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:{};if(t==null||or.isSsr)return{width:0,height:0};var n=ZS(r),i=JSON.stringify({text:t,copyStyle:n});if(fr.widthCache[i])return fr.widthCache[i];try{var a=document.getElementById(Ay);a||(a=document.createElement("span"),a.setAttribute("id",Ay),a.setAttribute("aria-hidden","true"),document.body.appendChild(a));var o=kl(kl({},YS),n);Object.assign(a.style,o),a.textContent="".concat(t);var u=a.getBoundingClientRect(),c={width:u.width,height:u.height};return fr.widthCache[i]=c,++fr.cacheCount>XS&&(fr.cacheCount=0,fr.widthCache={}),c}catch{return{width:0,height:0}}},JS=function(t){return{top:t.top+window.scrollY-document.documentElement.clientTop,left:t.left+window.scrollX-document.documentElement.clientLeft}};function Mn(e){"@babel/helpers - typeof";return Mn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Mn(e)}function Fi(e,t){return rP(e)||tP(e,t)||eP(e,t)||QS()}function QS(){throw new TypeError(`Invalid attempt to destructure non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function eP(e,t){if(e){if(typeof e=="string")return Sy(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Sy(e,t)}}function Sy(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function yP(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function $y(e,t){return xP(e)||bP(e,t)||gP(e,t)||mP()}function mP(){throw new TypeError(`Invalid attempt to destructure non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function gP(e,t){if(e){if(typeof e=="string")return Cy(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Cy(e,t)}}function Cy(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r0&&arguments[0]!==void 0?arguments[0]:[];return $.reduce(function(k,R){var L=R.word,B=R.width,U=k[k.length-1];if(U&&(i==null||a||U.width+B+nR.width?k:R})};if(!f)return d;for(var v="…",p=function($){var k=l.slice(0,$),R=V0({breakAll:s,style:c,children:k+v}).wordsWithComputedWidth,L=h(R),B=L.length>o||y(L).width>Number(i);return[B,L]},g=0,x=l.length-1,w=0,O;g<=x&&w<=l.length-1;){var m=Math.floor((g+x)/2),b=m-1,_=p(b),A=$y(_,2),T=A[0],M=A[1],P=p(m),E=$y(P,1),j=E[0];if(!T&&!j&&(g=m+1),T&&j&&(x=m-1),!T&&j){O=M;break}w++}return O||d},Iy=function(t){var r=Y(t)?[]:t.toString().split(G0);return[{words:r}]},OP=function(t){var r=t.width,n=t.scaleToFit,i=t.children,a=t.style,o=t.breakAll,u=t.maxLines;if((r||n)&&!or.isSsr){var c,s,f=V0({breakAll:o,children:i,style:a});if(f){var l=f.wordsWithComputedWidth,h=f.spaceWidth;c=l,s=h}else return Iy(i);return wP({breakAll:o,children:i,maxLines:u,style:a},c,s,r,n)}return Iy(i)},ky="#808080",rr=function(t){var r=t.x,n=r===void 0?0:r,i=t.y,a=i===void 0?0:i,o=t.lineHeight,u=o===void 0?"1em":o,c=t.capHeight,s=c===void 0?"0.71em":c,f=t.scaleToFit,l=f===void 0?!1:f,h=t.textAnchor,d=h===void 0?"start":h,y=t.verticalAnchor,v=y===void 0?"end":y,p=t.fill,g=p===void 0?ky:p,x=My(t,dP),w=N.useMemo(function(){return OP({breakAll:x.breakAll,children:x.children,maxLines:x.maxLines,scaleToFit:l,style:x.style,width:x.width})},[x.breakAll,x.children,x.maxLines,l,x.style,x.width]),O=x.dx,m=x.dy,b=x.angle,_=x.className,A=x.breakAll,T=My(x,vP);if(!Ae(n)||!Ae(a))return null;var M=n+(q(O)?O:0),P=a+(q(m)?m:0),E;switch(v){case"start":E=ws("calc(".concat(s,")"));break;case"middle":E=ws("calc(".concat((w.length-1)/2," * -").concat(u," + (").concat(s," / 2))"));break;default:E=ws("calc(".concat(w.length-1," * -").concat(u,")"));break}var j=[];if(l){var C=w[0].width,$=x.width;j.push("scale(".concat((q($)?$/C:1)/C,")"))}return b&&j.push("rotate(".concat(b,", ").concat(M,", ").concat(P,")")),j.length&&(T.transform=j.join(" ")),S.createElement("text",Rl({},H(T,!0),{x:M,y:P,className:J("recharts-text",_),textAnchor:d,fill:g.includes("url")?ky:g}),w.map(function(k,R){var L=k.words.join(A?"":" ");return S.createElement("tspan",{x:M,dy:R===0?E:u,key:"".concat(L,"-").concat(R)},L)}))};function Ct(e,t){return e==null||t==null?NaN:et?1:e>=t?0:NaN}function _P(e,t){return e==null||t==null?NaN:te?1:t>=e?0:NaN}function uh(e){let t,r,n;e.length!==2?(t=Ct,r=(u,c)=>Ct(e(u),c),n=(u,c)=>e(u)-c):(t=e===Ct||e===_P?e:AP,r=e,n=e);function i(u,c,s=0,f=u.length){if(s>>1;r(u[l],c)<0?s=l+1:f=l}while(s>>1;r(u[l],c)<=0?s=l+1:f=l}while(ss&&n(u[l-1],c)>-n(u[l],c)?l-1:l}return{left:i,center:o,right:a}}function AP(){return 0}function X0(e){return e===null?NaN:+e}function*SP(e,t){for(let r of e)r!=null&&(r=+r)>=r&&(yield r)}const PP=uh(Ct),ci=PP.right;uh(X0).center;class Ry extends Map{constructor(t,r=jP){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),t!=null)for(const[n,i]of t)this.set(n,i)}get(t){return super.get(Dy(this,t))}has(t){return super.has(Dy(this,t))}set(t,r){return super.set(TP(this,t),r)}delete(t){return super.delete(EP(this,t))}}function Dy({_intern:e,_key:t},r){const n=t(r);return e.has(n)?e.get(n):r}function TP({_intern:e,_key:t},r){const n=t(r);return e.has(n)?e.get(n):(e.set(n,r),r)}function EP({_intern:e,_key:t},r){const n=t(r);return e.has(n)&&(r=e.get(n),e.delete(n)),r}function jP(e){return e!==null&&typeof e=="object"?e.valueOf():e}function MP(e=Ct){if(e===Ct)return Y0;if(typeof e!="function")throw new TypeError("compare is not a function");return(t,r)=>{const n=e(t,r);return n||n===0?n:(e(r,r)===0)-(e(t,t)===0)}}function Y0(e,t){return(e==null||!(e>=e))-(t==null||!(t>=t))||(et?1:0)}const $P=Math.sqrt(50),CP=Math.sqrt(10),IP=Math.sqrt(2);function Wi(e,t,r){const n=(t-e)/Math.max(0,r),i=Math.floor(Math.log10(n)),a=n/Math.pow(10,i),o=a>=$P?10:a>=CP?5:a>=IP?2:1;let u,c,s;return i<0?(s=Math.pow(10,-i)/o,u=Math.round(e*s),c=Math.round(t*s),u/st&&--c,s=-s):(s=Math.pow(10,i)*o,u=Math.round(e/s),c=Math.round(t/s),u*st&&--c),c0))return[];if(e===t)return[e];const n=t=i))return[];const u=a-i+1,c=new Array(u);if(n)if(o<0)for(let s=0;s=n)&&(r=n);return r}function qy(e,t){let r;for(const n of e)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);return r}function Z0(e,t,r=0,n=1/0,i){if(t=Math.floor(t),r=Math.floor(Math.max(0,r)),n=Math.floor(Math.min(e.length-1,n)),!(r<=t&&t<=n))return e;for(i=i===void 0?Y0:MP(i);n>r;){if(n-r>600){const c=n-r+1,s=t-r+1,f=Math.log(c),l=.5*Math.exp(2*f/3),h=.5*Math.sqrt(f*l*(c-l)/c)*(s-c/2<0?-1:1),d=Math.max(r,Math.floor(t-s*l/c+h)),y=Math.min(n,Math.floor(t+(c-s)*l/c+h));Z0(e,t,d,y,i)}const a=e[t];let o=r,u=n;for(on(e,r,t),i(e[n],a)>0&&on(e,r,n);o0;)--u}i(e[r],a)===0?on(e,r,u):(++u,on(e,u,n)),u<=t&&(r=u+1),t<=u&&(n=u-1)}return e}function on(e,t,r){const n=e[t];e[t]=e[r],e[r]=n}function kP(e,t,r){if(e=Float64Array.from(SP(e)),!(!(n=e.length)||isNaN(t=+t))){if(t<=0||n<2)return qy(e);if(t>=1)return Ny(e);var n,i=(n-1)*t,a=Math.floor(i),o=Ny(Z0(e,a).subarray(0,a+1)),u=qy(e.subarray(a+1));return o+(u-o)*(i-a)}}function RP(e,t,r=X0){if(!(!(n=e.length)||isNaN(t=+t))){if(t<=0||n<2)return+r(e[0],0,e);if(t>=1)return+r(e[n-1],n-1,e);var n,i=(n-1)*t,a=Math.floor(i),o=+r(e[a],a,e),u=+r(e[a+1],a+1,e);return o+(u-o)*(i-a)}}function DP(e,t,r){e=+e,t=+t,r=(i=arguments.length)<2?(t=e,e=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((t-e)/r))|0,a=new Array(i);++n>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):r===8?xi(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):r===4?xi(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=qP.exec(e))?new Ne(t[1],t[2],t[3],1):(t=LP.exec(e))?new Ne(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=BP.exec(e))?xi(t[1],t[2],t[3],t[4]):(t=FP.exec(e))?xi(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=WP.exec(e))?Hy(t[1],t[2]/100,t[3]/100,1):(t=zP.exec(e))?Hy(t[1],t[2]/100,t[3]/100,t[4]):Ly.hasOwnProperty(e)?Wy(Ly[e]):e==="transparent"?new Ne(NaN,NaN,NaN,0):null}function Wy(e){return new Ne(e>>16&255,e>>8&255,e&255,1)}function xi(e,t,r,n){return n<=0&&(e=t=r=NaN),new Ne(e,t,r,n)}function KP(e){return e instanceof si||(e=kn(e)),e?(e=e.rgb(),new Ne(e.r,e.g,e.b,e.opacity)):new Ne}function Bl(e,t,r,n){return arguments.length===1?KP(e):new Ne(e,t,r,n??1)}function Ne(e,t,r,n){this.r=+e,this.g=+t,this.b=+r,this.opacity=+n}sh(Ne,Bl,Q0(si,{brighter(e){return e=e==null?zi:Math.pow(zi,e),new Ne(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Cn:Math.pow(Cn,e),new Ne(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new Ne(Zt(this.r),Zt(this.g),Zt(this.b),Ui(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:zy,formatHex:zy,formatHex8:GP,formatRgb:Uy,toString:Uy}));function zy(){return`#${Vt(this.r)}${Vt(this.g)}${Vt(this.b)}`}function GP(){return`#${Vt(this.r)}${Vt(this.g)}${Vt(this.b)}${Vt((isNaN(this.opacity)?1:this.opacity)*255)}`}function Uy(){const e=Ui(this.opacity);return`${e===1?"rgb(":"rgba("}${Zt(this.r)}, ${Zt(this.g)}, ${Zt(this.b)}${e===1?")":`, ${e})`}`}function Ui(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Zt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Vt(e){return e=Zt(e),(e<16?"0":"")+e.toString(16)}function Hy(e,t,r,n){return n<=0?e=t=r=NaN:r<=0||r>=1?e=t=NaN:t<=0&&(e=NaN),new nt(e,t,r,n)}function ex(e){if(e instanceof nt)return new nt(e.h,e.s,e.l,e.opacity);if(e instanceof si||(e=kn(e)),!e)return new nt;if(e instanceof nt)return e;e=e.rgb();var t=e.r/255,r=e.g/255,n=e.b/255,i=Math.min(t,r,n),a=Math.max(t,r,n),o=NaN,u=a-i,c=(a+i)/2;return u?(t===a?o=(r-n)/u+(r0&&c<1?0:o,new nt(o,u,c,e.opacity)}function VP(e,t,r,n){return arguments.length===1?ex(e):new nt(e,t,r,n??1)}function nt(e,t,r,n){this.h=+e,this.s=+t,this.l=+r,this.opacity=+n}sh(nt,VP,Q0(si,{brighter(e){return e=e==null?zi:Math.pow(zi,e),new nt(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Cn:Math.pow(Cn,e),new nt(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*t,i=2*r-n;return new Ne(Os(e>=240?e-240:e+120,i,n),Os(e,i,n),Os(e<120?e+240:e-120,i,n),this.opacity)},clamp(){return new nt(Ky(this.h),wi(this.s),wi(this.l),Ui(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Ui(this.opacity);return`${e===1?"hsl(":"hsla("}${Ky(this.h)}, ${wi(this.s)*100}%, ${wi(this.l)*100}%${e===1?")":`, ${e})`}`}}));function Ky(e){return e=(e||0)%360,e<0?e+360:e}function wi(e){return Math.max(0,Math.min(1,e||0))}function Os(e,t,r){return(e<60?t+(r-t)*e/60:e<180?r:e<240?t+(r-t)*(240-e)/60:t)*255}const lh=e=>()=>e;function XP(e,t){return function(r){return e+r*t}}function YP(e,t,r){return e=Math.pow(e,r),t=Math.pow(t,r)-e,r=1/r,function(n){return Math.pow(e+n*t,r)}}function ZP(e){return(e=+e)==1?tx:function(t,r){return r-t?YP(t,r,e):lh(isNaN(t)?r:t)}}function tx(e,t){var r=t-e;return r?XP(e,r):lh(isNaN(e)?t:e)}const Gy=(function e(t){var r=ZP(t);function n(i,a){var o=r((i=Bl(i)).r,(a=Bl(a)).r),u=r(i.g,a.g),c=r(i.b,a.b),s=tx(i.opacity,a.opacity);return function(f){return i.r=o(f),i.g=u(f),i.b=c(f),i.opacity=s(f),i+""}}return n.gamma=e,n})(1);function JP(e,t){t||(t=[]);var r=e?Math.min(t.length,e.length):0,n=t.slice(),i;return function(a){for(i=0;ir&&(a=t.slice(r,a),u[o]?u[o]+=a:u[++o]=a),(n=n[0])===(i=i[0])?u[o]?u[o]+=i:u[++o]=i:(u[++o]=null,c.push({i:o,x:Hi(n,i)})),r=_s.lastIndex;return rt&&(r=e,e=t,t=r),function(n){return Math.max(e,Math.min(t,n))}}function sT(e,t,r){var n=e[0],i=e[1],a=t[0],o=t[1];return i2?lT:sT,c=s=null,l}function l(h){return h==null||isNaN(h=+h)?a:(c||(c=u(e.map(n),t,r)))(n(o(h)))}return l.invert=function(h){return o(i((s||(s=u(t,e.map(n),Hi)))(h)))},l.domain=function(h){return arguments.length?(e=Array.from(h,Ki),f()):e.slice()},l.range=function(h){return arguments.length?(t=Array.from(h),f()):t.slice()},l.rangeRound=function(h){return t=Array.from(h),r=fh,f()},l.clamp=function(h){return arguments.length?(o=h?!0:ke,f()):o!==ke},l.interpolate=function(h){return arguments.length?(r=h,f()):r},l.unknown=function(h){return arguments.length?(a=h,l):a},function(h,d){return n=h,i=d,f()}}function hh(){return Ba()(ke,ke)}function fT(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function Gi(e,t){if((r=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var r,n=e.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+e.slice(r+1)]}function jr(e){return e=Gi(Math.abs(e)),e?e[1]:NaN}function hT(e,t){return function(r,n){for(var i=r.length,a=[],o=0,u=e[0],c=0;i>0&&u>0&&(c+u+1>n&&(u=Math.max(1,n-c)),a.push(r.substring(i-=u,i+u)),!((c+=u+1)>n));)u=e[o=(o+1)%e.length];return a.reverse().join(t)}}function pT(e){return function(t){return t.replace(/[0-9]/g,function(r){return e[+r]})}}var dT=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Rn(e){if(!(t=dT.exec(e)))throw new Error("invalid format: "+e);var t;return new ph({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}Rn.prototype=ph.prototype;function ph(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}ph.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function vT(e){e:for(var t=e.length,r=1,n=-1,i;r0&&(n=0);break}return n>0?e.slice(0,n)+e.slice(i+1):e}var rx;function yT(e,t){var r=Gi(e,t);if(!r)return e+"";var n=r[0],i=r[1],a=i-(rx=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,o=n.length;return a===o?n:a>o?n+new Array(a-o+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+Gi(e,Math.max(0,t+a-1))[0]}function Xy(e,t){var r=Gi(e,t);if(!r)return e+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}const Yy={"%":(e,t)=>(e*100).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:fT,e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>Xy(e*100,t),r:Xy,s:yT,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function Zy(e){return e}var Jy=Array.prototype.map,Qy=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function mT(e){var t=e.grouping===void 0||e.thousands===void 0?Zy:hT(Jy.call(e.grouping,Number),e.thousands+""),r=e.currency===void 0?"":e.currency[0]+"",n=e.currency===void 0?"":e.currency[1]+"",i=e.decimal===void 0?".":e.decimal+"",a=e.numerals===void 0?Zy:pT(Jy.call(e.numerals,String)),o=e.percent===void 0?"%":e.percent+"",u=e.minus===void 0?"−":e.minus+"",c=e.nan===void 0?"NaN":e.nan+"";function s(l){l=Rn(l);var h=l.fill,d=l.align,y=l.sign,v=l.symbol,p=l.zero,g=l.width,x=l.comma,w=l.precision,O=l.trim,m=l.type;m==="n"?(x=!0,m="g"):Yy[m]||(w===void 0&&(w=12),O=!0,m="g"),(p||h==="0"&&d==="=")&&(p=!0,h="0",d="=");var b=v==="$"?r:v==="#"&&/[boxX]/.test(m)?"0"+m.toLowerCase():"",_=v==="$"?n:/[%p]/.test(m)?o:"",A=Yy[m],T=/[defgprs%]/.test(m);w=w===void 0?6:/[gprs]/.test(m)?Math.max(1,Math.min(21,w)):Math.max(0,Math.min(20,w));function M(P){var E=b,j=_,C,$,k;if(m==="c")j=A(P)+j,P="";else{P=+P;var R=P<0||1/P<0;if(P=isNaN(P)?c:A(Math.abs(P),w),O&&(P=vT(P)),R&&+P==0&&y!=="+"&&(R=!1),E=(R?y==="("?y:u:y==="-"||y==="("?"":y)+E,j=(m==="s"?Qy[8+rx/3]:"")+j+(R&&y==="("?")":""),T){for(C=-1,$=P.length;++C<$;)if(k=P.charCodeAt(C),48>k||k>57){j=(k===46?i+P.slice(C+1):P.slice(C))+j,P=P.slice(0,C);break}}}x&&!p&&(P=t(P,1/0));var L=E.length+P.length+j.length,B=L>1)+E+P+j+B.slice(L);break;default:P=B+E+P+j;break}return a(P)}return M.toString=function(){return l+""},M}function f(l,h){var d=s((l=Rn(l),l.type="f",l)),y=Math.max(-8,Math.min(8,Math.floor(jr(h)/3)))*3,v=Math.pow(10,-y),p=Qy[8+y/3];return function(g){return d(v*g)+p}}return{format:s,formatPrefix:f}}var Oi,dh,nx;gT({thousands:",",grouping:[3],currency:["$",""]});function gT(e){return Oi=mT(e),dh=Oi.format,nx=Oi.formatPrefix,Oi}function bT(e){return Math.max(0,-jr(Math.abs(e)))}function xT(e,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(jr(t)/3)))*3-jr(Math.abs(e)))}function wT(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,jr(t)-jr(e))+1}function ix(e,t,r,n){var i=ql(e,t,r),a;switch(n=Rn(n??",f"),n.type){case"s":{var o=Math.max(Math.abs(e),Math.abs(t));return n.precision==null&&!isNaN(a=xT(i,o))&&(n.precision=a),nx(n,o)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=wT(i,Math.max(Math.abs(e),Math.abs(t))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=bT(i))&&(n.precision=a-(n.type==="%")*2);break}}return dh(n)}function kt(e){var t=e.domain;return e.ticks=function(r){var n=t();return Dl(n[0],n[n.length-1],r??10)},e.tickFormat=function(r,n){var i=t();return ix(i[0],i[i.length-1],r??10,n)},e.nice=function(r){r==null&&(r=10);var n=t(),i=0,a=n.length-1,o=n[i],u=n[a],c,s,f=10;for(u0;){if(s=Nl(o,u,r),s===c)return n[i]=o,n[a]=u,t(n);if(s>0)o=Math.floor(o/s)*s,u=Math.ceil(u/s)*s;else if(s<0)o=Math.ceil(o*s)/s,u=Math.floor(u*s)/s;else break;c=s}return e},e}function Vi(){var e=hh();return e.copy=function(){return li(e,Vi())},Qe.apply(e,arguments),kt(e)}function ax(e){var t;function r(n){return n==null||isNaN(n=+n)?t:n}return r.invert=r,r.domain=r.range=function(n){return arguments.length?(e=Array.from(n,Ki),r):e.slice()},r.unknown=function(n){return arguments.length?(t=n,r):t},r.copy=function(){return ax(e).unknown(t)},e=arguments.length?Array.from(e,Ki):[0,1],kt(r)}function ox(e,t){e=e.slice();var r=0,n=e.length-1,i=e[r],a=e[n],o;return aMath.pow(e,t)}function PT(e){return e===Math.E?Math.log:e===10&&Math.log10||e===2&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}function rm(e){return(t,r)=>-e(-t,r)}function vh(e){const t=e(em,tm),r=t.domain;let n=10,i,a;function o(){return i=PT(n),a=ST(n),r()[0]<0?(i=rm(i),a=rm(a),e(OT,_T)):e(em,tm),t}return t.base=function(u){return arguments.length?(n=+u,o()):n},t.domain=function(u){return arguments.length?(r(u),o()):r()},t.ticks=u=>{const c=r();let s=c[0],f=c[c.length-1];const l=f0){for(;h<=d;++h)for(y=1;yf)break;g.push(v)}}else for(;h<=d;++h)for(y=n-1;y>=1;--y)if(v=h>0?y/a(-h):y*a(h),!(vf)break;g.push(v)}g.length*2{if(u==null&&(u=10),c==null&&(c=n===10?"s":","),typeof c!="function"&&(!(n%1)&&(c=Rn(c)).precision==null&&(c.trim=!0),c=dh(c)),u===1/0)return c;const s=Math.max(1,n*u/t.ticks().length);return f=>{let l=f/a(Math.round(i(f)));return l*nr(ox(r(),{floor:u=>a(Math.floor(i(u))),ceil:u=>a(Math.ceil(i(u)))})),t}function ux(){const e=vh(Ba()).domain([1,10]);return e.copy=()=>li(e,ux()).base(e.base()),Qe.apply(e,arguments),e}function nm(e){return function(t){return Math.sign(t)*Math.log1p(Math.abs(t/e))}}function im(e){return function(t){return Math.sign(t)*Math.expm1(Math.abs(t))*e}}function yh(e){var t=1,r=e(nm(t),im(t));return r.constant=function(n){return arguments.length?e(nm(t=+n),im(t)):t},kt(r)}function cx(){var e=yh(Ba());return e.copy=function(){return li(e,cx()).constant(e.constant())},Qe.apply(e,arguments)}function am(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function TT(e){return e<0?-Math.sqrt(-e):Math.sqrt(e)}function ET(e){return e<0?-e*e:e*e}function mh(e){var t=e(ke,ke),r=1;function n(){return r===1?e(ke,ke):r===.5?e(TT,ET):e(am(r),am(1/r))}return t.exponent=function(i){return arguments.length?(r=+i,n()):r},kt(t)}function gh(){var e=mh(Ba());return e.copy=function(){return li(e,gh()).exponent(e.exponent())},Qe.apply(e,arguments),e}function jT(){return gh.apply(null,arguments).exponent(.5)}function om(e){return Math.sign(e)*e*e}function MT(e){return Math.sign(e)*Math.sqrt(Math.abs(e))}function sx(){var e=hh(),t=[0,1],r=!1,n;function i(a){var o=MT(e(a));return isNaN(o)?n:r?Math.round(o):o}return i.invert=function(a){return e.invert(om(a))},i.domain=function(a){return arguments.length?(e.domain(a),i):e.domain()},i.range=function(a){return arguments.length?(e.range((t=Array.from(a,Ki)).map(om)),i):t.slice()},i.rangeRound=function(a){return i.range(a).round(!0)},i.round=function(a){return arguments.length?(r=!!a,i):r},i.clamp=function(a){return arguments.length?(e.clamp(a),i):e.clamp()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return sx(e.domain(),t).round(r).clamp(e.clamp()).unknown(n)},Qe.apply(i,arguments),kt(i)}function lx(){var e=[],t=[],r=[],n;function i(){var o=0,u=Math.max(1,t.length);for(r=new Array(u-1);++o0?r[u-1]:e[0],u=r?[n[r-1],t]:[n[s-1],n[s]]},o.unknown=function(c){return arguments.length&&(a=c),o},o.thresholds=function(){return n.slice()},o.copy=function(){return fx().domain([e,t]).range(i).unknown(a)},Qe.apply(kt(o),arguments)}function hx(){var e=[.5],t=[0,1],r,n=1;function i(a){return a!=null&&a<=a?t[ci(e,a,0,n)]:r}return i.domain=function(a){return arguments.length?(e=Array.from(a),n=Math.min(e.length,t.length-1),i):e.slice()},i.range=function(a){return arguments.length?(t=Array.from(a),n=Math.min(e.length,t.length-1),i):t.slice()},i.invertExtent=function(a){var o=t.indexOf(a);return[e[o-1],e[o]]},i.unknown=function(a){return arguments.length?(r=a,i):r},i.copy=function(){return hx().domain(e).range(t).unknown(r)},Qe.apply(i,arguments)}const As=new Date,Ss=new Date;function Se(e,t,r,n){function i(a){return e(a=arguments.length===0?new Date:new Date(+a)),a}return i.floor=a=>(e(a=new Date(+a)),a),i.ceil=a=>(e(a=new Date(a-1)),t(a,1),e(a),a),i.round=a=>{const o=i(a),u=i.ceil(a);return a-o(t(a=new Date(+a),o==null?1:Math.floor(o)),a),i.range=(a,o,u)=>{const c=[];if(a=i.ceil(a),u=u==null?1:Math.floor(u),!(a0))return c;let s;do c.push(s=new Date(+a)),t(a,u),e(a);while(sSe(o=>{if(o>=o)for(;e(o),!a(o);)o.setTime(o-1)},(o,u)=>{if(o>=o)if(u<0)for(;++u<=0;)for(;t(o,-1),!a(o););else for(;--u>=0;)for(;t(o,1),!a(o););}),r&&(i.count=(a,o)=>(As.setTime(+a),Ss.setTime(+o),e(As),e(Ss),Math.floor(r(As,Ss))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?o=>n(o)%a===0:o=>i.count(0,o)%a===0):i)),i}const Xi=Se(()=>{},(e,t)=>{e.setTime(+e+t)},(e,t)=>t-e);Xi.every=e=>(e=Math.floor(e),!isFinite(e)||!(e>0)?null:e>1?Se(t=>{t.setTime(Math.floor(t/e)*e)},(t,r)=>{t.setTime(+t+r*e)},(t,r)=>(r-t)/e):Xi);Xi.range;const yt=1e3,Ze=yt*60,mt=Ze*60,Ot=mt*24,bh=Ot*7,um=Ot*30,Ps=Ot*365,Xt=Se(e=>{e.setTime(e-e.getMilliseconds())},(e,t)=>{e.setTime(+e+t*yt)},(e,t)=>(t-e)/yt,e=>e.getUTCSeconds());Xt.range;const xh=Se(e=>{e.setTime(e-e.getMilliseconds()-e.getSeconds()*yt)},(e,t)=>{e.setTime(+e+t*Ze)},(e,t)=>(t-e)/Ze,e=>e.getMinutes());xh.range;const wh=Se(e=>{e.setUTCSeconds(0,0)},(e,t)=>{e.setTime(+e+t*Ze)},(e,t)=>(t-e)/Ze,e=>e.getUTCMinutes());wh.range;const Oh=Se(e=>{e.setTime(e-e.getMilliseconds()-e.getSeconds()*yt-e.getMinutes()*Ze)},(e,t)=>{e.setTime(+e+t*mt)},(e,t)=>(t-e)/mt,e=>e.getHours());Oh.range;const _h=Se(e=>{e.setUTCMinutes(0,0,0)},(e,t)=>{e.setTime(+e+t*mt)},(e,t)=>(t-e)/mt,e=>e.getUTCHours());_h.range;const fi=Se(e=>e.setHours(0,0,0,0),(e,t)=>e.setDate(e.getDate()+t),(e,t)=>(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*Ze)/Ot,e=>e.getDate()-1);fi.range;const Fa=Se(e=>{e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCDate(e.getUTCDate()+t)},(e,t)=>(t-e)/Ot,e=>e.getUTCDate()-1);Fa.range;const px=Se(e=>{e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCDate(e.getUTCDate()+t)},(e,t)=>(t-e)/Ot,e=>Math.floor(e/Ot));px.range;function ur(e){return Se(t=>{t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)},(t,r)=>{t.setDate(t.getDate()+r*7)},(t,r)=>(r-t-(r.getTimezoneOffset()-t.getTimezoneOffset())*Ze)/bh)}const Wa=ur(0),Yi=ur(1),$T=ur(2),CT=ur(3),Mr=ur(4),IT=ur(5),kT=ur(6);Wa.range;Yi.range;$T.range;CT.range;Mr.range;IT.range;kT.range;function cr(e){return Se(t=>{t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)},(t,r)=>{t.setUTCDate(t.getUTCDate()+r*7)},(t,r)=>(r-t)/bh)}const za=cr(0),Zi=cr(1),RT=cr(2),DT=cr(3),$r=cr(4),NT=cr(5),qT=cr(6);za.range;Zi.range;RT.range;DT.range;$r.range;NT.range;qT.range;const Ah=Se(e=>{e.setDate(1),e.setHours(0,0,0,0)},(e,t)=>{e.setMonth(e.getMonth()+t)},(e,t)=>t.getMonth()-e.getMonth()+(t.getFullYear()-e.getFullYear())*12,e=>e.getMonth());Ah.range;const Sh=Se(e=>{e.setUTCDate(1),e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCMonth(e.getUTCMonth()+t)},(e,t)=>t.getUTCMonth()-e.getUTCMonth()+(t.getUTCFullYear()-e.getUTCFullYear())*12,e=>e.getUTCMonth());Sh.range;const _t=Se(e=>{e.setMonth(0,1),e.setHours(0,0,0,0)},(e,t)=>{e.setFullYear(e.getFullYear()+t)},(e,t)=>t.getFullYear()-e.getFullYear(),e=>e.getFullYear());_t.every=e=>!isFinite(e=Math.floor(e))||!(e>0)?null:Se(t=>{t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)},(t,r)=>{t.setFullYear(t.getFullYear()+r*e)});_t.range;const At=Se(e=>{e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCFullYear(e.getUTCFullYear()+t)},(e,t)=>t.getUTCFullYear()-e.getUTCFullYear(),e=>e.getUTCFullYear());At.every=e=>!isFinite(e=Math.floor(e))||!(e>0)?null:Se(t=>{t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,r)=>{t.setUTCFullYear(t.getUTCFullYear()+r*e)});At.range;function dx(e,t,r,n,i,a){const o=[[Xt,1,yt],[Xt,5,5*yt],[Xt,15,15*yt],[Xt,30,30*yt],[a,1,Ze],[a,5,5*Ze],[a,15,15*Ze],[a,30,30*Ze],[i,1,mt],[i,3,3*mt],[i,6,6*mt],[i,12,12*mt],[n,1,Ot],[n,2,2*Ot],[r,1,bh],[t,1,um],[t,3,3*um],[e,1,Ps]];function u(s,f,l){const h=fp).right(o,h);if(d===o.length)return e.every(ql(s/Ps,f/Ps,l));if(d===0)return Xi.every(Math.max(ql(s,f,l),1));const[y,v]=o[h/o[d-1][2]53)return null;"w"in D||(D.w=1),"Z"in D?(ee=Es(un(D.y,0,1)),be=ee.getUTCDay(),ee=be>4||be===0?Zi.ceil(ee):Zi(ee),ee=Fa.offset(ee,(D.V-1)*7),D.y=ee.getUTCFullYear(),D.m=ee.getUTCMonth(),D.d=ee.getUTCDate()+(D.w+6)%7):(ee=Ts(un(D.y,0,1)),be=ee.getDay(),ee=be>4||be===0?Yi.ceil(ee):Yi(ee),ee=fi.offset(ee,(D.V-1)*7),D.y=ee.getFullYear(),D.m=ee.getMonth(),D.d=ee.getDate()+(D.w+6)%7)}else("W"in D||"U"in D)&&("w"in D||(D.w="u"in D?D.u%7:"W"in D?1:0),be="Z"in D?Es(un(D.y,0,1)).getUTCDay():Ts(un(D.y,0,1)).getDay(),D.m=0,D.d="W"in D?(D.w+6)%7+D.W*7-(be+5)%7:D.w+D.U*7-(be+6)%7);return"Z"in D?(D.H+=D.Z/100|0,D.M+=D.Z%100,Es(D)):Ts(D)}}function A(F,Z,Q,D){for(var de=0,ee=Z.length,be=Q.length,xe,De;de=be)return-1;if(xe=Z.charCodeAt(de++),xe===37){if(xe=Z.charAt(de++),De=m[xe in cm?Z.charAt(de++):xe],!De||(D=De(F,Q,D))<0)return-1}else if(xe!=Q.charCodeAt(D++))return-1}return D}function T(F,Z,Q){var D=s.exec(Z.slice(Q));return D?(F.p=f.get(D[0].toLowerCase()),Q+D[0].length):-1}function M(F,Z,Q){var D=d.exec(Z.slice(Q));return D?(F.w=y.get(D[0].toLowerCase()),Q+D[0].length):-1}function P(F,Z,Q){var D=l.exec(Z.slice(Q));return D?(F.w=h.get(D[0].toLowerCase()),Q+D[0].length):-1}function E(F,Z,Q){var D=g.exec(Z.slice(Q));return D?(F.m=x.get(D[0].toLowerCase()),Q+D[0].length):-1}function j(F,Z,Q){var D=v.exec(Z.slice(Q));return D?(F.m=p.get(D[0].toLowerCase()),Q+D[0].length):-1}function C(F,Z,Q){return A(F,t,Z,Q)}function $(F,Z,Q){return A(F,r,Z,Q)}function k(F,Z,Q){return A(F,n,Z,Q)}function R(F){return o[F.getDay()]}function L(F){return a[F.getDay()]}function B(F){return c[F.getMonth()]}function U(F){return u[F.getMonth()]}function G(F){return i[+(F.getHours()>=12)]}function W(F){return 1+~~(F.getMonth()/3)}function V(F){return o[F.getUTCDay()]}function fe(F){return a[F.getUTCDay()]}function ye(F){return c[F.getUTCMonth()]}function Le(F){return u[F.getUTCMonth()]}function qt(F){return i[+(F.getUTCHours()>=12)]}function Re(F){return 1+~~(F.getUTCMonth()/3)}return{format:function(F){var Z=b(F+="",w);return Z.toString=function(){return F},Z},parse:function(F){var Z=_(F+="",!1);return Z.toString=function(){return F},Z},utcFormat:function(F){var Z=b(F+="",O);return Z.toString=function(){return F},Z},utcParse:function(F){var Z=_(F+="",!0);return Z.toString=function(){return F},Z}}}var cm={"-":"",_:" ",0:"0"},Ee=/^\s*\d+/,UT=/^%/,HT=/[\\^$*+?|[\]().{}]/g;function re(e,t,r){var n=e<0?"-":"",i=(n?-e:e)+"",a=i.length;return n+(a[t.toLowerCase(),r]))}function GT(e,t,r){var n=Ee.exec(t.slice(r,r+1));return n?(e.w=+n[0],r+n[0].length):-1}function VT(e,t,r){var n=Ee.exec(t.slice(r,r+1));return n?(e.u=+n[0],r+n[0].length):-1}function XT(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.U=+n[0],r+n[0].length):-1}function YT(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.V=+n[0],r+n[0].length):-1}function ZT(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.W=+n[0],r+n[0].length):-1}function sm(e,t,r){var n=Ee.exec(t.slice(r,r+4));return n?(e.y=+n[0],r+n[0].length):-1}function lm(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function JT(e,t,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(r,r+6));return n?(e.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function QT(e,t,r){var n=Ee.exec(t.slice(r,r+1));return n?(e.q=n[0]*3-3,r+n[0].length):-1}function eE(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.m=n[0]-1,r+n[0].length):-1}function fm(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.d=+n[0],r+n[0].length):-1}function tE(e,t,r){var n=Ee.exec(t.slice(r,r+3));return n?(e.m=0,e.d=+n[0],r+n[0].length):-1}function hm(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.H=+n[0],r+n[0].length):-1}function rE(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.M=+n[0],r+n[0].length):-1}function nE(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.S=+n[0],r+n[0].length):-1}function iE(e,t,r){var n=Ee.exec(t.slice(r,r+3));return n?(e.L=+n[0],r+n[0].length):-1}function aE(e,t,r){var n=Ee.exec(t.slice(r,r+6));return n?(e.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function oE(e,t,r){var n=UT.exec(t.slice(r,r+1));return n?r+n[0].length:-1}function uE(e,t,r){var n=Ee.exec(t.slice(r));return n?(e.Q=+n[0],r+n[0].length):-1}function cE(e,t,r){var n=Ee.exec(t.slice(r));return n?(e.s=+n[0],r+n[0].length):-1}function pm(e,t){return re(e.getDate(),t,2)}function sE(e,t){return re(e.getHours(),t,2)}function lE(e,t){return re(e.getHours()%12||12,t,2)}function fE(e,t){return re(1+fi.count(_t(e),e),t,3)}function vx(e,t){return re(e.getMilliseconds(),t,3)}function hE(e,t){return vx(e,t)+"000"}function pE(e,t){return re(e.getMonth()+1,t,2)}function dE(e,t){return re(e.getMinutes(),t,2)}function vE(e,t){return re(e.getSeconds(),t,2)}function yE(e){var t=e.getDay();return t===0?7:t}function mE(e,t){return re(Wa.count(_t(e)-1,e),t,2)}function yx(e){var t=e.getDay();return t>=4||t===0?Mr(e):Mr.ceil(e)}function gE(e,t){return e=yx(e),re(Mr.count(_t(e),e)+(_t(e).getDay()===4),t,2)}function bE(e){return e.getDay()}function xE(e,t){return re(Yi.count(_t(e)-1,e),t,2)}function wE(e,t){return re(e.getFullYear()%100,t,2)}function OE(e,t){return e=yx(e),re(e.getFullYear()%100,t,2)}function _E(e,t){return re(e.getFullYear()%1e4,t,4)}function AE(e,t){var r=e.getDay();return e=r>=4||r===0?Mr(e):Mr.ceil(e),re(e.getFullYear()%1e4,t,4)}function SE(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+re(t/60|0,"0",2)+re(t%60,"0",2)}function dm(e,t){return re(e.getUTCDate(),t,2)}function PE(e,t){return re(e.getUTCHours(),t,2)}function TE(e,t){return re(e.getUTCHours()%12||12,t,2)}function EE(e,t){return re(1+Fa.count(At(e),e),t,3)}function mx(e,t){return re(e.getUTCMilliseconds(),t,3)}function jE(e,t){return mx(e,t)+"000"}function ME(e,t){return re(e.getUTCMonth()+1,t,2)}function $E(e,t){return re(e.getUTCMinutes(),t,2)}function CE(e,t){return re(e.getUTCSeconds(),t,2)}function IE(e){var t=e.getUTCDay();return t===0?7:t}function kE(e,t){return re(za.count(At(e)-1,e),t,2)}function gx(e){var t=e.getUTCDay();return t>=4||t===0?$r(e):$r.ceil(e)}function RE(e,t){return e=gx(e),re($r.count(At(e),e)+(At(e).getUTCDay()===4),t,2)}function DE(e){return e.getUTCDay()}function NE(e,t){return re(Zi.count(At(e)-1,e),t,2)}function qE(e,t){return re(e.getUTCFullYear()%100,t,2)}function LE(e,t){return e=gx(e),re(e.getUTCFullYear()%100,t,2)}function BE(e,t){return re(e.getUTCFullYear()%1e4,t,4)}function FE(e,t){var r=e.getUTCDay();return e=r>=4||r===0?$r(e):$r.ceil(e),re(e.getUTCFullYear()%1e4,t,4)}function WE(){return"+0000"}function vm(){return"%"}function ym(e){return+e}function mm(e){return Math.floor(+e/1e3)}var hr,bx,xx;zE({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function zE(e){return hr=zT(e),bx=hr.format,hr.parse,xx=hr.utcFormat,hr.utcParse,hr}function UE(e){return new Date(e)}function HE(e){return e instanceof Date?+e:+new Date(+e)}function Ph(e,t,r,n,i,a,o,u,c,s){var f=hh(),l=f.invert,h=f.domain,d=s(".%L"),y=s(":%S"),v=s("%I:%M"),p=s("%I %p"),g=s("%a %d"),x=s("%b %d"),w=s("%B"),O=s("%Y");function m(b){return(c(b)t(i/(e.length-1)))},r.quantiles=function(n){return Array.from({length:n+1},(i,a)=>kP(e,a/n))},r.copy=function(){return Ax(t).domain(e)},Tt.apply(r,arguments)}function Ha(){var e=0,t=.5,r=1,n=1,i,a,o,u,c,s=ke,f,l=!1,h;function d(v){return isNaN(v=+v)?h:(v=.5+((v=+f(v))-a)*(n*vr}return Ms=e,Ms}var $s,wm;function YE(){if(wm)return $s;wm=1;var e=Ka(),t=Ex(),r=Jr();function n(i){return i&&i.length?e(i,r,t):void 0}return $s=n,$s}var ZE=YE();const Ga=oe(ZE);var Cs,Om;function jx(){if(Om)return Cs;Om=1;function e(t,r){return te.e^a.s<0?1:-1;for(n=a.d.length,i=e.d.length,t=0,r=ne.d[t]^a.s<0?1:-1;return n===i?0:n>i^a.s<0?1:-1};z.decimalPlaces=z.dp=function(){var e=this,t=e.d.length-1,r=(t-e.e)*he;if(t=e.d[t],t)for(;t%10==0;t/=10)r--;return r<0?0:r};z.dividedBy=z.div=function(e){return xt(this,new this.constructor(e))};z.dividedToIntegerBy=z.idiv=function(e){var t=this,r=t.constructor;return ue(xt(t,new r(e),0,1),r.precision)};z.equals=z.eq=function(e){return!this.cmp(e)};z.exponent=function(){return ge(this)};z.greaterThan=z.gt=function(e){return this.cmp(e)>0};z.greaterThanOrEqualTo=z.gte=function(e){return this.cmp(e)>=0};z.isInteger=z.isint=function(){return this.e>this.d.length-2};z.isNegative=z.isneg=function(){return this.s<0};z.isPositive=z.ispos=function(){return this.s>0};z.isZero=function(){return this.s===0};z.lessThan=z.lt=function(e){return this.cmp(e)<0};z.lessThanOrEqualTo=z.lte=function(e){return this.cmp(e)<1};z.logarithm=z.log=function(e){var t,r=this,n=r.constructor,i=n.precision,a=i+5;if(e===void 0)e=new n(10);else if(e=new n(e),e.s<1||e.eq(Ue))throw Error(Je+"NaN");if(r.s<1)throw Error(Je+(r.s?"NaN":"-Infinity"));return r.eq(Ue)?new n(0):(pe=!1,t=xt(Dn(r,a),Dn(e,a),a),pe=!0,ue(t,i))};z.minus=z.sub=function(e){var t=this;return e=new t.constructor(e),t.s==e.s?Ix(t,e):$x(t,(e.s=-e.s,e))};z.modulo=z.mod=function(e){var t,r=this,n=r.constructor,i=n.precision;if(e=new n(e),!e.s)throw Error(Je+"NaN");return r.s?(pe=!1,t=xt(r,e,0,1).times(e),pe=!0,r.minus(t)):ue(new n(r),i)};z.naturalExponential=z.exp=function(){return Cx(this)};z.naturalLogarithm=z.ln=function(){return Dn(this)};z.negated=z.neg=function(){var e=new this.constructor(this);return e.s=-e.s||0,e};z.plus=z.add=function(e){var t=this;return e=new t.constructor(e),t.s==e.s?$x(t,e):Ix(t,(e.s=-e.s,e))};z.precision=z.sd=function(e){var t,r,n,i=this;if(e!==void 0&&e!==!!e&&e!==1&&e!==0)throw Error(Jt+e);if(t=ge(i)+1,n=i.d.length-1,r=n*he+1,n=i.d[n],n){for(;n%10==0;n/=10)r--;for(n=i.d[0];n>=10;n/=10)r++}return e&&t>r?t:r};z.squareRoot=z.sqrt=function(){var e,t,r,n,i,a,o,u=this,c=u.constructor;if(u.s<1){if(!u.s)return new c(0);throw Error(Je+"NaN")}for(e=ge(u),pe=!1,i=Math.sqrt(+u),i==0||i==1/0?(t=ot(u.d),(t.length+e)%2==0&&(t+="0"),i=Math.sqrt(t),e=tn((e+1)/2)-(e<0||e%2),i==1/0?t="5e"+e:(t=i.toExponential(),t=t.slice(0,t.indexOf("e")+1)+e),n=new c(t)):n=new c(i.toString()),r=c.precision,i=o=r+3;;)if(a=n,n=a.plus(xt(u,a,o+2)).times(.5),ot(a.d).slice(0,o)===(t=ot(n.d)).slice(0,o)){if(t=t.slice(o-3,o+1),i==o&&t=="4999"){if(ue(a,r+1,0),a.times(a).eq(u)){n=a;break}}else if(t!="9999")break;o+=4}return pe=!0,ue(n,r)};z.times=z.mul=function(e){var t,r,n,i,a,o,u,c,s,f=this,l=f.constructor,h=f.d,d=(e=new l(e)).d;if(!f.s||!e.s)return new l(0);for(e.s*=f.s,r=f.e+e.e,c=h.length,s=d.length,c=0;){for(t=0,i=c+n;i>n;)u=a[i]+d[n]*h[i-n-1]+t,a[i--]=u%Pe|0,t=u/Pe|0;a[i]=(a[i]+t)%Pe|0}for(;!a[--o];)a.pop();return t?++r:a.shift(),e.d=a,e.e=r,pe?ue(e,l.precision):e};z.toDecimalPlaces=z.todp=function(e,t){var r=this,n=r.constructor;return r=new n(r),e===void 0?r:(st(e,0,en),t===void 0?t=n.rounding:st(t,0,8),ue(r,e+ge(r)+1,t))};z.toExponential=function(e,t){var r,n=this,i=n.constructor;return e===void 0?r=nr(n,!0):(st(e,0,en),t===void 0?t=i.rounding:st(t,0,8),n=ue(new i(n),e+1,t),r=nr(n,!0,e+1)),r};z.toFixed=function(e,t){var r,n,i=this,a=i.constructor;return e===void 0?nr(i):(st(e,0,en),t===void 0?t=a.rounding:st(t,0,8),n=ue(new a(i),e+ge(i)+1,t),r=nr(n.abs(),!1,e+ge(n)+1),i.isneg()&&!i.isZero()?"-"+r:r)};z.toInteger=z.toint=function(){var e=this,t=e.constructor;return ue(new t(e),ge(e)+1,t.rounding)};z.toNumber=function(){return+this};z.toPower=z.pow=function(e){var t,r,n,i,a,o,u=this,c=u.constructor,s=12,f=+(e=new c(e));if(!e.s)return new c(Ue);if(u=new c(u),!u.s){if(e.s<1)throw Error(Je+"Infinity");return u}if(u.eq(Ue))return u;if(n=c.precision,e.eq(Ue))return ue(u,n);if(t=e.e,r=e.d.length-1,o=t>=r,a=u.s,o){if((r=f<0?-f:f)<=Mx){for(i=new c(Ue),t=Math.ceil(n/he+4),pe=!1;r%2&&(i=i.times(u),Em(i.d,t)),r=tn(r/2),r!==0;)u=u.times(u),Em(u.d,t);return pe=!0,e.s<0?new c(Ue).div(i):ue(i,n)}}else if(a<0)throw Error(Je+"NaN");return a=a<0&&e.d[Math.max(t,r)]&1?-1:1,u.s=1,pe=!1,i=e.times(Dn(u,n+s)),pe=!0,i=Cx(i),i.s=a,i};z.toPrecision=function(e,t){var r,n,i=this,a=i.constructor;return e===void 0?(r=ge(i),n=nr(i,r<=a.toExpNeg||r>=a.toExpPos)):(st(e,1,en),t===void 0?t=a.rounding:st(t,0,8),i=ue(new a(i),e,t),r=ge(i),n=nr(i,e<=r||r<=a.toExpNeg,e)),n};z.toSignificantDigits=z.tosd=function(e,t){var r=this,n=r.constructor;return e===void 0?(e=n.precision,t=n.rounding):(st(e,1,en),t===void 0?t=n.rounding:st(t,0,8)),ue(new n(r),e,t)};z.toString=z.valueOf=z.val=z.toJSON=z[Symbol.for("nodejs.util.inspect.custom")]=function(){var e=this,t=ge(e),r=e.constructor;return nr(e,t<=r.toExpNeg||t>=r.toExpPos)};function $x(e,t){var r,n,i,a,o,u,c,s,f=e.constructor,l=f.precision;if(!e.s||!t.s)return t.s||(t=new f(e)),pe?ue(t,l):t;if(c=e.d,s=t.d,o=e.e,i=t.e,c=c.slice(),a=o-i,a){for(a<0?(n=c,a=-a,u=s.length):(n=s,i=o,u=c.length),o=Math.ceil(l/he),u=o>u?o+1:u+1,a>u&&(a=u,n.length=1),n.reverse();a--;)n.push(0);n.reverse()}for(u=c.length,a=s.length,u-a<0&&(a=u,n=s,s=c,c=n),r=0;a;)r=(c[--a]=c[a]+s[a]+r)/Pe|0,c[a]%=Pe;for(r&&(c.unshift(r),++i),u=c.length;c[--u]==0;)c.pop();return t.d=c,t.e=i,pe?ue(t,l):t}function st(e,t,r){if(e!==~~e||er)throw Error(Jt+e)}function ot(e){var t,r,n,i=e.length-1,a="",o=e[0];if(i>0){for(a+=o,t=1;to?1:-1;else for(u=c=0;ui[u]?1:-1;break}return c}function r(n,i,a){for(var o=0;a--;)n[a]-=o,o=n[a]1;)n.shift()}return function(n,i,a,o){var u,c,s,f,l,h,d,y,v,p,g,x,w,O,m,b,_,A,T=n.constructor,M=n.s==i.s?1:-1,P=n.d,E=i.d;if(!n.s)return new T(n);if(!i.s)throw Error(Je+"Division by zero");for(c=n.e-i.e,_=E.length,m=P.length,d=new T(M),y=d.d=[],s=0;E[s]==(P[s]||0);)++s;if(E[s]>(P[s]||0)&&--c,a==null?x=a=T.precision:o?x=a+(ge(n)-ge(i))+1:x=a,x<0)return new T(0);if(x=x/he+2|0,s=0,_==1)for(f=0,E=E[0],x++;(s1&&(E=e(E,f),P=e(P,f),_=E.length,m=P.length),O=_,v=P.slice(0,_),p=v.length;p<_;)v[p++]=0;A=E.slice(),A.unshift(0),b=E[0],E[1]>=Pe/2&&++b;do f=0,u=t(E,v,_,p),u<0?(g=v[0],_!=p&&(g=g*Pe+(v[1]||0)),f=g/b|0,f>1?(f>=Pe&&(f=Pe-1),l=e(E,f),h=l.length,p=v.length,u=t(l,v,h,p),u==1&&(f--,r(l,_16)throw Error(jh+ge(e));if(!e.s)return new f(Ue);for(pe=!1,u=l,o=new f(.03125);e.abs().gte(.1);)e=e.times(o),s+=5;for(n=Math.log(Ht(2,s))/Math.LN10*2+5|0,u+=n,r=i=a=new f(Ue),f.precision=u;;){if(i=ue(i.times(e),u),r=r.times(++c),o=a.plus(xt(i,r,u)),ot(o.d).slice(0,u)===ot(a.d).slice(0,u)){for(;s--;)a=ue(a.times(a),u);return f.precision=l,t==null?(pe=!0,ue(a,l)):a}a=o}}function ge(e){for(var t=e.e*he,r=e.d[0];r>=10;r/=10)t++;return t}function Ns(e,t,r){if(t>e.LN10.sd())throw pe=!0,r&&(e.precision=r),Error(Je+"LN10 precision limit exceeded");return ue(new e(e.LN10),t)}function jt(e){for(var t="";e--;)t+="0";return t}function Dn(e,t){var r,n,i,a,o,u,c,s,f,l=1,h=10,d=e,y=d.d,v=d.constructor,p=v.precision;if(d.s<1)throw Error(Je+(d.s?"NaN":"-Infinity"));if(d.eq(Ue))return new v(0);if(t==null?(pe=!1,s=p):s=t,d.eq(10))return t==null&&(pe=!0),Ns(v,s);if(s+=h,v.precision=s,r=ot(y),n=r.charAt(0),a=ge(d),Math.abs(a)<15e14){for(;n<7&&n!=1||n==1&&r.charAt(1)>3;)d=d.times(e),r=ot(d.d),n=r.charAt(0),l++;a=ge(d),n>1?(d=new v("0."+r),a++):d=new v(n+"."+r.slice(1))}else return c=Ns(v,s+2,p).times(a+""),d=Dn(new v(n+"."+r.slice(1)),s-h).plus(c),v.precision=p,t==null?(pe=!0,ue(d,p)):d;for(u=o=d=xt(d.minus(Ue),d.plus(Ue),s),f=ue(d.times(d),s),i=3;;){if(o=ue(o.times(f),s),c=u.plus(xt(o,new v(i),s)),ot(c.d).slice(0,s)===ot(u.d).slice(0,s))return u=u.times(2),a!==0&&(u=u.plus(Ns(v,s+2,p).times(a+""))),u=xt(u,new v(l),s),v.precision=p,t==null?(pe=!0,ue(u,p)):u;u=c,i+=2}}function Tm(e,t){var r,n,i;for((r=t.indexOf("."))>-1&&(t=t.replace(".","")),(n=t.search(/e/i))>0?(r<0&&(r=n),r+=+t.slice(n+1),t=t.substring(0,n)):r<0&&(r=t.length),n=0;t.charCodeAt(n)===48;)++n;for(i=t.length;t.charCodeAt(i-1)===48;)--i;if(t=t.slice(n,i),t){if(i-=n,r=r-n-1,e.e=tn(r/he),e.d=[],n=(r+1)%he,r<0&&(n+=he),nJi||e.e<-Ji))throw Error(jh+r)}else e.s=0,e.e=0,e.d=[0];return e}function ue(e,t,r){var n,i,a,o,u,c,s,f,l=e.d;for(o=1,a=l[0];a>=10;a/=10)o++;if(n=t-o,n<0)n+=he,i=t,s=l[f=0];else{if(f=Math.ceil((n+1)/he),a=l.length,f>=a)return e;for(s=a=l[f],o=1;a>=10;a/=10)o++;n%=he,i=n-he+o}if(r!==void 0&&(a=Ht(10,o-i-1),u=s/a%10|0,c=t<0||l[f+1]!==void 0||s%a,c=r<4?(u||c)&&(r==0||r==(e.s<0?3:2)):u>5||u==5&&(r==4||c||r==6&&(n>0?i>0?s/Ht(10,o-i):0:l[f-1])%10&1||r==(e.s<0?8:7))),t<1||!l[0])return c?(a=ge(e),l.length=1,t=t-a-1,l[0]=Ht(10,(he-t%he)%he),e.e=tn(-t/he)||0):(l.length=1,l[0]=e.e=e.s=0),e;if(n==0?(l.length=f,a=1,f--):(l.length=f+1,a=Ht(10,he-n),l[f]=i>0?(s/Ht(10,o-i)%Ht(10,i)|0)*a:0),c)for(;;)if(f==0){(l[0]+=a)==Pe&&(l[0]=1,++e.e);break}else{if(l[f]+=a,l[f]!=Pe)break;l[f--]=0,a=1}for(n=l.length;l[--n]===0;)l.pop();if(pe&&(e.e>Ji||e.e<-Ji))throw Error(jh+ge(e));return e}function Ix(e,t){var r,n,i,a,o,u,c,s,f,l,h=e.constructor,d=h.precision;if(!e.s||!t.s)return t.s?t.s=-t.s:t=new h(e),pe?ue(t,d):t;if(c=e.d,l=t.d,n=t.e,s=e.e,c=c.slice(),o=s-n,o){for(f=o<0,f?(r=c,o=-o,u=l.length):(r=l,n=s,u=c.length),i=Math.max(Math.ceil(d/he),u)+2,o>i&&(o=i,r.length=1),r.reverse(),i=o;i--;)r.push(0);r.reverse()}else{for(i=c.length,u=l.length,f=i0;--i)c[u++]=0;for(i=l.length;i>o;){if(c[--i]0?a=a.charAt(0)+"."+a.slice(1)+jt(n):o>1&&(a=a.charAt(0)+"."+a.slice(1)),a=a+(i<0?"e":"e+")+i):i<0?(a="0."+jt(-i-1)+a,r&&(n=r-o)>0&&(a+=jt(n))):i>=o?(a+=jt(i+1-o),r&&(n=r-i-1)>0&&(a=a+"."+jt(n))):((n=i+1)0&&(i+1===o&&(a+="."),a+=jt(n))),e.s<0?"-"+a:a}function Em(e,t){if(e.length>t)return e.length=t,!0}function kx(e){var t,r,n;function i(a){var o=this;if(!(o instanceof i))return new i(a);if(o.constructor=i,a instanceof i){o.s=a.s,o.e=a.e,o.d=(a=a.d)?a.slice():a;return}if(typeof a=="number"){if(a*0!==0)throw Error(Jt+a);if(a>0)o.s=1;else if(a<0)a=-a,o.s=-1;else{o.s=0,o.e=0,o.d=[0];return}if(a===~~a&&a<1e7){o.e=0,o.d=[a];return}return Tm(o,a.toString())}else if(typeof a!="string")throw Error(Jt+a);if(a.charCodeAt(0)===45?(a=a.slice(1),o.s=-1):o.s=1,uj.test(a))Tm(o,a);else throw Error(Jt+a)}if(i.prototype=z,i.ROUND_UP=0,i.ROUND_DOWN=1,i.ROUND_CEIL=2,i.ROUND_FLOOR=3,i.ROUND_HALF_UP=4,i.ROUND_HALF_DOWN=5,i.ROUND_HALF_EVEN=6,i.ROUND_HALF_CEIL=7,i.ROUND_HALF_FLOOR=8,i.clone=kx,i.config=i.set=cj,e===void 0&&(e={}),e)for(n=["precision","rounding","toExpNeg","toExpPos","LN10"],t=0;t=i[t+1]&&n<=i[t+2])this[r]=n;else throw Error(Jt+r+": "+n);if((n=e[r="LN10"])!==void 0)if(n==Math.LN10)this[r]=new this(n);else throw Error(Jt+r+": "+n);return this}var Mh=kx(oj);Ue=new Mh(1);const ae=Mh;function sj(e){return pj(e)||hj(e)||fj(e)||lj()}function lj(){throw new TypeError(`Invalid attempt to spread non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function fj(e,t){if(e){if(typeof e=="string")return zl(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return zl(e,t)}}function hj(e){if(typeof Symbol<"u"&&Symbol.iterator in Object(e))return Array.from(e)}function pj(e){if(Array.isArray(e))return zl(e)}function zl(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=t?r.apply(void 0,i):e(t-o,jm(function(){for(var u=arguments.length,c=new Array(u),s=0;se.length)&&(t=e.length);for(var r=0,n=new Array(t);r"u"||!(Symbol.iterator in Object(e)))){var r=[],n=!0,i=!1,a=void 0;try{for(var o=e[Symbol.iterator](),u;!(n=(u=o.next()).done)&&(r.push(u.value),!(t&&r.length===t));n=!0);}catch(c){i=!0,a=c}finally{try{!n&&o.return!=null&&o.return()}finally{if(i)throw a}}return r}}function Ej(e){if(Array.isArray(e))return e}function Lx(e){var t=Nn(e,2),r=t[0],n=t[1],i=r,a=n;return r>n&&(i=n,a=r),[i,a]}function Bx(e,t,r){if(e.lte(0))return new ae(0);var n=Ya.getDigitCount(e.toNumber()),i=new ae(10).pow(n),a=e.div(i),o=n!==1?.05:.1,u=new ae(Math.ceil(a.div(o).toNumber())).add(r).mul(o),c=u.mul(i);return t?c:new ae(Math.ceil(c))}function jj(e,t,r){var n=1,i=new ae(e);if(!i.isint()&&r){var a=Math.abs(e);a<1?(n=new ae(10).pow(Ya.getDigitCount(e)-1),i=new ae(Math.floor(i.div(n).toNumber())).mul(n)):a>1&&(i=new ae(Math.floor(e)))}else e===0?i=new ae(Math.floor((t-1)/2)):r||(i=new ae(Math.floor(e)));var o=Math.floor((t-1)/2),u=mj(yj(function(c){return i.add(new ae(c-o).mul(n)).toNumber()}),Ul);return u(0,t)}function Fx(e,t,r,n){var i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:0;if(!Number.isFinite((t-e)/(r-1)))return{step:new ae(0),tickMin:new ae(0),tickMax:new ae(0)};var a=Bx(new ae(t).sub(e).div(r-1),n,i),o;e<=0&&t>=0?o=new ae(0):(o=new ae(e).add(t).div(2),o=o.sub(new ae(o).mod(a)));var u=Math.ceil(o.sub(e).div(a).toNumber()),c=Math.ceil(new ae(t).sub(o).div(a).toNumber()),s=u+c+1;return s>r?Fx(e,t,r,n,i+1):(s0?c+(r-s):c,u=t>0?u:u+(r-s)),{step:a,tickMin:o.sub(new ae(u).mul(a)),tickMax:o.add(new ae(c).mul(a))})}function Mj(e){var t=Nn(e,2),r=t[0],n=t[1],i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:6,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,o=Math.max(i,2),u=Lx([r,n]),c=Nn(u,2),s=c[0],f=c[1];if(s===-1/0||f===1/0){var l=f===1/0?[s].concat(Kl(Ul(0,i-1).map(function(){return 1/0}))):[].concat(Kl(Ul(0,i-1).map(function(){return-1/0})),[f]);return r>n?Hl(l):l}if(s===f)return jj(s,i,a);var h=Fx(s,f,o,a),d=h.step,y=h.tickMin,v=h.tickMax,p=Ya.rangeStep(y,v.add(new ae(.1).mul(d)),d);return r>n?Hl(p):p}function $j(e,t){var r=Nn(e,2),n=r[0],i=r[1],a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,o=Lx([n,i]),u=Nn(o,2),c=u[0],s=u[1];if(c===-1/0||s===1/0)return[n,i];if(c===s)return[c];var f=Math.max(t,2),l=Bx(new ae(s).sub(c).div(f-1),a,0),h=[].concat(Kl(Ya.rangeStep(new ae(c),new ae(s).sub(new ae(.99).mul(l)),l)),[s]);return n>i?Hl(h):h}var Cj=Nx(Mj),Ij=Nx($j),kj=["offset","layout","width","dataKey","data","dataPointFormatter","xAxis","yAxis"];function Cr(e){"@babel/helpers - typeof";return Cr=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Cr(e)}function Qi(){return Qi=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function Fj(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function Wj(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function zj(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&arguments[1]!==void 0?arguments[1]:[],i=arguments.length>2?arguments[2]:void 0,a=arguments.length>3?arguments[3]:void 0,o=-1,u=(r=n?.length)!==null&&r!==void 0?r:0;if(u<=1)return 0;if(a&&a.axisType==="angleAxis"&&Math.abs(Math.abs(a.range[1]-a.range[0])-360)<=1e-6)for(var c=a.range,s=0;s0?i[s-1].coordinate:i[u-1].coordinate,l=i[s].coordinate,h=s>=u-1?i[0].coordinate:i[s+1].coordinate,d=void 0;if(Ce(l-f)!==Ce(h-l)){var y=[];if(Ce(h-l)===Ce(c[1]-c[0])){d=h;var v=l+c[1]-c[0];y[0]=Math.min(v,(v+f)/2),y[1]=Math.max(v,(v+f)/2)}else{d=f;var p=h+c[1]-c[0];y[0]=Math.min(l,(p+l)/2),y[1]=Math.max(l,(p+l)/2)}var g=[Math.min(l,(d+l)/2),Math.max(l,(d+l)/2)];if(t>g[0]&&t<=g[1]||t>=y[0]&&t<=y[1]){o=i[s].index;break}}else{var x=Math.min(f,h),w=Math.max(f,h);if(t>(x+l)/2&&t<=(w+l)/2){o=i[s].index;break}}}else for(var O=0;O0&&O(n[O].coordinate+n[O-1].coordinate)/2&&t<=(n[O].coordinate+n[O+1].coordinate)/2||O===u-1&&t>(n[O].coordinate+n[O-1].coordinate)/2){o=n[O].index;break}return o},$h=function(t){var r,n=t,i=n.type.displayName,a=(r=t.type)!==null&&r!==void 0&&r.defaultProps?ve(ve({},t.type.defaultProps),t.props):t.props,o=a.stroke,u=a.fill,c;switch(i){case"Line":c=o;break;case"Area":case"Radar":c=o&&o!=="none"?o:u;break;default:c=u;break}return c},oM=function(t){var r=t.barSize,n=t.totalSize,i=t.stackGroups,a=i===void 0?{}:i;if(!a)return{};for(var o={},u=Object.keys(a),c=0,s=u.length;c=0});if(g&&g.length){var x=g[0].type.defaultProps,w=x!==void 0?ve(ve({},x),g[0].props):g[0].props,O=w.barSize,m=w[p];o[m]||(o[m]=[]);var b=Y(O)?r:O;o[m].push({item:g[0],stackList:g.slice(1),barSize:Y(b)?void 0:Ie(b,n,0)})}}return o},uM=function(t){var r=t.barGap,n=t.barCategoryGap,i=t.bandSize,a=t.sizeList,o=a===void 0?[]:a,u=t.maxBarSize,c=o.length;if(c<1)return null;var s=Ie(r,i,0,!0),f,l=[];if(o[0].barSize===+o[0].barSize){var h=!1,d=i/c,y=o.reduce(function(O,m){return O+m.barSize||0},0);y+=(c-1)*s,y>=i&&(y-=(c-1)*s,s=0),y>=i&&d>0&&(h=!0,d*=.9,y=c*d);var v=(i-y)/2>>0,p={offset:v-s,size:0};f=o.reduce(function(O,m){var b={item:m.item,position:{offset:p.offset+p.size+s,size:h?d:m.barSize}},_=[].concat(Cm(O),[b]);return p=_[_.length-1].position,m.stackList&&m.stackList.length&&m.stackList.forEach(function(A){_.push({item:A,position:p})}),_},l)}else{var g=Ie(n,i,0,!0);i-2*g-(c-1)*s<=0&&(s=0);var x=(i-2*g-(c-1)*s)/c;x>1&&(x>>=0);var w=u===+u?Math.min(x,u):x;f=o.reduce(function(O,m,b){var _=[].concat(Cm(O),[{item:m.item,position:{offset:g+(x+s)*b+(x-w)/2,size:w}}]);return m.stackList&&m.stackList.length&&m.stackList.forEach(function(A){_.push({item:A,position:_[_.length-1].position})}),_},l)}return f},cM=function(t,r,n,i){var a=n.children,o=n.width,u=n.margin,c=o-(u.left||0)-(u.right||0),s=Hx({children:a,legendWidth:c});if(s){var f=i||{},l=f.width,h=f.height,d=s.align,y=s.verticalAlign,v=s.layout;if((v==="vertical"||v==="horizontal"&&y==="middle")&&d!=="center"&&q(t[d]))return ve(ve({},t),{},_r({},d,t[d]+(l||0)));if((v==="horizontal"||v==="vertical"&&d==="center")&&y!=="middle"&&q(t[y]))return ve(ve({},t),{},_r({},y,t[y]+(h||0)))}return t},sM=function(t,r,n){return Y(r)?!0:t==="horizontal"?r==="yAxis":t==="vertical"||n==="x"?r==="xAxis":n==="y"?r==="yAxis":!0},Kx=function(t,r,n,i,a){var o=r.props.children,u=Ke(o,pi).filter(function(s){return sM(i,a,s.props.direction)});if(u&&u.length){var c=u.map(function(s){return s.props.dataKey});return t.reduce(function(s,f){var l=_e(f,n);if(Y(l))return s;var h=Array.isArray(l)?[Va(l),Ga(l)]:[l,l],d=c.reduce(function(y,v){var p=_e(f,v,0),g=h[0]-Math.abs(Array.isArray(p)?p[0]:p),x=h[1]+Math.abs(Array.isArray(p)?p[1]:p);return[Math.min(g,y[0]),Math.max(x,y[1])]},[1/0,-1/0]);return[Math.min(d[0],s[0]),Math.max(d[1],s[1])]},[1/0,-1/0])}return null},lM=function(t,r,n,i,a){var o=r.map(function(u){return Kx(t,u,n,a,i)}).filter(function(u){return!Y(u)});return o&&o.length?o.reduce(function(u,c){return[Math.min(u[0],c[0]),Math.max(u[1],c[1])]},[1/0,-1/0]):null},Gx=function(t,r,n,i,a){var o=r.map(function(c){var s=c.props.dataKey;return n==="number"&&s&&Kx(t,c,s,i)||bn(t,s,n,a)});if(n==="number")return o.reduce(function(c,s){return[Math.min(c[0],s[0]),Math.max(c[1],s[1])]},[1/0,-1/0]);var u={};return o.reduce(function(c,s){for(var f=0,l=s.length;f=2?Ce(u[0]-u[1])*2*s:s,r&&(t.ticks||t.niceTicks)){var f=(t.ticks||t.niceTicks).map(function(l){var h=a?a.indexOf(l):l;return{coordinate:i(h)+s,value:l,offset:s}});return f.filter(function(l){return!oi(l.coordinate)})}return t.isCategorical&&t.categoricalDomain?t.categoricalDomain.map(function(l,h){return{coordinate:i(l)+s,value:l,index:h,offset:s}}):i.ticks&&!n?i.ticks(t.tickCount).map(function(l){return{coordinate:i(l)+s,value:l,offset:s}}):i.domain().map(function(l,h){return{coordinate:i(l)+s,value:a?a[l]:l,index:h,offset:s}})},qs=new WeakMap,_i=function(t,r){if(typeof r!="function")return t;qs.has(t)||qs.set(t,new WeakMap);var n=qs.get(t);if(n.has(r))return n.get(r);var i=function(){t.apply(void 0,arguments),r.apply(void 0,arguments)};return n.set(r,i),i},Yx=function(t,r,n){var i=t.scale,a=t.type,o=t.layout,u=t.axisType;if(i==="auto")return o==="radial"&&u==="radiusAxis"?{scale:$n(),realScaleType:"band"}:o==="radial"&&u==="angleAxis"?{scale:Vi(),realScaleType:"linear"}:a==="category"&&r&&(r.indexOf("LineChart")>=0||r.indexOf("AreaChart")>=0||r.indexOf("ComposedChart")>=0&&!n)?{scale:gn(),realScaleType:"point"}:a==="category"?{scale:$n(),realScaleType:"band"}:{scale:Vi(),realScaleType:"linear"};if(er(i)){var c="scale".concat(Ia(i));return{scale:(gm[c]||gn)(),realScaleType:gm[c]?c:"point"}}return X(i)?{scale:i}:{scale:gn(),realScaleType:"point"}},km=1e-4,Zx=function(t){var r=t.domain();if(!(!r||r.length<=2)){var n=r.length,i=t.range(),a=Math.min(i[0],i[1])-km,o=Math.max(i[0],i[1])+km,u=t(r[0]),c=t(r[n-1]);(uo||co)&&t.domain([r[0],r[n-1]])}},fM=function(t,r){if(!t)return null;for(var n=0,i=t.length;ni)&&(a[1]=i),a[0]>i&&(a[0]=i),a[1]=0?(t[u][n][0]=a,t[u][n][1]=a+c,a=t[u][n][1]):(t[u][n][0]=o,t[u][n][1]=o+c,o=t[u][n][1])}},dM=function(t){var r=t.length;if(!(r<=0))for(var n=0,i=t[0].length;n=0?(t[o][n][0]=a,t[o][n][1]=a+u,a=t[o][n][1]):(t[o][n][0]=0,t[o][n][1]=0)}},vM={sign:pM,expand:n1,none:Ar,silhouette:i1,wiggle:a1,positive:dM},yM=function(t,r,n){var i=r.map(function(u){return u.props.dataKey}),a=vM[n],o=r1().keys(i).value(function(u,c){return+_e(u,c,0)}).order(Sl).offset(a);return o(t)},mM=function(t,r,n,i,a,o){if(!t)return null;var u=o?r.reverse():r,c={},s=u.reduce(function(l,h){var d,y=(d=h.type)!==null&&d!==void 0&&d.defaultProps?ve(ve({},h.type.defaultProps),h.props):h.props,v=y.stackId,p=y.hide;if(p)return l;var g=y[n],x=l[g]||{hasStack:!1,stackGroups:{}};if(Ae(v)){var w=x.stackGroups[v]||{numericAxisId:n,cateAxisId:i,items:[]};w.items.push(h),x.hasStack=!0,x.stackGroups[v]=w}else x.stackGroups[Zr("_stackId_")]={numericAxisId:n,cateAxisId:i,items:[h]};return ve(ve({},l),{},_r({},g,x))},c),f={};return Object.keys(s).reduce(function(l,h){var d=s[h];if(d.hasStack){var y={};d.stackGroups=Object.keys(d.stackGroups).reduce(function(v,p){var g=d.stackGroups[p];return ve(ve({},v),{},_r({},p,{numericAxisId:n,cateAxisId:i,items:g.items,stackedData:yM(t,g.items,a)}))},y)}return ve(ve({},l),{},_r({},h,d))},f)},Jx=function(t,r){var n=r.realScaleType,i=r.type,a=r.tickCount,o=r.originalDomain,u=r.allowDecimals,c=n||r.scale;if(c!=="auto"&&c!=="linear")return null;if(a&&i==="number"&&o&&(o[0]==="auto"||o[1]==="auto")){var s=t.domain();if(!s.length)return null;var f=Cj(s,a,u);return t.domain([Va(f),Ga(f)]),{niceTicks:f}}if(a&&i==="number"){var l=t.domain(),h=Ij(l,a,u);return{niceTicks:h}}return null};function Rm(e){var t=e.axis,r=e.ticks,n=e.bandSize,i=e.entry,a=e.index,o=e.dataKey;if(t.type==="category"){if(!t.allowDuplicatedCategory&&t.dataKey&&!Y(i[t.dataKey])){var u=Mi(r,"value",i[t.dataKey]);if(u)return u.coordinate+n/2}return r[a]?r[a].coordinate+n/2:null}var c=_e(i,Y(o)?t.dataKey:o);return Y(c)?null:t.scale(c)}var Dm=function(t){var r=t.axis,n=t.ticks,i=t.offset,a=t.bandSize,o=t.entry,u=t.index;if(r.type==="category")return n[u]?n[u].coordinate+i:null;var c=_e(o,r.dataKey,r.domain[u]);return Y(c)?null:r.scale(c)-a/2+i},gM=function(t){var r=t.numericAxis,n=r.scale.domain();if(r.type==="number"){var i=Math.min(n[0],n[1]),a=Math.max(n[0],n[1]);return i<=0&&a>=0?0:a<0?a:i}return n[0]},bM=function(t,r){var n,i=(n=t.type)!==null&&n!==void 0&&n.defaultProps?ve(ve({},t.type.defaultProps),t.props):t.props,a=i.stackId;if(Ae(a)){var o=r[a];if(o){var u=o.items.indexOf(t);return u>=0?o.stackedData[u]:null}}return null},xM=function(t){return t.reduce(function(r,n){return[Va(n.concat([r[0]]).filter(q)),Ga(n.concat([r[1]]).filter(q))]},[1/0,-1/0])},Qx=function(t,r,n){return Object.keys(t).reduce(function(i,a){var o=t[a],u=o.stackedData,c=u.reduce(function(s,f){var l=xM(f.slice(r,n+1));return[Math.min(s[0],l[0]),Math.max(s[1],l[1])]},[1/0,-1/0]);return[Math.min(c[0],i[0]),Math.max(c[1],i[1])]},[1/0,-1/0]).map(function(i){return i===1/0||i===-1/0?0:i})},Nm=/^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,qm=/^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,Yl=function(t,r,n){if(X(t))return t(r,n);if(!Array.isArray(t))return r;var i=[];if(q(t[0]))i[0]=n?t[0]:Math.min(t[0],r[0]);else if(Nm.test(t[0])){var a=+Nm.exec(t[0])[1];i[0]=r[0]-a}else X(t[0])?i[0]=t[0](r[0]):i[0]=r[0];if(q(t[1]))i[1]=n?t[1]:Math.max(t[1],r[1]);else if(qm.test(t[1])){var o=+qm.exec(t[1])[1];i[1]=r[1]+o}else X(t[1])?i[1]=t[1](r[1]):i[1]=r[1];return i},ta=function(t,r,n){if(t&&t.scale&&t.scale.bandwidth){var i=t.scale.bandwidth();if(!n||i>0)return i}if(t&&r&&r.length>=2){for(var a=ih(r,function(l){return l.coordinate}),o=1/0,u=1,c=a.length;ue.length)&&(t=e.length);for(var r=0,n=new Array(t);r2&&arguments[2]!==void 0?arguments[2]:{top:0,right:0,bottom:0,left:0};return Math.min(Math.abs(t-(n.left||0)-(n.right||0)),Math.abs(r-(n.top||0)-(n.bottom||0)))/2},jM=function(t,r,n,i,a){var o=t.width,u=t.height,c=t.startAngle,s=t.endAngle,f=Ie(t.cx,o,o/2),l=Ie(t.cy,u,u/2),h=rw(o,u,n),d=Ie(t.innerRadius,h,0),y=Ie(t.outerRadius,h,h*.8),v=Object.keys(r);return v.reduce(function(p,g){var x=r[g],w=x.domain,O=x.reversed,m;if(Y(x.range))i==="angleAxis"?m=[c,s]:i==="radiusAxis"&&(m=[d,y]),O&&(m=[m[1],m[0]]);else{m=x.range;var b=m,_=_M(b,2);c=_[0],s=_[1]}var A=Yx(x,a),T=A.realScaleType,M=A.scale;M.domain(w).range(m),Zx(M);var P=Jx(M,vt(vt({},x),{},{realScaleType:T})),E=vt(vt(vt({},x),P),{},{range:m,radius:y,realScaleType:T,scale:M,cx:f,cy:l,innerRadius:d,outerRadius:y,startAngle:c,endAngle:s});return vt(vt({},p),{},tw({},g,E))},{})},MM=function(t,r){var n=t.x,i=t.y,a=r.x,o=r.y;return Math.sqrt(Math.pow(n-a,2)+Math.pow(i-o,2))},$M=function(t,r){var n=t.x,i=t.y,a=r.cx,o=r.cy,u=MM({x:n,y:i},{x:a,y:o});if(u<=0)return{radius:u};var c=(n-a)/u,s=Math.acos(c);return i>o&&(s=2*Math.PI-s),{radius:u,angle:EM(s),angleInRadian:s}},CM=function(t){var r=t.startAngle,n=t.endAngle,i=Math.floor(r/360),a=Math.floor(n/360),o=Math.min(i,a);return{startAngle:r-o*360,endAngle:n-o*360}},IM=function(t,r){var n=r.startAngle,i=r.endAngle,a=Math.floor(n/360),o=Math.floor(i/360),u=Math.min(a,o);return t+u*360},Wm=function(t,r){var n=t.x,i=t.y,a=$M({x:n,y:i},r),o=a.radius,u=a.angle,c=r.innerRadius,s=r.outerRadius;if(os)return!1;if(o===0)return!0;var f=CM(r),l=f.startAngle,h=f.endAngle,d=u,y;if(l<=h){for(;d>h;)d-=360;for(;d=l&&d<=h}else{for(;d>l;)d-=360;for(;d=h&&d<=l}return y?vt(vt({},r),{},{radius:o,angle:IM(d,r)}):null},nw=function(t){return!N.isValidElement(t)&&!X(t)&&typeof t!="boolean"?t.className:""};function Fn(e){"@babel/helpers - typeof";return Fn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Fn(e)}var kM=["offset"];function RM(e){return LM(e)||qM(e)||NM(e)||DM()}function DM(){throw new TypeError(`Invalid attempt to spread non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function NM(e,t){if(e){if(typeof e=="string")return Zl(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Zl(e,t)}}function qM(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function LM(e){if(Array.isArray(e))return Zl(e)}function Zl(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function FM(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function zm(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Oe(e){for(var t=1;t=0?1:-1,w,O;i==="insideStart"?(w=d+x*o,O=v):i==="insideEnd"?(w=y-x*o,O=!v):i==="end"&&(w=y+x*o,O=v),O=g<=0?O:!O;var m=le(s,f,p,w),b=le(s,f,p,w+(O?1:-1)*359),_="M".concat(m.x,",").concat(m.y,` - A`).concat(p,",").concat(p,",0,1,").concat(O?0:1,`, - `).concat(b.x,",").concat(b.y),A=Y(t.id)?Zr("recharts-radial-line-"):t.id;return S.createElement("text",Wn({},n,{dominantBaseline:"central",className:J("recharts-radial-bar-label",u)}),S.createElement("defs",null,S.createElement("path",{id:A,d:_})),S.createElement("textPath",{xlinkHref:"#".concat(A)},r))},VM=function(t){var r=t.viewBox,n=t.offset,i=t.position,a=r,o=a.cx,u=a.cy,c=a.innerRadius,s=a.outerRadius,f=a.startAngle,l=a.endAngle,h=(f+l)/2;if(i==="outside"){var d=le(o,u,s+n,h),y=d.x,v=d.y;return{x:y,y:v,textAnchor:y>=o?"start":"end",verticalAnchor:"middle"}}if(i==="center")return{x:o,y:u,textAnchor:"middle",verticalAnchor:"middle"};if(i==="centerTop")return{x:o,y:u,textAnchor:"middle",verticalAnchor:"start"};if(i==="centerBottom")return{x:o,y:u,textAnchor:"middle",verticalAnchor:"end"};var p=(c+s)/2,g=le(o,u,p,h),x=g.x,w=g.y;return{x,y:w,textAnchor:"middle",verticalAnchor:"middle"}},XM=function(t){var r=t.viewBox,n=t.parentViewBox,i=t.offset,a=t.position,o=r,u=o.x,c=o.y,s=o.width,f=o.height,l=f>=0?1:-1,h=l*i,d=l>0?"end":"start",y=l>0?"start":"end",v=s>=0?1:-1,p=v*i,g=v>0?"end":"start",x=v>0?"start":"end";if(a==="top"){var w={x:u+s/2,y:c-l*i,textAnchor:"middle",verticalAnchor:d};return Oe(Oe({},w),n?{height:Math.max(c-n.y,0),width:s}:{})}if(a==="bottom"){var O={x:u+s/2,y:c+f+h,textAnchor:"middle",verticalAnchor:y};return Oe(Oe({},O),n?{height:Math.max(n.y+n.height-(c+f),0),width:s}:{})}if(a==="left"){var m={x:u-p,y:c+f/2,textAnchor:g,verticalAnchor:"middle"};return Oe(Oe({},m),n?{width:Math.max(m.x-n.x,0),height:f}:{})}if(a==="right"){var b={x:u+s+p,y:c+f/2,textAnchor:x,verticalAnchor:"middle"};return Oe(Oe({},b),n?{width:Math.max(n.x+n.width-b.x,0),height:f}:{})}var _=n?{width:s,height:f}:{};return a==="insideLeft"?Oe({x:u+p,y:c+f/2,textAnchor:x,verticalAnchor:"middle"},_):a==="insideRight"?Oe({x:u+s-p,y:c+f/2,textAnchor:g,verticalAnchor:"middle"},_):a==="insideTop"?Oe({x:u+s/2,y:c+h,textAnchor:"middle",verticalAnchor:y},_):a==="insideBottom"?Oe({x:u+s/2,y:c+f-h,textAnchor:"middle",verticalAnchor:d},_):a==="insideTopLeft"?Oe({x:u+p,y:c+h,textAnchor:x,verticalAnchor:y},_):a==="insideTopRight"?Oe({x:u+s-p,y:c+h,textAnchor:g,verticalAnchor:y},_):a==="insideBottomLeft"?Oe({x:u+p,y:c+f-h,textAnchor:x,verticalAnchor:d},_):a==="insideBottomRight"?Oe({x:u+s-p,y:c+f-h,textAnchor:g,verticalAnchor:d},_):Yr(a)&&(q(a.x)||Gt(a.x))&&(q(a.y)||Gt(a.y))?Oe({x:u+Ie(a.x,s),y:c+Ie(a.y,f),textAnchor:"end",verticalAnchor:"end"},_):Oe({x:u+s/2,y:c+f/2,textAnchor:"middle",verticalAnchor:"middle"},_)},YM=function(t){return"cx"in t&&q(t.cx)};function Te(e){var t=e.offset,r=t===void 0?5:t,n=BM(e,kM),i=Oe({offset:r},n),a=i.viewBox,o=i.position,u=i.value,c=i.children,s=i.content,f=i.className,l=f===void 0?"":f,h=i.textBreakAll;if(!a||Y(u)&&Y(c)&&!N.isValidElement(s)&&!X(s))return null;if(N.isValidElement(s))return N.cloneElement(s,i);var d;if(X(s)){if(d=N.createElement(s,i),N.isValidElement(d))return d}else d=HM(i);var y=YM(a),v=H(i,!0);if(y&&(o==="insideStart"||o==="insideEnd"||o==="end"))return GM(i,d,v);var p=y?VM(i):XM(i);return S.createElement(rr,Wn({className:J("recharts-label",l)},v,p,{breakAll:h}),d)}Te.displayName="Label";var iw=function(t){var r=t.cx,n=t.cy,i=t.angle,a=t.startAngle,o=t.endAngle,u=t.r,c=t.radius,s=t.innerRadius,f=t.outerRadius,l=t.x,h=t.y,d=t.top,y=t.left,v=t.width,p=t.height,g=t.clockWise,x=t.labelViewBox;if(x)return x;if(q(v)&&q(p)){if(q(l)&&q(h))return{x:l,y:h,width:v,height:p};if(q(d)&&q(y))return{x:d,y,width:v,height:p}}return q(l)&&q(h)?{x:l,y:h,width:0,height:0}:q(r)&&q(n)?{cx:r,cy:n,startAngle:a||i||0,endAngle:o||i||0,innerRadius:s||0,outerRadius:f||c||u||0,clockWise:g}:t.viewBox?t.viewBox:{}},ZM=function(t,r){return t?t===!0?S.createElement(Te,{key:"label-implicit",viewBox:r}):Ae(t)?S.createElement(Te,{key:"label-implicit",viewBox:r,value:t}):N.isValidElement(t)?t.type===Te?N.cloneElement(t,{key:"label-implicit",viewBox:r}):S.createElement(Te,{key:"label-implicit",content:t,viewBox:r}):X(t)?S.createElement(Te,{key:"label-implicit",content:t,viewBox:r}):Yr(t)?S.createElement(Te,Wn({viewBox:r},t,{key:"label-implicit"})):null:null},JM=function(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(!t||!t.children&&n&&!t.label)return null;var i=t.children,a=iw(t),o=Ke(i,Te).map(function(c,s){return N.cloneElement(c,{viewBox:r||a,key:"label-".concat(s)})});if(!n)return o;var u=ZM(t.label,r||a);return[u].concat(RM(o))};Te.parseViewBox=iw;Te.renderCallByParent=JM;var Ls,Um;function QM(){if(Um)return Ls;Um=1;function e(t){var r=t==null?0:t.length;return r?t[r-1]:void 0}return Ls=e,Ls}var e$=QM();const t$=oe(e$);function zn(e){"@babel/helpers - typeof";return zn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},zn(e)}var r$=["valueAccessor"],n$=["data","dataKey","clockWise","id","textBreakAll"];function i$(e){return c$(e)||u$(e)||o$(e)||a$()}function a$(){throw new TypeError(`Invalid attempt to spread non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function o$(e,t){if(e){if(typeof e=="string")return Jl(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Jl(e,t)}}function u$(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function c$(e){if(Array.isArray(e))return Jl(e)}function Jl(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function h$(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}var p$=function(t){return Array.isArray(t.value)?t$(t.value):t.value};function wt(e){var t=e.valueAccessor,r=t===void 0?p$:t,n=Gm(e,r$),i=n.data,a=n.dataKey,o=n.clockWise,u=n.id,c=n.textBreakAll,s=Gm(n,n$);return!i||!i.length?null:S.createElement(te,{className:"recharts-label-list"},i.map(function(f,l){var h=Y(a)?r(f,l):_e(f&&f.payload,a),d=Y(u)?{}:{id:"".concat(u,"-").concat(l)};return S.createElement(Te,na({},H(f,!0),s,d,{parentViewBox:f.parentViewBox,value:h,textBreakAll:c,viewBox:Te.parseViewBox(Y(o)?f:Km(Km({},f),{},{clockWise:o})),key:"label-".concat(l),index:l}))}))}wt.displayName="LabelList";function d$(e,t){return e?e===!0?S.createElement(wt,{key:"labelList-implicit",data:t}):S.isValidElement(e)||X(e)?S.createElement(wt,{key:"labelList-implicit",data:t,content:e}):Yr(e)?S.createElement(wt,na({data:t},e,{key:"labelList-implicit"})):null:null}function v$(e,t){var r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(!e||!e.children&&r&&!e.label)return null;var n=e.children,i=Ke(n,wt).map(function(o,u){return N.cloneElement(o,{data:t,key:"labelList-".concat(u)})});if(!r)return i;var a=d$(e.label,t);return[a].concat(i$(i))}wt.renderCallByParent=v$;function Un(e){"@babel/helpers - typeof";return Un=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Un(e)}function Ql(){return Ql=Object.assign?Object.assign.bind():function(e){for(var t=1;t180),",").concat(+(o>s),`, - `).concat(l.x,",").concat(l.y,` - `);if(i>0){var d=le(r,n,i,o),y=le(r,n,i,s);h+="L ".concat(y.x,",").concat(y.y,` - A `).concat(i,",").concat(i,`,0, - `).concat(+(Math.abs(c)>180),",").concat(+(o<=s),`, - `).concat(d.x,",").concat(d.y," Z")}else h+="L ".concat(r,",").concat(n," Z");return h},x$=function(t){var r=t.cx,n=t.cy,i=t.innerRadius,a=t.outerRadius,o=t.cornerRadius,u=t.forceCornerRadius,c=t.cornerIsExternal,s=t.startAngle,f=t.endAngle,l=Ce(f-s),h=Ai({cx:r,cy:n,radius:a,angle:s,sign:l,cornerRadius:o,cornerIsExternal:c}),d=h.circleTangency,y=h.lineTangency,v=h.theta,p=Ai({cx:r,cy:n,radius:a,angle:f,sign:-l,cornerRadius:o,cornerIsExternal:c}),g=p.circleTangency,x=p.lineTangency,w=p.theta,O=c?Math.abs(s-f):Math.abs(s-f)-v-w;if(O<0)return u?"M ".concat(y.x,",").concat(y.y,` - a`).concat(o,",").concat(o,",0,0,1,").concat(o*2,`,0 - a`).concat(o,",").concat(o,",0,0,1,").concat(-o*2,`,0 - `):aw({cx:r,cy:n,innerRadius:i,outerRadius:a,startAngle:s,endAngle:f});var m="M ".concat(y.x,",").concat(y.y,` - A`).concat(o,",").concat(o,",0,0,").concat(+(l<0),",").concat(d.x,",").concat(d.y,` - A`).concat(a,",").concat(a,",0,").concat(+(O>180),",").concat(+(l<0),",").concat(g.x,",").concat(g.y,` - A`).concat(o,",").concat(o,",0,0,").concat(+(l<0),",").concat(x.x,",").concat(x.y,` - `);if(i>0){var b=Ai({cx:r,cy:n,radius:i,angle:s,sign:l,isExternal:!0,cornerRadius:o,cornerIsExternal:c}),_=b.circleTangency,A=b.lineTangency,T=b.theta,M=Ai({cx:r,cy:n,radius:i,angle:f,sign:-l,isExternal:!0,cornerRadius:o,cornerIsExternal:c}),P=M.circleTangency,E=M.lineTangency,j=M.theta,C=c?Math.abs(s-f):Math.abs(s-f)-T-j;if(C<0&&o===0)return"".concat(m,"L").concat(r,",").concat(n,"Z");m+="L".concat(E.x,",").concat(E.y,` - A`).concat(o,",").concat(o,",0,0,").concat(+(l<0),",").concat(P.x,",").concat(P.y,` - A`).concat(i,",").concat(i,",0,").concat(+(C>180),",").concat(+(l>0),",").concat(_.x,",").concat(_.y,` - A`).concat(o,",").concat(o,",0,0,").concat(+(l<0),",").concat(A.x,",").concat(A.y,"Z")}else m+="L".concat(r,",").concat(n,"Z");return m},w$={cx:0,cy:0,innerRadius:0,outerRadius:0,startAngle:0,endAngle:0,cornerRadius:0,forceCornerRadius:!1,cornerIsExternal:!1},ow=function(t){var r=Xm(Xm({},w$),t),n=r.cx,i=r.cy,a=r.innerRadius,o=r.outerRadius,u=r.cornerRadius,c=r.forceCornerRadius,s=r.cornerIsExternal,f=r.startAngle,l=r.endAngle,h=r.className;if(o0&&Math.abs(f-l)<360?p=x$({cx:n,cy:i,innerRadius:a,outerRadius:o,cornerRadius:Math.min(v,y/2),forceCornerRadius:c,cornerIsExternal:s,startAngle:f,endAngle:l}):p=aw({cx:n,cy:i,innerRadius:a,outerRadius:o,startAngle:f,endAngle:l}),S.createElement("path",Ql({},H(r,!0),{className:d,d:p,role:"img"}))};function Hn(e){"@babel/helpers - typeof";return Hn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Hn(e)}function ef(){return ef=Object.assign?Object.assign.bind():function(e){for(var t=1;t0;)if(!r.equals(e[n],t[n],n,n,e,t,r))return!1;return!0}function B$(e,t){return sr(e.getTime(),t.getTime())}function F$(e,t){return e.name===t.name&&e.message===t.message&&e.cause===t.cause&&e.stack===t.stack}function W$(e,t){return e===t}function og(e,t,r){var n=e.size;if(n!==t.size)return!1;if(!n)return!0;for(var i=new Array(n),a=e.entries(),o,u,c=0;(o=a.next())&&!o.done;){for(var s=t.entries(),f=!1,l=0;(u=s.next())&&!u.done;){if(i[l]){l++;continue}var h=o.value,d=u.value;if(r.equals(h[0],d[0],c,l,e,t,r)&&r.equals(h[1],d[1],h[0],d[0],e,t,r)){f=i[l]=!0;break}l++}if(!f)return!1;c++}return!0}var z$=sr;function U$(e,t,r){var n=ag(e),i=n.length;if(ag(t).length!==i)return!1;for(;i-- >0;)if(!uw(e,t,r,n[i]))return!1;return!0}function hn(e,t,r){var n=ng(e),i=n.length;if(ng(t).length!==i)return!1;for(var a,o,u;i-- >0;)if(a=n[i],!uw(e,t,r,a)||(o=ig(e,a),u=ig(t,a),(o||u)&&(!o||!u||o.configurable!==u.configurable||o.enumerable!==u.enumerable||o.writable!==u.writable)))return!1;return!0}function H$(e,t){return sr(e.valueOf(),t.valueOf())}function K$(e,t){return e.source===t.source&&e.flags===t.flags}function ug(e,t,r){var n=e.size;if(n!==t.size)return!1;if(!n)return!0;for(var i=new Array(n),a=e.values(),o,u;(o=a.next())&&!o.done;){for(var c=t.values(),s=!1,f=0;(u=c.next())&&!u.done;){if(!i[f]&&r.equals(o.value,u.value,o.value,u.value,e,t,r)){s=i[f]=!0;break}f++}if(!s)return!1}return!0}function G$(e,t){var r=e.length;if(t.length!==r)return!1;for(;r-- >0;)if(e[r]!==t[r])return!1;return!0}function V$(e,t){return e.hostname===t.hostname&&e.pathname===t.pathname&&e.protocol===t.protocol&&e.port===t.port&&e.hash===t.hash&&e.username===t.username&&e.password===t.password}function uw(e,t,r,n){return(n===q$||n===N$||n===D$)&&(e.$$typeof||t.$$typeof)?!0:R$(t,n)&&r.equals(e[n],t[n],n,n,e,t,r)}var X$="[object Arguments]",Y$="[object Boolean]",Z$="[object Date]",J$="[object Error]",Q$="[object Map]",eC="[object Number]",tC="[object Object]",rC="[object RegExp]",nC="[object Set]",iC="[object String]",aC="[object URL]",oC=Array.isArray,cg=typeof ArrayBuffer<"u"&&typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView:null,sg=Object.assign,uC=Object.prototype.toString.call.bind(Object.prototype.toString);function cC(e){var t=e.areArraysEqual,r=e.areDatesEqual,n=e.areErrorsEqual,i=e.areFunctionsEqual,a=e.areMapsEqual,o=e.areNumbersEqual,u=e.areObjectsEqual,c=e.arePrimitiveWrappersEqual,s=e.areRegExpsEqual,f=e.areSetsEqual,l=e.areTypedArraysEqual,h=e.areUrlsEqual,d=e.unknownTagComparators;return function(v,p,g){if(v===p)return!0;if(v==null||p==null)return!1;var x=typeof v;if(x!==typeof p)return!1;if(x!=="object")return x==="number"?o(v,p,g):x==="function"?i(v,p,g):!1;var w=v.constructor;if(w!==p.constructor)return!1;if(w===Object)return u(v,p,g);if(oC(v))return t(v,p,g);if(cg!=null&&cg(v))return l(v,p,g);if(w===Date)return r(v,p,g);if(w===RegExp)return s(v,p,g);if(w===Map)return a(v,p,g);if(w===Set)return f(v,p,g);var O=uC(v);if(O===Z$)return r(v,p,g);if(O===rC)return s(v,p,g);if(O===Q$)return a(v,p,g);if(O===nC)return f(v,p,g);if(O===tC)return typeof v.then!="function"&&typeof p.then!="function"&&u(v,p,g);if(O===aC)return h(v,p,g);if(O===J$)return n(v,p,g);if(O===X$)return u(v,p,g);if(O===Y$||O===eC||O===iC)return c(v,p,g);if(d){var m=d[O];if(!m){var b=k$(v);b&&(m=d[b])}if(m)return m(v,p,g)}return!1}}function sC(e){var t=e.circular,r=e.createCustomConfig,n=e.strict,i={areArraysEqual:n?hn:L$,areDatesEqual:B$,areErrorsEqual:F$,areFunctionsEqual:W$,areMapsEqual:n?rg(og,hn):og,areNumbersEqual:z$,areObjectsEqual:n?hn:U$,arePrimitiveWrappersEqual:H$,areRegExpsEqual:K$,areSetsEqual:n?rg(ug,hn):ug,areTypedArraysEqual:n?hn:G$,areUrlsEqual:V$,unknownTagComparators:void 0};if(r&&(i=sg({},i,r(i))),t){var a=Pi(i.areArraysEqual),o=Pi(i.areMapsEqual),u=Pi(i.areObjectsEqual),c=Pi(i.areSetsEqual);i=sg({},i,{areArraysEqual:a,areMapsEqual:o,areObjectsEqual:u,areSetsEqual:c})}return i}function lC(e){return function(t,r,n,i,a,o,u){return e(t,r,u)}}function fC(e){var t=e.circular,r=e.comparator,n=e.createState,i=e.equals,a=e.strict;if(n)return function(c,s){var f=n(),l=f.cache,h=l===void 0?t?new WeakMap:void 0:l,d=f.meta;return r(c,s,{cache:h,equals:i,meta:d,strict:a})};if(t)return function(c,s){return r(c,s,{cache:new WeakMap,equals:i,meta:void 0,strict:a})};var o={cache:void 0,equals:i,meta:void 0,strict:a};return function(c,s){return r(c,s,o)}}var hC=Dt();Dt({strict:!0});Dt({circular:!0});Dt({circular:!0,strict:!0});Dt({createInternalComparator:function(){return sr}});Dt({strict:!0,createInternalComparator:function(){return sr}});Dt({circular:!0,createInternalComparator:function(){return sr}});Dt({circular:!0,createInternalComparator:function(){return sr},strict:!0});function Dt(e){e===void 0&&(e={});var t=e.circular,r=t===void 0?!1:t,n=e.createInternalComparator,i=e.createState,a=e.strict,o=a===void 0?!1:a,u=sC(e),c=cC(u),s=n?n(c):lC(c);return fC({circular:r,comparator:c,createState:i,equals:s,strict:o})}function pC(e){typeof requestAnimationFrame<"u"&&requestAnimationFrame(e)}function lg(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=-1,n=function i(a){r<0&&(r=a),a-r>t?(e(a),r=-1):pC(i)};requestAnimationFrame(n)}function tf(e){"@babel/helpers - typeof";return tf=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},tf(e)}function dC(e){return gC(e)||mC(e)||yC(e)||vC()}function vC(){throw new TypeError(`Invalid attempt to destructure non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function yC(e,t){if(e){if(typeof e=="string")return fg(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return fg(e,t)}}function fg(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);re.length)&&(t=e.length);for(var r=0,n=new Array(t);r1?1:g<0?0:g},v=function(g){for(var x=g>1?1:g,w=x,O=0;O<8;++O){var m=l(w)-x,b=d(w);if(Math.abs(m-x)0&&arguments[0]!==void 0?arguments[0]:{},r=t.stiff,n=r===void 0?100:r,i=t.damping,a=i===void 0?8:i,o=t.dt,u=o===void 0?17:o,c=function(f,l,h){var d=-(f-l)*n,y=h*a,v=h+(d-y)*u/1e3,p=h*u/1e3+f;return Math.abs(p-l)e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function XC(e,t){if(e==null)return{};var r={},n=Object.keys(e),i,a;for(a=0;a=0)&&(r[i]=e[i]);return r}function zs(e){return QC(e)||JC(e)||ZC(e)||YC()}function YC(){throw new TypeError(`Invalid attempt to spread non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ZC(e,t){if(e){if(typeof e=="string")return uf(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return uf(e,t)}}function JC(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function QC(e){if(Array.isArray(e))return uf(e)}function uf(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function ua(e){return ua=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(r){return r.__proto__||Object.getPrototypeOf(r)},ua(e)}var lt=(function(e){iI(r,e);var t=aI(r);function r(n,i){var a;eI(this,r),a=t.call(this,n,i);var o=a.props,u=o.isActive,c=o.attributeName,s=o.from,f=o.to,l=o.steps,h=o.children,d=o.duration;if(a.handleStyleChange=a.handleStyleChange.bind(lf(a)),a.changeStyle=a.changeStyle.bind(lf(a)),!u||d<=0)return a.state={style:{}},typeof h=="function"&&(a.state={style:f}),sf(a);if(l&&l.length)a.state={style:l[0].style};else if(s){if(typeof h=="function")return a.state={style:s},sf(a);a.state={style:c?yn({},c,s):s}}else a.state={style:{}};return a}return rI(r,[{key:"componentDidMount",value:function(){var i=this.props,a=i.isActive,o=i.canBegin;this.mounted=!0,!(!a||!o)&&this.runAnimation(this.props)}},{key:"componentDidUpdate",value:function(i){var a=this.props,o=a.isActive,u=a.canBegin,c=a.attributeName,s=a.shouldReAnimate,f=a.to,l=a.from,h=this.state.style;if(u){if(!o){var d={style:c?yn({},c,f):f};this.state&&h&&(c&&h[c]!==f||!c&&h!==f)&&this.setState(d);return}if(!(hC(i.to,f)&&i.canBegin&&i.isActive)){var y=!i.canBegin||!i.isActive;this.manager&&this.manager.stop(),this.stopJSAnimation&&this.stopJSAnimation();var v=y||s?l:i.to;if(this.state&&h){var p={style:c?yn({},c,v):v};(c&&h[c]!==v||!c&&h!==v)&&this.setState(p)}this.runAnimation(et(et({},this.props),{},{from:v,begin:0}))}}}},{key:"componentWillUnmount",value:function(){this.mounted=!1;var i=this.props.onAnimationEnd;this.unSubscribe&&this.unSubscribe(),this.manager&&(this.manager.stop(),this.manager=null),this.stopJSAnimation&&this.stopJSAnimation(),i&&i()}},{key:"handleStyleChange",value:function(i){this.changeStyle(i)}},{key:"changeStyle",value:function(i){this.mounted&&this.setState({style:i})}},{key:"runJSAnimation",value:function(i){var a=this,o=i.from,u=i.to,c=i.duration,s=i.easing,f=i.begin,l=i.onAnimationEnd,h=i.onAnimationStart,d=KC(o,u,RC(s),c,this.changeStyle),y=function(){a.stopJSAnimation=d()};this.manager.start([h,f,y,c,l])}},{key:"runStepAnimation",value:function(i){var a=this,o=i.steps,u=i.begin,c=i.onAnimationStart,s=o[0],f=s.style,l=s.duration,h=l===void 0?0:l,d=function(v,p,g){if(g===0)return v;var x=p.duration,w=p.easing,O=w===void 0?"ease":w,m=p.style,b=p.properties,_=p.onAnimationEnd,A=g>0?o[g-1]:p,T=b||Object.keys(m);if(typeof O=="function"||O==="spring")return[].concat(zs(v),[a.runJSAnimation.bind(a,{from:A.style,to:m,duration:x,easing:O}),x]);var M=dg(T,x,O),P=et(et(et({},A.style),m),{},{transition:M});return[].concat(zs(v),[P,x,_]).filter(_C)};return this.manager.start([c].concat(zs(o.reduce(d,[f,Math.max(h,u)])),[i.onAnimationEnd]))}},{key:"runAnimation",value:function(i){this.manager||(this.manager=bC());var a=i.begin,o=i.duration,u=i.attributeName,c=i.to,s=i.easing,f=i.onAnimationStart,l=i.onAnimationEnd,h=i.steps,d=i.children,y=this.manager;if(this.unSubscribe=y.subscribe(this.handleStyleChange),typeof s=="function"||typeof d=="function"||s==="spring"){this.runJSAnimation(i);return}if(h.length>1){this.runStepAnimation(i);return}var v=u?yn({},u,c):c,p=dg(Object.keys(v),o,s);y.start([f,a,et(et({},v),{},{transition:p}),o,l])}},{key:"render",value:function(){var i=this.props,a=i.children;i.begin;var o=i.duration;i.attributeName,i.easing;var u=i.isActive;i.steps,i.from,i.to,i.canBegin,i.onAnimationEnd,i.shouldReAnimate,i.onAnimationReStart;var c=VC(i,GC),s=N.Children.count(a),f=this.state.style;if(typeof a=="function")return a(f);if(!u||s===0||o<=0)return a;var l=function(d){var y=d.props,v=y.style,p=v===void 0?{}:v,g=y.className,x=N.cloneElement(d,et(et({},c),{},{style:et(et({},p),f),className:g}));return x};return s===1?l(N.Children.only(a)):S.createElement("div",null,N.Children.map(a,function(h){return l(h)}))}}]),r})(N.PureComponent);lt.displayName="Animate";lt.defaultProps={begin:0,duration:1e3,from:"",to:"",attributeName:"",easing:"ease",isActive:!0,canBegin:!0,steps:[],onAnimationEnd:function(){},onAnimationStart:function(){}};lt.propTypes={from:ie.oneOfType([ie.object,ie.string]),to:ie.oneOfType([ie.object,ie.string]),attributeName:ie.string,duration:ie.number,begin:ie.number,easing:ie.oneOfType([ie.string,ie.func]),steps:ie.arrayOf(ie.shape({duration:ie.number.isRequired,style:ie.object.isRequired,easing:ie.oneOfType([ie.oneOf(["ease","ease-in","ease-out","ease-in-out","linear"]),ie.func]),properties:ie.arrayOf("string"),onAnimationEnd:ie.func})),children:ie.oneOfType([ie.node,ie.func]),isActive:ie.bool,canBegin:ie.bool,onAnimationEnd:ie.func,shouldReAnimate:ie.bool,onAnimationStart:ie.func,onAnimationReStart:ie.func};function xg(){return xg=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0?1:-1,c=n>=0?1:-1,s=i>=0&&n>=0||i<0&&n<0?1:0,f;if(o>0&&a instanceof Array){for(var l=[0,0,0,0],h=0,d=4;ho?o:a[h];f="M".concat(t,",").concat(r+u*l[0]),l[0]>0&&(f+="A ".concat(l[0],",").concat(l[0],",0,0,").concat(s,",").concat(t+c*l[0],",").concat(r)),f+="L ".concat(t+n-c*l[1],",").concat(r),l[1]>0&&(f+="A ".concat(l[1],",").concat(l[1],",0,0,").concat(s,`, - `).concat(t+n,",").concat(r+u*l[1])),f+="L ".concat(t+n,",").concat(r+i-u*l[2]),l[2]>0&&(f+="A ".concat(l[2],",").concat(l[2],",0,0,").concat(s,`, - `).concat(t+n-c*l[2],",").concat(r+i)),f+="L ".concat(t+c*l[3],",").concat(r+i),l[3]>0&&(f+="A ".concat(l[3],",").concat(l[3],",0,0,").concat(s,`, - `).concat(t,",").concat(r+i-u*l[3])),f+="Z"}else if(o>0&&a===+a&&a>0){var y=Math.min(o,a);f="M ".concat(t,",").concat(r+u*y,` - A `).concat(y,",").concat(y,",0,0,").concat(s,",").concat(t+c*y,",").concat(r,` - L `).concat(t+n-c*y,",").concat(r,` - A `).concat(y,",").concat(y,",0,0,").concat(s,",").concat(t+n,",").concat(r+u*y,` - L `).concat(t+n,",").concat(r+i-u*y,` - A `).concat(y,",").concat(y,",0,0,").concat(s,",").concat(t+n-c*y,",").concat(r+i,` - L `).concat(t+c*y,",").concat(r+i,` - A `).concat(y,",").concat(y,",0,0,").concat(s,",").concat(t,",").concat(r+i-u*y," Z")}else f="M ".concat(t,",").concat(r," h ").concat(n," v ").concat(i," h ").concat(-n," Z");return f},vI=function(t,r){if(!t||!r)return!1;var n=t.x,i=t.y,a=r.x,o=r.y,u=r.width,c=r.height;if(Math.abs(u)>0&&Math.abs(c)>0){var s=Math.min(a,a+u),f=Math.max(a,a+u),l=Math.min(o,o+c),h=Math.max(o,o+c);return n>=s&&n<=f&&i>=l&&i<=h}return!1},yI={x:0,y:0,width:0,height:0,radius:0,isAnimationActive:!1,isUpdateAnimationActive:!1,animationBegin:0,animationDuration:1500,animationEasing:"ease"},Ch=function(t){var r=_g(_g({},yI),t),n=N.useRef(),i=N.useState(-1),a=uI(i,2),o=a[0],u=a[1];N.useEffect(function(){if(n.current&&n.current.getTotalLength)try{var O=n.current.getTotalLength();O&&u(O)}catch{}},[]);var c=r.x,s=r.y,f=r.width,l=r.height,h=r.radius,d=r.className,y=r.animationEasing,v=r.animationDuration,p=r.animationBegin,g=r.isAnimationActive,x=r.isUpdateAnimationActive;if(c!==+c||s!==+s||f!==+f||l!==+l||f===0||l===0)return null;var w=J("recharts-rectangle",d);return x?S.createElement(lt,{canBegin:o>0,from:{width:f,height:l,x:c,y:s},to:{width:f,height:l,x:c,y:s},duration:v,animationEasing:y,isActive:x},function(O){var m=O.width,b=O.height,_=O.x,A=O.y;return S.createElement(lt,{canBegin:o>0,from:"0px ".concat(o===-1?1:o,"px"),to:"".concat(o,"px 0px"),attributeName:"strokeDasharray",begin:p,duration:v,isActive:g,easing:y},S.createElement("path",ca({},H(r,!0),{className:w,d:Ag(_,A,m,b,h),ref:n})))}):S.createElement("path",ca({},H(r,!0),{className:w,d:Ag(c,s,f,l,h)}))},mI=["points","className","baseLinePoints","connectNulls"];function yr(){return yr=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function bI(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function Sg(e){return _I(e)||OI(e)||wI(e)||xI()}function xI(){throw new TypeError(`Invalid attempt to spread non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function wI(e,t){if(e){if(typeof e=="string")return ff(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return ff(e,t)}}function OI(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function _I(e){if(Array.isArray(e))return ff(e)}function ff(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r0&&arguments[0]!==void 0?arguments[0]:[],r=[[]];return t.forEach(function(n){Pg(n)?r[r.length-1].push(n):r[r.length-1].length>0&&r.push([])}),Pg(t[0])&&r[r.length-1].push(t[0]),r[r.length-1].length<=0&&(r=r.slice(0,-1)),r},wn=function(t,r){var n=AI(t);r&&(n=[n.reduce(function(a,o){return[].concat(Sg(a),Sg(o))},[])]);var i=n.map(function(a){return a.reduce(function(o,u,c){return"".concat(o).concat(c===0?"M":"L").concat(u.x,",").concat(u.y)},"")}).join("");return n.length===1?"".concat(i,"Z"):i},SI=function(t,r,n){var i=wn(t,n);return"".concat(i.slice(-1)==="Z"?i.slice(0,-1):i,"L").concat(wn(r.reverse(),n).slice(1))},PI=function(t){var r=t.points,n=t.className,i=t.baseLinePoints,a=t.connectNulls,o=gI(t,mI);if(!r||!r.length)return null;var u=J("recharts-polygon",n);if(i&&i.length){var c=o.stroke&&o.stroke!=="none",s=SI(r,i,a);return S.createElement("g",{className:u},S.createElement("path",yr({},H(o,!0),{fill:s.slice(-1)==="Z"?o.fill:"none",stroke:"none",d:s})),c?S.createElement("path",yr({},H(o,!0),{fill:"none",d:wn(r,a)})):null,c?S.createElement("path",yr({},H(o,!0),{fill:"none",d:wn(i,a)})):null)}var f=wn(r,a);return S.createElement("path",yr({},H(o,!0),{fill:f.slice(-1)==="Z"?o.fill:"none",className:u,d:f}))};function hf(){return hf=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function II(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}var kI=function(t,r,n,i,a,o){return"M".concat(t,",").concat(a,"v").concat(i,"M").concat(o,",").concat(r,"h").concat(n)},RI=function(t){var r=t.x,n=r===void 0?0:r,i=t.y,a=i===void 0?0:i,o=t.top,u=o===void 0?0:o,c=t.left,s=c===void 0?0:c,f=t.width,l=f===void 0?0:f,h=t.height,d=h===void 0?0:h,y=t.className,v=CI(t,TI),p=EI({x:n,y:a,top:u,left:s,width:l,height:d},v);return!q(n)||!q(a)||!q(l)||!q(d)||!q(u)||!q(s)?null:S.createElement("path",pf({},H(p,!0),{className:J("recharts-cross",y),d:kI(n,a,l,d,u,s)}))},Us,Eg;function DI(){if(Eg)return Us;Eg=1;var e=Ka(),t=Ex(),r=ht();function n(i,a){return i&&i.length?e(i,r(a,2),t):void 0}return Us=n,Us}var NI=DI();const qI=oe(NI);var Hs,jg;function LI(){if(jg)return Hs;jg=1;var e=Ka(),t=ht(),r=jx();function n(i,a){return i&&i.length?e(i,t(a,2),r):void 0}return Hs=n,Hs}var BI=LI();const FI=oe(BI);var WI=["cx","cy","angle","ticks","axisLine"],zI=["ticks","tick","angle","tickFormatter","stroke"];function kr(e){"@babel/helpers - typeof";return kr=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},kr(e)}function On(){return On=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function UI(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function HI(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Cg(e,t){for(var r=0;rRg?o=i==="outer"?"start":"end":a<-Rg?o=i==="outer"?"end":"start":o="middle",o}},{key:"renderAxisLine",value:function(){var n=this.props,i=n.cx,a=n.cy,o=n.radius,u=n.axisLine,c=n.axisLineType,s=zt(zt({},H(this.props,!1)),{},{fill:"none"},H(u,!1));if(c==="circle")return S.createElement(Za,Kt({className:"recharts-polar-angle-axis-line"},s,{cx:i,cy:a,r:o}));var f=this.props.ticks,l=f.map(function(h){return le(i,a,o,h.coordinate)});return S.createElement(PI,Kt({className:"recharts-polar-angle-axis-line"},s,{points:l}))}},{key:"renderTicks",value:function(){var n=this,i=this.props,a=i.ticks,o=i.tick,u=i.tickLine,c=i.tickFormatter,s=i.stroke,f=H(this.props,!1),l=H(o,!1),h=zt(zt({},f),{},{fill:"none"},H(u,!1)),d=a.map(function(y,v){var p=n.getTickLineCoord(y),g=n.getTickTextAnchor(y),x=zt(zt(zt({textAnchor:g},f),{},{stroke:"none",fill:s},l),{},{index:v,payload:y,x:p.x2,y:p.y2});return S.createElement(te,Kt({className:J("recharts-polar-angle-axis-tick",nw(o)),key:"tick-".concat(y.coordinate)},tr(n.props,y,v)),u&&S.createElement("line",Kt({className:"recharts-polar-angle-axis-tick-line"},h,p)),o&&t.renderTickItem(o,x,c?c(y.value,v):y.value))});return S.createElement(te,{className:"recharts-polar-angle-axis-ticks"},d)}},{key:"render",value:function(){var n=this.props,i=n.ticks,a=n.radius,o=n.axisLine;return a<=0||!i||!i.length?null:S.createElement(te,{className:J("recharts-polar-angle-axis",this.props.className)},o&&this.renderAxisLine(),this.renderTicks())}}],[{key:"renderTickItem",value:function(n,i,a){var o;return S.isValidElement(n)?o=S.cloneElement(n,i):X(n)?o=n(i):o=S.createElement(rr,Kt({},i,{className:"recharts-polar-angle-axis-tick-value"}),a),o}}])})(N.PureComponent);eo(to,"displayName","PolarAngleAxis");eo(to,"axisType","angleAxis");eo(to,"defaultProps",{type:"category",angleAxisId:0,scale:"auto",cx:0,cy:0,orientation:"outer",axisLine:!0,tickLine:!0,tickSize:8,tick:!0,hide:!1,allowDuplicatedCategory:!0});var Ks,Dg;function ok(){if(Dg)return Ks;Dg=1;var e=T0(),t=e(Object.getPrototypeOf,Object);return Ks=t,Ks}var Gs,Ng;function uk(){if(Ng)return Gs;Ng=1;var e=St(),t=ok(),r=Pt(),n="[object Object]",i=Function.prototype,a=Object.prototype,o=i.toString,u=a.hasOwnProperty,c=o.call(Object);function s(f){if(!r(f)||e(f)!=n)return!1;var l=t(f);if(l===null)return!0;var h=u.call(l,"constructor")&&l.constructor;return typeof h=="function"&&h instanceof h&&o.call(h)==c}return Gs=s,Gs}var ck=uk();const sk=oe(ck);var Vs,qg;function lk(){if(qg)return Vs;qg=1;var e=St(),t=Pt(),r="[object Boolean]";function n(i){return i===!0||i===!1||t(i)&&e(i)==r}return Vs=n,Vs}var fk=lk();const hk=oe(fk);function Yn(e){"@babel/helpers - typeof";return Yn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Yn(e)}function fa(){return fa=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r0,from:{upperWidth:0,lowerWidth:0,height:h,x:c,y:s},to:{upperWidth:f,lowerWidth:l,height:h,x:c,y:s},duration:v,animationEasing:y,isActive:g},function(w){var O=w.upperWidth,m=w.lowerWidth,b=w.height,_=w.x,A=w.y;return S.createElement(lt,{canBegin:o>0,from:"0px ".concat(o===-1?1:o,"px"),to:"".concat(o,"px 0px"),attributeName:"strokeDasharray",begin:p,duration:v,easing:y},S.createElement("path",fa({},H(r,!0),{className:x,d:Wg(_,A,O,m,b),ref:n})))}):S.createElement("g",null,S.createElement("path",fa({},H(r,!0),{className:x,d:Wg(c,s,f,l,h)})))},_k=["option","shapeType","propTransformer","activeClassName","isActive"];function Zn(e){"@babel/helpers - typeof";return Zn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Zn(e)}function Ak(e,t){if(e==null)return{};var r=Sk(e,t),n,i;if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function Sk(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function zg(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function ha(e){for(var t=1;t0?He(w,"paddingAngle",0):0;if(m){var _=ze(m.endAngle-m.startAngle,w.endAngle-w.startAngle),A=ce(ce({},w),{},{startAngle:x+b,endAngle:x+_(v)+b});p.push(A),x=A.endAngle}else{var T=w.endAngle,M=w.startAngle,P=ze(0,T-M),E=P(v),j=ce(ce({},w),{},{startAngle:x+b,endAngle:x+E+b});p.push(j),x=j.endAngle}}),S.createElement(te,null,n.renderSectorsStatically(p))})}},{key:"attachKeyboardHandlers",value:function(n){var i=this;n.onkeydown=function(a){if(!a.altKey)switch(a.key){case"ArrowLeft":{var o=++i.state.sectorToFocus%i.sectorRefs.length;i.sectorRefs[o].focus(),i.setState({sectorToFocus:o});break}case"ArrowRight":{var u=--i.state.sectorToFocus<0?i.sectorRefs.length-1:i.state.sectorToFocus%i.sectorRefs.length;i.sectorRefs[u].focus(),i.setState({sectorToFocus:u});break}case"Escape":{i.sectorRefs[i.state.sectorToFocus].blur(),i.setState({sectorToFocus:0});break}}}}},{key:"renderSectors",value:function(){var n=this.props,i=n.sectors,a=n.isAnimationActive,o=this.state.prevSectors;return a&&i&&i.length&&(!o||!hi(o,i))?this.renderSectorsWithAnimation():this.renderSectorsStatically(i)}},{key:"componentDidMount",value:function(){this.pieRef&&this.attachKeyboardHandlers(this.pieRef)}},{key:"render",value:function(){var n=this,i=this.props,a=i.hide,o=i.sectors,u=i.className,c=i.label,s=i.cx,f=i.cy,l=i.innerRadius,h=i.outerRadius,d=i.isAnimationActive,y=this.state.isAnimationFinished;if(a||!o||!o.length||!q(s)||!q(f)||!q(l)||!q(h))return null;var v=J("recharts-pie",u);return S.createElement(te,{tabIndex:this.props.rootTabIndex,className:v,ref:function(g){n.pieRef=g}},this.renderSectors(),c&&this.renderLabels(o),Te.renderCallByParent(this.props,null,!1),(!d||y)&&wt.renderCallByParent(this.props,o,!1))}}],[{key:"getDerivedStateFromProps",value:function(n,i){return i.prevIsAnimationActive!==n.isAnimationActive?{prevIsAnimationActive:n.isAnimationActive,prevAnimationId:n.animationId,curSectors:n.sectors,prevSectors:[],isAnimationFinished:!0}:n.isAnimationActive&&n.animationId!==i.prevAnimationId?{prevAnimationId:n.animationId,curSectors:n.sectors,prevSectors:i.curSectors,isAnimationFinished:!0}:n.sectors!==i.curSectors?{curSectors:n.sectors,isAnimationFinished:!0}:null}},{key:"getTextAnchor",value:function(n,i){return n>i?"start":n=360?x:x-1)*c,O=p-x*d-w,m=i.reduce(function(A,T){var M=_e(T,g,0);return A+(q(M)?M:0)},0),b;if(m>0){var _;b=i.map(function(A,T){var M=_e(A,g,0),P=_e(A,f,T),E=(q(M)?M:0)/m,j;T?j=_.endAngle+Ce(v)*c*(M!==0?1:0):j=o;var C=j+Ce(v)*((M!==0?d:0)+E*O),$=(j+C)/2,k=(y.innerRadius+y.outerRadius)/2,R=[{name:P,value:M,payload:A,dataKey:g,type:h}],L=le(y.cx,y.cy,k,$);return _=ce(ce(ce({percent:E,cornerRadius:a,name:P,tooltipPayload:R,midAngle:$,middleRadius:k,tooltipPosition:L},A),y),{},{value:_e(A,g),startAngle:j,endAngle:C,payload:A,paddingAngle:Ce(v)*c}),_})}return ce(ce({},y),{},{sectors:b,data:i})});var Xs,Gg;function Kk(){if(Gg)return Xs;Gg=1;var e=Math.ceil,t=Math.max;function r(n,i,a,o){for(var u=-1,c=t(e((i-n)/(a||1)),0),s=Array(c);c--;)s[o?c:++u]=n,n+=a;return s}return Xs=r,Xs}var Ys,Vg;function ww(){if(Vg)return Ys;Vg=1;var e=z0(),t=1/0,r=17976931348623157e292;function n(i){if(!i)return i===0?i:0;if(i=e(i),i===t||i===-t){var a=i<0?-1:1;return a*r}return i===i?i:0}return Ys=n,Ys}var Zs,Xg;function Gk(){if(Xg)return Zs;Xg=1;var e=Kk(),t=La(),r=ww();function n(i){return function(a,o,u){return u&&typeof u!="number"&&t(a,o,u)&&(o=u=void 0),a=r(a),o===void 0?(o=a,a=0):o=r(o),u=u===void 0?a0&&n.handleDrag(i.changedTouches[0])}),Fe(n,"handleDragEnd",function(){n.setState({isTravellerMoving:!1,isSlideMoving:!1},function(){var i=n.props,a=i.endIndex,o=i.onDragEnd,u=i.startIndex;o?.({endIndex:a,startIndex:u})}),n.detachDragEndListener()}),Fe(n,"handleLeaveWrapper",function(){(n.state.isTravellerMoving||n.state.isSlideMoving)&&(n.leaveTimer=window.setTimeout(n.handleDragEnd,n.props.leaveTimeOut))}),Fe(n,"handleEnterSlideOrTraveller",function(){n.setState({isTextActive:!0})}),Fe(n,"handleLeaveSlideOrTraveller",function(){n.setState({isTextActive:!1})}),Fe(n,"handleSlideDragStart",function(i){var a=tb(i)?i.changedTouches[0]:i;n.setState({isTravellerMoving:!1,isSlideMoving:!0,slideMoveStartX:a.pageX}),n.attachDragEndListener()}),n.travellerDragStartHandlers={startX:n.handleTravellerDragStart.bind(n,"startX"),endX:n.handleTravellerDragStart.bind(n,"endX")},n.state={},n}return aR(t,e),tR(t,[{key:"componentWillUnmount",value:function(){this.leaveTimer&&(clearTimeout(this.leaveTimer),this.leaveTimer=null),this.detachDragEndListener()}},{key:"getIndex",value:function(n){var i=n.startX,a=n.endX,o=this.state.scaleValues,u=this.props,c=u.gap,s=u.data,f=s.length-1,l=Math.min(i,a),h=Math.max(i,a),d=t.getIndexInRange(o,l),y=t.getIndexInRange(o,h);return{startIndex:d-d%c,endIndex:y===f?f:y-y%c}}},{key:"getTextOfTick",value:function(n){var i=this.props,a=i.data,o=i.tickFormatter,u=i.dataKey,c=_e(a[n],u,n);return X(o)?o(c,n):c}},{key:"attachDragEndListener",value:function(){window.addEventListener("mouseup",this.handleDragEnd,!0),window.addEventListener("touchend",this.handleDragEnd,!0),window.addEventListener("mousemove",this.handleDrag,!0)}},{key:"detachDragEndListener",value:function(){window.removeEventListener("mouseup",this.handleDragEnd,!0),window.removeEventListener("touchend",this.handleDragEnd,!0),window.removeEventListener("mousemove",this.handleDrag,!0)}},{key:"handleSlideDrag",value:function(n){var i=this.state,a=i.slideMoveStartX,o=i.startX,u=i.endX,c=this.props,s=c.x,f=c.width,l=c.travellerWidth,h=c.startIndex,d=c.endIndex,y=c.onChange,v=n.pageX-a;v>0?v=Math.min(v,s+f-l-u,s+f-l-o):v<0&&(v=Math.max(v,s-o,s-u));var p=this.getIndex({startX:o+v,endX:u+v});(p.startIndex!==h||p.endIndex!==d)&&y&&y(p),this.setState({startX:o+v,endX:u+v,slideMoveStartX:n.pageX})}},{key:"handleTravellerDragStart",value:function(n,i){var a=tb(i)?i.changedTouches[0]:i;this.setState({isSlideMoving:!1,isTravellerMoving:!0,movingTravellerId:n,brushMoveStartX:a.pageX}),this.attachDragEndListener()}},{key:"handleTravellerMove",value:function(n){var i=this.state,a=i.brushMoveStartX,o=i.movingTravellerId,u=i.endX,c=i.startX,s=this.state[o],f=this.props,l=f.x,h=f.width,d=f.travellerWidth,y=f.onChange,v=f.gap,p=f.data,g={startX:this.state.startX,endX:this.state.endX},x=n.pageX-a;x>0?x=Math.min(x,l+h-d-s):x<0&&(x=Math.max(x,l-s)),g[o]=s+x;var w=this.getIndex(g),O=w.startIndex,m=w.endIndex,b=function(){var A=p.length-1;return o==="startX"&&(u>c?O%v===0:m%v===0)||uc?m%v===0:O%v===0)||u>c&&m===A};this.setState(Fe(Fe({},o,s+x),"brushMoveStartX",n.pageX),function(){y&&b()&&y(w)})}},{key:"handleTravellerMoveKeyboard",value:function(n,i){var a=this,o=this.state,u=o.scaleValues,c=o.startX,s=o.endX,f=this.state[i],l=u.indexOf(f);if(l!==-1){var h=l+n;if(!(h===-1||h>=u.length)){var d=u[h];i==="startX"&&d>=s||i==="endX"&&d<=c||this.setState(Fe({},i,d),function(){a.props.onChange(a.getIndex({startX:a.state.startX,endX:a.state.endX}))})}}}},{key:"renderBackground",value:function(){var n=this.props,i=n.x,a=n.y,o=n.width,u=n.height,c=n.fill,s=n.stroke;return S.createElement("rect",{stroke:s,fill:c,x:i,y:a,width:o,height:u})}},{key:"renderPanorama",value:function(){var n=this.props,i=n.x,a=n.y,o=n.width,u=n.height,c=n.data,s=n.children,f=n.padding,l=N.Children.only(s);return l?S.cloneElement(l,{x:i,y:a,width:o,height:u,margin:f,compact:!0,data:c}):null}},{key:"renderTravellerLayer",value:function(n,i){var a,o,u=this,c=this.props,s=c.y,f=c.travellerWidth,l=c.height,h=c.traveller,d=c.ariaLabel,y=c.data,v=c.startIndex,p=c.endIndex,g=Math.max(n,this.props.x),x=Qs(Qs({},H(this.props,!1)),{},{x:g,y:s,width:f,height:l}),w=d||"Min value: ".concat((a=y[v])===null||a===void 0?void 0:a.name,", Max value: ").concat((o=y[p])===null||o===void 0?void 0:o.name);return S.createElement(te,{tabIndex:0,role:"slider","aria-label":w,"aria-valuenow":n,className:"recharts-brush-traveller",onMouseEnter:this.handleEnterSlideOrTraveller,onMouseLeave:this.handleLeaveSlideOrTraveller,onMouseDown:this.travellerDragStartHandlers[i],onTouchStart:this.travellerDragStartHandlers[i],onKeyDown:function(m){["ArrowLeft","ArrowRight"].includes(m.key)&&(m.preventDefault(),m.stopPropagation(),u.handleTravellerMoveKeyboard(m.key==="ArrowRight"?1:-1,i))},onFocus:function(){u.setState({isTravellerFocused:!0})},onBlur:function(){u.setState({isTravellerFocused:!1})},style:{cursor:"col-resize"}},t.renderTraveller(h,x))}},{key:"renderSlide",value:function(n,i){var a=this.props,o=a.y,u=a.height,c=a.stroke,s=a.travellerWidth,f=Math.min(n,i)+s,l=Math.max(Math.abs(i-n)-s,0);return S.createElement("rect",{className:"recharts-brush-slide",onMouseEnter:this.handleEnterSlideOrTraveller,onMouseLeave:this.handleLeaveSlideOrTraveller,onMouseDown:this.handleSlideDragStart,onTouchStart:this.handleSlideDragStart,style:{cursor:"move"},stroke:"none",fill:c,fillOpacity:.2,x:f,y:o,width:l,height:u})}},{key:"renderText",value:function(){var n=this.props,i=n.startIndex,a=n.endIndex,o=n.y,u=n.height,c=n.travellerWidth,s=n.stroke,f=this.state,l=f.startX,h=f.endX,d=5,y={pointerEvents:"none",fill:s};return S.createElement(te,{className:"recharts-brush-texts"},S.createElement(rr,va({textAnchor:"end",verticalAnchor:"middle",x:Math.min(l,h)-d,y:o+u/2},y),this.getTextOfTick(i)),S.createElement(rr,va({textAnchor:"start",verticalAnchor:"middle",x:Math.max(l,h)+c+d,y:o+u/2},y),this.getTextOfTick(a)))}},{key:"render",value:function(){var n=this.props,i=n.data,a=n.className,o=n.children,u=n.x,c=n.y,s=n.width,f=n.height,l=n.alwaysShowText,h=this.state,d=h.startX,y=h.endX,v=h.isTextActive,p=h.isSlideMoving,g=h.isTravellerMoving,x=h.isTravellerFocused;if(!i||!i.length||!q(u)||!q(c)||!q(s)||!q(f)||s<=0||f<=0)return null;var w=J("recharts-brush",a),O=S.Children.count(o)===1,m=Qk("userSelect","none");return S.createElement(te,{className:w,onMouseLeave:this.handleLeaveWrapper,onTouchMove:this.handleTouchMove,style:m},this.renderBackground(),O&&this.renderPanorama(),this.renderSlide(d,y),this.renderTravellerLayer(d,"startX"),this.renderTravellerLayer(y,"endX"),(v||p||g||x||l)&&this.renderText())}}],[{key:"renderDefaultTraveller",value:function(n){var i=n.x,a=n.y,o=n.width,u=n.height,c=n.stroke,s=Math.floor(a+u/2)-1;return S.createElement(S.Fragment,null,S.createElement("rect",{x:i,y:a,width:o,height:u,fill:c,stroke:"none"}),S.createElement("line",{x1:i+1,y1:s,x2:i+o-1,y2:s,fill:"none",stroke:"#fff"}),S.createElement("line",{x1:i+1,y1:s+2,x2:i+o-1,y2:s+2,fill:"none",stroke:"#fff"}))}},{key:"renderTraveller",value:function(n,i){var a;return S.isValidElement(n)?a=S.cloneElement(n,i):X(n)?a=n(i):a=t.renderDefaultTraveller(i),a}},{key:"getDerivedStateFromProps",value:function(n,i){var a=n.data,o=n.width,u=n.x,c=n.travellerWidth,s=n.updateId,f=n.startIndex,l=n.endIndex;if(a!==i.prevData||s!==i.prevUpdateId)return Qs({prevData:a,prevTravellerWidth:c,prevUpdateId:s,prevX:u,prevWidth:o},a&&a.length?uR({data:a,width:o,x:u,travellerWidth:c,startIndex:f,endIndex:l}):{scale:null,scaleValues:null});if(i.scale&&(o!==i.prevWidth||u!==i.prevX||c!==i.prevTravellerWidth)){i.scale.range([u,u+o-c]);var h=i.scale.domain().map(function(d){return i.scale(d)});return{prevData:a,prevTravellerWidth:c,prevUpdateId:s,prevX:u,prevWidth:o,startX:i.scale(n.startIndex),endX:i.scale(n.endIndex),scaleValues:h}}return null}},{key:"getIndexInRange",value:function(n,i){for(var a=n.length,o=0,u=a-1;u-o>1;){var c=Math.floor((o+u)/2);n[c]>i?u=c:o=c}return i>=n[u]?u:o}}])})(N.PureComponent);Fe(qr,"displayName","Brush");Fe(qr,"defaultProps",{height:40,travellerWidth:5,gap:1,fill:"#fff",stroke:"#666",padding:{top:1,right:1,bottom:1,left:1},leaveTimeOut:1e3,alwaysShowText:!1});var el,rb;function cR(){if(rb)return el;rb=1;var e=nh();function t(r,n){var i;return e(r,function(a,o,u){return i=n(a,o,u),!i}),!!i}return el=t,el}var tl,nb;function sR(){if(nb)return tl;nb=1;var e=x0(),t=ht(),r=cR(),n=qe(),i=La();function a(o,u,c){var s=n(o)?e:r;return c&&i(o,u,c)&&(u=void 0),s(o,t(u,3))}return tl=a,tl}var lR=sR();const fR=oe(lR);var ct=function(t,r){var n=t.alwaysShow,i=t.ifOverflow;return n&&(i="extendDomain"),i===r},rl,ib;function hR(){if(ib)return rl;ib=1;var e=q0();function t(r,n,i){n=="__proto__"&&e?e(r,n,{configurable:!0,enumerable:!0,value:i,writable:!0}):r[n]=i}return rl=t,rl}var nl,ab;function pR(){if(ab)return nl;ab=1;var e=hR(),t=D0(),r=ht();function n(i,a){var o={};return a=r(a,3),t(i,function(u,c,s){e(o,c,a(u,c,s))}),o}return nl=n,nl}var dR=pR();const vR=oe(dR);var il,ob;function yR(){if(ob)return il;ob=1;function e(t,r){for(var n=-1,i=t==null?0:t.length;++n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function SR(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function PR(e,t){var r=e.x,n=e.y,i=AR(e,xR),a="".concat(r),o=parseInt(a,10),u="".concat(n),c=parseInt(u,10),s="".concat(t.height||i.height),f=parseInt(s,10),l="".concat(t.width||i.width),h=parseInt(l,10);return pn(pn(pn(pn(pn({},t),i),o?{x:o}:{}),c?{y:c}:{}),{},{height:f,width:h,name:t.name,radius:t.radius})}function lb(e){return S.createElement(gw,gf({shapeType:"rectangle",propTransformer:PR,activeClassName:"recharts-active-bar"},e))}var TR=function(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return function(n,i){if(typeof t=="number")return t;var a=q(n)||ZO(n);return a?t(n,i):(a||Qt(!1),r)}},ER=["value","background"],Pw;function Lr(e){"@babel/helpers - typeof";return Lr=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Lr(e)}function jR(e,t){if(e==null)return{};var r=MR(e,t),n,i;if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function MR(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function ma(){return ma=Object.assign?Object.assign.bind():function(e){for(var t=1;t0&&Math.abs($)0&&Math.abs(C)0&&(j=Math.min((fe||0)-(C[ye-1]||0),j))}),Number.isFinite(j)){var $=j/E,k=v.layout==="vertical"?n.height:n.width;if(v.padding==="gap"&&(_=$*k/2),v.padding==="no-gap"){var R=Ie(t.barCategoryGap,$*k),L=$*k/2;_=L-R-(L-R)/k*R}}}i==="xAxis"?A=[n.left+(w.left||0)+(_||0),n.left+n.width-(w.right||0)-(_||0)]:i==="yAxis"?A=c==="horizontal"?[n.top+n.height-(w.bottom||0),n.top+(w.top||0)]:[n.top+(w.top||0)+(_||0),n.top+n.height-(w.bottom||0)-(_||0)]:A=v.range,m&&(A=[A[1],A[0]]);var B=Yx(v,a,h),U=B.scale,G=B.realScaleType;U.domain(g).range(A),Zx(U);var W=Jx(U,tt(tt({},v),{},{realScaleType:G}));i==="xAxis"?(P=p==="top"&&!O||p==="bottom"&&O,T=n.left,M=l[b]-P*v.height):i==="yAxis"&&(P=p==="left"&&!O||p==="right"&&O,T=l[b]-P*v.width,M=n.top);var V=tt(tt(tt({},v),W),{},{realScaleType:G,x:T,y:M,scale:U,width:i==="xAxis"?n.width:v.width,height:i==="yAxis"?n.height:v.height});return V.bandSize=ta(V,W),!v.hide&&i==="xAxis"?l[b]+=(P?-1:1)*V.height:v.hide||(l[b]+=(P?-1:1)*V.width),tt(tt({},d),{},io({},y,V))},{})},$w=function(t,r){var n=t.x,i=t.y,a=r.x,o=r.y;return{x:Math.min(n,a),y:Math.min(i,o),width:Math.abs(a-n),height:Math.abs(o-i)}},FR=function(t){var r=t.x1,n=t.y1,i=t.x2,a=t.y2;return $w({x:r,y:n},{x:i,y:a})},Cw=(function(){function e(t){qR(this,e),this.scale=t}return LR(e,[{key:"domain",get:function(){return this.scale.domain}},{key:"range",get:function(){return this.scale.range}},{key:"rangeMin",get:function(){return this.range()[0]}},{key:"rangeMax",get:function(){return this.range()[1]}},{key:"bandwidth",get:function(){return this.scale.bandwidth}},{key:"apply",value:function(r){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=n.bandAware,a=n.position;if(r!==void 0){if(a)switch(a){case"start":return this.scale(r);case"middle":{var o=this.bandwidth?this.bandwidth()/2:0;return this.scale(r)+o}case"end":{var u=this.bandwidth?this.bandwidth():0;return this.scale(r)+u}default:return this.scale(r)}if(i){var c=this.bandwidth?this.bandwidth()/2:0;return this.scale(r)+c}return this.scale(r)}}},{key:"isInRange",value:function(r){var n=this.range(),i=n[0],a=n[n.length-1];return i<=a?r>=i&&r<=a:r>=a&&r<=i}}],[{key:"create",value:function(r){return new e(r)}}])})();io(Cw,"EPS",1e-4);var Ih=function(t){var r=Object.keys(t).reduce(function(n,i){return tt(tt({},n),{},io({},i,Cw.create(t[i])))},{});return tt(tt({},r),{},{apply:function(i){var a=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},o=a.bandAware,u=a.position;return vR(i,function(c,s){return r[s].apply(c,{bandAware:o,position:u})})},isInRange:function(i){return Sw(i,function(a,o){return r[o].isInRange(a)})}})};function WR(e){return(e%180+180)%180}var zR=function(t){var r=t.width,n=t.height,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,a=WR(i),o=a*Math.PI/180,u=Math.atan(n/r),c=o>u&&o-1?c[s?a[f]:f]:void 0}}return ul=n,ul}var cl,yb;function HR(){if(yb)return cl;yb=1;var e=ww();function t(r){var n=e(r),i=n%1;return n===n?i?n-i:n:0}return cl=t,cl}var sl,mb;function KR(){if(mb)return sl;mb=1;var e=$0(),t=ht(),r=HR(),n=Math.max;function i(a,o,u){var c=a==null?0:a.length;if(!c)return-1;var s=u==null?0:r(u);return s<0&&(s=n(c+s,0)),e(a,t(o,3),s)}return sl=i,sl}var ll,gb;function GR(){if(gb)return ll;gb=1;var e=UR(),t=KR(),r=e(t);return ll=r,ll}var VR=GR();const XR=oe(VR);var YR=Gb();const ZR=oe(YR);var JR=ZR(function(e){return{x:e.left,y:e.top,width:e.width,height:e.height}},function(e){return["l",e.left,"t",e.top,"w",e.width,"h",e.height].join("")}),kh=N.createContext(void 0),Rh=N.createContext(void 0),Iw=N.createContext(void 0),kw=N.createContext({}),Rw=N.createContext(void 0),Dw=N.createContext(0),Nw=N.createContext(0),bb=function(t){var r=t.state,n=r.xAxisMap,i=r.yAxisMap,a=r.offset,o=t.clipPathId,u=t.children,c=t.width,s=t.height,f=JR(a);return S.createElement(kh.Provider,{value:n},S.createElement(Rh.Provider,{value:i},S.createElement(kw.Provider,{value:a},S.createElement(Iw.Provider,{value:f},S.createElement(Rw.Provider,{value:o},S.createElement(Dw.Provider,{value:s},S.createElement(Nw.Provider,{value:c},u)))))))},QR=function(){return N.useContext(Rw)},qw=function(t){var r=N.useContext(kh);r==null&&Qt(!1);var n=r[t];return n==null&&Qt(!1),n},eD=function(){var t=N.useContext(kh);return Mt(t)},tD=function(){var t=N.useContext(Rh),r=XR(t,function(n){return Sw(n.domain,Number.isFinite)});return r||Mt(t)},Lw=function(t){var r=N.useContext(Rh);r==null&&Qt(!1);var n=r[t];return n==null&&Qt(!1),n},rD=function(){var t=N.useContext(Iw);return t},nD=function(){return N.useContext(kw)},Dh=function(){return N.useContext(Nw)},Nh=function(){return N.useContext(Dw)};function Br(e){"@babel/helpers - typeof";return Br=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Br(e)}function iD(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function aD(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);re*i)return!1;var a=r();return e*(t-e*a/2-n)>=0&&e*(t+e*a/2-i)<=0}function BD(e,t){return Kw(e,t+1)}function FD(e,t,r,n,i){for(var a=(n||[]).slice(),o=t.start,u=t.end,c=0,s=1,f=o,l=function(){var y=n?.[c];if(y===void 0)return{v:Kw(n,s)};var v=c,p,g=function(){return p===void 0&&(p=r(y,v)),p},x=y.coordinate,w=c===0||Oa(e,x,g,f,u);w||(c=0,f=o,s+=1),w&&(f=x+e*(g()/2+i),c+=s)},h;s<=a.length;)if(h=l(),h)return h.v;return[]}function ri(e){"@babel/helpers - typeof";return ri=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ri(e)}function Tb(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Me(e){for(var t=1;t0?d.coordinate-p*e:d.coordinate})}else a[h]=d=Me(Me({},d),{},{tickCoord:d.coordinate});var g=Oa(e,d.tickCoord,v,u,c);g&&(c=d.tickCoord-e*(v()/2+i),a[h]=Me(Me({},d),{},{isShow:!0}))},f=o-1;f>=0;f--)s(f);return a}function KD(e,t,r,n,i,a){var o=(n||[]).slice(),u=o.length,c=t.start,s=t.end;if(a){var f=n[u-1],l=r(f,u-1),h=e*(f.coordinate+e*l/2-s);o[u-1]=f=Me(Me({},f),{},{tickCoord:h>0?f.coordinate-h*e:f.coordinate});var d=Oa(e,f.tickCoord,function(){return l},c,s);d&&(s=f.tickCoord-e*(l/2+i),o[u-1]=Me(Me({},f),{},{isShow:!0}))}for(var y=a?u-1:u,v=function(x){var w=o[x],O,m=function(){return O===void 0&&(O=r(w,x)),O};if(x===0){var b=e*(w.coordinate-e*m()/2-c);o[x]=w=Me(Me({},w),{},{tickCoord:b<0?w.coordinate-b*e:w.coordinate})}else o[x]=w=Me(Me({},w),{},{tickCoord:w.coordinate});var _=Oa(e,w.tickCoord,m,c,s);_&&(c=w.tickCoord+e*(m()/2+i),o[x]=Me(Me({},w),{},{isShow:!0}))},p=0;p=2?Ce(i[1].coordinate-i[0].coordinate):1,g=LD(a,p,d);return c==="equidistantPreserveStart"?FD(p,g,v,i,o):(c==="preserveStart"||c==="preserveStartEnd"?h=KD(p,g,v,i,o,c==="preserveStartEnd"):h=HD(p,g,v,i,o),h.filter(function(x){return x.isShow}))}var GD=["viewBox"],VD=["viewBox"],XD=["ticks"];function zr(e){"@babel/helpers - typeof";return zr=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},zr(e)}function gr(){return gr=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function YD(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function ZD(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function jb(e,t){for(var r=0;r0?c(this.props):c(d)),o<=0||u<=0||!y||!y.length?null:S.createElement(te,{className:J("recharts-cartesian-axis",s),ref:function(p){n.layerReference=p}},a&&this.renderAxisLine(),this.renderTicks(y,this.state.fontSize,this.state.letterSpacing),Te.renderCallByParent(this.props))}}],[{key:"renderTickItem",value:function(n,i,a){var o,u=J(i.className,"recharts-cartesian-axis-tick-value");return S.isValidElement(n)?o=S.cloneElement(n,we(we({},i),{},{className:u})):X(n)?o=n(we(we({},i),{},{className:u})):o=S.createElement(rr,gr({},i,{className:"recharts-cartesian-axis-tick-value"}),a),o}}])})(N.Component);Fh(nn,"displayName","CartesianAxis");Fh(nn,"defaultProps",{x:0,y:0,width:0,height:0,viewBox:{x:0,y:0,width:0,height:0},orientation:"bottom",ticks:[],stroke:"#666",tickLine:!0,axisLine:!0,tick:!0,mirror:!1,minTickGap:5,tickSize:6,tickMargin:2,interval:"preserveEnd"});var iN=["x1","y1","x2","y2","key"],aN=["offset"];function ir(e){"@babel/helpers - typeof";return ir=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ir(e)}function Mb(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function $e(e){for(var t=1;t=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function sN(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}var lN=function(t){var r=t.fill;if(!r||r==="none")return null;var n=t.fillOpacity,i=t.x,a=t.y,o=t.width,u=t.height,c=t.ry;return S.createElement("rect",{x:i,y:a,ry:c,width:o,height:u,stroke:"none",fill:r,fillOpacity:n,className:"recharts-cartesian-grid-bg"})};function Xw(e,t){var r;if(S.isValidElement(e))r=S.cloneElement(e,t);else if(X(e))r=e(t);else{var n=t.x1,i=t.y1,a=t.x2,o=t.y2,u=t.key,c=$b(t,iN),s=H(c,!1);s.offset;var f=$b(s,aN);r=S.createElement("line",Yt({},f,{x1:n,y1:i,x2:a,y2:o,fill:"none",key:u}))}return r}function fN(e){var t=e.x,r=e.width,n=e.horizontal,i=n===void 0?!0:n,a=e.horizontalPoints;if(!i||!a||!a.length)return null;var o=a.map(function(u,c){var s=$e($e({},e),{},{x1:t,y1:u,x2:t+r,y2:u,key:"line-".concat(c),index:c});return Xw(i,s)});return S.createElement("g",{className:"recharts-cartesian-grid-horizontal"},o)}function hN(e){var t=e.y,r=e.height,n=e.vertical,i=n===void 0?!0:n,a=e.verticalPoints;if(!i||!a||!a.length)return null;var o=a.map(function(u,c){var s=$e($e({},e),{},{x1:u,y1:t,x2:u,y2:t+r,key:"line-".concat(c),index:c});return Xw(i,s)});return S.createElement("g",{className:"recharts-cartesian-grid-vertical"},o)}function pN(e){var t=e.horizontalFill,r=e.fillOpacity,n=e.x,i=e.y,a=e.width,o=e.height,u=e.horizontalPoints,c=e.horizontal,s=c===void 0?!0:c;if(!s||!t||!t.length)return null;var f=u.map(function(h){return Math.round(h+i-i)}).sort(function(h,d){return h-d});i!==f[0]&&f.unshift(0);var l=f.map(function(h,d){var y=!f[d+1],v=y?i+o-h:f[d+1]-h;if(v<=0)return null;var p=d%t.length;return S.createElement("rect",{key:"react-".concat(d),y:h,x:n,height:v,width:a,stroke:"none",fill:t[p],fillOpacity:r,className:"recharts-cartesian-grid-bg"})});return S.createElement("g",{className:"recharts-cartesian-gridstripes-horizontal"},l)}function dN(e){var t=e.vertical,r=t===void 0?!0:t,n=e.verticalFill,i=e.fillOpacity,a=e.x,o=e.y,u=e.width,c=e.height,s=e.verticalPoints;if(!r||!n||!n.length)return null;var f=s.map(function(h){return Math.round(h+a-a)}).sort(function(h,d){return h-d});a!==f[0]&&f.unshift(0);var l=f.map(function(h,d){var y=!f[d+1],v=y?a+u-h:f[d+1]-h;if(v<=0)return null;var p=d%n.length;return S.createElement("rect",{key:"react-".concat(d),x:h,y:o,width:v,height:c,stroke:"none",fill:n[p],fillOpacity:i,className:"recharts-cartesian-grid-bg"})});return S.createElement("g",{className:"recharts-cartesian-gridstripes-vertical"},l)}var vN=function(t,r){var n=t.xAxis,i=t.width,a=t.height,o=t.offset;return Xx(Bh($e($e($e({},nn.defaultProps),n),{},{ticks:gt(n,!0),viewBox:{x:0,y:0,width:i,height:a}})),o.left,o.left+o.width,r)},yN=function(t,r){var n=t.yAxis,i=t.width,a=t.height,o=t.offset;return Xx(Bh($e($e($e({},nn.defaultProps),n),{},{ticks:gt(n,!0),viewBox:{x:0,y:0,width:i,height:a}})),o.top,o.top+o.height,r)},pr={horizontal:!0,vertical:!0,stroke:"#ccc",fill:"none",verticalFill:[],horizontalFill:[]};function mN(e){var t,r,n,i,a,o,u=Dh(),c=Nh(),s=nD(),f=$e($e({},e),{},{stroke:(t=e.stroke)!==null&&t!==void 0?t:pr.stroke,fill:(r=e.fill)!==null&&r!==void 0?r:pr.fill,horizontal:(n=e.horizontal)!==null&&n!==void 0?n:pr.horizontal,horizontalFill:(i=e.horizontalFill)!==null&&i!==void 0?i:pr.horizontalFill,vertical:(a=e.vertical)!==null&&a!==void 0?a:pr.vertical,verticalFill:(o=e.verticalFill)!==null&&o!==void 0?o:pr.verticalFill,x:q(e.x)?e.x:s.left,y:q(e.y)?e.y:s.top,width:q(e.width)?e.width:s.width,height:q(e.height)?e.height:s.height}),l=f.x,h=f.y,d=f.width,y=f.height,v=f.syncWithTicks,p=f.horizontalValues,g=f.verticalValues,x=eD(),w=tD();if(!q(d)||d<=0||!q(y)||y<=0||!q(l)||l!==+l||!q(h)||h!==+h)return null;var O=f.verticalCoordinatesGenerator||vN,m=f.horizontalCoordinatesGenerator||yN,b=f.horizontalPoints,_=f.verticalPoints;if((!b||!b.length)&&X(m)){var A=p&&p.length,T=m({yAxis:w?$e($e({},w),{},{ticks:A?p:w.ticks}):void 0,width:u,height:c,offset:s},A?!0:v);it(Array.isArray(T),"horizontalCoordinatesGenerator should return Array but instead it returned [".concat(ir(T),"]")),Array.isArray(T)&&(b=T)}if((!_||!_.length)&&X(O)){var M=g&&g.length,P=O({xAxis:x?$e($e({},x),{},{ticks:M?g:x.ticks}):void 0,width:u,height:c,offset:s},M?!0:v);it(Array.isArray(P),"verticalCoordinatesGenerator should return Array but instead it returned [".concat(ir(P),"]")),Array.isArray(P)&&(_=P)}return S.createElement("g",{className:"recharts-cartesian-grid"},S.createElement(lN,{fill:f.fill,fillOpacity:f.fillOpacity,x:f.x,y:f.y,width:f.width,height:f.height,ry:f.ry}),S.createElement(fN,Yt({},f,{offset:s,horizontalPoints:b,xAxis:x,yAxis:w})),S.createElement(hN,Yt({},f,{offset:s,verticalPoints:_,xAxis:x,yAxis:w})),S.createElement(pN,Yt({},f,{horizontalPoints:b})),S.createElement(dN,Yt({},f,{verticalPoints:_})))}mN.displayName="CartesianGrid";var gN=["type","layout","connectNulls","ref"],bN=["key"];function Ur(e){"@babel/helpers - typeof";return Ur=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Ur(e)}function Cb(e,t){if(e==null)return{};var r=xN(e,t),n,i;if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function xN(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function _n(){return _n=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);rl){d=[].concat(dr(c.slice(0,y)),[l-v]);break}var p=d.length%2===0?[0,h]:[h];return[].concat(dr(t.repeat(c,f)),dr(d),p).map(function(g){return"".concat(g,"px")}).join(", ")}),rt(r,"id",Zr("recharts-line-")),rt(r,"pathRef",function(o){r.mainCurve=o}),rt(r,"handleAnimationEnd",function(){r.setState({isAnimationFinished:!0}),r.props.onAnimationEnd&&r.props.onAnimationEnd()}),rt(r,"handleAnimationStart",function(){r.setState({isAnimationFinished:!1}),r.props.onAnimationStart&&r.props.onAnimationStart()}),r}return MN(t,e),PN(t,[{key:"componentDidMount",value:function(){if(this.props.isAnimationActive){var n=this.getTotalLength();this.setState({totalLength:n})}}},{key:"componentDidUpdate",value:function(){if(this.props.isAnimationActive){var n=this.getTotalLength();n!==this.state.totalLength&&this.setState({totalLength:n})}}},{key:"getTotalLength",value:function(){var n=this.mainCurve;try{return n&&n.getTotalLength&&n.getTotalLength()||0}catch{return 0}}},{key:"renderErrorBar",value:function(n,i){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var a=this.props,o=a.points,u=a.xAxis,c=a.yAxis,s=a.layout,f=a.children,l=Ke(f,pi);if(!l)return null;var h=function(v,p){return{x:v.x,y:v.y,value:v.value,errorVal:_e(v.payload,p)}},d={clipPath:n?"url(#clipPath-".concat(i,")"):null};return S.createElement(te,d,l.map(function(y){return S.cloneElement(y,{key:"bar-".concat(y.props.dataKey),data:o,xAxis:u,yAxis:c,layout:s,dataPointFormatter:h})}))}},{key:"renderDots",value:function(n,i,a){var o=this.props.isAnimationActive;if(o&&!this.state.isAnimationFinished)return null;var u=this.props,c=u.dot,s=u.points,f=u.dataKey,l=H(this.props,!1),h=H(c,!0),d=s.map(function(v,p){var g=Be(Be(Be({key:"dot-".concat(p),r:3},l),h),{},{index:p,cx:v.x,cy:v.y,value:v.value,dataKey:f,payload:v.payload,points:s});return t.renderDotItem(c,g)}),y={clipPath:n?"url(#clipPath-".concat(i?"":"dots-").concat(a,")"):null};return S.createElement(te,_n({className:"recharts-line-dots",key:"dots"},y),d)}},{key:"renderCurveStatically",value:function(n,i,a,o){var u=this.props,c=u.type,s=u.layout,f=u.connectNulls;u.ref;var l=Cb(u,gN),h=Be(Be(Be({},H(l,!0)),{},{fill:"none",className:"recharts-line-curve",clipPath:i?"url(#clipPath-".concat(a,")"):null,points:n},o),{},{type:c,layout:s,connectNulls:f});return S.createElement(ia,_n({},h,{pathRef:this.pathRef}))}},{key:"renderCurveWithAnimation",value:function(n,i){var a=this,o=this.props,u=o.points,c=o.strokeDasharray,s=o.isAnimationActive,f=o.animationBegin,l=o.animationDuration,h=o.animationEasing,d=o.animationId,y=o.animateNewValues,v=o.width,p=o.height,g=this.state,x=g.prevPoints,w=g.totalLength;return S.createElement(lt,{begin:f,duration:l,isActive:s,easing:h,from:{t:0},to:{t:1},key:"line-".concat(d),onAnimationEnd:this.handleAnimationEnd,onAnimationStart:this.handleAnimationStart},function(O){var m=O.t;if(x){var b=x.length/u.length,_=u.map(function(E,j){var C=Math.floor(j*b);if(x[C]){var $=x[C],k=ze($.x,E.x),R=ze($.y,E.y);return Be(Be({},E),{},{x:k(m),y:R(m)})}if(y){var L=ze(v*2,E.x),B=ze(p/2,E.y);return Be(Be({},E),{},{x:L(m),y:B(m)})}return Be(Be({},E),{},{x:E.x,y:E.y})});return a.renderCurveStatically(_,n,i)}var A=ze(0,w),T=A(m),M;if(c){var P="".concat(c).split(/[,\s]+/gim).map(function(E){return parseFloat(E)});M=a.getStrokeDasharray(T,w,P)}else M=a.generateSimpleStrokeDasharray(w,T);return a.renderCurveStatically(u,n,i,{strokeDasharray:M})})}},{key:"renderCurve",value:function(n,i){var a=this.props,o=a.points,u=a.isAnimationActive,c=this.state,s=c.prevPoints,f=c.totalLength;return u&&o&&o.length&&(!s&&f>0||!hi(s,o))?this.renderCurveWithAnimation(n,i):this.renderCurveStatically(o,n,i)}},{key:"render",value:function(){var n,i=this.props,a=i.hide,o=i.dot,u=i.points,c=i.className,s=i.xAxis,f=i.yAxis,l=i.top,h=i.left,d=i.width,y=i.height,v=i.isAnimationActive,p=i.id;if(a||!u||!u.length)return null;var g=this.state.isAnimationFinished,x=u.length===1,w=J("recharts-line",c),O=s&&s.allowDataOverflow,m=f&&f.allowDataOverflow,b=O||m,_=Y(p)?this.id:p,A=(n=H(o,!1))!==null&&n!==void 0?n:{r:3,strokeWidth:2},T=A.r,M=T===void 0?3:T,P=A.strokeWidth,E=P===void 0?2:P,j=s_(o)?o:{},C=j.clipDot,$=C===void 0?!0:C,k=M*2+E;return S.createElement(te,{className:w},O||m?S.createElement("defs",null,S.createElement("clipPath",{id:"clipPath-".concat(_)},S.createElement("rect",{x:O?h:h-d/2,y:m?l:l-y/2,width:O?d:d*2,height:m?y:y*2})),!$&&S.createElement("clipPath",{id:"clipPath-dots-".concat(_)},S.createElement("rect",{x:h-k/2,y:l-k/2,width:d+k,height:y+k}))):null,!x&&this.renderCurve(b,_),this.renderErrorBar(b,_),(x||o)&&this.renderDots(b,$,_),(!v||g)&&wt.renderCallByParent(this.props,u))}}],[{key:"getDerivedStateFromProps",value:function(n,i){return n.animationId!==i.prevAnimationId?{prevAnimationId:n.animationId,curPoints:n.points,prevPoints:i.curPoints}:n.points!==i.curPoints?{curPoints:n.points}:null}},{key:"repeat",value:function(n,i){for(var a=n.length%2!==0?[].concat(dr(n),[0]):n,o=[],u=0;ue.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function x2(e,t){if(e==null)return{};var r={};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){if(t.indexOf(n)>=0)continue;r[n]=e[n]}return r}function w2(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function O2(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r0?o:t&&t.length&&q(i)&&q(a)?t.slice(i,a+1):[]};function lO(e){return e==="number"?[0,"auto"]:void 0}var Nf=function(t,r,n,i){var a=t.graphicalItems,o=t.tooltipAxis,u=ho(r,t);return n<0||!a||!a.length||n>=u.length?null:a.reduce(function(c,s){var f,l=(f=s.props.data)!==null&&f!==void 0?f:r;l&&t.dataStartIndex+t.dataEndIndex!==0&&t.dataEndIndex-t.dataStartIndex>=n&&(l=l.slice(t.dataStartIndex,t.dataEndIndex+1));var h;if(o.dataKey&&!o.allowDuplicatedCategory){var d=l===void 0?u:l;h=Mi(d,o.dataKey,i)}else h=l&&l[n]||u[n];return h?[].concat(Vr(c),[ew(s,h)]):c},[])},Fb=function(t,r,n,i){var a=i||{x:t.chartX,y:t.chartY},o=k2(a,n),u=t.orderedTooltipTicks,c=t.tooltipAxis,s=t.tooltipTicks,f=aM(o,u,s,c);if(f>=0&&s){var l=s[f]&&s[f].value,h=Nf(t,r,f,l),d=R2(n,u,f,a);return{activeTooltipIndex:f,activeLabel:l,activePayload:h,activeCoordinate:d}}return null},D2=function(t,r){var n=r.axes,i=r.graphicalItems,a=r.axisType,o=r.axisIdKey,u=r.stackGroups,c=r.dataStartIndex,s=r.dataEndIndex,f=t.layout,l=t.children,h=t.stackOffset,d=Vx(f,a);return n.reduce(function(y,v){var p,g=v.type.defaultProps!==void 0?I(I({},v.type.defaultProps),v.props):v.props,x=g.type,w=g.dataKey,O=g.allowDataOverflow,m=g.allowDuplicatedCategory,b=g.scale,_=g.ticks,A=g.includeHidden,T=g[o];if(y[T])return y;var M=ho(t.data,{graphicalItems:i.filter(function(W){var V,fe=o in W.props?W.props[o]:(V=W.type.defaultProps)===null||V===void 0?void 0:V[o];return fe===T}),dataStartIndex:c,dataEndIndex:s}),P=M.length,E,j,C;c2(g.domain,O,x)&&(E=Yl(g.domain,null,O),d&&(x==="number"||b!=="auto")&&(C=bn(M,w,"category")));var $=lO(x);if(!E||E.length===0){var k,R=(k=g.domain)!==null&&k!==void 0?k:$;if(w){if(E=bn(M,w,x),x==="category"&&d){var L=QO(E);m&&L?(j=E,E=da(0,P)):m||(E=Lm(R,E,v).reduce(function(W,V){return W.indexOf(V)>=0?W:[].concat(Vr(W),[V])},[]))}else if(x==="category")m?E=E.filter(function(W){return W!==""&&!Y(W)}):E=Lm(R,E,v).reduce(function(W,V){return W.indexOf(V)>=0||V===""||Y(V)?W:[].concat(Vr(W),[V])},[]);else if(x==="number"){var B=lM(M,i.filter(function(W){var V,fe,ye=o in W.props?W.props[o]:(V=W.type.defaultProps)===null||V===void 0?void 0:V[o],Le="hide"in W.props?W.props.hide:(fe=W.type.defaultProps)===null||fe===void 0?void 0:fe.hide;return ye===T&&(A||!Le)}),w,a,f);B&&(E=B)}d&&(x==="number"||b!=="auto")&&(C=bn(M,w,"category"))}else d?E=da(0,P):u&&u[T]&&u[T].hasStack&&x==="number"?E=h==="expand"?[0,1]:Qx(u[T].stackGroups,c,s):E=Gx(M,i.filter(function(W){var V=o in W.props?W.props[o]:W.type.defaultProps[o],fe="hide"in W.props?W.props.hide:W.type.defaultProps.hide;return V===T&&(A||!fe)}),x,f,!0);if(x==="number")E=kf(l,E,T,a,_),R&&(E=Yl(R,E,O));else if(x==="category"&&R){var U=R,G=E.every(function(W){return U.indexOf(W)>=0});G&&(E=U)}}return I(I({},y),{},K({},T,I(I({},g),{},{axisType:a,domain:E,categoricalDomain:C,duplicateDomain:j,originalDomain:(p=g.domain)!==null&&p!==void 0?p:$,isCategorical:d,layout:f})))},{})},N2=function(t,r){var n=r.graphicalItems,i=r.Axis,a=r.axisType,o=r.axisIdKey,u=r.stackGroups,c=r.dataStartIndex,s=r.dataEndIndex,f=t.layout,l=t.children,h=ho(t.data,{graphicalItems:n,dataStartIndex:c,dataEndIndex:s}),d=h.length,y=Vx(f,a),v=-1;return n.reduce(function(p,g){var x=g.type.defaultProps!==void 0?I(I({},g.type.defaultProps),g.props):g.props,w=x[o],O=lO("number");if(!p[w]){v++;var m;return y?m=da(0,d):u&&u[w]&&u[w].hasStack?(m=Qx(u[w].stackGroups,c,s),m=kf(l,m,w,a)):(m=Yl(O,Gx(h,n.filter(function(b){var _,A,T=o in b.props?b.props[o]:(_=b.type.defaultProps)===null||_===void 0?void 0:_[o],M="hide"in b.props?b.props.hide:(A=b.type.defaultProps)===null||A===void 0?void 0:A.hide;return T===w&&!M}),"number",f),i.defaultProps.allowDataOverflow),m=kf(l,m,w,a)),I(I({},p),{},K({},w,I(I({axisType:a},i.defaultProps),{},{hide:!0,orientation:He(C2,"".concat(a,".").concat(v%2),null),domain:m,originalDomain:O,isCategorical:y,layout:f})))}return p},{})},q2=function(t,r){var n=r.axisType,i=n===void 0?"xAxis":n,a=r.AxisComp,o=r.graphicalItems,u=r.stackGroups,c=r.dataStartIndex,s=r.dataEndIndex,f=t.children,l="".concat(i,"Id"),h=Ke(f,a),d={};return h&&h.length?d=D2(t,{axes:h,graphicalItems:o,axisType:i,axisIdKey:l,stackGroups:u,dataStartIndex:c,dataEndIndex:s}):o&&o.length&&(d=N2(t,{Axis:a,graphicalItems:o,axisType:i,axisIdKey:l,stackGroups:u,dataStartIndex:c,dataEndIndex:s})),d},L2=function(t){var r=Mt(t),n=gt(r,!1,!0);return{tooltipTicks:n,orderedTooltipTicks:ih(n,function(i){return i.coordinate}),tooltipAxis:r,tooltipAxisBandSize:ta(r,n)}},Wb=function(t){var r=t.children,n=t.defaultShowTooltip,i=We(r,qr),a=0,o=0;return t.data&&t.data.length!==0&&(o=t.data.length-1),i&&i.props&&(i.props.startIndex>=0&&(a=i.props.startIndex),i.props.endIndex>=0&&(o=i.props.endIndex)),{chartX:0,chartY:0,dataStartIndex:a,dataEndIndex:o,activeTooltipIndex:-1,isTooltipActive:!!n}},B2=function(t){return!t||!t.length?!1:t.some(function(r){var n=bt(r&&r.type);return n&&n.indexOf("Bar")>=0})},zb=function(t){return t==="horizontal"?{numericAxisName:"yAxis",cateAxisName:"xAxis"}:t==="vertical"?{numericAxisName:"xAxis",cateAxisName:"yAxis"}:t==="centric"?{numericAxisName:"radiusAxis",cateAxisName:"angleAxis"}:{numericAxisName:"angleAxis",cateAxisName:"radiusAxis"}},F2=function(t,r){var n=t.props,i=t.graphicalItems,a=t.xAxisMap,o=a===void 0?{}:a,u=t.yAxisMap,c=u===void 0?{}:u,s=n.width,f=n.height,l=n.children,h=n.margin||{},d=We(l,qr),y=We(l,wr),v=Object.keys(c).reduce(function(m,b){var _=c[b],A=_.orientation;return!_.mirror&&!_.hide?I(I({},m),{},K({},A,m[A]+_.width)):m},{left:h.left||0,right:h.right||0}),p=Object.keys(o).reduce(function(m,b){var _=o[b],A=_.orientation;return!_.mirror&&!_.hide?I(I({},m),{},K({},A,He(m,"".concat(A))+_.height)):m},{top:h.top||0,bottom:h.bottom||0}),g=I(I({},p),v),x=g.bottom;d&&(g.bottom+=d.props.height||qr.defaultProps.height),y&&r&&(g=cM(g,i,n,r));var w=s-g.left-g.right,O=f-g.top-g.bottom;return I(I({brushBottom:x},g),{},{width:Math.max(w,0),height:Math.max(O,0)})},W2=function(t,r){if(r==="xAxis")return t[r].width;if(r==="yAxis")return t[r].height},Wh=function(t){var r=t.chartName,n=t.GraphicalChild,i=t.defaultTooltipEventType,a=i===void 0?"axis":i,o=t.validateTooltipEventTypes,u=o===void 0?["axis"]:o,c=t.axisComponents,s=t.legendContent,f=t.formatAxisMap,l=t.defaultProps,h=function(g,x){var w=x.graphicalItems,O=x.stackGroups,m=x.offset,b=x.updateId,_=x.dataStartIndex,A=x.dataEndIndex,T=g.barSize,M=g.layout,P=g.barGap,E=g.barCategoryGap,j=g.maxBarSize,C=zb(M),$=C.numericAxisName,k=C.cateAxisName,R=B2(w),L=[];return w.forEach(function(B,U){var G=ho(g.data,{graphicalItems:[B],dataStartIndex:_,dataEndIndex:A}),W=B.type.defaultProps!==void 0?I(I({},B.type.defaultProps),B.props):B.props,V=W.dataKey,fe=W.maxBarSize,ye=W["".concat($,"Id")],Le=W["".concat(k,"Id")],qt={},Re=c.reduce(function(Lt,Bt){var po=x["".concat(Bt.axisType,"Map")],zh=W["".concat(Bt.axisType,"Id")];po&&po[zh]||Bt.axisType==="zAxis"||Qt(!1);var Uh=po[zh];return I(I({},Lt),{},K(K({},Bt.axisType,Uh),"".concat(Bt.axisType,"Ticks"),gt(Uh)))},qt),F=Re[k],Z=Re["".concat(k,"Ticks")],Q=O&&O[ye]&&O[ye].hasStack&&bM(B,O[ye].stackGroups),D=bt(B.type).indexOf("Bar")>=0,de=ta(F,Z),ee=[],be=R&&oM({barSize:T,stackGroups:O,totalSize:W2(Re,k)});if(D){var xe,De,Et=Y(fe)?j:fe,lr=(xe=(De=ta(F,Z,!0))!==null&&De!==void 0?De:Et)!==null&&xe!==void 0?xe:0;ee=uM({barGap:P,barCategoryGap:E,bandSize:lr!==de?lr:de,sizeList:be[Le],maxBarSize:Et}),lr!==de&&(ee=ee.map(function(Lt){return I(I({},Lt),{},{position:I(I({},Lt.position),{},{offset:Lt.position.offset-lr/2})})}))}var di=B&&B.type&&B.type.getComposedData;di&&L.push({props:I(I({},di(I(I({},Re),{},{displayedData:G,props:g,dataKey:V,item:B,bandSize:de,barPosition:ee,offset:m,stackedData:Q,layout:M,dataStartIndex:_,dataEndIndex:A}))),{},K(K(K({key:B.key||"item-".concat(U)},$,Re[$]),k,Re[k]),"animationId",b)),childIndex:h_(B,g.children),item:B})}),L},d=function(g,x){var w=g.props,O=g.dataStartIndex,m=g.dataEndIndex,b=g.updateId;if(!Qp({props:w}))return null;var _=w.children,A=w.layout,T=w.stackOffset,M=w.data,P=w.reverseStackOrder,E=zb(A),j=E.numericAxisName,C=E.cateAxisName,$=Ke(_,n),k=mM(M,$,"".concat(j,"Id"),"".concat(C,"Id"),T,P),R=c.reduce(function(W,V){var fe="".concat(V.axisType,"Map");return I(I({},W),{},K({},fe,q2(w,I(I({},V),{},{graphicalItems:$,stackGroups:V.axisType===j&&k,dataStartIndex:O,dataEndIndex:m}))))},{}),L=F2(I(I({},R),{},{props:w,graphicalItems:$}),x?.legendBBox);Object.keys(R).forEach(function(W){R[W]=f(w,R[W],L,W.replace("Map",""),r)});var B=R["".concat(C,"Map")],U=L2(B),G=h(w,I(I({},R),{},{dataStartIndex:O,dataEndIndex:m,updateId:b,graphicalItems:$,stackGroups:k,offset:L}));return I(I({formattedGraphicalItems:G,graphicalItems:$,offset:L,stackGroups:k},U),R)},y=(function(p){function g(x){var w,O,m;return w2(this,g),m=A2(this,g,[x]),K(m,"eventEmitterSymbol",Symbol("rechartsEventEmitter")),K(m,"accessibilityManager",new u2),K(m,"handleLegendBBoxUpdate",function(b){if(b){var _=m.state,A=_.dataStartIndex,T=_.dataEndIndex,M=_.updateId;m.setState(I({legendBBox:b},d({props:m.props,dataStartIndex:A,dataEndIndex:T,updateId:M},I(I({},m.state),{},{legendBBox:b}))))}}),K(m,"handleReceiveSyncEvent",function(b,_,A){if(m.props.syncId===b){if(A===m.eventEmitterSymbol&&typeof m.props.syncMethod!="function")return;m.applySyncEvent(_)}}),K(m,"handleBrushChange",function(b){var _=b.startIndex,A=b.endIndex;if(_!==m.state.dataStartIndex||A!==m.state.dataEndIndex){var T=m.state.updateId;m.setState(function(){return I({dataStartIndex:_,dataEndIndex:A},d({props:m.props,dataStartIndex:_,dataEndIndex:A,updateId:T},m.state))}),m.triggerSyncEvent({dataStartIndex:_,dataEndIndex:A})}}),K(m,"handleMouseEnter",function(b){var _=m.getMouseInfo(b);if(_){var A=I(I({},_),{},{isTooltipActive:!0});m.setState(A),m.triggerSyncEvent(A);var T=m.props.onMouseEnter;X(T)&&T(A,b)}}),K(m,"triggeredAfterMouseMove",function(b){var _=m.getMouseInfo(b),A=_?I(I({},_),{},{isTooltipActive:!0}):{isTooltipActive:!1};m.setState(A),m.triggerSyncEvent(A);var T=m.props.onMouseMove;X(T)&&T(A,b)}),K(m,"handleItemMouseEnter",function(b){m.setState(function(){return{isTooltipActive:!0,activeItem:b,activePayload:b.tooltipPayload,activeCoordinate:b.tooltipPosition||{x:b.cx,y:b.cy}}})}),K(m,"handleItemMouseLeave",function(){m.setState(function(){return{isTooltipActive:!1}})}),K(m,"handleMouseMove",function(b){b.persist(),m.throttleTriggeredAfterMouseMove(b)}),K(m,"handleMouseLeave",function(b){m.throttleTriggeredAfterMouseMove.cancel();var _={isTooltipActive:!1};m.setState(_),m.triggerSyncEvent(_);var A=m.props.onMouseLeave;X(A)&&A(_,b)}),K(m,"handleOuterEvent",function(b){var _=f_(b),A=He(m.props,"".concat(_));if(_&&X(A)){var T,M;/.*touch.*/i.test(_)?M=m.getMouseInfo(b.changedTouches[0]):M=m.getMouseInfo(b),A((T=M)!==null&&T!==void 0?T:{},b)}}),K(m,"handleClick",function(b){var _=m.getMouseInfo(b);if(_){var A=I(I({},_),{},{isTooltipActive:!0});m.setState(A),m.triggerSyncEvent(A);var T=m.props.onClick;X(T)&&T(A,b)}}),K(m,"handleMouseDown",function(b){var _=m.props.onMouseDown;if(X(_)){var A=m.getMouseInfo(b);_(A,b)}}),K(m,"handleMouseUp",function(b){var _=m.props.onMouseUp;if(X(_)){var A=m.getMouseInfo(b);_(A,b)}}),K(m,"handleTouchMove",function(b){b.changedTouches!=null&&b.changedTouches.length>0&&m.throttleTriggeredAfterMouseMove(b.changedTouches[0])}),K(m,"handleTouchStart",function(b){b.changedTouches!=null&&b.changedTouches.length>0&&m.handleMouseDown(b.changedTouches[0])}),K(m,"handleTouchEnd",function(b){b.changedTouches!=null&&b.changedTouches.length>0&&m.handleMouseUp(b.changedTouches[0])}),K(m,"handleDoubleClick",function(b){var _=m.props.onDoubleClick;if(X(_)){var A=m.getMouseInfo(b);_(A,b)}}),K(m,"handleContextMenu",function(b){var _=m.props.onContextMenu;if(X(_)){var A=m.getMouseInfo(b);_(A,b)}}),K(m,"triggerSyncEvent",function(b){m.props.syncId!==void 0&&pl.emit(dl,m.props.syncId,b,m.eventEmitterSymbol)}),K(m,"applySyncEvent",function(b){var _=m.props,A=_.layout,T=_.syncMethod,M=m.state.updateId,P=b.dataStartIndex,E=b.dataEndIndex;if(b.dataStartIndex!==void 0||b.dataEndIndex!==void 0)m.setState(I({dataStartIndex:P,dataEndIndex:E},d({props:m.props,dataStartIndex:P,dataEndIndex:E,updateId:M},m.state)));else if(b.activeTooltipIndex!==void 0){var j=b.chartX,C=b.chartY,$=b.activeTooltipIndex,k=m.state,R=k.offset,L=k.tooltipTicks;if(!R)return;if(typeof T=="function")$=T(L,b);else if(T==="value"){$=-1;for(var B=0;B=0){var Q,D;if(j.dataKey&&!j.allowDuplicatedCategory){var de=typeof j.dataKey=="function"?Z:"payload.".concat(j.dataKey.toString());Q=Mi(B,de,$),D=U&&G&&Mi(G,de,$)}else Q=B?.[C],D=U&&G&&G[C];if(Le||ye){var ee=b.props.activeIndex!==void 0?b.props.activeIndex:C;return[N.cloneElement(b,I(I(I({},T.props),Re),{},{activeIndex:ee})),null,null]}if(!Y(Q))return[F].concat(Vr(m.renderActivePoints({item:T,activePoint:Q,basePoint:D,childIndex:C,isRange:U})))}else{var be,xe=(be=m.getItemByXY(m.state.activeCoordinate))!==null&&be!==void 0?be:{graphicalItem:F},De=xe.graphicalItem,Et=De.item,lr=Et===void 0?b:Et,di=De.childIndex,Lt=I(I(I({},T.props),Re),{},{activeIndex:di});return[N.cloneElement(lr,Lt),null,null]}return U?[F,null,null]:[F,null]}),K(m,"renderCustomized",function(b,_,A){return N.cloneElement(b,I(I({key:"recharts-customized-".concat(A)},m.props),m.state))}),K(m,"renderMap",{CartesianGrid:{handler:Ei,once:!0},ReferenceArea:{handler:m.renderReferenceElement},ReferenceLine:{handler:Ei},ReferenceDot:{handler:m.renderReferenceElement},XAxis:{handler:Ei},YAxis:{handler:Ei},Brush:{handler:m.renderBrush,once:!0},Bar:{handler:m.renderGraphicChild},Line:{handler:m.renderGraphicChild},Area:{handler:m.renderGraphicChild},Radar:{handler:m.renderGraphicChild},RadialBar:{handler:m.renderGraphicChild},Scatter:{handler:m.renderGraphicChild},Pie:{handler:m.renderGraphicChild},Funnel:{handler:m.renderGraphicChild},Tooltip:{handler:m.renderCursor,once:!0},PolarGrid:{handler:m.renderPolarGrid,once:!0},PolarAngleAxis:{handler:m.renderPolarAxis},PolarRadiusAxis:{handler:m.renderPolarAxis},Customized:{handler:m.renderCustomized}}),m.clipPathId="".concat((w=x.id)!==null&&w!==void 0?w:Zr("recharts"),"-clip"),m.throttleTriggeredAfterMouseMove=U0(m.triggeredAfterMouseMove,(O=x.throttleDelay)!==null&&O!==void 0?O:1e3/60),m.state={},m}return T2(g,p),_2(g,[{key:"componentDidMount",value:function(){var w,O;this.addListener(),this.accessibilityManager.setDetails({container:this.container,offset:{left:(w=this.props.margin.left)!==null&&w!==void 0?w:0,top:(O=this.props.margin.top)!==null&&O!==void 0?O:0},coordinateList:this.state.tooltipTicks,mouseHandlerCallback:this.triggeredAfterMouseMove,layout:this.props.layout}),this.displayDefaultTooltip()}},{key:"displayDefaultTooltip",value:function(){var w=this.props,O=w.children,m=w.data,b=w.height,_=w.layout,A=We(O,dt);if(A){var T=A.props.defaultIndex;if(!(typeof T!="number"||T<0||T>this.state.tooltipTicks.length-1)){var M=this.state.tooltipTicks[T]&&this.state.tooltipTicks[T].value,P=Nf(this.state,m,T,M),E=this.state.tooltipTicks[T].coordinate,j=(this.state.offset.top+b)/2,C=_==="horizontal",$=C?{x:E,y:j}:{y:E,x:j},k=this.state.formattedGraphicalItems.find(function(L){var B=L.item;return B.type.name==="Scatter"});k&&($=I(I({},$),k.props.points[T].tooltipPosition),P=k.props.points[T].tooltipPayload);var R={activeTooltipIndex:T,isTooltipActive:!0,activeLabel:M,activePayload:P,activeCoordinate:$};this.setState(R),this.renderCursor(A),this.accessibilityManager.setIndex(T)}}}},{key:"getSnapshotBeforeUpdate",value:function(w,O){if(!this.props.accessibilityLayer)return null;if(this.state.tooltipTicks!==O.tooltipTicks&&this.accessibilityManager.setDetails({coordinateList:this.state.tooltipTicks}),this.props.layout!==w.layout&&this.accessibilityManager.setDetails({layout:this.props.layout}),this.props.margin!==w.margin){var m,b;this.accessibilityManager.setDetails({offset:{left:(m=this.props.margin.left)!==null&&m!==void 0?m:0,top:(b=this.props.margin.top)!==null&&b!==void 0?b:0}})}return null}},{key:"componentDidUpdate",value:function(w){gl([We(w.children,dt)],[We(this.props.children,dt)])||this.displayDefaultTooltip()}},{key:"componentWillUnmount",value:function(){this.removeListener(),this.throttleTriggeredAfterMouseMove.cancel()}},{key:"getTooltipEventType",value:function(){var w=We(this.props.children,dt);if(w&&typeof w.props.shared=="boolean"){var O=w.props.shared?"axis":"item";return u.indexOf(O)>=0?O:a}return a}},{key:"getMouseInfo",value:function(w){if(!this.container)return null;var O=this.container,m=O.getBoundingClientRect(),b=JS(m),_={chartX:Math.round(w.pageX-b.left),chartY:Math.round(w.pageY-b.top)},A=m.width/O.offsetWidth||1,T=this.inRange(_.chartX,_.chartY,A);if(!T)return null;var M=this.state,P=M.xAxisMap,E=M.yAxisMap,j=this.getTooltipEventType(),C=Fb(this.state,this.props.data,this.props.layout,T);if(j!=="axis"&&P&&E){var $=Mt(P).scale,k=Mt(E).scale,R=$&&$.invert?$.invert(_.chartX):null,L=k&&k.invert?k.invert(_.chartY):null;return I(I({},_),{},{xValue:R,yValue:L},C)}return C?I(I({},_),C):null}},{key:"inRange",value:function(w,O){var m=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,b=this.props.layout,_=w/m,A=O/m;if(b==="horizontal"||b==="vertical"){var T=this.state.offset,M=_>=T.left&&_<=T.left+T.width&&A>=T.top&&A<=T.top+T.height;return M?{x:_,y:A}:null}var P=this.state,E=P.angleAxisMap,j=P.radiusAxisMap;if(E&&j){var C=Mt(E);return Wm({x:_,y:A},C)}return null}},{key:"parseEventsOfWrapper",value:function(){var w=this.props.children,O=this.getTooltipEventType(),m=We(w,dt),b={};m&&O==="axis"&&(m.props.trigger==="click"?b={onClick:this.handleClick}:b={onMouseEnter:this.handleMouseEnter,onDoubleClick:this.handleDoubleClick,onMouseMove:this.handleMouseMove,onMouseLeave:this.handleMouseLeave,onTouchMove:this.handleTouchMove,onTouchStart:this.handleTouchStart,onTouchEnd:this.handleTouchEnd,onContextMenu:this.handleContextMenu});var _=$i(this.props,this.handleOuterEvent);return I(I({},_),b)}},{key:"addListener",value:function(){pl.on(dl,this.handleReceiveSyncEvent)}},{key:"removeListener",value:function(){pl.removeListener(dl,this.handleReceiveSyncEvent)}},{key:"filterFormatItem",value:function(w,O,m){for(var b=this.state.formattedGraphicalItems,_=0,A=b.length;_{var{children:r,width:n,height:i,viewBox:a,className:o,style:u,title:l,desc:s}=e,c=gb(e,yb),f=a||{width:n,height:i,x:0,y:0},d=H("recharts-surface",o);return h.createElement("svg",Tu({},$e(c),{className:d,width:n,height:i,style:u,viewBox:"".concat(f.x," ").concat(f.y," ").concat(f.width," ").concat(f.height),ref:t}),h.createElement("title",null,l),h.createElement("desc",null,s),r)}),wb=["children","className"];function Du(){return Du=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var{children:r,className:n}=e,i=xb(e,wb),a=H("recharts-layer",n);return h.createElement("g",Du({className:a},$e(i),{ref:t}),r)}),fp=h.createContext(null),Ob=()=>h.useContext(fp);function J(e){return function(){return e}}const dp=Math.cos,wi=Math.sin,ht=Math.sqrt,xi=Math.PI,fa=2*xi,Nu=Math.PI,$u=2*Nu,ar=1e-6,Ab=$u-ar;function vp(e){this._+=e[0];for(let t=1,r=e.length;t=0))throw new Error(`invalid digits: ${e}`);if(t>15)return vp;const r=10**t;return function(n){this._+=n[0];for(let i=1,a=n.length;iar)if(!(Math.abs(f*l-s*c)>ar)||!a)this._append`L${this._x1=t},${this._y1=r}`;else{let v=n-o,p=i-u,y=l*l+s*s,m=v*v+p*p,g=Math.sqrt(y),x=Math.sqrt(d),w=a*Math.tan((Nu-Math.acos((y+d-m)/(2*g*x)))/2),P=w/x,b=w/g;Math.abs(P-1)>ar&&this._append`L${t+P*c},${r+P*f}`,this._append`A${a},${a},0,0,${+(f*v>c*p)},${this._x1=t+b*l},${this._y1=r+b*s}`}}arc(t,r,n,i,a,o){if(t=+t,r=+r,n=+n,o=!!o,n<0)throw new Error(`negative radius: ${n}`);let u=n*Math.cos(i),l=n*Math.sin(i),s=t+u,c=r+l,f=1^o,d=o?i-a:a-i;this._x1===null?this._append`M${s},${c}`:(Math.abs(this._x1-s)>ar||Math.abs(this._y1-c)>ar)&&this._append`L${s},${c}`,n&&(d<0&&(d=d%$u+$u),d>Ab?this._append`A${n},${n},0,1,${f},${t-u},${r-l}A${n},${n},0,1,${f},${this._x1=s},${this._y1=c}`:d>ar&&this._append`A${n},${n},0,${+(d>=Nu)},${f},${this._x1=t+n*Math.cos(a)},${this._y1=r+n*Math.sin(a)}`)}rect(t,r,n,i){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+r}h${n=+n}v${+i}h${-n}Z`}toString(){return this._}}function Ll(e){let t=3;return e.digits=function(r){if(!arguments.length)return t;if(r==null)t=null;else{const n=Math.floor(r);if(!(n>=0))throw new RangeError(`invalid digits: ${r}`);t=n}return e},()=>new Eb(t)}function zl(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function hp(e){this._context=e}hp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t);break}}};function da(e){return new hp(e)}function pp(e){return e[0]}function mp(e){return e[1]}function yp(e,t){var r=J(!0),n=null,i=da,a=null,o=Ll(u);e=typeof e=="function"?e:e===void 0?pp:J(e),t=typeof t=="function"?t:t===void 0?mp:J(t);function u(l){var s,c=(l=zl(l)).length,f,d=!1,v;for(n==null&&(a=i(v=o())),s=0;s<=c;++s)!(s=v;--p)u.point(w[p],P[p]);u.lineEnd(),u.areaEnd()}g&&(w[d]=+e(m,d,f),P[d]=+t(m,d,f),u.point(n?+n(m,d,f):w[d],r?+r(m,d,f):P[d]))}if(x)return u=null,x+""||null}function c(){return yp().defined(i).curve(o).context(a)}return s.x=function(f){return arguments.length?(e=typeof f=="function"?f:J(+f),n=null,s):e},s.x0=function(f){return arguments.length?(e=typeof f=="function"?f:J(+f),s):e},s.x1=function(f){return arguments.length?(n=f==null?null:typeof f=="function"?f:J(+f),s):n},s.y=function(f){return arguments.length?(t=typeof f=="function"?f:J(+f),r=null,s):t},s.y0=function(f){return arguments.length?(t=typeof f=="function"?f:J(+f),s):t},s.y1=function(f){return arguments.length?(r=f==null?null:typeof f=="function"?f:J(+f),s):r},s.lineX0=s.lineY0=function(){return c().x(e).y(t)},s.lineY1=function(){return c().x(e).y(r)},s.lineX1=function(){return c().x(n).y(t)},s.defined=function(f){return arguments.length?(i=typeof f=="function"?f:J(!!f),s):i},s.curve=function(f){return arguments.length?(o=f,a!=null&&(u=o(a)),s):o},s.context=function(f){return arguments.length?(f==null?a=u=null:u=o(a=f),s):a},s}class gp{constructor(t,r){this._context=t,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(t,r){switch(t=+t,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(t,r):this._context.moveTo(t,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,r,t,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,t,this._y0,t,r);break}}this._x0=t,this._y0=r}}function _b(e){return new gp(e,!0)}function kb(e){return new gp(e,!1)}const Bl={draw(e,t){const r=ht(t/xi);e.moveTo(r,0),e.arc(0,0,r,0,fa)}},jb={draw(e,t){const r=ht(t/5)/2;e.moveTo(-3*r,-r),e.lineTo(-r,-r),e.lineTo(-r,-3*r),e.lineTo(r,-3*r),e.lineTo(r,-r),e.lineTo(3*r,-r),e.lineTo(3*r,r),e.lineTo(r,r),e.lineTo(r,3*r),e.lineTo(-r,3*r),e.lineTo(-r,r),e.lineTo(-3*r,r),e.closePath()}},bp=ht(1/3),Cb=bp*2,Ib={draw(e,t){const r=ht(t/Cb),n=r*bp;e.moveTo(0,-r),e.lineTo(n,0),e.lineTo(0,r),e.lineTo(-n,0),e.closePath()}},Mb={draw(e,t){const r=ht(t),n=-r/2;e.rect(n,n,r,r)}},Tb=.8908130915292852,wp=wi(xi/10)/wi(7*xi/10),Db=wi(fa/10)*wp,Nb=-dp(fa/10)*wp,$b={draw(e,t){const r=ht(t*Tb),n=Db*r,i=Nb*r;e.moveTo(0,-r),e.lineTo(n,i);for(let a=1;a<5;++a){const o=fa*a/5,u=dp(o),l=wi(o);e.lineTo(l*r,-u*r),e.lineTo(u*n-l*i,l*n+u*i)}e.closePath()}},ro=ht(3),Rb={draw(e,t){const r=-ht(t/(ro*3));e.moveTo(0,r*2),e.lineTo(-ro*r,-r),e.lineTo(ro*r,-r),e.closePath()}},et=-.5,tt=ht(3)/2,Ru=1/ht(12),Lb=(Ru/2+1)*3,zb={draw(e,t){const r=ht(t/Lb),n=r/2,i=r*Ru,a=n,o=r*Ru+r,u=-a,l=o;e.moveTo(n,i),e.lineTo(a,o),e.lineTo(u,l),e.lineTo(et*n-tt*i,tt*n+et*i),e.lineTo(et*a-tt*o,tt*a+et*o),e.lineTo(et*u-tt*l,tt*u+et*l),e.lineTo(et*n+tt*i,et*i-tt*n),e.lineTo(et*a+tt*o,et*o-tt*a),e.lineTo(et*u+tt*l,et*l-tt*u),e.closePath()}};function Bb(e,t){let r=null,n=Ll(i);e=typeof e=="function"?e:J(e||Bl),t=typeof t=="function"?t:J(t===void 0?64:+t);function i(){let a;if(r||(r=a=n()),e.apply(this,arguments).draw(r,+t.apply(this,arguments)),a)return r=null,a+""||null}return i.type=function(a){return arguments.length?(e=typeof a=="function"?a:J(a),i):e},i.size=function(a){return arguments.length?(t=typeof a=="function"?a:J(+a),i):t},i.context=function(a){return arguments.length?(r=a??null,i):r},i}function Pi(){}function Oi(e,t,r){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+r)/6)}function xp(e){this._context=e}xp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Oi(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Oi(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Fb(e){return new xp(e)}function Pp(e){this._context=e}Pp.prototype={areaStart:Pi,areaEnd:Pi,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Oi(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Kb(e){return new Pp(e)}function Op(e){this._context=e}Op.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+e)/6,n=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:Oi(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function qb(e){return new Op(e)}function Ap(e){this._context=e}Ap.prototype={areaStart:Pi,areaEnd:Pi,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function Wb(e){return new Ap(e)}function Fs(e){return e<0?-1:1}function Ks(e,t,r){var n=e._x1-e._x0,i=t-e._x1,a=(e._y1-e._y0)/(n||i<0&&-0),o=(r-e._y1)/(i||n<0&&-0),u=(a*i+o*n)/(n+i);return(Fs(a)+Fs(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(u))||0}function qs(e,t){var r=e._x1-e._x0;return r?(3*(e._y1-e._y0)/r-t)/2:t}function no(e,t,r){var n=e._x0,i=e._y0,a=e._x1,o=e._y1,u=(a-n)/3;e._context.bezierCurveTo(n+u,i+u*t,a-u,o-u*r,a,o)}function Ai(e){this._context=e}Ai.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:no(this,this._t0,qs(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){var r=NaN;if(e=+e,t=+t,!(e===this._x1&&t===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,no(this,qs(this,r=Ks(this,e,t)),r);break;default:no(this,this._t0,r=Ks(this,e,t));break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t,this._t0=r}}};function Sp(e){this._context=new Ep(e)}(Sp.prototype=Object.create(Ai.prototype)).point=function(e,t){Ai.prototype.point.call(this,t,e)};function Ep(e){this._context=e}Ep.prototype={moveTo:function(e,t){this._context.moveTo(t,e)},closePath:function(){this._context.closePath()},lineTo:function(e,t){this._context.lineTo(t,e)},bezierCurveTo:function(e,t,r,n,i,a){this._context.bezierCurveTo(t,e,n,r,a,i)}};function Ub(e){return new Ai(e)}function Hb(e){return new Sp(e)}function _p(e){this._context=e}_p.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var e=this._x,t=this._y,r=e.length;if(r)if(this._line?this._context.lineTo(e[0],t[0]):this._context.moveTo(e[0],t[0]),r===2)this._context.lineTo(e[1],t[1]);else for(var n=Ws(e),i=Ws(t),a=0,o=1;o=0;--t)i[t]=(o[t]-i[t+1])/a[t];for(a[r-1]=(e[r]+i[r-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var r=this._x*(1-this._t)+e*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,t)}break}}this._x=e,this._y=t}};function Gb(e){return new va(e,.5)}function Vb(e){return new va(e,0)}function Xb(e){return new va(e,1)}function Ir(e,t){if((o=e.length)>1)for(var r=1,n,i,a=e[t[0]],o,u=a.length;r=0;)r[t]=t;return r}function Zb(e,t){return e[t]}function Qb(e){const t=[];return t.key=e,t}function Jb(){var e=J([]),t=Lu,r=Ir,n=Zb;function i(a){var o=Array.from(e.apply(this,arguments),Qb),u,l=o.length,s=-1,c;for(const f of a)for(u=0,++s;u0){for(var r,n,i=0,a=e[0].length,o;i0){for(var r=0,n=e[t[0]],i,a=n.length;r0)||!((a=(i=e[t[0]]).length)>0))){for(var r=0,n=1,i,a,o;ne===0?0:e>0?1:-1,dt=e=>typeof e=="number"&&e!=+e,Ct=e=>typeof e=="string"&&e.indexOf("%")===e.length-1,N=e=>(typeof e=="number"||e instanceof Number)&&!dt(e),bt=e=>N(e)||typeof e=="string",uw=0,cn=e=>{var t=++uw;return"".concat(e||"").concat(t)},Ie=function(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(!N(t)&&typeof t!="string")return n;var a;if(Ct(t)){if(r==null)return n;var o=t.indexOf("%");a=r*parseFloat(t.slice(0,o))/100}else a=+t;return dt(a)&&(a=n),i&&r!=null&&a>r&&(a=r),a},jp=e=>{if(!Array.isArray(e))return!1;for(var t=e.length,r={},n=0;nn&&(typeof t=="function"?t(n):pr(n,t))===r)}var ae=e=>e===null||typeof e>"u",An=e=>ae(e)?e:"".concat(e.charAt(0).toUpperCase()).concat(e.slice(1));function lw(e){return e!=null}function Sn(){}var cw=["type","size","sizeType"];function zu(){return zu=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var t="symbol".concat(An(e));return Ip[t]||Bl},yw=(e,t,r)=>{if(t==="area")return e;switch(r){case"cross":return 5*e*e/9;case"diamond":return .5*e*e/Math.sqrt(3);case"square":return e*e;case"star":{var n=18*pw;return 1.25*e*e*(Math.tan(n)-Math.tan(n*2)*Math.tan(n)**2)}case"triangle":return Math.sqrt(3)*e*e/4;case"wye":return(21-10*Math.sqrt(3))*e*e/8;default:return Math.PI*e*e/4}},gw=(e,t)=>{Ip["symbol".concat(An(e))]=t},Wl=e=>{var{type:t="circle",size:r=64,sizeType:n="area"}=e,i=vw(e,cw),a=Js(Js({},i),{},{type:t,size:r,sizeType:n}),o="circle";typeof t=="string"&&(o=t);var u=()=>{var d=mw(o),v=Bb().type(d).size(yw(r,n,o)),p=v();if(p!==null)return p},{className:l,cx:s,cy:c}=a,f=$e(a);return N(s)&&N(c)&&N(r)?h.createElement("path",zu({},f,{className:H("recharts-symbols",l),transform:"translate(".concat(s,", ").concat(c,")"),d:u()})):null};Wl.registerSymbol=gw;var Mp=e=>"radius"in e&&"startAngle"in e&&"endAngle"in e,Ul=(e,t)=>{if(!e||typeof e=="function"||typeof e=="boolean")return null;var r=e;if(h.isValidElement(e)&&(r=e.props),typeof r!="object"&&typeof r!="function")return null;var n={};return Object.keys(r).forEach(i=>{$l(i)&&(n[i]=(a=>r[i](r,a)))}),n},bw=(e,t,r)=>n=>(e(t,r,n),null),En=(e,t,r)=>{if(e===null||typeof e!="object"&&typeof e!="function")return null;var n=null;return Object.keys(e).forEach(i=>{var a=e[i];$l(i)&&typeof a=="function"&&(n||(n={}),n[i]=bw(a,t,r))}),n};function ef(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function ww(e){for(var t=1;t(o[u]===void 0&&n[u]!==void 0&&(o[u]=n[u]),o),r);return a}function Si(){return Si=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var d=c.formatter||i,v=H({"recharts-legend-item":!0,["legend-item-".concat(f)]:!0,inactive:c.inactive});if(c.type==="none")return null;var p=c.inactive?a:c.color,y=d?d(c.value,c,f):c.value;return h.createElement("li",Si({className:v,style:l,key:"legend-item-".concat(f)},En(e,c,f)),h.createElement(Rl,{width:r,height:r,viewBox:u,style:s,"aria-label":"".concat(y," legend icon")},h.createElement(jw,{data:c,iconType:o,inactiveColor:a})),h.createElement("span",{className:"recharts-legend-item-text",style:{color:p}},y))})}var Iw=e=>{var t=pe(e,kw),{payload:r,layout:n,align:i}=t;if(!r||!r.length)return null;var a={padding:0,margin:0,textAlign:n==="horizontal"?i:"left"};return h.createElement("ul",{className:"recharts-default-legend",style:a},h.createElement(Cw,Si({},t,{payload:r})))},fo={},vo={},rf;function Mw(){return rf||(rf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r,n){const i=new Map;for(let a=0;a=0}e.isLength=t})(yo)),yo}var of;function Hl(){return of||(of=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Tw();function r(n){return n!=null&&typeof n!="function"&&t.isLength(n.length)}e.isArrayLike=r})(mo)),mo}var go={},uf;function Dw(){return uf||(uf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return typeof r=="object"&&r!==null}e.isObjectLike=t})(go)),go}var lf;function Nw(){return lf||(lf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Hl(),r=Dw();function n(i){return r.isObjectLike(i)&&t.isArrayLike(i)}e.isArrayLikeObject=n})(po)),po}var bo={},wo={},cf;function $w(){return cf||(cf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=ql();function r(n){return function(i){return t.get(i,n)}}e.property=r})(wo)),wo}var xo={},Po={},Oo={},Ao={},sf;function Dp(){return sf||(sf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return r!==null&&(typeof r=="object"||typeof r=="function")}e.isObject=t})(Ao)),Ao}var So={},ff;function Np(){return ff||(ff=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return r==null||typeof r!="object"&&typeof r!="function"}e.isPrimitive=t})(So)),So}var Eo={},df;function $p(){return df||(df=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r,n){return r===n||Number.isNaN(r)&&Number.isNaN(n)}e.eq=t})(Eo)),Eo}var vf;function Rw(){return vf||(vf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Dp(),r=Np(),n=$p();function i(c,f,d){return typeof d!="function"?i(c,f,()=>{}):a(c,f,function v(p,y,m,g,x,w){const P=d(p,y,m,g,x,w);return P!==void 0?!!P:a(p,y,v,w)},new Map)}function a(c,f,d,v){if(f===c)return!0;switch(typeof f){case"object":return o(c,f,d,v);case"function":return Object.keys(f).length>0?a(c,{...f},d,v):n.eq(c,f);default:return t.isObject(c)?typeof f=="string"?f==="":!0:n.eq(c,f)}}function o(c,f,d,v){if(f==null)return!0;if(Array.isArray(f))return l(c,f,d,v);if(f instanceof Map)return u(c,f,d,v);if(f instanceof Set)return s(c,f,d,v);const p=Object.keys(f);if(c==null)return p.length===0;if(p.length===0)return!0;if(v?.has(f))return v.get(f)===c;v?.set(f,c);try{for(let y=0;y{})}e.isMatch=r})(Po)),Po}var _o={},ko={},jo={},pf;function Lw(){return pf||(pf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return Object.getOwnPropertySymbols(r).filter(n=>Object.prototype.propertyIsEnumerable.call(r,n))}e.getSymbols=t})(jo)),jo}var Co={},mf;function Lp(){return mf||(mf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return r==null?r===void 0?"[object Undefined]":"[object Null]":Object.prototype.toString.call(r)}e.getTag=t})(Co)),Co}var Io={},yf;function zp(){return yf||(yf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t="[object RegExp]",r="[object String]",n="[object Number]",i="[object Boolean]",a="[object Arguments]",o="[object Symbol]",u="[object Date]",l="[object Map]",s="[object Set]",c="[object Array]",f="[object Function]",d="[object ArrayBuffer]",v="[object Object]",p="[object Error]",y="[object DataView]",m="[object Uint8Array]",g="[object Uint8ClampedArray]",x="[object Uint16Array]",w="[object Uint32Array]",P="[object BigUint64Array]",b="[object Int8Array]",O="[object Int16Array]",S="[object Int32Array]",_="[object BigInt64Array]",I="[object Float32Array]",M="[object Float64Array]";e.argumentsTag=a,e.arrayBufferTag=d,e.arrayTag=c,e.bigInt64ArrayTag=_,e.bigUint64ArrayTag=P,e.booleanTag=i,e.dataViewTag=y,e.dateTag=u,e.errorTag=p,e.float32ArrayTag=I,e.float64ArrayTag=M,e.functionTag=f,e.int16ArrayTag=O,e.int32ArrayTag=S,e.int8ArrayTag=b,e.mapTag=l,e.numberTag=n,e.objectTag=v,e.regexpTag=t,e.setTag=s,e.stringTag=r,e.symbolTag=o,e.uint16ArrayTag=x,e.uint32ArrayTag=w,e.uint8ArrayTag=m,e.uint8ClampedArrayTag=g})(Io)),Io}var Mo={},gf;function zw(){return gf||(gf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return ArrayBuffer.isView(r)&&!(r instanceof DataView)}e.isTypedArray=t})(Mo)),Mo}var bf;function Bp(){return bf||(bf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Lw(),r=Lp(),n=zp(),i=Np(),a=zw();function o(c,f){return u(c,void 0,c,new Map,f)}function u(c,f,d,v=new Map,p=void 0){const y=p?.(c,f,d,v);if(y!==void 0)return y;if(i.isPrimitive(c))return c;if(v.has(c))return v.get(c);if(Array.isArray(c)){const m=new Array(c.length);v.set(c,m);for(let g=0;gt.isMatch(a,i)}e.matches=n})(xo)),xo}var To={},Do={},No={},Pf;function Kw(){return Pf||(Pf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Bp(),r=zp();function n(i,a){return t.cloneDeepWith(i,(o,u,l,s)=>{const c=a?.(o,u,l,s);if(c!==void 0)return c;if(typeof i=="object")switch(Object.prototype.toString.call(i)){case r.numberTag:case r.stringTag:case r.booleanTag:{const f=new i.constructor(i?.valueOf());return t.copyProperties(f,i),f}case r.argumentsTag:{const f={};return t.copyProperties(f,i),f.length=i.length,f[Symbol.iterator]=i[Symbol.iterator],f}default:return}})}e.cloneDeepWith=n})(No)),No}var Of;function qw(){return Of||(Of=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Kw();function r(n){return t.cloneDeepWith(n)}e.cloneDeep=r})(Do)),Do}var $o={},Ro={},Af;function Fp(){return Af||(Af=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=/^(?:0|[1-9]\d*)$/;function r(n,i=Number.MAX_SAFE_INTEGER){switch(typeof n){case"number":return Number.isInteger(n)&&n>=0&&ne,ee=()=>{var e=h.useContext(Yl);return e?e.store.dispatch:Zw},pi=()=>{},Qw=()=>pi,Jw=(e,t)=>e===t;function T(e){var t=h.useContext(Yl);return cb.useSyncExternalStoreWithSelector(t?t.subscription.addNestedSub:Qw,t?t.store.getState:pi,t?t.store.getState:pi,t?e:pi,Jw)}function ex(e,t=`expected a function, instead received ${typeof e}`){if(typeof e!="function")throw new TypeError(t)}function tx(e,t=`expected an object, instead received ${typeof e}`){if(typeof e!="object")throw new TypeError(t)}function rx(e,t="expected all items to be functions, instead received the following types: "){if(!e.every(r=>typeof r=="function")){const r=e.map(n=>typeof n=="function"?`function ${n.name||"unnamed"}()`:typeof n).join(", ");throw new TypeError(`${t}[${r}]`)}}var Mf=e=>Array.isArray(e)?e:[e];function nx(e){const t=Array.isArray(e[0])?e[0]:e;return rx(t,"createSelector expects all input-selectors to be functions, but received the following types: "),t}function ix(e,t){const r=[],{length:n}=e;for(let i=0;i{r=Qn(),o.resetResultsCount()},o.resultsCount=()=>a,o.resetResultsCount=()=>{a=0},o}function lx(e,...t){const r=typeof e=="function"?{memoize:e,memoizeOptions:t}:e,n=(...i)=>{let a=0,o=0,u,l={},s=i.pop();typeof s=="object"&&(l=s,s=i.pop()),ex(s,`createSelector expects an output function after the inputs, but received: [${typeof s}]`);const c={...r,...l},{memoize:f,memoizeOptions:d=[],argsMemoize:v=qp,argsMemoizeOptions:p=[]}=c,y=Mf(d),m=Mf(p),g=nx(i),x=f(function(){return a++,s.apply(null,arguments)},...y),w=v(function(){o++;const b=ix(g,arguments);return u=x.apply(null,b),u},...m);return Object.assign(w,{resultFunc:s,memoizedResultFunc:x,dependencies:g,dependencyRecomputations:()=>o,resetDependencyRecomputations:()=>{o=0},lastResult:()=>u,recomputations:()=>a,resetRecomputations:()=>{a=0},memoize:f,argsMemoize:v})};return Object.assign(n,{withTypes:()=>n}),n}var A=lx(qp),cx=Object.assign((e,t=A)=>{tx(e,`createStructuredSelector expects first argument to be an object where each property is a selector, instead received a ${typeof e}`);const r=Object.keys(e),n=r.map(a=>e[a]);return t(n,(...a)=>a.reduce((o,u,l)=>(o[r[l]]=u,o),{}))},{withTypes:()=>cx}),Bo={},Fo={},Ko={},Df;function sx(){return Df||(Df=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(n){return typeof n=="symbol"?1:n===null?2:n===void 0?3:n!==n?4:0}const r=(n,i,a)=>{if(n!==i){const o=t(n),u=t(i);if(o===u&&o===0){if(ni)return a==="desc"?-1:1}return a==="desc"?u-o:o-u}return 0};e.compareValues=r})(Ko)),Ko}var qo={},Wo={},Nf;function Wp(){return Nf||(Nf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return typeof r=="symbol"||r instanceof Symbol}e.isSymbol=t})(Wo)),Wo}var $f;function fx(){return $f||($f=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Wp(),r=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,n=/^\w*$/;function i(a,o){return Array.isArray(a)?!1:typeof a=="number"||typeof a=="boolean"||a==null||t.isSymbol(a)?!0:typeof a=="string"&&(n.test(a)||!r.test(a))||o!=null&&Object.hasOwn(o,a)}e.isKey=i})(qo)),qo}var Rf;function dx(){return Rf||(Rf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=sx(),r=fx(),n=Kl();function i(a,o,u,l){if(a==null)return[];u=l?void 0:u,Array.isArray(a)||(a=Object.values(a)),Array.isArray(o)||(o=o==null?[null]:[o]),o.length===0&&(o=[null]),Array.isArray(u)||(u=u==null?[]:[u]),u=u.map(v=>String(v));const s=(v,p)=>{let y=v;for(let m=0;mp==null||v==null?p:typeof v=="object"&&"key"in v?Object.hasOwn(p,v.key)?p[v.key]:s(p,v.path):typeof v=="function"?v(p):Array.isArray(v)?s(p,v):typeof p=="object"?p[v]:p,f=o.map(v=>(Array.isArray(v)&&v.length===1&&(v=v[0]),v==null||typeof v=="function"||Array.isArray(v)||r.isKey(v)?v:{key:v,path:n.toPath(v)}));return a.map(v=>({original:v,criteria:f.map(p=>c(p,v))})).slice().sort((v,p)=>{for(let y=0;yv.original)}e.orderBy=i})(Fo)),Fo}var Uo={},Lf;function vx(){return Lf||(Lf=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r,n=1){const i=[],a=Math.floor(n),o=(u,l)=>{for(let s=0;s1&&n.isIterateeCall(a,o[0],o[1])?o=[]:u>2&&n.isIterateeCall(o[0],o[1],o[2])&&(o=[o[0]]),t.orderBy(a,r.flatten(o),["asc"])}e.sortBy=i})(Bo)),Bo}var Yo,Ff;function px(){return Ff||(Ff=1,Yo=hx().sortBy),Yo}var mx=px();const ha=Qt(mx);var Hp=e=>e.legend.settings,yx=e=>e.legend.size,gx=e=>e.legend.payload,bx=A([gx,Hp],(e,t)=>{var{itemSorter:r}=t,n=e.flat(1);return r?ha(n,r):n});function wx(){return T(bx)}var Jn=1;function Yp(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],[t,r]=h.useState({height:0,left:0,top:0,width:0}),n=h.useCallback(i=>{if(i!=null){var a=i.getBoundingClientRect(),o={height:a.height,left:a.left,top:a.top,width:a.width};(Math.abs(o.height-t.height)>Jn||Math.abs(o.left-t.left)>Jn||Math.abs(o.top-t.top)>Jn||Math.abs(o.width-t.width)>Jn)&&r({height:o.height,left:o.left,top:o.top,width:o.width})}},[t.width,t.height,t.top,t.left,...e]);return[t,n]}function _e(e){return`Minified Redux error #${e}; visit https://redux.js.org/Errors?code=${e} for the full message or use the non-minified dev environment for full errors. `}var xx=typeof Symbol=="function"&&Symbol.observable||"@@observable",Kf=xx,Go=()=>Math.random().toString(36).substring(7).split("").join("."),Px={INIT:`@@redux/INIT${Go()}`,REPLACE:`@@redux/REPLACE${Go()}`,PROBE_UNKNOWN_ACTION:()=>`@@redux/PROBE_UNKNOWN_ACTION${Go()}`},Ei=Px;function Gl(e){if(typeof e!="object"||e===null)return!1;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t||Object.getPrototypeOf(e)===null}function Gp(e,t,r){if(typeof e!="function")throw new Error(_e(2));if(typeof t=="function"&&typeof r=="function"||typeof r=="function"&&typeof arguments[3]=="function")throw new Error(_e(0));if(typeof t=="function"&&typeof r>"u"&&(r=t,t=void 0),typeof r<"u"){if(typeof r!="function")throw new Error(_e(1));return r(Gp)(e,t)}let n=e,i=t,a=new Map,o=a,u=0,l=!1;function s(){o===a&&(o=new Map,a.forEach((m,g)=>{o.set(g,m)}))}function c(){if(l)throw new Error(_e(3));return i}function f(m){if(typeof m!="function")throw new Error(_e(4));if(l)throw new Error(_e(5));let g=!0;s();const x=u++;return o.set(x,m),function(){if(g){if(l)throw new Error(_e(6));g=!1,s(),o.delete(x),a=null}}}function d(m){if(!Gl(m))throw new Error(_e(7));if(typeof m.type>"u")throw new Error(_e(8));if(typeof m.type!="string")throw new Error(_e(17));if(l)throw new Error(_e(9));try{l=!0,i=n(i,m)}finally{l=!1}return(a=o).forEach(x=>{x()}),m}function v(m){if(typeof m!="function")throw new Error(_e(10));n=m,d({type:Ei.REPLACE})}function p(){const m=f;return{subscribe(g){if(typeof g!="object"||g===null)throw new Error(_e(11));function x(){const P=g;P.next&&P.next(c())}return x(),{unsubscribe:m(x)}},[Kf](){return this}}}return d({type:Ei.INIT}),{dispatch:d,subscribe:f,getState:c,replaceReducer:v,[Kf]:p}}function Ox(e){Object.keys(e).forEach(t=>{const r=e[t];if(typeof r(void 0,{type:Ei.INIT})>"u")throw new Error(_e(12));if(typeof r(void 0,{type:Ei.PROBE_UNKNOWN_ACTION()})>"u")throw new Error(_e(13))})}function Vp(e){const t=Object.keys(e),r={};for(let a=0;a"u")throw u&&u.type,new Error(_e(14));s[f]=p,l=l||p!==v}return l=l||n.length!==Object.keys(o).length,l?s:o}}function _i(...e){return e.length===0?t=>t:e.length===1?e[0]:e.reduce((t,r)=>(...n)=>t(r(...n)))}function Ax(...e){return t=>(r,n)=>{const i=t(r,n);let a=()=>{throw new Error(_e(15))};const o={getState:i.getState,dispatch:(l,...s)=>a(l,...s)},u=e.map(l=>l(o));return a=_i(...u)(i.dispatch),{...i,dispatch:a}}}function Xp(e){return Gl(e)&&"type"in e&&typeof e.type=="string"}var Zp=Symbol.for("immer-nothing"),qf=Symbol.for("immer-draftable"),Re=Symbol.for("immer-state");function lt(e,...t){throw new Error(`[Immer] minified error nr: ${e}. Full error at: https://bit.ly/3cXEKWf`)}var Ve=Object,Mr=Ve.getPrototypeOf,ki="constructor",pa="prototype",Bu="configurable",ji="enumerable",mi="writable",sn="value",It=e=>!!e&&!!e[Re];function vt(e){return e?Qp(e)||ma(e)||!!e[qf]||!!e[ki]?.[qf]||ya(e)||ga(e):!1}var Sx=Ve[pa][ki].toString(),Wf=new WeakMap;function Qp(e){if(!e||!Vl(e))return!1;const t=Mr(e);if(t===null||t===Ve[pa])return!0;const r=Ve.hasOwnProperty.call(t,ki)&&t[ki];if(r===Object)return!0;if(!Er(r))return!1;let n=Wf.get(r);return n===void 0&&(n=Function.toString.call(r),Wf.set(r,n)),n===Sx}function _n(e,t,r=!0){kn(e)===0?(r?Reflect.ownKeys(e):Ve.keys(e)).forEach(i=>{t(i,e[i],e)}):e.forEach((n,i)=>t(i,n,e))}function kn(e){const t=e[Re];return t?t.type_:ma(e)?1:ya(e)?2:ga(e)?3:0}var Uf=(e,t,r=kn(e))=>r===2?e.has(t):Ve[pa].hasOwnProperty.call(e,t),Fu=(e,t,r=kn(e))=>r===2?e.get(t):e[t],Ci=(e,t,r,n=kn(e))=>{n===2?e.set(t,r):n===3?e.add(r):e[t]=r};function Ex(e,t){return e===t?e!==0||1/e===1/t:e!==e&&t!==t}var ma=Array.isArray,ya=e=>e instanceof Map,ga=e=>e instanceof Set,Vl=e=>typeof e=="object",Er=e=>typeof e=="function",Vo=e=>typeof e=="boolean",Ot=e=>e.copy_||e.base_,Xl=e=>e.modified_?e.copy_:e.base_;function Ku(e,t){if(ya(e))return new Map(e);if(ga(e))return new Set(e);if(ma(e))return Array[pa].slice.call(e);const r=Qp(e);if(t===!0||t==="class_only"&&!r){const n=Ve.getOwnPropertyDescriptors(e);delete n[Re];let i=Reflect.ownKeys(n);for(let a=0;a1&&Ve.defineProperties(e,{set:ei,add:ei,clear:ei,delete:ei}),Ve.freeze(e),t&&_n(e,(r,n)=>{Zl(n,!0)},!1)),e}function _x(){lt(2)}var ei={[sn]:_x};function ba(e){return e===null||!Vl(e)?!0:Ve.isFrozen(e)}var Ii="MapSet",qu="Patches",Jp={};function Tr(e){const t=Jp[e];return t||lt(0,e),t}var kx=e=>!!Jp[e],fn,em=()=>fn,jx=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:kx(Ii)?Tr(Ii):void 0});function Hf(e,t){t&&(e.patchPlugin_=Tr(qu),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Wu(e){Uu(e),e.drafts_.forEach(Cx),e.drafts_=null}function Uu(e){e===fn&&(fn=e.parent_)}var Yf=e=>fn=jx(fn,e);function Cx(e){const t=e[Re];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function Gf(e,t){t.unfinalizedDrafts_=t.drafts_.length;const r=t.drafts_[0];if(e!==void 0&&e!==r){r[Re].modified_&&(Wu(t),lt(4)),vt(e)&&(e=Vf(t,e));const{patchPlugin_:i}=t;i&&i.generateReplacementPatches_(r[Re].base_,e,t)}else e=Vf(t,r);return Ix(t,e,!0),Wu(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e!==Zp?e:void 0}function Vf(e,t){if(ba(t))return t;const r=t[Re];if(!r)return Ql(t,e.handledSet_,e);if(!wa(r,e))return t;if(!r.modified_)return r.base_;if(!r.finalized_){const{callbacks_:n}=r;if(n)for(;n.length>0;)n.pop()(e);nm(r,e)}return r.copy_}function Ix(e,t,r=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&Zl(t,r)}function tm(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var wa=(e,t)=>e.scope_===t,Mx=[];function rm(e,t,r,n){const i=Ot(e),a=e.type_;if(n!==void 0&&Fu(i,n,a)===t){Ci(i,n,r,a);return}if(!e.draftLocations_){const u=e.draftLocations_=new Map;_n(i,(l,s)=>{if(It(s)){const c=u.get(s)||[];c.push(l),u.set(s,c)}})}const o=e.draftLocations_.get(t)??Mx;for(const u of o)Ci(i,u,r,a)}function Tx(e,t,r){e.callbacks_.push(function(i){const a=t;if(!a||!wa(a,i))return;i.mapSetPlugin_?.fixSetContents(a);const o=Xl(a);rm(e,a.draft_??a,o,r),nm(a,i)})}function nm(e,t){if(e.modified_&&!e.finalized_&&(e.type_===3||(e.assigned_?.size??0)>0)){const{patchPlugin_:n}=t;if(n){const i=n.getPath(e);i&&n.generatePatches_(e,i,t)}tm(e)}}function Dx(e,t,r){const{scope_:n}=e;if(It(r)){const i=r[Re];wa(i,n)&&i.callbacks_.push(function(){yi(e);const o=Xl(i);rm(e,r,o,t)})}else vt(r)&&e.callbacks_.push(function(){const a=Ot(e);Fu(a,t,e.type_)===r&&n.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&Ql(Fu(e.copy_,t,e.type_),n.handledSet_,n)})}function Ql(e,t,r){return!r.immer_.autoFreeze_&&r.unfinalizedDrafts_<1||It(e)||t.has(e)||!vt(e)||ba(e)||(t.add(e),_n(e,(n,i)=>{if(It(i)){const a=i[Re];if(wa(a,r)){const o=Xl(a);Ci(e,n,o,e.type_),tm(a)}}else vt(i)&&Ql(i,t,r)})),e}function Nx(e,t){const r=ma(e),n={type_:r?1:0,scope_:t?t.scope_:em(),modified_:!1,finalized_:!1,assigned_:void 0,parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1,callbacks_:void 0};let i=n,a=Jl;r&&(i=[n],a=dn);const{revoke:o,proxy:u}=Proxy.revocable(i,a);return n.draft_=u,n.revoke_=o,[u,n]}var Jl={get(e,t){if(t===Re)return e;const r=Ot(e);if(!Uf(r,t,e.type_))return $x(e,r,t);const n=r[t];if(e.finalized_||!vt(n))return n;if(n===Xo(e.base_,t)){yi(e);const i=e.type_===1?+t:t,a=Yu(e.scope_,n,e,i);return e.copy_[i]=a}return n},has(e,t){return t in Ot(e)},ownKeys(e){return Reflect.ownKeys(Ot(e))},set(e,t,r){const n=im(Ot(e),t);if(n?.set)return n.set.call(e.draft_,r),!0;if(!e.modified_){const i=Xo(Ot(e),t),a=i?.[Re];if(a&&a.base_===r)return e.copy_[t]=r,e.assigned_.set(t,!1),!0;if(Ex(r,i)&&(r!==void 0||Uf(e.base_,t,e.type_)))return!0;yi(e),Hu(e)}return e.copy_[t]===r&&(r!==void 0||t in e.copy_)||Number.isNaN(r)&&Number.isNaN(e.copy_[t])||(e.copy_[t]=r,e.assigned_.set(t,!0),Dx(e,t,r)),!0},deleteProperty(e,t){return yi(e),Xo(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),Hu(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){const r=Ot(e),n=Reflect.getOwnPropertyDescriptor(r,t);return n&&{[mi]:!0,[Bu]:e.type_!==1||t!=="length",[ji]:n[ji],[sn]:r[t]}},defineProperty(){lt(11)},getPrototypeOf(e){return Mr(e.base_)},setPrototypeOf(){lt(12)}},dn={};_n(Jl,(e,t)=>{dn[e]=function(){const r=arguments;return r[0]=r[0][0],t.apply(this,r)}});dn.deleteProperty=function(e,t){return dn.set.call(this,e,t,void 0)};dn.set=function(e,t,r){return Jl.set.call(this,e[0],t,r,e[0])};function Xo(e,t){const r=e[Re];return(r?Ot(r):e)[t]}function $x(e,t,r){const n=im(t,r);return n?sn in n?n[sn]:n.get?.call(e.draft_):void 0}function im(e,t){if(!(t in e))return;let r=Mr(e);for(;r;){const n=Object.getOwnPropertyDescriptor(r,t);if(n)return n;r=Mr(r)}}function Hu(e){e.modified_||(e.modified_=!0,e.parent_&&Hu(e.parent_))}function yi(e){e.copy_||(e.assigned_=new Map,e.copy_=Ku(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var Rx=class{constructor(t){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(r,n,i)=>{if(Er(r)&&!Er(n)){const o=n;n=r;const u=this;return function(s=o,...c){return u.produce(s,f=>n.call(this,f,...c))}}Er(n)||lt(6),i!==void 0&&!Er(i)&<(7);let a;if(vt(r)){const o=Yf(this),u=Yu(o,r,void 0);let l=!0;try{a=n(u),l=!1}finally{l?Wu(o):Uu(o)}return Hf(o,i),Gf(a,o)}else if(!r||!Vl(r)){if(a=n(r),a===void 0&&(a=r),a===Zp&&(a=void 0),this.autoFreeze_&&Zl(a,!0),i){const o=[],u=[];Tr(qu).generateReplacementPatches_(r,a,{patches_:o,inversePatches_:u}),i(o,u)}return a}else lt(1,r)},this.produceWithPatches=(r,n)=>{if(Er(r))return(u,...l)=>this.produceWithPatches(u,s=>r(s,...l));let i,a;return[this.produce(r,n,(u,l)=>{i=u,a=l}),i,a]},Vo(t?.autoFreeze)&&this.setAutoFreeze(t.autoFreeze),Vo(t?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(t.useStrictShallowCopy),Vo(t?.useStrictIteration)&&this.setUseStrictIteration(t.useStrictIteration)}createDraft(t){vt(t)||lt(8),It(t)&&(t=ft(t));const r=Yf(this),n=Yu(r,t,void 0);return n[Re].isManual_=!0,Uu(r),n}finishDraft(t,r){const n=t&&t[Re];(!n||!n.isManual_)&<(9);const{scope_:i}=n;return Hf(i,r),Gf(void 0,i)}setAutoFreeze(t){this.autoFreeze_=t}setUseStrictShallowCopy(t){this.useStrictShallowCopy_=t}setUseStrictIteration(t){this.useStrictIteration_=t}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(t,r){let n;for(n=r.length-1;n>=0;n--){const a=r[n];if(a.path.length===0&&a.op==="replace"){t=a.value;break}}n>-1&&(r=r.slice(n+1));const i=Tr(qu).applyPatches_;return It(t)?i(t,r):this.produce(t,a=>i(a,r))}};function Yu(e,t,r,n){const[i,a]=ya(t)?Tr(Ii).proxyMap_(t,r):ga(t)?Tr(Ii).proxySet_(t,r):Nx(t,r);return(r?.scope_??em()).drafts_.push(i),a.callbacks_=r?.callbacks_??[],a.key_=n,r&&n!==void 0?Tx(r,a,n):a.callbacks_.push(function(l){l.mapSetPlugin_?.fixSetContents(a);const{patchPlugin_:s}=l;a.modified_&&s&&s.generatePatches_(a,[],l)}),i}function ft(e){return It(e)||lt(10,e),am(e)}function am(e){if(!vt(e)||ba(e))return e;const t=e[Re];let r,n=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,r=Ku(e,t.scope_.immer_.useStrictShallowCopy_),n=t.scope_.immer_.shouldUseStrictIteration()}else r=Ku(e,!0);return _n(r,(i,a)=>{Ci(r,i,am(a))},n),t&&(t.finalized_=!1),r}var Lx=new Rx,om=Lx.produce;function um(e){return({dispatch:r,getState:n})=>i=>a=>typeof a=="function"?a(r,n,e):i(a)}var zx=um(),Bx=um,Fx=typeof window<"u"&&window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__:function(){if(arguments.length!==0)return typeof arguments[0]=="object"?_i:_i.apply(null,arguments)};function at(e,t){function r(...n){if(t){let i=t(...n);if(!i)throw new Error(Xe(0));return{type:e,payload:i.payload,..."meta"in i&&{meta:i.meta},..."error"in i&&{error:i.error}}}return{type:e,payload:n[0]}}return r.toString=()=>`${e}`,r.type=e,r.match=n=>Xp(n)&&n.type===e,r}var lm=class on extends Array{constructor(...t){super(...t),Object.setPrototypeOf(this,on.prototype)}static get[Symbol.species](){return on}concat(...t){return super.concat.apply(this,t)}prepend(...t){return t.length===1&&Array.isArray(t[0])?new on(...t[0].concat(this)):new on(...t.concat(this))}};function Xf(e){return vt(e)?om(e,()=>{}):e}function ti(e,t,r){return e.has(t)?e.get(t):e.set(t,r(t)).get(t)}function Kx(e){return typeof e=="boolean"}var qx=()=>function(t){const{thunk:r=!0,immutableCheck:n=!0,serializableCheck:i=!0,actionCreatorCheck:a=!0}=t??{};let o=new lm;return r&&(Kx(r)?o.push(zx):o.push(Bx(r.extraArgument))),o},cm="RTK_autoBatch",re=()=>e=>({payload:e,meta:{[cm]:!0}}),Zf=e=>t=>{setTimeout(t,e)},sm=(e={type:"raf"})=>t=>(...r)=>{const n=t(...r);let i=!0,a=!1,o=!1;const u=new Set,l=e.type==="tick"?queueMicrotask:e.type==="raf"?typeof window<"u"&&window.requestAnimationFrame?window.requestAnimationFrame:Zf(10):e.type==="callback"?e.queueNotification:Zf(e.timeout),s=()=>{o=!1,a&&(a=!1,u.forEach(c=>c()))};return Object.assign({},n,{subscribe(c){const f=()=>i&&c(),d=n.subscribe(f);return u.add(c),()=>{d(),u.delete(c)}},dispatch(c){try{return i=!c?.meta?.[cm],a=!i,a&&(o||(o=!0,l(s))),n.dispatch(c)}finally{i=!0}}})},Wx=e=>function(r){const{autoBatch:n=!0}=r??{};let i=new lm(e);return n&&i.push(sm(typeof n=="object"?n:void 0)),i};function Ux(e){const t=qx(),{reducer:r=void 0,middleware:n,devTools:i=!0,preloadedState:a=void 0,enhancers:o=void 0}=e||{};let u;if(typeof r=="function")u=r;else if(Gl(r))u=Vp(r);else throw new Error(Xe(1));let l;typeof n=="function"?l=n(t):l=t();let s=_i;i&&(s=Fx({trace:!1,...typeof i=="object"&&i}));const c=Ax(...l),f=Wx(c);let d=typeof o=="function"?o(f):f();const v=s(...d);return Gp(u,a,v)}function fm(e){const t={},r=[];let n;const i={addCase(a,o){const u=typeof a=="string"?a:a.type;if(!u)throw new Error(Xe(28));if(u in t)throw new Error(Xe(29));return t[u]=o,i},addAsyncThunk(a,o){return o.pending&&(t[a.pending.type]=o.pending),o.rejected&&(t[a.rejected.type]=o.rejected),o.fulfilled&&(t[a.fulfilled.type]=o.fulfilled),o.settled&&r.push({matcher:a.settled,reducer:o.settled}),i},addMatcher(a,o){return r.push({matcher:a,reducer:o}),i},addDefaultCase(a){return n=a,i}};return e(i),[t,r,n]}function Hx(e){return typeof e=="function"}function Yx(e,t){let[r,n,i]=fm(t),a;if(Hx(e))a=()=>Xf(e());else{const u=Xf(e);a=()=>u}function o(u=a(),l){let s=[r[l.type],...n.filter(({matcher:c})=>c(l)).map(({reducer:c})=>c)];return s.filter(c=>!!c).length===0&&(s=[i]),s.reduce((c,f)=>{if(f)if(It(c)){const v=f(c,l);return v===void 0?c:v}else{if(vt(c))return om(c,d=>f(d,l));{const d=f(c,l);if(d===void 0){if(c===null)return c;throw Error("A case reducer on a non-draftable value must not return undefined")}return d}}return c},u)}return o.getInitialState=a,o}var Gx="ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW",Vx=(e=21)=>{let t="",r=e;for(;r--;)t+=Gx[Math.random()*64|0];return t},Xx=Symbol.for("rtk-slice-createasyncthunk");function Zx(e,t){return`${e}/${t}`}function Qx({creators:e}={}){const t=e?.asyncThunk?.[Xx];return function(n){const{name:i,reducerPath:a=i}=n;if(!i)throw new Error(Xe(11));const o=(typeof n.reducers=="function"?n.reducers(eP()):n.reducers)||{},u=Object.keys(o),l={sliceCaseReducersByName:{},sliceCaseReducersByType:{},actionCreators:{},sliceMatchers:[]},s={addCase(w,P){const b=typeof w=="string"?w:w.type;if(!b)throw new Error(Xe(12));if(b in l.sliceCaseReducersByType)throw new Error(Xe(13));return l.sliceCaseReducersByType[b]=P,s},addMatcher(w,P){return l.sliceMatchers.push({matcher:w,reducer:P}),s},exposeAction(w,P){return l.actionCreators[w]=P,s},exposeCaseReducer(w,P){return l.sliceCaseReducersByName[w]=P,s}};u.forEach(w=>{const P=o[w],b={reducerName:w,type:Zx(i,w),createNotation:typeof n.reducers=="function"};rP(P)?iP(b,P,s,t):tP(b,P,s)});function c(){const[w={},P=[],b=void 0]=typeof n.extraReducers=="function"?fm(n.extraReducers):[n.extraReducers],O={...w,...l.sliceCaseReducersByType};return Yx(n.initialState,S=>{for(let _ in O)S.addCase(_,O[_]);for(let _ of l.sliceMatchers)S.addMatcher(_.matcher,_.reducer);for(let _ of P)S.addMatcher(_.matcher,_.reducer);b&&S.addDefaultCase(b)})}const f=w=>w,d=new Map,v=new WeakMap;let p;function y(w,P){return p||(p=c()),p(w,P)}function m(){return p||(p=c()),p.getInitialState()}function g(w,P=!1){function b(S){let _=S[w];return typeof _>"u"&&P&&(_=ti(v,b,m)),_}function O(S=f){const _=ti(d,P,()=>new WeakMap);return ti(_,S,()=>{const I={};for(const[M,E]of Object.entries(n.selectors??{}))I[M]=Jx(E,S,()=>ti(v,S,m),P);return I})}return{reducerPath:w,getSelectors:O,get selectors(){return O(b)},selectSlice:b}}const x={name:i,reducer:y,actions:l.actionCreators,caseReducers:l.sliceCaseReducersByName,getInitialState:m,...g(a),injectInto(w,{reducerPath:P,...b}={}){const O=P??a;return w.inject({reducerPath:O,reducer:y},b),{...x,...g(O,!0)}}};return x}}function Jx(e,t,r,n){function i(a,...o){let u=t(a);return typeof u>"u"&&n&&(u=r()),e(u,...o)}return i.unwrapped=e,i}var qe=Qx();function eP(){function e(t,r){return{_reducerDefinitionType:"asyncThunk",payloadCreator:t,...r}}return e.withTypes=()=>e,{reducer(t){return Object.assign({[t.name](...r){return t(...r)}}[t.name],{_reducerDefinitionType:"reducer"})},preparedReducer(t,r){return{_reducerDefinitionType:"reducerWithPrepare",prepare:t,reducer:r}},asyncThunk:e}}function tP({type:e,reducerName:t,createNotation:r},n,i){let a,o;if("reducer"in n){if(r&&!nP(n))throw new Error(Xe(17));a=n.reducer,o=n.prepare}else a=n;i.addCase(e,a).exposeCaseReducer(t,a).exposeAction(t,o?at(e,o):at(e))}function rP(e){return e._reducerDefinitionType==="asyncThunk"}function nP(e){return e._reducerDefinitionType==="reducerWithPrepare"}function iP({type:e,reducerName:t},r,n,i){if(!i)throw new Error(Xe(18));const{payloadCreator:a,fulfilled:o,pending:u,rejected:l,settled:s,options:c}=r,f=i(e,a,c);n.exposeAction(t,f),o&&n.addCase(f.fulfilled,o),u&&n.addCase(f.pending,u),l&&n.addCase(f.rejected,l),s&&n.addMatcher(f.settled,s),n.exposeCaseReducer(t,{fulfilled:o||ri,pending:u||ri,rejected:l||ri,settled:s||ri})}function ri(){}var aP="task",dm="listener",vm="completed",ec="cancelled",oP=`task-${ec}`,uP=`task-${vm}`,Gu=`${dm}-${ec}`,lP=`${dm}-${vm}`,xa=class{constructor(e){this.code=e,this.message=`${aP} ${ec} (reason: ${e})`}name="TaskAbortError";message},tc=(e,t)=>{if(typeof e!="function")throw new TypeError(Xe(32))},Mi=()=>{},hm=(e,t=Mi)=>(e.catch(t),e),pm=(e,t)=>(e.addEventListener("abort",t,{once:!0}),()=>e.removeEventListener("abort",t)),fr=e=>{if(e.aborted)throw new xa(e.reason)};function mm(e,t){let r=Mi;return new Promise((n,i)=>{const a=()=>i(new xa(e.reason));if(e.aborted){a();return}r=pm(e,a),t.finally(()=>r()).then(n,i)}).finally(()=>{r=Mi})}var cP=async(e,t)=>{try{return await Promise.resolve(),{status:"ok",value:await e()}}catch(r){return{status:r instanceof xa?"cancelled":"rejected",error:r}}finally{t?.()}},Ti=e=>t=>hm(mm(e,t).then(r=>(fr(e),r))),ym=e=>{const t=Ti(e);return r=>t(new Promise(n=>setTimeout(n,r)))},{assign:jr}=Object,Qf={},Pa="listenerMiddleware",sP=(e,t)=>{const r=n=>pm(e,()=>n.abort(e.reason));return(n,i)=>{tc(n);const a=new AbortController;r(a);const o=cP(async()=>{fr(e),fr(a.signal);const u=await n({pause:Ti(a.signal),delay:ym(a.signal),signal:a.signal});return fr(a.signal),u},()=>a.abort(uP));return i?.autoJoin&&t.push(o.catch(Mi)),{result:Ti(e)(o),cancel(){a.abort(oP)}}}},fP=(e,t)=>{const r=async(n,i)=>{fr(t);let a=()=>{};const u=[new Promise((l,s)=>{let c=e({predicate:n,effect:(f,d)=>{d.unsubscribe(),l([f,d.getState(),d.getOriginalState()])}});a=()=>{c(),s()}})];i!=null&&u.push(new Promise(l=>setTimeout(l,i,null)));try{const l=await mm(t,Promise.race(u));return fr(t),l}finally{a()}};return(n,i)=>hm(r(n,i))},gm=e=>{let{type:t,actionCreator:r,matcher:n,predicate:i,effect:a}=e;if(t)i=at(t).match;else if(r)t=r.type,i=r.match;else if(n)i=n;else if(!i)throw new Error(Xe(21));return tc(a),{predicate:i,type:t,effect:a}},bm=jr(e=>{const{type:t,predicate:r,effect:n}=gm(e);return{id:Vx(),effect:n,type:t,predicate:r,pending:new Set,unsubscribe:()=>{throw new Error(Xe(22))}}},{withTypes:()=>bm}),Jf=(e,t)=>{const{type:r,effect:n,predicate:i}=gm(t);return Array.from(e.values()).find(a=>(typeof r=="string"?a.type===r:a.predicate===i)&&a.effect===n)},Vu=e=>{e.pending.forEach(t=>{t.abort(Gu)})},dP=(e,t)=>()=>{for(const r of t.keys())Vu(r);e.clear()},ed=(e,t,r)=>{try{e(t,r)}catch(n){setTimeout(()=>{throw n},0)}},wm=jr(at(`${Pa}/add`),{withTypes:()=>wm}),vP=at(`${Pa}/removeAll`),xm=jr(at(`${Pa}/remove`),{withTypes:()=>xm}),hP=(...e)=>{console.error(`${Pa}/error`,...e)},jn=(e={})=>{const t=new Map,r=new Map,n=v=>{const p=r.get(v)??0;r.set(v,p+1)},i=v=>{const p=r.get(v)??1;p===1?r.delete(v):r.set(v,p-1)},{extra:a,onError:o=hP}=e;tc(o);const u=v=>(v.unsubscribe=()=>t.delete(v.id),t.set(v.id,v),p=>{v.unsubscribe(),p?.cancelActive&&Vu(v)}),l=v=>{const p=Jf(t,v)??bm(v);return u(p)};jr(l,{withTypes:()=>l});const s=v=>{const p=Jf(t,v);return p&&(p.unsubscribe(),v.cancelActive&&Vu(p)),!!p};jr(s,{withTypes:()=>s});const c=async(v,p,y,m)=>{const g=new AbortController,x=fP(l,g.signal),w=[];try{v.pending.add(g),n(v),await Promise.resolve(v.effect(p,jr({},y,{getOriginalState:m,condition:(P,b)=>x(P,b).then(Boolean),take:x,delay:ym(g.signal),pause:Ti(g.signal),extra:a,signal:g.signal,fork:sP(g.signal,w),unsubscribe:v.unsubscribe,subscribe:()=>{t.set(v.id,v)},cancelActiveListeners:()=>{v.pending.forEach((P,b,O)=>{P!==g&&(P.abort(Gu),O.delete(P))})},cancel:()=>{g.abort(Gu),v.pending.delete(g)},throwIfCancelled:()=>{fr(g.signal)}})))}catch(P){P instanceof xa||ed(o,P,{raisedBy:"effect"})}finally{await Promise.all(w),g.abort(lP),i(v),v.pending.delete(g)}},f=dP(t,r);return{middleware:v=>p=>y=>{if(!Xp(y))return p(y);if(wm.match(y))return l(y.payload);if(vP.match(y)){f();return}if(xm.match(y))return s(y.payload);let m=v.getState();const g=()=>{if(m===Qf)throw new Error(Xe(23));return m};let x;try{if(x=p(y),t.size>0){const w=v.getState(),P=Array.from(t.values());for(const b of P){let O=!1;try{O=b.predicate(y,w,m)}catch(S){O=!1,ed(o,S,{raisedBy:"predicate"})}O&&c(b,y,v,g)}}}finally{m=Qf}return x},startListening:l,stopListening:s,clearListeners:f}};function Xe(e){return`Minified Redux Toolkit error #${e}; visit https://redux-toolkit.js.org/Errors?code=${e} for the full message or use the non-minified dev environment for full errors. `}var pP={layoutType:"horizontal",width:0,height:0,margin:{top:5,right:5,bottom:5,left:5},scale:1},Pm=qe({name:"chartLayout",initialState:pP,reducers:{setLayout(e,t){e.layoutType=t.payload},setChartSize(e,t){e.width=t.payload.width,e.height=t.payload.height},setMargin(e,t){var r,n,i,a;e.margin.top=(r=t.payload.top)!==null&&r!==void 0?r:0,e.margin.right=(n=t.payload.right)!==null&&n!==void 0?n:0,e.margin.bottom=(i=t.payload.bottom)!==null&&i!==void 0?i:0,e.margin.left=(a=t.payload.left)!==null&&a!==void 0?a:0},setScale(e,t){e.scale=t.payload}}}),{setMargin:mP,setLayout:yP,setChartSize:gP,setScale:bP}=Pm.actions,wP=Pm.reducer;function Om(e,t,r){return Array.isArray(e)&&e&&t+r!==0?e.slice(t,r+1):e}function td(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function _r(e){for(var t=1;t{if(t&&r){var{width:n,height:i}=r,{align:a,verticalAlign:o,layout:u}=t;if((u==="vertical"||u==="horizontal"&&o==="middle")&&a!=="center"&&N(e[a]))return _r(_r({},e),{},{[a]:e[a]+(n||0)});if((u==="horizontal"||u==="vertical"&&a==="center")&&o!=="middle"&&N(e[o]))return _r(_r({},e),{},{[o]:e[o]+(i||0)})}return e},Jt=(e,t)=>e==="horizontal"&&t==="xAxis"||e==="vertical"&&t==="yAxis"||e==="centric"&&t==="angleAxis"||e==="radial"&&t==="radiusAxis",Am=(e,t,r,n)=>{if(n)return e.map(u=>u.coordinate);var i,a,o=e.map(u=>(u.coordinate===t&&(i=!0),u.coordinate===r&&(a=!0),u.coordinate));return i||o.push(t),a||o.push(r),o},Sm=(e,t,r)=>{if(!e)return null;var{duplicateDomain:n,type:i,range:a,scale:o,realScaleType:u,isCategorical:l,categoricalDomain:s,tickCount:c,ticks:f,niceTicks:d,axisType:v}=e;if(!o)return null;var p=u==="scaleBand"&&o.bandwidth?o.bandwidth()/2:2,y=i==="category"&&o.bandwidth?o.bandwidth()/p:0;if(y=v==="angleAxis"&&a&&a.length>=2?Ae(a[0]-a[1])*2*y:y,f||d){var m=(f||d||[]).map((g,x)=>{var w=n?n.indexOf(g):g;return{coordinate:o(w)+y,value:g,offset:y,index:x}});return m.filter(g=>!dt(g.coordinate))}return l&&s?s.map((g,x)=>({coordinate:o(g)+y,value:g,index:x,offset:y})):o.ticks&&c!=null?o.ticks(c).map((g,x)=>({coordinate:o(g)+y,value:g,offset:y,index:x})):o.domain().map((g,x)=>({coordinate:o(g)+y,value:n?n[g]:g,index:x,offset:y}))},rd=1e-4,SP=e=>{var t=e.domain();if(!(!t||t.length<=2)){var r=t.length,n=e.range(),i=Math.min(n[0],n[1])-rd,a=Math.max(n[0],n[1])+rd,o=e(t[0]),u=e(t[r-1]);(oa||ua)&&e.domain([t[0],t[r-1]])}},EP=(e,t)=>{if(!t||t.length!==2||!N(t[0])||!N(t[1]))return e;var r=Math.min(t[0],t[1]),n=Math.max(t[0],t[1]),i=[e[0],e[1]];return(!N(e[0])||e[0]n)&&(i[1]=n),i[0]>n&&(i[0]=n),i[1]{var t=e.length;if(!(t<=0))for(var r=0,n=e[0].length;r=0?(e[o][r][0]=i,e[o][r][1]=i+u,i=e[o][r][1]):(e[o][r][0]=a,e[o][r][1]=a+u,a=e[o][r][1])}},kP=e=>{var t=e.length;if(!(t<=0))for(var r=0,n=e[0].length;r=0?(e[a][r][0]=i,e[a][r][1]=i+o,i=e[a][r][1]):(e[a][r][0]=0,e[a][r][1]=0)}},jP={sign:_P,expand:ew,none:Ir,silhouette:tw,wiggle:rw,positive:kP},CP=(e,t,r)=>{var n=jP[r],i=Jb().keys(t).value((a,o)=>Number(X(a,o,0))).order(Lu).offset(n);return i(e)};function IP(e){return e==null?void 0:String(e)}function nd(e){var{axis:t,ticks:r,bandSize:n,entry:i,index:a,dataKey:o}=e;if(t.type==="category"){if(!t.allowDuplicatedCategory&&t.dataKey&&!ae(i[t.dataKey])){var u=Cp(r,"value",i[t.dataKey]);if(u)return u.coordinate+n/2}return r[a]?r[a].coordinate+n/2:null}var l=X(i,ae(o)?t.dataKey:o);return ae(l)?null:t.scale(l)}var id=e=>{var{axis:t,ticks:r,offset:n,bandSize:i,entry:a,index:o}=e;if(t.type==="category")return r[o]?r[o].coordinate+n:null;var u=X(a,t.dataKey,t.scale.domain()[o]);return ae(u)?null:t.scale(u)-i/2+n},MP=e=>{var{numericAxis:t}=e,r=t.scale.domain();if(t.type==="number"){var n=Math.min(r[0],r[1]),i=Math.max(r[0],r[1]);return n<=0&&i>=0?0:i<0?i:n}return r[0]},TP=e=>{var t=e.flat(2).filter(N);return[Math.min(...t),Math.max(...t)]},DP=e=>[e[0]===1/0?0:e[0],e[1]===-1/0?0:e[1]],NP=(e,t,r)=>{if(e!=null)return DP(Object.keys(e).reduce((n,i)=>{var a=e[i],{stackedData:o}=a,u=o.reduce((l,s)=>{var c=Om(s,t,r),f=TP(c);return[Math.min(l[0],f[0]),Math.max(l[1],f[1])]},[1/0,-1/0]);return[Math.min(u[0],n[0]),Math.max(u[1],n[1])]},[1/0,-1/0]))},ad=/^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,od=/^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,Dr=(e,t,r)=>{if(e&&e.scale&&e.scale.bandwidth){var n=e.scale.bandwidth();if(!r||n>0)return n}if(e&&t&&t.length>=2){for(var i=ha(t,c=>c.coordinate),a=1/0,o=1,u=i.length;o{if(t==="horizontal")return e.chartX;if(t==="vertical")return e.chartY},RP=(e,t)=>t==="centric"?e.angle:e.radius,Rt=e=>e.layout.width,Lt=e=>e.layout.height,LP=e=>e.layout.scale,Em=e=>e.layout.margin,Oa=A(e=>e.cartesianAxis.xAxis,e=>Object.values(e)),Aa=A(e=>e.cartesianAxis.yAxis,e=>Object.values(e)),_m="data-recharts-item-index",km="data-recharts-item-data-key",Cn=60;function ld(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function ni(e){for(var t=1;te.brush.height;function qP(e){var t=Aa(e);return t.reduce((r,n)=>{if(n.orientation==="left"&&!n.mirror&&!n.hide){var i=typeof n.width=="number"?n.width:Cn;return r+i}return r},0)}function WP(e){var t=Aa(e);return t.reduce((r,n)=>{if(n.orientation==="right"&&!n.mirror&&!n.hide){var i=typeof n.width=="number"?n.width:Cn;return r+i}return r},0)}function UP(e){var t=Oa(e);return t.reduce((r,n)=>n.orientation==="top"&&!n.mirror&&!n.hide?r+n.height:r,0)}function HP(e){var t=Oa(e);return t.reduce((r,n)=>n.orientation==="bottom"&&!n.mirror&&!n.hide?r+n.height:r,0)}var ye=A([Rt,Lt,Em,KP,qP,WP,UP,HP,Hp,yx],(e,t,r,n,i,a,o,u,l,s)=>{var c={left:(r.left||0)+i,right:(r.right||0)+a},f={top:(r.top||0)+o,bottom:(r.bottom||0)+u},d=ni(ni({},f),c),v=d.bottom;d.bottom+=n,d=AP(d,l,s);var p=e-d.left-d.right,y=t-d.top-d.bottom;return ni(ni({brushBottom:v},d),{},{width:Math.max(p,0),height:Math.max(y,0)})}),YP=A(ye,e=>({x:e.left,y:e.top,width:e.width,height:e.height})),rc=A(Rt,Lt,(e,t)=>({x:0,y:0,width:e,height:t})),GP=h.createContext(null),Me=()=>h.useContext(GP)!=null,Sa=e=>e.brush,Ea=A([Sa,ye,Em],(e,t,r)=>({height:e.height,x:N(e.x)?e.x:t.left,y:N(e.y)?e.y:t.top+t.height+t.brushBottom-(r?.bottom||0),width:N(e.width)?e.width:t.width})),Zo={},Qo={},Jo={},cd;function VP(){return cd||(cd=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r,n,{signal:i,edges:a}={}){let o,u=null;const l=a!=null&&a.includes("leading"),s=a==null||a.includes("trailing"),c=()=>{u!==null&&(r.apply(o,u),o=void 0,u=null)},f=()=>{s&&c(),y()};let d=null;const v=()=>{d!=null&&clearTimeout(d),d=setTimeout(()=>{d=null,f()},n)},p=()=>{d!==null&&(clearTimeout(d),d=null)},y=()=>{p(),o=void 0,u=null},m=()=>{c()},g=function(...x){if(i?.aborted)return;o=this,u=x;const w=d==null;v(),l&&w&&c()};return g.schedule=v,g.cancel=y,g.flush=m,i?.addEventListener("abort",y,{once:!0}),g}e.debounce=t})(Jo)),Jo}var sd;function XP(){return sd||(sd=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=VP();function r(n,i=0,a={}){typeof a!="object"&&(a={});const{leading:o=!1,trailing:u=!0,maxWait:l}=a,s=Array(2);o&&(s[0]="leading"),u&&(s[1]="trailing");let c,f=null;const d=t.debounce(function(...y){c=n.apply(this,y),f=null},i,{edges:s}),v=function(...y){return l!=null&&(f===null&&(f=Date.now()),Date.now()-f>=l)?(c=n.apply(this,y),f=Date.now(),d.cancel(),d.schedule(),c):(d.apply(this,y),c)},p=()=>(d.flush(),c);return v.cancel=d.cancel,v.flush=p,v}e.debounce=r})(Qo)),Qo}var fd;function ZP(){return fd||(fd=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=XP();function r(n,i=0,a={}){const{leading:o=!0,trailing:u=!0}=a;return t.debounce(n,i,{leading:o,maxWait:i,trailing:u})}e.throttle=r})(Zo)),Zo}var eu,dd;function QP(){return dd||(dd=1,eu=ZP().throttle),eu}var JP=QP();const eO=Qt(JP);var Di=function(t,r){for(var n=arguments.length,i=new Array(n>2?n-2:0),a=2;ai[o++]))}},jm=(e,t,r)=>{var{width:n="100%",height:i="100%",aspect:a,maxHeight:o}=r,u=Ct(n)?e:Number(n),l=Ct(i)?t:Number(i);return a&&a>0&&(u?l=u/a:l&&(u=l*a),o&&l!=null&&l>o&&(l=o)),{calculatedWidth:u,calculatedHeight:l}},tO={width:0,height:0,overflow:"visible"},rO={width:0,overflowX:"visible"},nO={height:0,overflowY:"visible"},iO={},aO=e=>{var{width:t,height:r}=e,n=Ct(t),i=Ct(r);return n&&i?tO:n?rO:i?nO:iO};function oO(e){var{width:t,height:r,aspect:n}=e,i=t,a=r;return i===void 0&&a===void 0?(i="100%",a="100%"):i===void 0?i=n&&n>0?void 0:"100%":a===void 0&&(a=n&&n>0?void 0:"100%"),{width:i,height:a}}function se(e){return Number.isFinite(e)}function wt(e){return typeof e=="number"&&e>0&&Number.isFinite(e)}function Xu(){return Xu=Object.assign?Object.assign.bind():function(e){for(var t=1;t({width:r,height:n}),[r,n]);return sO(i)?h.createElement(Cm.Provider,{value:i},t):null}var nc=()=>h.useContext(Cm),fO=h.forwardRef((e,t)=>{var{aspect:r,initialDimension:n={width:-1,height:-1},width:i,height:a,minWidth:o=0,minHeight:u,maxHeight:l,children:s,debounce:c=0,id:f,className:d,onResize:v,style:p={}}=e,y=h.useRef(null),m=h.useRef();m.current=v,h.useImperativeHandle(t,()=>y.current);var[g,x]=h.useState({containerWidth:n.width,containerHeight:n.height}),w=h.useCallback((_,I)=>{x(M=>{var E=Math.round(_),j=Math.round(I);return M.containerWidth===E&&M.containerHeight===j?M:{containerWidth:E,containerHeight:j}})},[]);h.useEffect(()=>{if(y.current==null||typeof ResizeObserver>"u")return Sn;var _=j=>{var $,{width:L,height:z}=j[0].contentRect;w(L,z),($=m.current)===null||$===void 0||$.call(m,L,z)};c>0&&(_=eO(_,c,{trailing:!0,leading:!1}));var I=new ResizeObserver(_),{width:M,height:E}=y.current.getBoundingClientRect();return w(M,E),I.observe(y.current),()=>{I.disconnect()}},[w,c]);var{containerWidth:P,containerHeight:b}=g;Di(!r||r>0,"The aspect(%s) must be greater than zero.",r);var{calculatedWidth:O,calculatedHeight:S}=jm(P,b,{width:i,height:a,aspect:r,maxHeight:l});return Di(O!=null&&O>0||S!=null&&S>0,`The width(%s) and height(%s) of chart should be greater than 0, + please check the style of container, or the props width(%s) and height(%s), + or add a minWidth(%s) or minHeight(%s) or use aspect(%s) to control the + height and width.`,O,S,i,a,o,u,r),h.createElement("div",{id:f?"".concat(f):void 0,className:H("recharts-responsive-container",d),style:hd(hd({},p),{},{width:i,height:a,minWidth:o,minHeight:u,maxHeight:l}),ref:y},h.createElement("div",{style:aO({width:i,height:a})},h.createElement(Im,{width:O,height:S},s)))}),I$=h.forwardRef((e,t)=>{var r=nc();if(wt(r.width)&&wt(r.height))return e.children;var{width:n,height:i}=oO({width:e.width,height:e.height,aspect:e.aspect}),{calculatedWidth:a,calculatedHeight:o}=jm(void 0,void 0,{width:n,height:i,aspect:e.aspect,maxHeight:e.maxHeight});return N(a)&&N(o)?h.createElement(Im,{width:a,height:o},e.children):h.createElement(fO,Xu({},e,{width:n,height:i,ref:t}))});function Mm(e){if(e)return{x:e.x,y:e.y,upperWidth:"upperWidth"in e?e.upperWidth:e.width,lowerWidth:"lowerWidth"in e?e.lowerWidth:e.width,width:e.width,height:e.height}}var _a=()=>{var e,t=Me(),r=T(YP),n=T(Ea),i=(e=T(Sa))===null||e===void 0?void 0:e.padding;return!t||!n||!i?r:{width:n.width-i.left-i.right,height:n.height-i.top-i.bottom,x:i.left,y:i.top}},dO={top:0,bottom:0,left:0,right:0,width:0,height:0,brushBottom:0},Tm=()=>{var e;return(e=T(ye))!==null&&e!==void 0?e:dO},ic=()=>T(Rt),ac=()=>T(Lt),vO=()=>T(e=>e.layout.margin),q=e=>e.layout.layoutType,In=()=>T(q),hO=()=>{var e=In();return e!==void 0},ka=e=>{var t=ee(),r=Me(),{width:n,height:i}=e,a=nc(),o=n,u=i;return a&&(o=a.width>0?a.width:n,u=a.height>0?a.height:i),h.useEffect(()=>{!r&&wt(o)&&wt(u)&&t(gP({width:o,height:u}))},[t,r,o,u]),null},Dm=Symbol.for("immer-nothing"),pd=Symbol.for("immer-draftable"),Qe=Symbol.for("immer-state");function ct(e,...t){throw new Error(`[Immer] minified error nr: ${e}. Full error at: https://bit.ly/3cXEKWf`)}var vn=Object.getPrototypeOf;function Nr(e){return!!e&&!!e[Qe]}function mr(e){return e?Nm(e)||Array.isArray(e)||!!e[pd]||!!e.constructor?.[pd]||Mn(e)||Ca(e):!1}var pO=Object.prototype.constructor.toString(),md=new WeakMap;function Nm(e){if(!e||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);if(t===null||t===Object.prototype)return!0;const r=Object.hasOwnProperty.call(t,"constructor")&&t.constructor;if(r===Object)return!0;if(typeof r!="function")return!1;let n=md.get(r);return n===void 0&&(n=Function.toString.call(r),md.set(r,n)),n===pO}function Ni(e,t,r=!0){ja(e)===0?(r?Reflect.ownKeys(e):Object.keys(e)).forEach(i=>{t(i,e[i],e)}):e.forEach((n,i)=>t(i,n,e))}function ja(e){const t=e[Qe];return t?t.type_:Array.isArray(e)?1:Mn(e)?2:Ca(e)?3:0}function Zu(e,t){return ja(e)===2?e.has(t):Object.prototype.hasOwnProperty.call(e,t)}function $m(e,t,r){const n=ja(e);n===2?e.set(t,r):n===3?e.add(r):e[t]=r}function mO(e,t){return e===t?e!==0||1/e===1/t:e!==e&&t!==t}function Mn(e){return e instanceof Map}function Ca(e){return e instanceof Set}function or(e){return e.copy_||e.base_}function Qu(e,t){if(Mn(e))return new Map(e);if(Ca(e))return new Set(e);if(Array.isArray(e))return Array.prototype.slice.call(e);const r=Nm(e);if(t===!0||t==="class_only"&&!r){const n=Object.getOwnPropertyDescriptors(e);delete n[Qe];let i=Reflect.ownKeys(n);for(let a=0;a1&&Object.defineProperties(e,{set:ii,add:ii,clear:ii,delete:ii}),Object.freeze(e),t&&Object.values(e).forEach(r=>oc(r,!0))),e}function yO(){ct(2)}var ii={value:yO};function Ia(e){return e===null||typeof e!="object"?!0:Object.isFrozen(e)}var gO={};function yr(e){const t=gO[e];return t||ct(0,e),t}var hn;function Rm(){return hn}function bO(e,t){return{drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function yd(e,t){t&&(yr("Patches"),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Ju(e){el(e),e.drafts_.forEach(wO),e.drafts_=null}function el(e){e===hn&&(hn=e.parent_)}function gd(e){return hn=bO(hn,e)}function wO(e){const t=e[Qe];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function bd(e,t){t.unfinalizedDrafts_=t.drafts_.length;const r=t.drafts_[0];return e!==void 0&&e!==r?(r[Qe].modified_&&(Ju(t),ct(4)),mr(e)&&(e=$i(t,e),t.parent_||Ri(t,e)),t.patches_&&yr("Patches").generateReplacementPatches_(r[Qe].base_,e,t.patches_,t.inversePatches_)):e=$i(t,r,[]),Ju(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e!==Dm?e:void 0}function $i(e,t,r){if(Ia(t))return t;const n=e.immer_.shouldUseStrictIteration(),i=t[Qe];if(!i)return Ni(t,(a,o)=>wd(e,i,t,a,o,r),n),t;if(i.scope_!==e)return t;if(!i.modified_)return Ri(e,i.base_,!0),i.base_;if(!i.finalized_){i.finalized_=!0,i.scope_.unfinalizedDrafts_--;const a=i.copy_;let o=a,u=!1;i.type_===3&&(o=new Set(a),a.clear(),u=!0),Ni(o,(l,s)=>wd(e,i,a,l,s,r,u),n),Ri(e,a,!1),r&&e.patches_&&yr("Patches").generatePatches_(i,r,e.patches_,e.inversePatches_)}return i.copy_}function wd(e,t,r,n,i,a,o){if(i==null||typeof i!="object"&&!o)return;const u=Ia(i);if(!(u&&!o)){if(Nr(i)){const l=a&&t&&t.type_!==3&&!Zu(t.assigned_,n)?a.concat(n):void 0,s=$i(e,i,l);if($m(r,n,s),Nr(s))e.canAutoFreeze_=!1;else return}else o&&r.add(i);if(mr(i)&&!u){if(!e.immer_.autoFreeze_&&e.unfinalizedDrafts_<1||t&&t.base_&&t.base_[n]===i&&u)return;$i(e,i),(!t||!t.scope_.parent_)&&typeof n!="symbol"&&(Mn(r)?r.has(n):Object.prototype.propertyIsEnumerable.call(r,n))&&Ri(e,i)}}}function Ri(e,t,r=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&oc(t,r)}function xO(e,t){const r=Array.isArray(e),n={type_:r?1:0,scope_:t?t.scope_:Rm(),modified_:!1,finalized_:!1,assigned_:{},parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1};let i=n,a=uc;r&&(i=[n],a=pn);const{revoke:o,proxy:u}=Proxy.revocable(i,a);return n.draft_=u,n.revoke_=o,u}var uc={get(e,t){if(t===Qe)return e;const r=or(e);if(!Zu(r,t))return PO(e,r,t);const n=r[t];return e.finalized_||!mr(n)?n:n===tu(e.base_,t)?(ru(e),e.copy_[t]=rl(n,e)):n},has(e,t){return t in or(e)},ownKeys(e){return Reflect.ownKeys(or(e))},set(e,t,r){const n=Lm(or(e),t);if(n?.set)return n.set.call(e.draft_,r),!0;if(!e.modified_){const i=tu(or(e),t),a=i?.[Qe];if(a&&a.base_===r)return e.copy_[t]=r,e.assigned_[t]=!1,!0;if(mO(r,i)&&(r!==void 0||Zu(e.base_,t)))return!0;ru(e),tl(e)}return e.copy_[t]===r&&(r!==void 0||t in e.copy_)||Number.isNaN(r)&&Number.isNaN(e.copy_[t])||(e.copy_[t]=r,e.assigned_[t]=!0),!0},deleteProperty(e,t){return tu(e.base_,t)!==void 0||t in e.base_?(e.assigned_[t]=!1,ru(e),tl(e)):delete e.assigned_[t],e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){const r=or(e),n=Reflect.getOwnPropertyDescriptor(r,t);return n&&{writable:!0,configurable:e.type_!==1||t!=="length",enumerable:n.enumerable,value:r[t]}},defineProperty(){ct(11)},getPrototypeOf(e){return vn(e.base_)},setPrototypeOf(){ct(12)}},pn={};Ni(uc,(e,t)=>{pn[e]=function(){return arguments[0]=arguments[0][0],t.apply(this,arguments)}});pn.deleteProperty=function(e,t){return pn.set.call(this,e,t,void 0)};pn.set=function(e,t,r){return uc.set.call(this,e[0],t,r,e[0])};function tu(e,t){const r=e[Qe];return(r?or(r):e)[t]}function PO(e,t,r){const n=Lm(t,r);return n?"value"in n?n.value:n.get?.call(e.draft_):void 0}function Lm(e,t){if(!(t in e))return;let r=vn(e);for(;r;){const n=Object.getOwnPropertyDescriptor(r,t);if(n)return n;r=vn(r)}}function tl(e){e.modified_||(e.modified_=!0,e.parent_&&tl(e.parent_))}function ru(e){e.copy_||(e.copy_=Qu(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var OO=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!0,this.produce=(t,r,n)=>{if(typeof t=="function"&&typeof r!="function"){const a=r;r=t;const o=this;return function(l=a,...s){return o.produce(l,c=>r.call(this,c,...s))}}typeof r!="function"&&ct(6),n!==void 0&&typeof n!="function"&&ct(7);let i;if(mr(t)){const a=gd(this),o=rl(t,void 0);let u=!0;try{i=r(o),u=!1}finally{u?Ju(a):el(a)}return yd(a,n),bd(i,a)}else if(!t||typeof t!="object"){if(i=r(t),i===void 0&&(i=t),i===Dm&&(i=void 0),this.autoFreeze_&&oc(i,!0),n){const a=[],o=[];yr("Patches").generateReplacementPatches_(t,i,a,o),n(a,o)}return i}else ct(1,t)},this.produceWithPatches=(t,r)=>{if(typeof t=="function")return(o,...u)=>this.produceWithPatches(o,l=>t(l,...u));let n,i;return[this.produce(t,r,(o,u)=>{n=o,i=u}),n,i]},typeof e?.autoFreeze=="boolean"&&this.setAutoFreeze(e.autoFreeze),typeof e?.useStrictShallowCopy=="boolean"&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),typeof e?.useStrictIteration=="boolean"&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){mr(e)||ct(8),Nr(e)&&(e=AO(e));const t=gd(this),r=rl(e,void 0);return r[Qe].isManual_=!0,el(t),r}finishDraft(e,t){const r=e&&e[Qe];(!r||!r.isManual_)&&ct(9);const{scope_:n}=r;return yd(n,t),bd(void 0,n)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let r;for(r=t.length-1;r>=0;r--){const i=t[r];if(i.path.length===0&&i.op==="replace"){e=i.value;break}}r>-1&&(t=t.slice(r+1));const n=yr("Patches").applyPatches_;return Nr(e)?n(e,t):this.produce(e,i=>n(i,t))}};function rl(e,t){const r=Mn(e)?yr("MapSet").proxyMap_(e,t):Ca(e)?yr("MapSet").proxySet_(e,t):xO(e,t);return(t?t.scope_:Rm()).drafts_.push(r),r}function AO(e){return Nr(e)||ct(10,e),zm(e)}function zm(e){if(!mr(e)||Ia(e))return e;const t=e[Qe];let r,n=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,r=Qu(e,t.scope_.immer_.useStrictShallowCopy_),n=t.scope_.immer_.shouldUseStrictIteration()}else r=Qu(e,!0);return Ni(r,(i,a)=>{$m(r,i,zm(a))},n),t&&(t.finalized_=!1),r}var SO=new OO;SO.produce;var EO={settings:{layout:"horizontal",align:"center",verticalAlign:"middle",itemSorter:"value"},size:{width:0,height:0},payload:[]},Bm=qe({name:"legend",initialState:EO,reducers:{setLegendSize(e,t){e.size.width=t.payload.width,e.size.height=t.payload.height},setLegendSettings(e,t){e.settings.align=t.payload.align,e.settings.layout=t.payload.layout,e.settings.verticalAlign=t.payload.verticalAlign,e.settings.itemSorter=t.payload.itemSorter},addLegendPayload:{reducer(e,t){e.payload.push(t.payload)},prepare:re()},replaceLegendPayload:{reducer(e,t){var{prev:r,next:n}=t.payload,i=ft(e).payload.indexOf(r);i>-1&&(e.payload[i]=n)},prepare:re()},removeLegendPayload:{reducer(e,t){var r=ft(e).payload.indexOf(t.payload);r>-1&&e.payload.splice(r,1)},prepare:re()}}}),{setLegendSize:xd,setLegendSettings:_O,addLegendPayload:Fm,replaceLegendPayload:Km,removeLegendPayload:qm}=Bm.actions,kO=Bm.reducer,jO=["contextPayload"];function nl(){return nl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{t(_O(e))},[t,e]),null}function zO(e){var t=ee();return h.useEffect(()=>(t(xd(e)),()=>{t(xd({width:0,height:0}))}),[t,e]),null}function BO(e,t,r,n){return e==="vertical"&&N(t)?{height:t}:e==="horizontal"?{width:r||n}:null}var FO={align:"center",iconSize:14,itemSorter:"value",layout:"horizontal",verticalAlign:"bottom"};function KO(e){var t=pe(e,FO),r=wx(),n=Ob(),i=vO(),{width:a,height:o,wrapperStyle:u,portal:l}=t,[s,c]=Yp([r]),f=ic(),d=ac();if(f==null||d==null)return null;var v=f-(i?.left||0)-(i?.right||0),p=BO(t.layout,o,a,v),y=l?u:$r($r({position:"absolute",width:p?.width||a||"auto",height:p?.height||o||"auto"},RO(u,t,i,f,d,s)),u),m=l??n;if(m==null||r==null)return null;var g=h.createElement("div",{className:"recharts-legend-wrapper",style:y,ref:c},h.createElement(LO,{layout:t.layout,align:t.align,verticalAlign:t.verticalAlign,itemSorter:t.itemSorter}),!l&&h.createElement(zO,{width:s.width,height:s.height}),h.createElement($O,nl({},t,p,{margin:i,chartWidth:f,chartHeight:d,contextPayload:r})));return Nl.createPortal(g,m)}KO.displayName="Legend";function il(){return il=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var{separator:t=" : ",contentStyle:r={},itemStyle:n={},labelStyle:i={},payload:a,formatter:o,itemSorter:u,wrapperClassName:l,labelClassName:s,label:c,labelFormatter:f,accessibilityLayer:d=!1}=e,v=()=>{if(a&&a.length){var b={padding:0,margin:0},O=(u?ha(a,u):a).map((S,_)=>{if(S.type==="none")return null;var I=S.formatter||o||HO,{value:M,name:E}=S,j=M,$=E;if(I){var L=I(M,E,S,_,a);if(Array.isArray(L))[j,$]=L;else if(L!=null)j=L;else return null}var z=nu({display:"block",paddingTop:4,paddingBottom:4,color:S.color||"#000"},n);return h.createElement("li",{className:"recharts-tooltip-item",key:"tooltip-item-".concat(_),style:z},bt($)?h.createElement("span",{className:"recharts-tooltip-item-name"},$):null,bt($)?h.createElement("span",{className:"recharts-tooltip-item-separator"},t):null,h.createElement("span",{className:"recharts-tooltip-item-value"},j),h.createElement("span",{className:"recharts-tooltip-item-unit"},S.unit||""))});return h.createElement("ul",{className:"recharts-tooltip-item-list",style:b},O)}return null},p=nu({margin:0,padding:10,backgroundColor:"#fff",border:"1px solid #ccc",whiteSpace:"nowrap"},r),y=nu({margin:0},i),m=!ae(c),g=m?c:"",x=H("recharts-default-tooltip",l),w=H("recharts-tooltip-label",s);m&&f&&a!==void 0&&a!==null&&(g=f(c,a));var P=d?{role:"status","aria-live":"assertive"}:{};return h.createElement("div",il({className:x,style:p},P),h.createElement("p",{className:w,style:y},h.isValidElement(g)?g:"".concat(g)),v())},Zr="recharts-tooltip-wrapper",GO={visibility:"hidden"};function VO(e){var{coordinate:t,translateX:r,translateY:n}=e;return H(Zr,{["".concat(Zr,"-right")]:N(r)&&t&&N(t.x)&&r>=t.x,["".concat(Zr,"-left")]:N(r)&&t&&N(t.x)&&r=t.y,["".concat(Zr,"-top")]:N(n)&&t&&N(t.y)&&n0?i:0),f=r[n]+i;if(t[n])return o[n]?c:f;var d=l[n];if(d==null)return 0;if(o[n]){var v=c,p=d;return vm?Math.max(c,d):Math.max(f,d)}function XO(e){var{translateX:t,translateY:r,useTranslate3d:n}=e;return{transform:n?"translate3d(".concat(t,"px, ").concat(r,"px, 0)"):"translate(".concat(t,"px, ").concat(r,"px)")}}function ZO(e){var{allowEscapeViewBox:t,coordinate:r,offsetTopLeft:n,position:i,reverseDirection:a,tooltipBox:o,useTranslate3d:u,viewBox:l}=e,s,c,f;return o.height>0&&o.width>0&&r?(c=Ad({allowEscapeViewBox:t,coordinate:r,key:"x",offsetTopLeft:n,position:i,reverseDirection:a,tooltipDimension:o.width,viewBox:l,viewBoxDimension:l.width}),f=Ad({allowEscapeViewBox:t,coordinate:r,key:"y",offsetTopLeft:n,position:i,reverseDirection:a,tooltipDimension:o.height,viewBox:l,viewBoxDimension:l.height}),s=XO({translateX:c,translateY:f,useTranslate3d:u})):s=GO,{cssProperties:s,cssClasses:VO({translateX:c,translateY:f,coordinate:r})}}function Sd(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function ai(e){for(var t=1;t{if(t.key==="Escape"){var r,n,i,a;this.setState({dismissed:!0,dismissedAtCoordinate:{x:(r=(n=this.props.coordinate)===null||n===void 0?void 0:n.x)!==null&&r!==void 0?r:0,y:(i=(a=this.props.coordinate)===null||a===void 0?void 0:a.y)!==null&&i!==void 0?i:0}})}})}componentDidMount(){document.addEventListener("keydown",this.handleKeyDown)}componentWillUnmount(){document.removeEventListener("keydown",this.handleKeyDown)}componentDidUpdate(){var t,r;this.state.dismissed&&(((t=this.props.coordinate)===null||t===void 0?void 0:t.x)!==this.state.dismissedAtCoordinate.x||((r=this.props.coordinate)===null||r===void 0?void 0:r.y)!==this.state.dismissedAtCoordinate.y)&&(this.state.dismissed=!1)}render(){var{active:t,allowEscapeViewBox:r,animationDuration:n,animationEasing:i,children:a,coordinate:o,hasPayload:u,isAnimationActive:l,offset:s,position:c,reverseDirection:f,useTranslate3d:d,viewBox:v,wrapperStyle:p,lastBoundingBox:y,innerRef:m,hasPortalFromProps:g}=this.props,{cssClasses:x,cssProperties:w}=ZO({allowEscapeViewBox:r,coordinate:o,offsetTopLeft:s,position:c,reverseDirection:f,tooltipBox:{height:y.height,width:y.width},useTranslate3d:d,viewBox:v}),P=g?{}:ai(ai({transition:l&&t?"transform ".concat(n,"ms ").concat(i):void 0},w),{},{pointerEvents:"none",visibility:!this.state.dismissed&&t&&u?"visible":"hidden",position:"absolute",top:0,left:0}),b=ai(ai({},P),{},{visibility:!this.state.dismissed&&t&&u?"visible":"hidden"},p);return h.createElement("div",{xmlns:"http://www.w3.org/1999/xhtml",tabIndex:-1,className:x,style:b,ref:m},a)}}var Wm=()=>{var e;return(e=T(t=>t.rootProps.accessibilityLayer))!==null&&e!==void 0?e:!0};function ol(){return ol=Object.assign?Object.assign.bind():function(e){for(var t=1;tse(e.x)&&se(e.y),jd=e=>e.base!=null&&Li(e.base)&&Li(e),Qr=e=>e.x,Jr=e=>e.y,i1=(e,t)=>{if(typeof e=="function")return e;var r="curve".concat(An(e));return(r==="curveMonotone"||r==="curveBump")&&t?kd["".concat(r).concat(t==="vertical"?"Y":"X")]:kd[r]||da},a1=e=>{var{type:t="linear",points:r=[],baseLine:n,layout:i,connectNulls:a=!1}=e,o=i1(t,i),u=a?r.filter(Li):r,l;if(Array.isArray(n)){var s=r.map((v,p)=>_d(_d({},v),{},{base:n[p]}));i==="vertical"?l=Zn().y(Jr).x1(Qr).x0(v=>v.base.x):l=Zn().x(Qr).y1(Jr).y0(v=>v.base.y);var c=l.defined(jd).curve(o),f=a?s.filter(jd):s;return c(f)}i==="vertical"&&N(n)?l=Zn().y(Jr).x1(Qr).x0(n):N(n)?l=Zn().x(Qr).y1(Jr).y0(n):l=yp().x(Qr).y(Jr);var d=l.defined(Li).curve(o);return d(u)},lc=e=>{var{className:t,points:r,path:n,pathRef:i}=e;if((!r||!r.length)&&!n)return null;var a=r&&r.length?a1(e):n;return h.createElement("path",ol({},Ze(e),Ul(e),{className:H("recharts-curve",t),d:a===null?void 0:a,ref:i}))},o1=["x","y","top","left","width","height","className"];function ul(){return ul=Object.assign?Object.assign.bind():function(e){for(var t=1;t"M".concat(e,",").concat(i,"v").concat(n,"M").concat(a,",").concat(t,"h").concat(r),h1=e=>{var{x:t=0,y:r=0,top:n=0,left:i=0,width:a=0,height:o=0,className:u}=e,l=f1(e,o1),s=u1({x:t,y:r,top:n,left:i,width:a,height:o},l);return!N(t)||!N(r)||!N(a)||!N(o)||!N(n)||!N(i)?null:h.createElement("path",ul({},$e(s),{className:H("recharts-cross",u),d:v1(t,r,a,o,n,i)}))};function p1(e,t,r,n){var i=n/2;return{stroke:"none",fill:"#ccc",x:e==="horizontal"?t.x-i:r.left+.5,y:e==="horizontal"?r.top+.5:t.y-i,width:e==="horizontal"?n:r.width-1,height:e==="horizontal"?r.height-1:n}}function Id(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Md(e){for(var t=1;te.replace(/([A-Z])/g,t=>"-".concat(t.toLowerCase())),Um=(e,t,r)=>e.map(n=>"".concat(b1(n)," ").concat(t,"ms ").concat(r)).join(","),w1=(e,t)=>[Object.keys(e),Object.keys(t)].reduce((r,n)=>r.filter(i=>n.includes(i))),mn=(e,t)=>Object.keys(t).reduce((r,n)=>Md(Md({},r),{},{[n]:e(n,t[n])}),{});function Td(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function me(e){for(var t=1;te+(t-e)*r,ll=e=>{var{from:t,to:r}=e;return t!==r},Hm=(e,t,r)=>{var n=mn((i,a)=>{if(ll(a)){var[o,u]=e(a.from,a.to,a.velocity);return me(me({},a),{},{from:o,velocity:u})}return a},t);return r<1?mn((i,a)=>ll(a)?me(me({},a),{},{velocity:zi(a.velocity,n[i].velocity,r),from:zi(a.from,n[i].from,r)}):a,t):Hm(e,n,r-1)};function A1(e,t,r,n,i,a){var o,u=n.reduce((d,v)=>me(me({},d),{},{[v]:{from:e[v],velocity:0,to:t[v]}}),{}),l=()=>mn((d,v)=>v.from,u),s=()=>!Object.values(u).filter(ll).length,c=null,f=d=>{o||(o=d);var v=d-o,p=v/r.dt;u=Hm(r,u,p),i(me(me(me({},e),t),l())),o=d,s()||(c=a.setTimeout(f))};return()=>(c=a.setTimeout(f),()=>{var d;(d=c)===null||d===void 0||d()})}function S1(e,t,r,n,i,a,o){var u=null,l=i.reduce((f,d)=>me(me({},f),{},{[d]:[e[d],t[d]]}),{}),s,c=f=>{s||(s=f);var d=(f-s)/n,v=mn((y,m)=>zi(...m,r(d)),l);if(a(me(me(me({},e),t),v)),d<1)u=o.setTimeout(c);else{var p=mn((y,m)=>zi(...m,r(1)),l);a(me(me(me({},e),t),p))}};return()=>(u=o.setTimeout(c),()=>{var f;(f=u)===null||f===void 0||f()})}const E1=(e,t,r,n,i,a)=>{var o=w1(e,t);return r==null?()=>(i(me(me({},e),t)),()=>{}):r.isStepper===!0?A1(e,t,r,o,i,a):S1(e,t,r,n,o,i,a)};var Bi=1e-4,Ym=(e,t)=>[0,3*e,3*t-6*e,3*e-3*t+1],Gm=(e,t)=>e.map((r,n)=>r*t**n).reduce((r,n)=>r+n),Dd=(e,t)=>r=>{var n=Ym(e,t);return Gm(n,r)},_1=(e,t)=>r=>{var n=Ym(e,t),i=[...n.map((a,o)=>a*o).slice(1),0];return Gm(i,r)},k1=function(){for(var t=arguments.length,r=new Array(t),n=0;nparseFloat(u));return[o[0],o[1],o[2],o[3]]}}}return r.length===4?r:[0,0,1,1]},j1=(e,t,r,n)=>{var i=Dd(e,r),a=Dd(t,n),o=_1(e,r),u=s=>s>1?1:s<0?0:s,l=s=>{for(var c=s>1?1:s,f=c,d=0;d<8;++d){var v=i(f)-c,p=o(f);if(Math.abs(v-c)0&&arguments[0]!==void 0?arguments[0]:{},{stiff:r=100,damping:n=8,dt:i=17}=t,a=(o,u,l)=>{var s=-(o-u)*r,c=l*n,f=l+(s-c)*i/1e3,d=l*i/1e3+o;return Math.abs(d-u){if(typeof e=="string")switch(e){case"ease":case"ease-in-out":case"ease-out":case"ease-in":case"linear":return Nd(e);case"spring":return C1();default:if(e.split("(")[0]==="cubic-bezier")return Nd(e)}return typeof e=="function"?e:null};function M1(e){var t,r=()=>null,n=!1,i=null,a=o=>{if(!n){if(Array.isArray(o)){if(!o.length)return;var u=o,[l,...s]=u;if(typeof l=="number"){i=e.setTimeout(a.bind(null,s),l);return}a(l),i=e.setTimeout(a.bind(null,s));return}typeof o=="string"&&(t=o,r(t)),typeof o=="object"&&(t=o,r(t)),typeof o=="function"&&o()}};return{stop:()=>{n=!0},start:o=>{n=!1,i&&(i(),i=null),a(o)},subscribe:o=>(r=o,()=>{r=()=>null}),getTimeoutController:()=>e}}class T1{setTimeout(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=performance.now(),i=null,a=o=>{o-n>=r?t(o):typeof requestAnimationFrame=="function"&&(i=requestAnimationFrame(a))};return i=requestAnimationFrame(a),()=>{i!=null&&cancelAnimationFrame(i)}}}function D1(){return M1(new T1)}var N1=h.createContext(D1);function $1(e,t){var r=h.useContext(N1);return h.useMemo(()=>t??r(e),[e,t,r])}var R1=()=>!(typeof window<"u"&&window.document&&window.document.createElement&&window.setTimeout),Tn={devToolsEnabled:!1,isSsr:R1()},L1={begin:0,duration:1e3,easing:"ease",isActive:!0,canBegin:!0,onAnimationEnd:()=>{},onAnimationStart:()=>{}},$d={t:0},iu={t:1};function Dn(e){var t=pe(e,L1),{isActive:r,canBegin:n,duration:i,easing:a,begin:o,onAnimationEnd:u,onAnimationStart:l,children:s}=t,c=r==="auto"?!Tn.isSsr:r,f=$1(t.animationId,t.animationManager),[d,v]=h.useState(c?$d:iu),p=h.useRef(null);return h.useEffect(()=>{c||v(iu)},[c]),h.useEffect(()=>{if(!c||!n)return Sn;var y=E1($d,iu,I1(a),i,v,f.getTimeoutController()),m=()=>{p.current=y()};return f.start([l,o,m,i,u]),()=>{f.stop(),p.current&&p.current(),u()}},[c,n,i,a,o,l,u,f]),s(d.t)}function Nn(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"animation-",r=h.useRef(cn(t)),n=h.useRef(e);return n.current!==e&&(r.current=cn(t),n.current=e),r.current}var z1=["radius"],B1=["radius"];function Rd(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Ld(e){for(var t=1;t{var a=Math.min(Math.abs(r)/2,Math.abs(n)/2),o=n>=0?1:-1,u=r>=0?1:-1,l=n>=0&&r>=0||n<0&&r<0?1:0,s;if(a>0&&i instanceof Array){for(var c=[0,0,0,0],f=0,d=4;fa?a:i[f];s="M".concat(e,",").concat(t+o*c[0]),c[0]>0&&(s+="A ".concat(c[0],",").concat(c[0],",0,0,").concat(l,",").concat(e+u*c[0],",").concat(t)),s+="L ".concat(e+r-u*c[1],",").concat(t),c[1]>0&&(s+="A ".concat(c[1],",").concat(c[1],",0,0,").concat(l,`, + `).concat(e+r,",").concat(t+o*c[1])),s+="L ".concat(e+r,",").concat(t+n-o*c[2]),c[2]>0&&(s+="A ".concat(c[2],",").concat(c[2],",0,0,").concat(l,`, + `).concat(e+r-u*c[2],",").concat(t+n)),s+="L ".concat(e+u*c[3],",").concat(t+n),c[3]>0&&(s+="A ".concat(c[3],",").concat(c[3],",0,0,").concat(l,`, + `).concat(e,",").concat(t+n-o*c[3])),s+="Z"}else if(a>0&&i===+i&&i>0){var v=Math.min(a,i);s="M ".concat(e,",").concat(t+o*v,` + A `).concat(v,",").concat(v,",0,0,").concat(l,",").concat(e+u*v,",").concat(t,` + L `).concat(e+r-u*v,",").concat(t,` + A `).concat(v,",").concat(v,",0,0,").concat(l,",").concat(e+r,",").concat(t+o*v,` + L `).concat(e+r,",").concat(t+n-o*v,` + A `).concat(v,",").concat(v,",0,0,").concat(l,",").concat(e+r-u*v,",").concat(t+n,` + L `).concat(e+u*v,",").concat(t+n,` + A `).concat(v,",").concat(v,",0,0,").concat(l,",").concat(e,",").concat(t+n-o*v," Z")}else s="M ".concat(e,",").concat(t," h ").concat(r," v ").concat(n," h ").concat(-r," Z");return s},Fd={x:0,y:0,width:0,height:0,radius:0,isAnimationActive:!1,isUpdateAnimationActive:!1,animationBegin:0,animationDuration:1500,animationEasing:"ease"},Vm=e=>{var t=pe(e,Fd),r=h.useRef(null),[n,i]=h.useState(-1);h.useEffect(()=>{if(r.current&&r.current.getTotalLength)try{var B=r.current.getTotalLength();B&&i(B)}catch{}},[]);var{x:a,y:o,width:u,height:l,radius:s,className:c}=t,{animationEasing:f,animationDuration:d,animationBegin:v,isAnimationActive:p,isUpdateAnimationActive:y}=t,m=h.useRef(u),g=h.useRef(l),x=h.useRef(a),w=h.useRef(o),P=h.useMemo(()=>({x:a,y:o,width:u,height:l,radius:s}),[a,o,u,l,s]),b=Nn(P,"rectangle-");if(a!==+a||o!==+o||u!==+u||l!==+l||u===0||l===0)return null;var O=H("recharts-rectangle",c);if(!y){var S=$e(t),{radius:_}=S,I=zd(S,z1);return h.createElement("path",Fi({},I,{radius:typeof s=="number"?s:void 0,className:O,d:Bd(a,o,u,l,s)}))}var M=m.current,E=g.current,j=x.current,$=w.current,L="0px ".concat(n===-1?1:n,"px"),z="".concat(n,"px 0px"),K=Um(["strokeDasharray"],d,typeof f=="string"?f:Fd.animationEasing);return h.createElement(Dn,{animationId:b,key:b,canBegin:n>0,duration:d,easing:f,isActive:y,begin:v},B=>{var W=ne(M,u,B),R=ne(E,l,B),ke=ne(j,a,B),Te=ne($,o,B);r.current&&(m.current=W,g.current=R,x.current=ke,w.current=Te);var Le;p?B>0?Le={transition:K,strokeDasharray:z}:Le={strokeDasharray:L}:Le={strokeDasharray:z};var Pt=$e(t),{radius:Je}=Pt,nr=zd(Pt,B1);return h.createElement("path",Fi({},nr,{radius:typeof s=="number"?s:void 0,className:O,d:Bd(ke,Te,W,R,s),ref:r,style:Ld(Ld({},Le),t.style)}))})};function Kd(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function qd(e){for(var t=1;te*180/Math.PI,de=(e,t,r,n)=>({x:e+Math.cos(-Ki*n)*r,y:t+Math.sin(-Ki*n)*r}),Xm=function(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{top:0,right:0,bottom:0,left:0};return Math.min(Math.abs(t-(n.left||0)-(n.right||0)),Math.abs(r-(n.top||0)-(n.bottom||0)))/2},V1=(e,t)=>{var{x:r,y:n}=e,{x:i,y:a}=t;return Math.sqrt((r-i)**2+(n-a)**2)},X1=(e,t)=>{var{x:r,y:n}=e,{cx:i,cy:a}=t,o=V1({x:r,y:n},{x:i,y:a});if(o<=0)return{radius:o,angle:0};var u=(r-i)/o,l=Math.acos(u);return n>a&&(l=2*Math.PI-l),{radius:o,angle:G1(l),angleInRadian:l}},Z1=e=>{var{startAngle:t,endAngle:r}=e,n=Math.floor(t/360),i=Math.floor(r/360),a=Math.min(n,i);return{startAngle:t-a*360,endAngle:r-a*360}},Q1=(e,t)=>{var{startAngle:r,endAngle:n}=t,i=Math.floor(r/360),a=Math.floor(n/360),o=Math.min(i,a);return e+o*360},J1=(e,t)=>{var{chartX:r,chartY:n}=e,{radius:i,angle:a}=X1({x:r,y:n},t),{innerRadius:o,outerRadius:u}=t;if(iu||i===0)return null;var{startAngle:l,endAngle:s}=Z1(t),c=a,f;if(l<=s){for(;c>s;)c-=360;for(;c=l&&c<=s}else{for(;c>l;)c-=360;for(;c=s&&c<=l}return f?qd(qd({},t),{},{radius:i,angle:Q1(c,t)}):null};function Zm(e){var{cx:t,cy:r,radius:n,startAngle:i,endAngle:a}=e,o=de(t,r,n,i),u=de(t,r,n,a);return{points:[o,u],cx:t,cy:r,radius:n,startAngle:i,endAngle:a}}function cl(){return cl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var r=Ae(t-e),n=Math.min(Math.abs(t-e),359.999);return r*n},oi=e=>{var{cx:t,cy:r,radius:n,angle:i,sign:a,isExternal:o,cornerRadius:u,cornerIsExternal:l}=e,s=u*(o?1:-1)+n,c=Math.asin(u/s)/Ki,f=l?i:i+a*c,d=de(t,r,s,f),v=de(t,r,n,f),p=l?i-a*c:i,y=de(t,r,s*Math.cos(c*Ki),p);return{center:d,circleTangency:v,lineTangency:y,theta:c}},Qm=e=>{var{cx:t,cy:r,innerRadius:n,outerRadius:i,startAngle:a,endAngle:o}=e,u=eA(a,o),l=a+u,s=de(t,r,i,a),c=de(t,r,i,l),f="M ".concat(s.x,",").concat(s.y,` + A `).concat(i,",").concat(i,`,0, + `).concat(+(Math.abs(u)>180),",").concat(+(a>l),`, + `).concat(c.x,",").concat(c.y,` + `);if(n>0){var d=de(t,r,n,a),v=de(t,r,n,l);f+="L ".concat(v.x,",").concat(v.y,` + A `).concat(n,",").concat(n,`,0, + `).concat(+(Math.abs(u)>180),",").concat(+(a<=l),`, + `).concat(d.x,",").concat(d.y," Z")}else f+="L ".concat(t,",").concat(r," Z");return f},tA=e=>{var{cx:t,cy:r,innerRadius:n,outerRadius:i,cornerRadius:a,forceCornerRadius:o,cornerIsExternal:u,startAngle:l,endAngle:s}=e,c=Ae(s-l),{circleTangency:f,lineTangency:d,theta:v}=oi({cx:t,cy:r,radius:i,angle:l,sign:c,cornerRadius:a,cornerIsExternal:u}),{circleTangency:p,lineTangency:y,theta:m}=oi({cx:t,cy:r,radius:i,angle:s,sign:-c,cornerRadius:a,cornerIsExternal:u}),g=u?Math.abs(l-s):Math.abs(l-s)-v-m;if(g<0)return o?"M ".concat(d.x,",").concat(d.y,` + a`).concat(a,",").concat(a,",0,0,1,").concat(a*2,`,0 + a`).concat(a,",").concat(a,",0,0,1,").concat(-a*2,`,0 + `):Qm({cx:t,cy:r,innerRadius:n,outerRadius:i,startAngle:l,endAngle:s});var x="M ".concat(d.x,",").concat(d.y,` + A`).concat(a,",").concat(a,",0,0,").concat(+(c<0),",").concat(f.x,",").concat(f.y,` + A`).concat(i,",").concat(i,",0,").concat(+(g>180),",").concat(+(c<0),",").concat(p.x,",").concat(p.y,` + A`).concat(a,",").concat(a,",0,0,").concat(+(c<0),",").concat(y.x,",").concat(y.y,` + `);if(n>0){var{circleTangency:w,lineTangency:P,theta:b}=oi({cx:t,cy:r,radius:n,angle:l,sign:c,isExternal:!0,cornerRadius:a,cornerIsExternal:u}),{circleTangency:O,lineTangency:S,theta:_}=oi({cx:t,cy:r,radius:n,angle:s,sign:-c,isExternal:!0,cornerRadius:a,cornerIsExternal:u}),I=u?Math.abs(l-s):Math.abs(l-s)-b-_;if(I<0&&a===0)return"".concat(x,"L").concat(t,",").concat(r,"Z");x+="L".concat(S.x,",").concat(S.y,` + A`).concat(a,",").concat(a,",0,0,").concat(+(c<0),",").concat(O.x,",").concat(O.y,` + A`).concat(n,",").concat(n,",0,").concat(+(I>180),",").concat(+(c>0),",").concat(w.x,",").concat(w.y,` + A`).concat(a,",").concat(a,",0,0,").concat(+(c<0),",").concat(P.x,",").concat(P.y,"Z")}else x+="L".concat(t,",").concat(r,"Z");return x},rA={cx:0,cy:0,innerRadius:0,outerRadius:0,startAngle:0,endAngle:0,cornerRadius:0,forceCornerRadius:!1,cornerIsExternal:!1},Jm=e=>{var t=pe(e,rA),{cx:r,cy:n,innerRadius:i,outerRadius:a,cornerRadius:o,forceCornerRadius:u,cornerIsExternal:l,startAngle:s,endAngle:c,className:f}=t;if(a0&&Math.abs(s-c)<360?y=tA({cx:r,cy:n,innerRadius:i,outerRadius:a,cornerRadius:Math.min(p,v/2),forceCornerRadius:u,cornerIsExternal:l,startAngle:s,endAngle:c}):y=Qm({cx:r,cy:n,innerRadius:i,outerRadius:a,startAngle:s,endAngle:c}),h.createElement("path",cl({},$e(t),{className:d,d:y}))};function nA(e,t,r){if(e==="horizontal")return[{x:t.x,y:r.top},{x:t.x,y:r.top+r.height}];if(e==="vertical")return[{x:r.left,y:t.y},{x:r.left+r.width,y:t.y}];if(Mp(t)){if(e==="centric"){var{cx:n,cy:i,innerRadius:a,outerRadius:o,angle:u}=t,l=de(n,i,a,u),s=de(n,i,o,u);return[{x:l.x,y:l.y},{x:s.x,y:s.y}]}return Zm(t)}}var au={},ou={},uu={},Wd;function iA(){return Wd||(Wd=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Wp();function r(n){return t.isSymbol(n)?NaN:Number(n)}e.toNumber=r})(uu)),uu}var Ud;function aA(){return Ud||(Ud=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=iA();function r(n){return n?(n=t.toNumber(n),n===1/0||n===-1/0?(n<0?-1:1)*Number.MAX_VALUE:n===n?n:0):n===0?n:0}e.toFinite=r})(ou)),ou}var Hd;function oA(){return Hd||(Hd=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=Up(),r=aA();function n(i,a,o){o&&typeof o!="number"&&t.isIterateeCall(i,a,o)&&(a=o=void 0),i=r.toFinite(i),a===void 0?(a=i,i=0):a=r.toFinite(a),o=o===void 0?it?1:e>=t?0:NaN}function cA(e,t){return e==null||t==null?NaN:te?1:t>=e?0:NaN}function cc(e){let t,r,n;e.length!==2?(t=Ht,r=(u,l)=>Ht(e(u),l),n=(u,l)=>e(u)-l):(t=e===Ht||e===cA?e:sA,r=e,n=e);function i(u,l,s=0,c=u.length){if(s>>1;r(u[f],l)<0?s=f+1:c=f}while(s>>1;r(u[f],l)<=0?s=f+1:c=f}while(ss&&n(u[f-1],l)>-n(u[f],l)?f-1:f}return{left:i,center:o,right:a}}function sA(){return 0}function ty(e){return e===null?NaN:+e}function*fA(e,t){for(let r of e)r!=null&&(r=+r)>=r&&(yield r)}const dA=cc(Ht),$n=dA.right;cc(ty).center;class Gd extends Map{constructor(t,r=pA){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),t!=null)for(const[n,i]of t)this.set(n,i)}get(t){return super.get(Vd(this,t))}has(t){return super.has(Vd(this,t))}set(t,r){return super.set(vA(this,t),r)}delete(t){return super.delete(hA(this,t))}}function Vd({_intern:e,_key:t},r){const n=t(r);return e.has(n)?e.get(n):r}function vA({_intern:e,_key:t},r){const n=t(r);return e.has(n)?e.get(n):(e.set(n,r),r)}function hA({_intern:e,_key:t},r){const n=t(r);return e.has(n)&&(r=e.get(n),e.delete(n)),r}function pA(e){return e!==null&&typeof e=="object"?e.valueOf():e}function mA(e=Ht){if(e===Ht)return ry;if(typeof e!="function")throw new TypeError("compare is not a function");return(t,r)=>{const n=e(t,r);return n||n===0?n:(e(r,r)===0)-(e(t,t)===0)}}function ry(e,t){return(e==null||!(e>=e))-(t==null||!(t>=t))||(et?1:0)}const yA=Math.sqrt(50),gA=Math.sqrt(10),bA=Math.sqrt(2);function qi(e,t,r){const n=(t-e)/Math.max(0,r),i=Math.floor(Math.log10(n)),a=n/Math.pow(10,i),o=a>=yA?10:a>=gA?5:a>=bA?2:1;let u,l,s;return i<0?(s=Math.pow(10,-i)/o,u=Math.round(e*s),l=Math.round(t*s),u/st&&--l,s=-s):(s=Math.pow(10,i)*o,u=Math.round(e/s),l=Math.round(t/s),u*st&&--l),l0))return[];if(e===t)return[e];const n=t=i))return[];const u=a-i+1,l=new Array(u);if(n)if(o<0)for(let s=0;s=n)&&(r=n);return r}function Zd(e,t){let r;for(const n of e)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);return r}function ny(e,t,r=0,n=1/0,i){if(t=Math.floor(t),r=Math.floor(Math.max(0,r)),n=Math.floor(Math.min(e.length-1,n)),!(r<=t&&t<=n))return e;for(i=i===void 0?ry:mA(i);n>r;){if(n-r>600){const l=n-r+1,s=t-r+1,c=Math.log(l),f=.5*Math.exp(2*c/3),d=.5*Math.sqrt(c*f*(l-f)/l)*(s-l/2<0?-1:1),v=Math.max(r,Math.floor(t-s*f/l+d)),p=Math.min(n,Math.floor(t+(l-s)*f/l+d));ny(e,t,v,p,i)}const a=e[t];let o=r,u=n;for(en(e,r,t),i(e[n],a)>0&&en(e,r,n);o0;)--u}i(e[r],a)===0?en(e,r,u):(++u,en(e,u,n)),u<=t&&(r=u+1),t<=u&&(n=u-1)}return e}function en(e,t,r){const n=e[t];e[t]=e[r],e[r]=n}function wA(e,t,r){if(e=Float64Array.from(fA(e)),!(!(n=e.length)||isNaN(t=+t))){if(t<=0||n<2)return Zd(e);if(t>=1)return Xd(e);var n,i=(n-1)*t,a=Math.floor(i),o=Xd(ny(e,a).subarray(0,a+1)),u=Zd(e.subarray(a+1));return o+(u-o)*(i-a)}}function xA(e,t,r=ty){if(!(!(n=e.length)||isNaN(t=+t))){if(t<=0||n<2)return+r(e[0],0,e);if(t>=1)return+r(e[n-1],n-1,e);var n,i=(n-1)*t,a=Math.floor(i),o=+r(e[a],a,e),u=+r(e[a+1],a+1,e);return o+(u-o)*(i-a)}}function PA(e,t,r){e=+e,t=+t,r=(i=arguments.length)<2?(t=e,e=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((t-e)/r))|0,a=new Array(i);++n>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):r===8?ui(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):r===4?ui(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=SA.exec(e))?new Ke(t[1],t[2],t[3],1):(t=EA.exec(e))?new Ke(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=_A.exec(e))?ui(t[1],t[2],t[3],t[4]):(t=kA.exec(e))?ui(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=jA.exec(e))?iv(t[1],t[2]/100,t[3]/100,1):(t=CA.exec(e))?iv(t[1],t[2]/100,t[3]/100,t[4]):Qd.hasOwnProperty(e)?tv(Qd[e]):e==="transparent"?new Ke(NaN,NaN,NaN,0):null}function tv(e){return new Ke(e>>16&255,e>>8&255,e&255,1)}function ui(e,t,r,n){return n<=0&&(e=t=r=NaN),new Ke(e,t,r,n)}function TA(e){return e instanceof Rn||(e=bn(e)),e?(e=e.rgb(),new Ke(e.r,e.g,e.b,e.opacity)):new Ke}function hl(e,t,r,n){return arguments.length===1?TA(e):new Ke(e,t,r,n??1)}function Ke(e,t,r,n){this.r=+e,this.g=+t,this.b=+r,this.opacity=+n}dc(Ke,hl,ay(Rn,{brighter(e){return e=e==null?Wi:Math.pow(Wi,e),new Ke(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?yn:Math.pow(yn,e),new Ke(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new Ke(dr(this.r),dr(this.g),dr(this.b),Ui(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:rv,formatHex:rv,formatHex8:DA,formatRgb:nv,toString:nv}));function rv(){return`#${lr(this.r)}${lr(this.g)}${lr(this.b)}`}function DA(){return`#${lr(this.r)}${lr(this.g)}${lr(this.b)}${lr((isNaN(this.opacity)?1:this.opacity)*255)}`}function nv(){const e=Ui(this.opacity);return`${e===1?"rgb(":"rgba("}${dr(this.r)}, ${dr(this.g)}, ${dr(this.b)}${e===1?")":`, ${e})`}`}function Ui(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function dr(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function lr(e){return e=dr(e),(e<16?"0":"")+e.toString(16)}function iv(e,t,r,n){return n<=0?e=t=r=NaN:r<=0||r>=1?e=t=NaN:t<=0&&(e=NaN),new st(e,t,r,n)}function oy(e){if(e instanceof st)return new st(e.h,e.s,e.l,e.opacity);if(e instanceof Rn||(e=bn(e)),!e)return new st;if(e instanceof st)return e;e=e.rgb();var t=e.r/255,r=e.g/255,n=e.b/255,i=Math.min(t,r,n),a=Math.max(t,r,n),o=NaN,u=a-i,l=(a+i)/2;return u?(t===a?o=(r-n)/u+(r0&&l<1?0:o,new st(o,u,l,e.opacity)}function NA(e,t,r,n){return arguments.length===1?oy(e):new st(e,t,r,n??1)}function st(e,t,r,n){this.h=+e,this.s=+t,this.l=+r,this.opacity=+n}dc(st,NA,ay(Rn,{brighter(e){return e=e==null?Wi:Math.pow(Wi,e),new st(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?yn:Math.pow(yn,e),new st(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*t,i=2*r-n;return new Ke(cu(e>=240?e-240:e+120,i,n),cu(e,i,n),cu(e<120?e+240:e-120,i,n),this.opacity)},clamp(){return new st(av(this.h),li(this.s),li(this.l),Ui(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Ui(this.opacity);return`${e===1?"hsl(":"hsla("}${av(this.h)}, ${li(this.s)*100}%, ${li(this.l)*100}%${e===1?")":`, ${e})`}`}}));function av(e){return e=(e||0)%360,e<0?e+360:e}function li(e){return Math.max(0,Math.min(1,e||0))}function cu(e,t,r){return(e<60?t+(r-t)*e/60:e<180?r:e<240?t+(r-t)*(240-e)/60:t)*255}const vc=e=>()=>e;function $A(e,t){return function(r){return e+r*t}}function RA(e,t,r){return e=Math.pow(e,r),t=Math.pow(t,r)-e,r=1/r,function(n){return Math.pow(e+n*t,r)}}function LA(e){return(e=+e)==1?uy:function(t,r){return r-t?RA(t,r,e):vc(isNaN(t)?r:t)}}function uy(e,t){var r=t-e;return r?$A(e,r):vc(isNaN(e)?t:e)}const ov=(function e(t){var r=LA(t);function n(i,a){var o=r((i=hl(i)).r,(a=hl(a)).r),u=r(i.g,a.g),l=r(i.b,a.b),s=uy(i.opacity,a.opacity);return function(c){return i.r=o(c),i.g=u(c),i.b=l(c),i.opacity=s(c),i+""}}return n.gamma=e,n})(1);function zA(e,t){t||(t=[]);var r=e?Math.min(t.length,e.length):0,n=t.slice(),i;return function(a){for(i=0;ir&&(a=t.slice(r,a),u[o]?u[o]+=a:u[++o]=a),(n=n[0])===(i=i[0])?u[o]?u[o]+=i:u[++o]=i:(u[++o]=null,l.push({i:o,x:pt(n,i)})),r=su.lastIndex;return r180?c+=360:c-s>180&&(s+=360),d.push({i:f.push(i(f)+"rotate(",null,n)-2,x:pt(s,c)})):c&&f.push(i(f)+"rotate("+c+n)}function u(s,c,f,d){s!==c?d.push({i:f.push(i(f)+"skewX(",null,n)-2,x:pt(s,c)}):c&&f.push(i(f)+"skewX("+c+n)}function l(s,c,f,d,v,p){if(s!==f||c!==d){var y=v.push(i(v)+"scale(",null,",",null,")");p.push({i:y-4,x:pt(s,f)},{i:y-2,x:pt(c,d)})}else(f!==1||d!==1)&&v.push(i(v)+"scale("+f+","+d+")")}return function(s,c){var f=[],d=[];return s=e(s),c=e(c),a(s.translateX,s.translateY,c.translateX,c.translateY,f,d),o(s.rotate,c.rotate,f,d),u(s.skewX,c.skewX,f,d),l(s.scaleX,s.scaleY,c.scaleX,c.scaleY,f,d),s=c=null,function(v){for(var p=-1,y=d.length,m;++pt&&(r=e,e=t,t=r),function(n){return Math.max(e,Math.min(t,n))}}function tS(e,t,r){var n=e[0],i=e[1],a=t[0],o=t[1];return i2?rS:tS,l=s=null,f}function f(d){return d==null||isNaN(d=+d)?a:(l||(l=u(e.map(n),t,r)))(n(o(d)))}return f.invert=function(d){return o(i((s||(s=u(t,e.map(n),pt)))(d)))},f.domain=function(d){return arguments.length?(e=Array.from(d,Hi),c()):e.slice()},f.range=function(d){return arguments.length?(t=Array.from(d),c()):t.slice()},f.rangeRound=function(d){return t=Array.from(d),r=hc,c()},f.clamp=function(d){return arguments.length?(o=d?!0:Ne,c()):o!==Ne},f.interpolate=function(d){return arguments.length?(r=d,c()):r},f.unknown=function(d){return arguments.length?(a=d,f):a},function(d,v){return n=d,i=v,c()}}function pc(){return Ma()(Ne,Ne)}function nS(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function Yi(e,t){if((r=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var r,n=e.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+e.slice(r+1)]}function Rr(e){return e=Yi(Math.abs(e)),e?e[1]:NaN}function iS(e,t){return function(r,n){for(var i=r.length,a=[],o=0,u=e[0],l=0;i>0&&u>0&&(l+u+1>n&&(u=Math.max(1,n-l)),a.push(r.substring(i-=u,i+u)),!((l+=u+1)>n));)u=e[o=(o+1)%e.length];return a.reverse().join(t)}}function aS(e){return function(t){return t.replace(/[0-9]/g,function(r){return e[+r]})}}var oS=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function wn(e){if(!(t=oS.exec(e)))throw new Error("invalid format: "+e);var t;return new mc({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}wn.prototype=mc.prototype;function mc(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}mc.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function uS(e){e:for(var t=e.length,r=1,n=-1,i;r0&&(n=0);break}return n>0?e.slice(0,n)+e.slice(i+1):e}var sy;function lS(e,t){var r=Yi(e,t);if(!r)return e+"";var n=r[0],i=r[1],a=i-(sy=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,o=n.length;return a===o?n:a>o?n+new Array(a-o+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+Yi(e,Math.max(0,t+a-1))[0]}function sv(e,t){var r=Yi(e,t);if(!r)return e+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}const fv={"%":(e,t)=>(e*100).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:nS,e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>sv(e*100,t),r:sv,s:lS,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function dv(e){return e}var vv=Array.prototype.map,hv=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function cS(e){var t=e.grouping===void 0||e.thousands===void 0?dv:iS(vv.call(e.grouping,Number),e.thousands+""),r=e.currency===void 0?"":e.currency[0]+"",n=e.currency===void 0?"":e.currency[1]+"",i=e.decimal===void 0?".":e.decimal+"",a=e.numerals===void 0?dv:aS(vv.call(e.numerals,String)),o=e.percent===void 0?"%":e.percent+"",u=e.minus===void 0?"−":e.minus+"",l=e.nan===void 0?"NaN":e.nan+"";function s(f){f=wn(f);var d=f.fill,v=f.align,p=f.sign,y=f.symbol,m=f.zero,g=f.width,x=f.comma,w=f.precision,P=f.trim,b=f.type;b==="n"?(x=!0,b="g"):fv[b]||(w===void 0&&(w=12),P=!0,b="g"),(m||d==="0"&&v==="=")&&(m=!0,d="0",v="=");var O=y==="$"?r:y==="#"&&/[boxX]/.test(b)?"0"+b.toLowerCase():"",S=y==="$"?n:/[%p]/.test(b)?o:"",_=fv[b],I=/[defgprs%]/.test(b);w=w===void 0?6:/[gprs]/.test(b)?Math.max(1,Math.min(21,w)):Math.max(0,Math.min(20,w));function M(E){var j=O,$=S,L,z,K;if(b==="c")$=_(E)+$,E="";else{E=+E;var B=E<0||1/E<0;if(E=isNaN(E)?l:_(Math.abs(E),w),P&&(E=uS(E)),B&&+E==0&&p!=="+"&&(B=!1),j=(B?p==="("?p:u:p==="-"||p==="("?"":p)+j,$=(b==="s"?hv[8+sy/3]:"")+$+(B&&p==="("?")":""),I){for(L=-1,z=E.length;++LK||K>57){$=(K===46?i+E.slice(L+1):E.slice(L))+$,E=E.slice(0,L);break}}}x&&!m&&(E=t(E,1/0));var W=j.length+E.length+$.length,R=W>1)+j+E+$+R.slice(W);break;default:E=R+j+E+$;break}return a(E)}return M.toString=function(){return f+""},M}function c(f,d){var v=s((f=wn(f),f.type="f",f)),p=Math.max(-8,Math.min(8,Math.floor(Rr(d)/3)))*3,y=Math.pow(10,-p),m=hv[8+p/3];return function(g){return v(y*g)+m}}return{format:s,formatPrefix:c}}var si,yc,fy;sS({thousands:",",grouping:[3],currency:["$",""]});function sS(e){return si=cS(e),yc=si.format,fy=si.formatPrefix,si}function fS(e){return Math.max(0,-Rr(Math.abs(e)))}function dS(e,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Rr(t)/3)))*3-Rr(Math.abs(e)))}function vS(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,Rr(t)-Rr(e))+1}function dy(e,t,r,n){var i=dl(e,t,r),a;switch(n=wn(n??",f"),n.type){case"s":{var o=Math.max(Math.abs(e),Math.abs(t));return n.precision==null&&!isNaN(a=dS(i,o))&&(n.precision=a),fy(n,o)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=vS(i,Math.max(Math.abs(e),Math.abs(t))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=fS(i))&&(n.precision=a-(n.type==="%")*2);break}}return yc(n)}function er(e){var t=e.domain;return e.ticks=function(r){var n=t();return sl(n[0],n[n.length-1],r??10)},e.tickFormat=function(r,n){var i=t();return dy(i[0],i[i.length-1],r??10,n)},e.nice=function(r){r==null&&(r=10);var n=t(),i=0,a=n.length-1,o=n[i],u=n[a],l,s,c=10;for(u0;){if(s=fl(o,u,r),s===l)return n[i]=o,n[a]=u,t(n);if(s>0)o=Math.floor(o/s)*s,u=Math.ceil(u/s)*s;else if(s<0)o=Math.ceil(o*s)/s,u=Math.floor(u*s)/s;else break;l=s}return e},e}function vy(){var e=pc();return e.copy=function(){return Ln(e,vy())},ut.apply(e,arguments),er(e)}function hy(e){var t;function r(n){return n==null||isNaN(n=+n)?t:n}return r.invert=r,r.domain=r.range=function(n){return arguments.length?(e=Array.from(n,Hi),r):e.slice()},r.unknown=function(n){return arguments.length?(t=n,r):t},r.copy=function(){return hy(e).unknown(t)},e=arguments.length?Array.from(e,Hi):[0,1],er(r)}function py(e,t){e=e.slice();var r=0,n=e.length-1,i=e[r],a=e[n],o;return aMath.pow(e,t)}function gS(e){return e===Math.E?Math.log:e===10&&Math.log10||e===2&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}function yv(e){return(t,r)=>-e(-t,r)}function gc(e){const t=e(pv,mv),r=t.domain;let n=10,i,a;function o(){return i=gS(n),a=yS(n),r()[0]<0?(i=yv(i),a=yv(a),e(hS,pS)):e(pv,mv),t}return t.base=function(u){return arguments.length?(n=+u,o()):n},t.domain=function(u){return arguments.length?(r(u),o()):r()},t.ticks=u=>{const l=r();let s=l[0],c=l[l.length-1];const f=c0){for(;d<=v;++d)for(p=1;pc)break;g.push(y)}}else for(;d<=v;++d)for(p=n-1;p>=1;--p)if(y=d>0?p/a(-d):p*a(d),!(yc)break;g.push(y)}g.length*2{if(u==null&&(u=10),l==null&&(l=n===10?"s":","),typeof l!="function"&&(!(n%1)&&(l=wn(l)).precision==null&&(l.trim=!0),l=yc(l)),u===1/0)return l;const s=Math.max(1,n*u/t.ticks().length);return c=>{let f=c/a(Math.round(i(c)));return f*nr(py(r(),{floor:u=>a(Math.floor(i(u))),ceil:u=>a(Math.ceil(i(u)))})),t}function my(){const e=gc(Ma()).domain([1,10]);return e.copy=()=>Ln(e,my()).base(e.base()),ut.apply(e,arguments),e}function gv(e){return function(t){return Math.sign(t)*Math.log1p(Math.abs(t/e))}}function bv(e){return function(t){return Math.sign(t)*Math.expm1(Math.abs(t))*e}}function bc(e){var t=1,r=e(gv(t),bv(t));return r.constant=function(n){return arguments.length?e(gv(t=+n),bv(t)):t},er(r)}function yy(){var e=bc(Ma());return e.copy=function(){return Ln(e,yy()).constant(e.constant())},ut.apply(e,arguments)}function wv(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function bS(e){return e<0?-Math.sqrt(-e):Math.sqrt(e)}function wS(e){return e<0?-e*e:e*e}function wc(e){var t=e(Ne,Ne),r=1;function n(){return r===1?e(Ne,Ne):r===.5?e(bS,wS):e(wv(r),wv(1/r))}return t.exponent=function(i){return arguments.length?(r=+i,n()):r},er(t)}function xc(){var e=wc(Ma());return e.copy=function(){return Ln(e,xc()).exponent(e.exponent())},ut.apply(e,arguments),e}function xS(){return xc.apply(null,arguments).exponent(.5)}function xv(e){return Math.sign(e)*e*e}function PS(e){return Math.sign(e)*Math.sqrt(Math.abs(e))}function gy(){var e=pc(),t=[0,1],r=!1,n;function i(a){var o=PS(e(a));return isNaN(o)?n:r?Math.round(o):o}return i.invert=function(a){return e.invert(xv(a))},i.domain=function(a){return arguments.length?(e.domain(a),i):e.domain()},i.range=function(a){return arguments.length?(e.range((t=Array.from(a,Hi)).map(xv)),i):t.slice()},i.rangeRound=function(a){return i.range(a).round(!0)},i.round=function(a){return arguments.length?(r=!!a,i):r},i.clamp=function(a){return arguments.length?(e.clamp(a),i):e.clamp()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return gy(e.domain(),t).round(r).clamp(e.clamp()).unknown(n)},ut.apply(i,arguments),er(i)}function by(){var e=[],t=[],r=[],n;function i(){var o=0,u=Math.max(1,t.length);for(r=new Array(u-1);++o0?r[u-1]:e[0],u=r?[n[r-1],t]:[n[s-1],n[s]]},o.unknown=function(l){return arguments.length&&(a=l),o},o.thresholds=function(){return n.slice()},o.copy=function(){return wy().domain([e,t]).range(i).unknown(a)},ut.apply(er(o),arguments)}function xy(){var e=[.5],t=[0,1],r,n=1;function i(a){return a!=null&&a<=a?t[$n(e,a,0,n)]:r}return i.domain=function(a){return arguments.length?(e=Array.from(a),n=Math.min(e.length,t.length-1),i):e.slice()},i.range=function(a){return arguments.length?(t=Array.from(a),n=Math.min(e.length,t.length-1),i):t.slice()},i.invertExtent=function(a){var o=t.indexOf(a);return[e[o-1],e[o]]},i.unknown=function(a){return arguments.length?(r=a,i):r},i.copy=function(){return xy().domain(e).range(t).unknown(r)},ut.apply(i,arguments)}const fu=new Date,du=new Date;function ge(e,t,r,n){function i(a){return e(a=arguments.length===0?new Date:new Date(+a)),a}return i.floor=a=>(e(a=new Date(+a)),a),i.ceil=a=>(e(a=new Date(a-1)),t(a,1),e(a),a),i.round=a=>{const o=i(a),u=i.ceil(a);return a-o(t(a=new Date(+a),o==null?1:Math.floor(o)),a),i.range=(a,o,u)=>{const l=[];if(a=i.ceil(a),u=u==null?1:Math.floor(u),!(a0))return l;let s;do l.push(s=new Date(+a)),t(a,u),e(a);while(sge(o=>{if(o>=o)for(;e(o),!a(o);)o.setTime(o-1)},(o,u)=>{if(o>=o)if(u<0)for(;++u<=0;)for(;t(o,-1),!a(o););else for(;--u>=0;)for(;t(o,1),!a(o););}),r&&(i.count=(a,o)=>(fu.setTime(+a),du.setTime(+o),e(fu),e(du),Math.floor(r(fu,du))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?o=>n(o)%a===0:o=>i.count(0,o)%a===0):i)),i}const Gi=ge(()=>{},(e,t)=>{e.setTime(+e+t)},(e,t)=>t-e);Gi.every=e=>(e=Math.floor(e),!isFinite(e)||!(e>0)?null:e>1?ge(t=>{t.setTime(Math.floor(t/e)*e)},(t,r)=>{t.setTime(+t+r*e)},(t,r)=>(r-t)/e):Gi);Gi.range;const Et=1e3,it=Et*60,_t=it*60,Mt=_t*24,Pc=Mt*7,Pv=Mt*30,vu=Mt*365,cr=ge(e=>{e.setTime(e-e.getMilliseconds())},(e,t)=>{e.setTime(+e+t*Et)},(e,t)=>(t-e)/Et,e=>e.getUTCSeconds());cr.range;const Oc=ge(e=>{e.setTime(e-e.getMilliseconds()-e.getSeconds()*Et)},(e,t)=>{e.setTime(+e+t*it)},(e,t)=>(t-e)/it,e=>e.getMinutes());Oc.range;const Ac=ge(e=>{e.setUTCSeconds(0,0)},(e,t)=>{e.setTime(+e+t*it)},(e,t)=>(t-e)/it,e=>e.getUTCMinutes());Ac.range;const Sc=ge(e=>{e.setTime(e-e.getMilliseconds()-e.getSeconds()*Et-e.getMinutes()*it)},(e,t)=>{e.setTime(+e+t*_t)},(e,t)=>(t-e)/_t,e=>e.getHours());Sc.range;const Ec=ge(e=>{e.setUTCMinutes(0,0,0)},(e,t)=>{e.setTime(+e+t*_t)},(e,t)=>(t-e)/_t,e=>e.getUTCHours());Ec.range;const zn=ge(e=>e.setHours(0,0,0,0),(e,t)=>e.setDate(e.getDate()+t),(e,t)=>(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*it)/Mt,e=>e.getDate()-1);zn.range;const Ta=ge(e=>{e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCDate(e.getUTCDate()+t)},(e,t)=>(t-e)/Mt,e=>e.getUTCDate()-1);Ta.range;const Py=ge(e=>{e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCDate(e.getUTCDate()+t)},(e,t)=>(t-e)/Mt,e=>Math.floor(e/Mt));Py.range;function xr(e){return ge(t=>{t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)},(t,r)=>{t.setDate(t.getDate()+r*7)},(t,r)=>(r-t-(r.getTimezoneOffset()-t.getTimezoneOffset())*it)/Pc)}const Da=xr(0),Vi=xr(1),OS=xr(2),AS=xr(3),Lr=xr(4),SS=xr(5),ES=xr(6);Da.range;Vi.range;OS.range;AS.range;Lr.range;SS.range;ES.range;function Pr(e){return ge(t=>{t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)},(t,r)=>{t.setUTCDate(t.getUTCDate()+r*7)},(t,r)=>(r-t)/Pc)}const Na=Pr(0),Xi=Pr(1),_S=Pr(2),kS=Pr(3),zr=Pr(4),jS=Pr(5),CS=Pr(6);Na.range;Xi.range;_S.range;kS.range;zr.range;jS.range;CS.range;const _c=ge(e=>{e.setDate(1),e.setHours(0,0,0,0)},(e,t)=>{e.setMonth(e.getMonth()+t)},(e,t)=>t.getMonth()-e.getMonth()+(t.getFullYear()-e.getFullYear())*12,e=>e.getMonth());_c.range;const kc=ge(e=>{e.setUTCDate(1),e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCMonth(e.getUTCMonth()+t)},(e,t)=>t.getUTCMonth()-e.getUTCMonth()+(t.getUTCFullYear()-e.getUTCFullYear())*12,e=>e.getUTCMonth());kc.range;const Tt=ge(e=>{e.setMonth(0,1),e.setHours(0,0,0,0)},(e,t)=>{e.setFullYear(e.getFullYear()+t)},(e,t)=>t.getFullYear()-e.getFullYear(),e=>e.getFullYear());Tt.every=e=>!isFinite(e=Math.floor(e))||!(e>0)?null:ge(t=>{t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)},(t,r)=>{t.setFullYear(t.getFullYear()+r*e)});Tt.range;const Dt=ge(e=>{e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCFullYear(e.getUTCFullYear()+t)},(e,t)=>t.getUTCFullYear()-e.getUTCFullYear(),e=>e.getUTCFullYear());Dt.every=e=>!isFinite(e=Math.floor(e))||!(e>0)?null:ge(t=>{t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,r)=>{t.setUTCFullYear(t.getUTCFullYear()+r*e)});Dt.range;function Oy(e,t,r,n,i,a){const o=[[cr,1,Et],[cr,5,5*Et],[cr,15,15*Et],[cr,30,30*Et],[a,1,it],[a,5,5*it],[a,15,15*it],[a,30,30*it],[i,1,_t],[i,3,3*_t],[i,6,6*_t],[i,12,12*_t],[n,1,Mt],[n,2,2*Mt],[r,1,Pc],[t,1,Pv],[t,3,3*Pv],[e,1,vu]];function u(s,c,f){const d=cm).right(o,d);if(v===o.length)return e.every(dl(s/vu,c/vu,f));if(v===0)return Gi.every(Math.max(dl(s,c,f),1));const[p,y]=o[d/o[v-1][2]53)return null;"w"in C||(C.w=1),"Z"in C?(Q=pu(tn(C.y,0,1)),Ue=Q.getUTCDay(),Q=Ue>4||Ue===0?Xi.ceil(Q):Xi(Q),Q=Ta.offset(Q,(C.V-1)*7),C.y=Q.getUTCFullYear(),C.m=Q.getUTCMonth(),C.d=Q.getUTCDate()+(C.w+6)%7):(Q=hu(tn(C.y,0,1)),Ue=Q.getDay(),Q=Ue>4||Ue===0?Vi.ceil(Q):Vi(Q),Q=zn.offset(Q,(C.V-1)*7),C.y=Q.getFullYear(),C.m=Q.getMonth(),C.d=Q.getDate()+(C.w+6)%7)}else("W"in C||"U"in C)&&("w"in C||(C.w="u"in C?C.u%7:"W"in C?1:0),Ue="Z"in C?pu(tn(C.y,0,1)).getUTCDay():hu(tn(C.y,0,1)).getDay(),C.m=0,C.d="W"in C?(C.w+6)%7+C.W*7-(Ue+5)%7:C.w+C.U*7-(Ue+6)%7);return"Z"in C?(C.H+=C.Z/100|0,C.M+=C.Z%100,pu(C)):hu(C)}}function _(k,F,U,C){for(var Be=0,Q=F.length,Ue=U.length,He,ir;Be=Ue)return-1;if(He=F.charCodeAt(Be++),He===37){if(He=F.charAt(Be++),ir=b[He in Ov?F.charAt(Be++):He],!ir||(C=ir(k,U,C))<0)return-1}else if(He!=U.charCodeAt(C++))return-1}return C}function I(k,F,U){var C=s.exec(F.slice(U));return C?(k.p=c.get(C[0].toLowerCase()),U+C[0].length):-1}function M(k,F,U){var C=v.exec(F.slice(U));return C?(k.w=p.get(C[0].toLowerCase()),U+C[0].length):-1}function E(k,F,U){var C=f.exec(F.slice(U));return C?(k.w=d.get(C[0].toLowerCase()),U+C[0].length):-1}function j(k,F,U){var C=g.exec(F.slice(U));return C?(k.m=x.get(C[0].toLowerCase()),U+C[0].length):-1}function $(k,F,U){var C=y.exec(F.slice(U));return C?(k.m=m.get(C[0].toLowerCase()),U+C[0].length):-1}function L(k,F,U){return _(k,t,F,U)}function z(k,F,U){return _(k,r,F,U)}function K(k,F,U){return _(k,n,F,U)}function B(k){return o[k.getDay()]}function W(k){return a[k.getDay()]}function R(k){return l[k.getMonth()]}function ke(k){return u[k.getMonth()]}function Te(k){return i[+(k.getHours()>=12)]}function Le(k){return 1+~~(k.getMonth()/3)}function Pt(k){return o[k.getUTCDay()]}function Je(k){return a[k.getUTCDay()]}function nr(k){return l[k.getUTCMonth()]}function Xr(k){return u[k.getUTCMonth()]}function ze(k){return i[+(k.getUTCHours()>=12)]}function to(k){return 1+~~(k.getUTCMonth()/3)}return{format:function(k){var F=O(k+="",w);return F.toString=function(){return k},F},parse:function(k){var F=S(k+="",!1);return F.toString=function(){return k},F},utcFormat:function(k){var F=O(k+="",P);return F.toString=function(){return k},F},utcParse:function(k){var F=S(k+="",!0);return F.toString=function(){return k},F}}}var Ov={"-":"",_:" ",0:"0"},Ee=/^\s*\d+/,$S=/^%/,RS=/[\\^$*+?|[\]().{}]/g;function Y(e,t,r){var n=e<0?"-":"",i=(n?-e:e)+"",a=i.length;return n+(a[t.toLowerCase(),r]))}function zS(e,t,r){var n=Ee.exec(t.slice(r,r+1));return n?(e.w=+n[0],r+n[0].length):-1}function BS(e,t,r){var n=Ee.exec(t.slice(r,r+1));return n?(e.u=+n[0],r+n[0].length):-1}function FS(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.U=+n[0],r+n[0].length):-1}function KS(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.V=+n[0],r+n[0].length):-1}function qS(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.W=+n[0],r+n[0].length):-1}function Av(e,t,r){var n=Ee.exec(t.slice(r,r+4));return n?(e.y=+n[0],r+n[0].length):-1}function Sv(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function WS(e,t,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(r,r+6));return n?(e.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function US(e,t,r){var n=Ee.exec(t.slice(r,r+1));return n?(e.q=n[0]*3-3,r+n[0].length):-1}function HS(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.m=n[0]-1,r+n[0].length):-1}function Ev(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.d=+n[0],r+n[0].length):-1}function YS(e,t,r){var n=Ee.exec(t.slice(r,r+3));return n?(e.m=0,e.d=+n[0],r+n[0].length):-1}function _v(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.H=+n[0],r+n[0].length):-1}function GS(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.M=+n[0],r+n[0].length):-1}function VS(e,t,r){var n=Ee.exec(t.slice(r,r+2));return n?(e.S=+n[0],r+n[0].length):-1}function XS(e,t,r){var n=Ee.exec(t.slice(r,r+3));return n?(e.L=+n[0],r+n[0].length):-1}function ZS(e,t,r){var n=Ee.exec(t.slice(r,r+6));return n?(e.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function QS(e,t,r){var n=$S.exec(t.slice(r,r+1));return n?r+n[0].length:-1}function JS(e,t,r){var n=Ee.exec(t.slice(r));return n?(e.Q=+n[0],r+n[0].length):-1}function eE(e,t,r){var n=Ee.exec(t.slice(r));return n?(e.s=+n[0],r+n[0].length):-1}function kv(e,t){return Y(e.getDate(),t,2)}function tE(e,t){return Y(e.getHours(),t,2)}function rE(e,t){return Y(e.getHours()%12||12,t,2)}function nE(e,t){return Y(1+zn.count(Tt(e),e),t,3)}function Ay(e,t){return Y(e.getMilliseconds(),t,3)}function iE(e,t){return Ay(e,t)+"000"}function aE(e,t){return Y(e.getMonth()+1,t,2)}function oE(e,t){return Y(e.getMinutes(),t,2)}function uE(e,t){return Y(e.getSeconds(),t,2)}function lE(e){var t=e.getDay();return t===0?7:t}function cE(e,t){return Y(Da.count(Tt(e)-1,e),t,2)}function Sy(e){var t=e.getDay();return t>=4||t===0?Lr(e):Lr.ceil(e)}function sE(e,t){return e=Sy(e),Y(Lr.count(Tt(e),e)+(Tt(e).getDay()===4),t,2)}function fE(e){return e.getDay()}function dE(e,t){return Y(Vi.count(Tt(e)-1,e),t,2)}function vE(e,t){return Y(e.getFullYear()%100,t,2)}function hE(e,t){return e=Sy(e),Y(e.getFullYear()%100,t,2)}function pE(e,t){return Y(e.getFullYear()%1e4,t,4)}function mE(e,t){var r=e.getDay();return e=r>=4||r===0?Lr(e):Lr.ceil(e),Y(e.getFullYear()%1e4,t,4)}function yE(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+Y(t/60|0,"0",2)+Y(t%60,"0",2)}function jv(e,t){return Y(e.getUTCDate(),t,2)}function gE(e,t){return Y(e.getUTCHours(),t,2)}function bE(e,t){return Y(e.getUTCHours()%12||12,t,2)}function wE(e,t){return Y(1+Ta.count(Dt(e),e),t,3)}function Ey(e,t){return Y(e.getUTCMilliseconds(),t,3)}function xE(e,t){return Ey(e,t)+"000"}function PE(e,t){return Y(e.getUTCMonth()+1,t,2)}function OE(e,t){return Y(e.getUTCMinutes(),t,2)}function AE(e,t){return Y(e.getUTCSeconds(),t,2)}function SE(e){var t=e.getUTCDay();return t===0?7:t}function EE(e,t){return Y(Na.count(Dt(e)-1,e),t,2)}function _y(e){var t=e.getUTCDay();return t>=4||t===0?zr(e):zr.ceil(e)}function _E(e,t){return e=_y(e),Y(zr.count(Dt(e),e)+(Dt(e).getUTCDay()===4),t,2)}function kE(e){return e.getUTCDay()}function jE(e,t){return Y(Xi.count(Dt(e)-1,e),t,2)}function CE(e,t){return Y(e.getUTCFullYear()%100,t,2)}function IE(e,t){return e=_y(e),Y(e.getUTCFullYear()%100,t,2)}function ME(e,t){return Y(e.getUTCFullYear()%1e4,t,4)}function TE(e,t){var r=e.getUTCDay();return e=r>=4||r===0?zr(e):zr.ceil(e),Y(e.getUTCFullYear()%1e4,t,4)}function DE(){return"+0000"}function Cv(){return"%"}function Iv(e){return+e}function Mv(e){return Math.floor(+e/1e3)}var Or,ky,jy;NE({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function NE(e){return Or=NS(e),ky=Or.format,Or.parse,jy=Or.utcFormat,Or.utcParse,Or}function $E(e){return new Date(e)}function RE(e){return e instanceof Date?+e:+new Date(+e)}function jc(e,t,r,n,i,a,o,u,l,s){var c=pc(),f=c.invert,d=c.domain,v=s(".%L"),p=s(":%S"),y=s("%I:%M"),m=s("%I %p"),g=s("%a %d"),x=s("%b %d"),w=s("%B"),P=s("%Y");function b(O){return(l(O)t(i/(e.length-1)))},r.quantiles=function(n){return Array.from({length:n+1},(i,a)=>wA(e,a/n))},r.copy=function(){return Ty(t).domain(e)},zt.apply(r,arguments)}function Ra(){var e=0,t=.5,r=1,n=1,i,a,o,u,l,s=Ne,c,f=!1,d;function v(y){return isNaN(y=+y)?d:(y=.5+((y=+c(y))-a)*(n*ye.chartData,Mc=A([rr],e=>{var t=e.chartData!=null?e.chartData.length-1:0;return{chartData:e.chartData,computedData:e.computedData,dataEndIndex:t,dataStartIndex:0}}),La=(e,t,r,n)=>n?Mc(e):rr(e);function Yt(e){if(Array.isArray(e)&&e.length===2){var[t,r]=e;if(se(t)&&se(r))return!0}return!1}function Tv(e,t,r){return r?e:[Math.min(e[0],t[0]),Math.max(e[1],t[1])]}function Ry(e,t){if(t&&typeof e!="function"&&Array.isArray(e)&&e.length===2){var[r,n]=e,i,a;if(se(r))i=r;else if(typeof r=="function")return;if(se(n))a=n;else if(typeof n=="function")return;var o=[i,a];if(Yt(o))return o}}function KE(e,t,r){if(!(!r&&t==null)){if(typeof e=="function"&&t!=null)try{var n=e(t,r);if(Yt(n))return Tv(n,t,r)}catch{}if(Array.isArray(e)&&e.length===2){var[i,a]=e,o,u;if(i==="auto")t!=null&&(o=Math.min(...t));else if(N(i))o=i;else if(typeof i=="function")try{t!=null&&(o=i(t?.[0]))}catch{}else if(typeof i=="string"&&ad.test(i)){var l=ad.exec(i);if(l==null||t==null)o=void 0;else{var s=+l[1];o=t[0]-s}}else o=t?.[0];if(a==="auto")t!=null&&(u=Math.max(...t));else if(N(a))u=a;else if(typeof a=="function")try{t!=null&&(u=a(t?.[1]))}catch{}else if(typeof a=="string"&&od.test(a)){var c=od.exec(a);if(c==null||t==null)u=void 0;else{var f=+c[1];u=t[1]+f}}else u=t?.[1];var d=[o,u];if(Yt(d))return t==null?d:Tv(d,t,r)}}}var Kr=1e9,qE={precision:20,rounding:4,toExpNeg:-7,toExpPos:21,LN10:"2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286"},Dc,ie=!0,ot="[DecimalError] ",vr=ot+"Invalid argument: ",Tc=ot+"Exponent out of range: ",qr=Math.floor,ur=Math.pow,WE=/^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,Ge,Oe=1e7,te=7,Ly=9007199254740991,Zi=qr(Ly/te),D={};D.absoluteValue=D.abs=function(){var e=new this.constructor(this);return e.s&&(e.s=1),e};D.comparedTo=D.cmp=function(e){var t,r,n,i,a=this;if(e=new a.constructor(e),a.s!==e.s)return a.s||-e.s;if(a.e!==e.e)return a.e>e.e^a.s<0?1:-1;for(n=a.d.length,i=e.d.length,t=0,r=ne.d[t]^a.s<0?1:-1;return n===i?0:n>i^a.s<0?1:-1};D.decimalPlaces=D.dp=function(){var e=this,t=e.d.length-1,r=(t-e.e)*te;if(t=e.d[t],t)for(;t%10==0;t/=10)r--;return r<0?0:r};D.dividedBy=D.div=function(e){return kt(this,new this.constructor(e))};D.dividedToIntegerBy=D.idiv=function(e){var t=this,r=t.constructor;return Z(kt(t,new r(e),0,1),r.precision)};D.equals=D.eq=function(e){return!this.cmp(e)};D.exponent=function(){return he(this)};D.greaterThan=D.gt=function(e){return this.cmp(e)>0};D.greaterThanOrEqualTo=D.gte=function(e){return this.cmp(e)>=0};D.isInteger=D.isint=function(){return this.e>this.d.length-2};D.isNegative=D.isneg=function(){return this.s<0};D.isPositive=D.ispos=function(){return this.s>0};D.isZero=function(){return this.s===0};D.lessThan=D.lt=function(e){return this.cmp(e)<0};D.lessThanOrEqualTo=D.lte=function(e){return this.cmp(e)<1};D.logarithm=D.log=function(e){var t,r=this,n=r.constructor,i=n.precision,a=i+5;if(e===void 0)e=new n(10);else if(e=new n(e),e.s<1||e.eq(Ge))throw Error(ot+"NaN");if(r.s<1)throw Error(ot+(r.s?"NaN":"-Infinity"));return r.eq(Ge)?new n(0):(ie=!1,t=kt(xn(r,a),xn(e,a),a),ie=!0,Z(t,i))};D.minus=D.sub=function(e){var t=this;return e=new t.constructor(e),t.s==e.s?Fy(t,e):zy(t,(e.s=-e.s,e))};D.modulo=D.mod=function(e){var t,r=this,n=r.constructor,i=n.precision;if(e=new n(e),!e.s)throw Error(ot+"NaN");return r.s?(ie=!1,t=kt(r,e,0,1).times(e),ie=!0,r.minus(t)):Z(new n(r),i)};D.naturalExponential=D.exp=function(){return By(this)};D.naturalLogarithm=D.ln=function(){return xn(this)};D.negated=D.neg=function(){var e=new this.constructor(this);return e.s=-e.s||0,e};D.plus=D.add=function(e){var t=this;return e=new t.constructor(e),t.s==e.s?zy(t,e):Fy(t,(e.s=-e.s,e))};D.precision=D.sd=function(e){var t,r,n,i=this;if(e!==void 0&&e!==!!e&&e!==1&&e!==0)throw Error(vr+e);if(t=he(i)+1,n=i.d.length-1,r=n*te+1,n=i.d[n],n){for(;n%10==0;n/=10)r--;for(n=i.d[0];n>=10;n/=10)r++}return e&&t>r?t:r};D.squareRoot=D.sqrt=function(){var e,t,r,n,i,a,o,u=this,l=u.constructor;if(u.s<1){if(!u.s)return new l(0);throw Error(ot+"NaN")}for(e=he(u),ie=!1,i=Math.sqrt(+u),i==0||i==1/0?(t=yt(u.d),(t.length+e)%2==0&&(t+="0"),i=Math.sqrt(t),e=qr((e+1)/2)-(e<0||e%2),i==1/0?t="5e"+e:(t=i.toExponential(),t=t.slice(0,t.indexOf("e")+1)+e),n=new l(t)):n=new l(i.toString()),r=l.precision,i=o=r+3;;)if(a=n,n=a.plus(kt(u,a,o+2)).times(.5),yt(a.d).slice(0,o)===(t=yt(n.d)).slice(0,o)){if(t=t.slice(o-3,o+1),i==o&&t=="4999"){if(Z(a,r+1,0),a.times(a).eq(u)){n=a;break}}else if(t!="9999")break;o+=4}return ie=!0,Z(n,r)};D.times=D.mul=function(e){var t,r,n,i,a,o,u,l,s,c=this,f=c.constructor,d=c.d,v=(e=new f(e)).d;if(!c.s||!e.s)return new f(0);for(e.s*=c.s,r=c.e+e.e,l=d.length,s=v.length,l=0;){for(t=0,i=l+n;i>n;)u=a[i]+v[n]*d[i-n-1]+t,a[i--]=u%Oe|0,t=u/Oe|0;a[i]=(a[i]+t)%Oe|0}for(;!a[--o];)a.pop();return t?++r:a.shift(),e.d=a,e.e=r,ie?Z(e,f.precision):e};D.toDecimalPlaces=D.todp=function(e,t){var r=this,n=r.constructor;return r=new n(r),e===void 0?r:(xt(e,0,Kr),t===void 0?t=n.rounding:xt(t,0,8),Z(r,e+he(r)+1,t))};D.toExponential=function(e,t){var r,n=this,i=n.constructor;return e===void 0?r=gr(n,!0):(xt(e,0,Kr),t===void 0?t=i.rounding:xt(t,0,8),n=Z(new i(n),e+1,t),r=gr(n,!0,e+1)),r};D.toFixed=function(e,t){var r,n,i=this,a=i.constructor;return e===void 0?gr(i):(xt(e,0,Kr),t===void 0?t=a.rounding:xt(t,0,8),n=Z(new a(i),e+he(i)+1,t),r=gr(n.abs(),!1,e+he(n)+1),i.isneg()&&!i.isZero()?"-"+r:r)};D.toInteger=D.toint=function(){var e=this,t=e.constructor;return Z(new t(e),he(e)+1,t.rounding)};D.toNumber=function(){return+this};D.toPower=D.pow=function(e){var t,r,n,i,a,o,u=this,l=u.constructor,s=12,c=+(e=new l(e));if(!e.s)return new l(Ge);if(u=new l(u),!u.s){if(e.s<1)throw Error(ot+"Infinity");return u}if(u.eq(Ge))return u;if(n=l.precision,e.eq(Ge))return Z(u,n);if(t=e.e,r=e.d.length-1,o=t>=r,a=u.s,o){if((r=c<0?-c:c)<=Ly){for(i=new l(Ge),t=Math.ceil(n/te+4),ie=!1;r%2&&(i=i.times(u),Nv(i.d,t)),r=qr(r/2),r!==0;)u=u.times(u),Nv(u.d,t);return ie=!0,e.s<0?new l(Ge).div(i):Z(i,n)}}else if(a<0)throw Error(ot+"NaN");return a=a<0&&e.d[Math.max(t,r)]&1?-1:1,u.s=1,ie=!1,i=e.times(xn(u,n+s)),ie=!0,i=By(i),i.s=a,i};D.toPrecision=function(e,t){var r,n,i=this,a=i.constructor;return e===void 0?(r=he(i),n=gr(i,r<=a.toExpNeg||r>=a.toExpPos)):(xt(e,1,Kr),t===void 0?t=a.rounding:xt(t,0,8),i=Z(new a(i),e,t),r=he(i),n=gr(i,e<=r||r<=a.toExpNeg,e)),n};D.toSignificantDigits=D.tosd=function(e,t){var r=this,n=r.constructor;return e===void 0?(e=n.precision,t=n.rounding):(xt(e,1,Kr),t===void 0?t=n.rounding:xt(t,0,8)),Z(new n(r),e,t)};D.toString=D.valueOf=D.val=D.toJSON=D[Symbol.for("nodejs.util.inspect.custom")]=function(){var e=this,t=he(e),r=e.constructor;return gr(e,t<=r.toExpNeg||t>=r.toExpPos)};function zy(e,t){var r,n,i,a,o,u,l,s,c=e.constructor,f=c.precision;if(!e.s||!t.s)return t.s||(t=new c(e)),ie?Z(t,f):t;if(l=e.d,s=t.d,o=e.e,i=t.e,l=l.slice(),a=o-i,a){for(a<0?(n=l,a=-a,u=s.length):(n=s,i=o,u=l.length),o=Math.ceil(f/te),u=o>u?o+1:u+1,a>u&&(a=u,n.length=1),n.reverse();a--;)n.push(0);n.reverse()}for(u=l.length,a=s.length,u-a<0&&(a=u,n=s,s=l,l=n),r=0;a;)r=(l[--a]=l[a]+s[a]+r)/Oe|0,l[a]%=Oe;for(r&&(l.unshift(r),++i),u=l.length;l[--u]==0;)l.pop();return t.d=l,t.e=i,ie?Z(t,f):t}function xt(e,t,r){if(e!==~~e||er)throw Error(vr+e)}function yt(e){var t,r,n,i=e.length-1,a="",o=e[0];if(i>0){for(a+=o,t=1;to?1:-1;else for(u=l=0;ui[u]?1:-1;break}return l}function r(n,i,a){for(var o=0;a--;)n[a]-=o,o=n[a]1;)n.shift()}return function(n,i,a,o){var u,l,s,c,f,d,v,p,y,m,g,x,w,P,b,O,S,_,I=n.constructor,M=n.s==i.s?1:-1,E=n.d,j=i.d;if(!n.s)return new I(n);if(!i.s)throw Error(ot+"Division by zero");for(l=n.e-i.e,S=j.length,b=E.length,v=new I(M),p=v.d=[],s=0;j[s]==(E[s]||0);)++s;if(j[s]>(E[s]||0)&&--l,a==null?x=a=I.precision:o?x=a+(he(n)-he(i))+1:x=a,x<0)return new I(0);if(x=x/te+2|0,s=0,S==1)for(c=0,j=j[0],x++;(s1&&(j=e(j,c),E=e(E,c),S=j.length,b=E.length),P=S,y=E.slice(0,S),m=y.length;m=Oe/2&&++O;do c=0,u=t(j,y,S,m),u<0?(g=y[0],S!=m&&(g=g*Oe+(y[1]||0)),c=g/O|0,c>1?(c>=Oe&&(c=Oe-1),f=e(j,c),d=f.length,m=y.length,u=t(f,y,d,m),u==1&&(c--,r(f,S16)throw Error(Tc+he(e));if(!e.s)return new c(Ge);for(ie=!1,u=f,o=new c(.03125);e.abs().gte(.1);)e=e.times(o),s+=5;for(n=Math.log(ur(2,s))/Math.LN10*2+5|0,u+=n,r=i=a=new c(Ge),c.precision=u;;){if(i=Z(i.times(e),u),r=r.times(++l),o=a.plus(kt(i,r,u)),yt(o.d).slice(0,u)===yt(a.d).slice(0,u)){for(;s--;)a=Z(a.times(a),u);return c.precision=f,t==null?(ie=!0,Z(a,f)):a}a=o}}function he(e){for(var t=e.e*te,r=e.d[0];r>=10;r/=10)t++;return t}function mu(e,t,r){if(t>e.LN10.sd())throw ie=!0,r&&(e.precision=r),Error(ot+"LN10 precision limit exceeded");return Z(new e(e.LN10),t)}function qt(e){for(var t="";e--;)t+="0";return t}function xn(e,t){var r,n,i,a,o,u,l,s,c,f=1,d=10,v=e,p=v.d,y=v.constructor,m=y.precision;if(v.s<1)throw Error(ot+(v.s?"NaN":"-Infinity"));if(v.eq(Ge))return new y(0);if(t==null?(ie=!1,s=m):s=t,v.eq(10))return t==null&&(ie=!0),mu(y,s);if(s+=d,y.precision=s,r=yt(p),n=r.charAt(0),a=he(v),Math.abs(a)<15e14){for(;n<7&&n!=1||n==1&&r.charAt(1)>3;)v=v.times(e),r=yt(v.d),n=r.charAt(0),f++;a=he(v),n>1?(v=new y("0."+r),a++):v=new y(n+"."+r.slice(1))}else return l=mu(y,s+2,m).times(a+""),v=xn(new y(n+"."+r.slice(1)),s-d).plus(l),y.precision=m,t==null?(ie=!0,Z(v,m)):v;for(u=o=v=kt(v.minus(Ge),v.plus(Ge),s),c=Z(v.times(v),s),i=3;;){if(o=Z(o.times(c),s),l=u.plus(kt(o,new y(i),s)),yt(l.d).slice(0,s)===yt(u.d).slice(0,s))return u=u.times(2),a!==0&&(u=u.plus(mu(y,s+2,m).times(a+""))),u=kt(u,new y(f),s),y.precision=m,t==null?(ie=!0,Z(u,m)):u;u=l,i+=2}}function Dv(e,t){var r,n,i;for((r=t.indexOf("."))>-1&&(t=t.replace(".","")),(n=t.search(/e/i))>0?(r<0&&(r=n),r+=+t.slice(n+1),t=t.substring(0,n)):r<0&&(r=t.length),n=0;t.charCodeAt(n)===48;)++n;for(i=t.length;t.charCodeAt(i-1)===48;)--i;if(t=t.slice(n,i),t){if(i-=n,r=r-n-1,e.e=qr(r/te),e.d=[],n=(r+1)%te,r<0&&(n+=te),nZi||e.e<-Zi))throw Error(Tc+r)}else e.s=0,e.e=0,e.d=[0];return e}function Z(e,t,r){var n,i,a,o,u,l,s,c,f=e.d;for(o=1,a=f[0];a>=10;a/=10)o++;if(n=t-o,n<0)n+=te,i=t,s=f[c=0];else{if(c=Math.ceil((n+1)/te),a=f.length,c>=a)return e;for(s=a=f[c],o=1;a>=10;a/=10)o++;n%=te,i=n-te+o}if(r!==void 0&&(a=ur(10,o-i-1),u=s/a%10|0,l=t<0||f[c+1]!==void 0||s%a,l=r<4?(u||l)&&(r==0||r==(e.s<0?3:2)):u>5||u==5&&(r==4||l||r==6&&(n>0?i>0?s/ur(10,o-i):0:f[c-1])%10&1||r==(e.s<0?8:7))),t<1||!f[0])return l?(a=he(e),f.length=1,t=t-a-1,f[0]=ur(10,(te-t%te)%te),e.e=qr(-t/te)||0):(f.length=1,f[0]=e.e=e.s=0),e;if(n==0?(f.length=c,a=1,c--):(f.length=c+1,a=ur(10,te-n),f[c]=i>0?(s/ur(10,o-i)%ur(10,i)|0)*a:0),l)for(;;)if(c==0){(f[0]+=a)==Oe&&(f[0]=1,++e.e);break}else{if(f[c]+=a,f[c]!=Oe)break;f[c--]=0,a=1}for(n=f.length;f[--n]===0;)f.pop();if(ie&&(e.e>Zi||e.e<-Zi))throw Error(Tc+he(e));return e}function Fy(e,t){var r,n,i,a,o,u,l,s,c,f,d=e.constructor,v=d.precision;if(!e.s||!t.s)return t.s?t.s=-t.s:t=new d(e),ie?Z(t,v):t;if(l=e.d,f=t.d,n=t.e,s=e.e,l=l.slice(),o=s-n,o){for(c=o<0,c?(r=l,o=-o,u=f.length):(r=f,n=s,u=l.length),i=Math.max(Math.ceil(v/te),u)+2,o>i&&(o=i,r.length=1),r.reverse(),i=o;i--;)r.push(0);r.reverse()}else{for(i=l.length,u=f.length,c=i0;--i)l[u++]=0;for(i=f.length;i>o;){if(l[--i]0?a=a.charAt(0)+"."+a.slice(1)+qt(n):o>1&&(a=a.charAt(0)+"."+a.slice(1)),a=a+(i<0?"e":"e+")+i):i<0?(a="0."+qt(-i-1)+a,r&&(n=r-o)>0&&(a+=qt(n))):i>=o?(a+=qt(i+1-o),r&&(n=r-i-1)>0&&(a=a+"."+qt(n))):((n=i+1)0&&(i+1===o&&(a+="."),a+=qt(n))),e.s<0?"-"+a:a}function Nv(e,t){if(e.length>t)return e.length=t,!0}function Ky(e){var t,r,n;function i(a){var o=this;if(!(o instanceof i))return new i(a);if(o.constructor=i,a instanceof i){o.s=a.s,o.e=a.e,o.d=(a=a.d)?a.slice():a;return}if(typeof a=="number"){if(a*0!==0)throw Error(vr+a);if(a>0)o.s=1;else if(a<0)a=-a,o.s=-1;else{o.s=0,o.e=0,o.d=[0];return}if(a===~~a&&a<1e7){o.e=0,o.d=[a];return}return Dv(o,a.toString())}else if(typeof a!="string")throw Error(vr+a);if(a.charCodeAt(0)===45?(a=a.slice(1),o.s=-1):o.s=1,WE.test(a))Dv(o,a);else throw Error(vr+a)}if(i.prototype=D,i.ROUND_UP=0,i.ROUND_DOWN=1,i.ROUND_CEIL=2,i.ROUND_FLOOR=3,i.ROUND_HALF_UP=4,i.ROUND_HALF_DOWN=5,i.ROUND_HALF_EVEN=6,i.ROUND_HALF_CEIL=7,i.ROUND_HALF_FLOOR=8,i.clone=Ky,i.config=i.set=UE,e===void 0&&(e={}),e)for(n=["precision","rounding","toExpNeg","toExpPos","LN10"],t=0;t=i[t+1]&&n<=i[t+2])this[r]=n;else throw Error(vr+r+": "+n);if((n=e[r="LN10"])!==void 0)if(n==Math.LN10)this[r]=new this(n);else throw Error(vr+r+": "+n);return this}var Dc=Ky(qE);Ge=new Dc(1);const V=Dc;var HE=e=>e,qy={},Wy=e=>e===qy,$v=e=>function t(){return arguments.length===0||arguments.length===1&&Wy(arguments.length<=0?void 0:arguments[0])?t:e(...arguments)},Uy=(e,t)=>e===1?t:$v(function(){for(var r=arguments.length,n=new Array(r),i=0;io!==qy).length;return a>=e?t(...n):Uy(e-a,$v(function(){for(var o=arguments.length,u=new Array(o),l=0;lWy(c)?u.shift():c);return t(...s,...u)}))}),YE=e=>Uy(e.length,e),gl=(e,t)=>{for(var r=[],n=e;nArray.isArray(t)?t.map(e):Object.keys(t).map(r=>t[r]).map(e)),VE=function(){for(var t=arguments.length,r=new Array(t),n=0;nl(u),a(...arguments))}},bl=e=>Array.isArray(e)?e.reverse():e.split("").reverse().join("");function Hy(e){var t;return e===0?t=1:t=Math.floor(new V(e).abs().log(10).toNumber())+1,t}function Yy(e,t,r){for(var n=new V(e),i=0,a=[];n.lt(t)&&i<1e5;)a.push(n.toNumber()),n=n.add(r),i++;return a}var Gy=e=>{var[t,r]=e,[n,i]=[t,r];return t>r&&([n,i]=[r,t]),[n,i]},Vy=(e,t,r)=>{if(e.lte(0))return new V(0);var n=Hy(e.toNumber()),i=new V(10).pow(n),a=e.div(i),o=n!==1?.05:.1,u=new V(Math.ceil(a.div(o).toNumber())).add(r).mul(o),l=u.mul(i);return t?new V(l.toNumber()):new V(Math.ceil(l.toNumber()))},XE=(e,t,r)=>{var n=new V(1),i=new V(e);if(!i.isint()&&r){var a=Math.abs(e);a<1?(n=new V(10).pow(Hy(e)-1),i=new V(Math.floor(i.div(n).toNumber())).mul(n)):a>1&&(i=new V(Math.floor(e)))}else e===0?i=new V(Math.floor((t-1)/2)):r||(i=new V(Math.floor(e)));var o=Math.floor((t-1)/2),u=VE(GE(l=>i.add(new V(l-o).mul(n)).toNumber()),gl);return u(0,t)},Xy=function(t,r,n,i){var a=arguments.length>4&&arguments[4]!==void 0?arguments[4]:0;if(!Number.isFinite((r-t)/(n-1)))return{step:new V(0),tickMin:new V(0),tickMax:new V(0)};var o=Vy(new V(r).sub(t).div(n-1),i,a),u;t<=0&&r>=0?u=new V(0):(u=new V(t).add(r).div(2),u=u.sub(new V(u).mod(o)));var l=Math.ceil(u.sub(t).div(o).toNumber()),s=Math.ceil(new V(r).sub(u).div(o).toNumber()),c=l+s+1;return c>n?Xy(t,r,n,i,a+1):(c0?s+(n-c):s,l=r>0?l:l+(n-c)),{step:o,tickMin:u.sub(new V(l).mul(o)),tickMax:u.add(new V(s).mul(o))})},ZE=function(t){var[r,n]=t,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:6,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,o=Math.max(i,2),[u,l]=Gy([r,n]);if(u===-1/0||l===1/0){var s=l===1/0?[u,...gl(0,i-1).map(()=>1/0)]:[...gl(0,i-1).map(()=>-1/0),l];return r>n?bl(s):s}if(u===l)return XE(u,i,a);var{step:c,tickMin:f,tickMax:d}=Xy(u,l,o,a,0),v=Yy(f,d.add(new V(.1).mul(c)),c);return r>n?bl(v):v},QE=function(t,r){var[n,i]=t,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,[o,u]=Gy([n,i]);if(o===-1/0||u===1/0)return[n,i];if(o===u)return[o];var l=Math.max(r,2),s=Vy(new V(u).sub(o).div(l-1),a,0),c=[...Yy(new V(o),new V(u),s),u];return a===!1&&(c=c.map(f=>Math.round(f))),n>i?bl(c):c},Zy=e=>e.rootProps.maxBarSize,JE=e=>e.rootProps.barGap,Qy=e=>e.rootProps.barCategoryGap,e_=e=>e.rootProps.barSize,Bn=e=>e.rootProps.stackOffset,Jy=e=>e.rootProps.reverseStackOrder,Nc=e=>e.options.chartName,$c=e=>e.rootProps.syncId,eg=e=>e.rootProps.syncMethod,Rc=e=>e.options.eventEmitter,ve={grid:-100,barBackground:-50,area:100,cursorRectangle:200,bar:300,line:400,axis:500,scatter:600,activeBar:1e3,cursorLine:1100,activeDot:1200,label:2e3},At={allowDuplicatedCategory:!0,angleAxisId:0,reversed:!1,scale:"auto",tick:!0,type:"category"},Ye={allowDataOverflow:!1,allowDuplicatedCategory:!0,radiusAxisId:0,scale:"auto",tick:!0,tickCount:5,type:"number"},za=(e,t)=>{if(!(!e||!t))return e!=null&&e.reversed?[t[1],t[0]]:t},t_={allowDataOverflow:!1,allowDecimals:!1,allowDuplicatedCategory:!1,dataKey:void 0,domain:void 0,id:At.angleAxisId,includeHidden:!1,name:void 0,reversed:At.reversed,scale:At.scale,tick:At.tick,tickCount:void 0,ticks:void 0,type:At.type,unit:void 0},r_={allowDataOverflow:Ye.allowDataOverflow,allowDecimals:!1,allowDuplicatedCategory:Ye.allowDuplicatedCategory,dataKey:void 0,domain:void 0,id:Ye.radiusAxisId,includeHidden:!1,name:void 0,reversed:!1,scale:Ye.scale,tick:Ye.tick,tickCount:Ye.tickCount,ticks:void 0,type:Ye.type,unit:void 0},n_={allowDataOverflow:!1,allowDecimals:!1,allowDuplicatedCategory:At.allowDuplicatedCategory,dataKey:void 0,domain:void 0,id:At.angleAxisId,includeHidden:!1,name:void 0,reversed:!1,scale:At.scale,tick:At.tick,tickCount:void 0,ticks:void 0,type:"number",unit:void 0},i_={allowDataOverflow:Ye.allowDataOverflow,allowDecimals:!1,allowDuplicatedCategory:Ye.allowDuplicatedCategory,dataKey:void 0,domain:void 0,id:Ye.radiusAxisId,includeHidden:!1,name:void 0,reversed:!1,scale:Ye.scale,tick:Ye.tick,tickCount:Ye.tickCount,ticks:void 0,type:"category",unit:void 0},Lc=(e,t)=>e.polarAxis.angleAxis[t]!=null?e.polarAxis.angleAxis[t]:e.layout.layoutType==="radial"?n_:t_,zc=(e,t)=>e.polarAxis.radiusAxis[t]!=null?e.polarAxis.radiusAxis[t]:e.layout.layoutType==="radial"?i_:r_,Ba=e=>e.polarOptions,Bc=A([Rt,Lt,ye],Xm),tg=A([Ba,Bc],(e,t)=>{if(e!=null)return Ie(e.innerRadius,t,0)}),rg=A([Ba,Bc],(e,t)=>{if(e!=null)return Ie(e.outerRadius,t,t*.8)}),a_=e=>{if(e==null)return[0,0];var{startAngle:t,endAngle:r}=e;return[t,r]},ng=A([Ba],a_);A([Lc,ng],za);var ig=A([Bc,tg,rg],(e,t,r)=>{if(!(e==null||t==null||r==null))return[t,r]});A([zc,ig],za);var ag=A([q,Ba,tg,rg,Rt,Lt],(e,t,r,n,i,a)=>{if(!(e!=="centric"&&e!=="radial"||t==null||r==null||n==null)){var{cx:o,cy:u,startAngle:l,endAngle:s}=t;return{cx:Ie(o,i,i/2),cy:Ie(u,a,a/2),innerRadius:r,outerRadius:n,startAngle:l,endAngle:s,clockWise:!1}}}),oe=(e,t)=>t,Fn=(e,t,r)=>r;function Fc(e){return e?.id}function og(e,t,r){var{chartData:n=[]}=t,{allowDuplicatedCategory:i,dataKey:a}=r,o=new Map;return e.forEach(u=>{var l,s=(l=u.data)!==null&&l!==void 0?l:n;if(!(s==null||s.length===0)){var c=Fc(u);s.forEach((f,d)=>{var v=a==null||i?d:String(X(f,a,null)),p=X(f,u.dataKey,0),y;o.has(v)?y=o.get(v):y={},Object.assign(y,{[c]:p}),o.set(v,y)})}}),Array.from(o.values())}function Fa(e){return e.stackId!=null&&e.dataKey!=null}var Ka=(e,t)=>e===t?!0:e==null||t==null?!1:e[0]===t[0]&&e[1]===t[1];function qa(e,t){return Array.isArray(e)&&Array.isArray(t)&&e.length===0&&t.length===0?!0:e===t}function o_(e,t){if(e.length===t.length){for(var r=0;r{var t=q(e);return t==="horizontal"?"xAxis":t==="vertical"?"yAxis":t==="centric"?"angleAxis":"radiusAxis"},Wr=e=>e.tooltip.settings.axisId;function Rv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Qi(e){for(var t=1;te.cartesianAxis.xAxis[t],Bt=(e,t)=>{var r=ug(e,t);return r??xe},Pe={allowDataOverflow:!1,allowDecimals:!0,allowDuplicatedCategory:!0,angle:0,dataKey:void 0,domain:wl,hide:!0,id:0,includeHidden:!1,interval:"preserveEnd",minTickGap:5,mirror:!1,name:void 0,orientation:"left",padding:{top:0,bottom:0},reversed:!1,scale:"auto",tick:!0,tickCount:5,tickFormatter:void 0,ticks:void 0,type:"number",unit:void 0,width:Cn},lg=(e,t)=>e.cartesianAxis.yAxis[t],Ft=(e,t)=>{var r=lg(e,t);return r??Pe},s_={domain:[0,"auto"],includeHidden:!1,reversed:!1,allowDataOverflow:!1,allowDuplicatedCategory:!1,dataKey:void 0,id:0,name:"",range:[64,64],scale:"auto",type:"number",unit:""},Kc=(e,t)=>{var r=e.cartesianAxis.zAxis[t];return r??s_},ue=(e,t,r)=>{switch(t){case"xAxis":return Bt(e,r);case"yAxis":return Ft(e,r);case"zAxis":return Kc(e,r);case"angleAxis":return Lc(e,r);case"radiusAxis":return zc(e,r);default:throw new Error("Unexpected axis type: ".concat(t))}},f_=(e,t,r)=>{switch(t){case"xAxis":return Bt(e,r);case"yAxis":return Ft(e,r);default:throw new Error("Unexpected axis type: ".concat(t))}},Kn=(e,t,r)=>{switch(t){case"xAxis":return Bt(e,r);case"yAxis":return Ft(e,r);case"angleAxis":return Lc(e,r);case"radiusAxis":return zc(e,r);default:throw new Error("Unexpected axis type: ".concat(t))}},cg=e=>e.graphicalItems.cartesianItems.some(t=>t.type==="bar")||e.graphicalItems.polarItems.some(t=>t.type==="radialBar");function qc(e,t){return r=>{switch(e){case"xAxis":return"xAxisId"in r&&r.xAxisId===t;case"yAxis":return"yAxisId"in r&&r.yAxisId===t;case"zAxis":return"zAxisId"in r&&r.zAxisId===t;case"angleAxis":return"angleAxisId"in r&&r.angleAxisId===t;case"radiusAxis":return"radiusAxisId"in r&&r.radiusAxisId===t;default:return!1}}}var Wa=e=>e.graphicalItems.cartesianItems,d_=A([oe,Fn],qc),Wc=(e,t,r)=>e.filter(r).filter(n=>t?.includeHidden===!0?!0:!n.hide),qn=A([Wa,ue,d_],Wc,{memoizeOptions:{resultEqualityCheck:qa}}),sg=A([qn],e=>e.filter(t=>t.type==="area"||t.type==="bar").filter(Fa)),fg=e=>e.filter(t=>!("stackId"in t)||t.stackId===void 0),v_=A([qn],fg),Uc=e=>e.map(t=>t.data).filter(Boolean).flat(1),h_=A([qn],Uc,{memoizeOptions:{resultEqualityCheck:qa}}),Hc=(e,t)=>{var{chartData:r=[],dataStartIndex:n,dataEndIndex:i}=t;return e.length>0?e:r.slice(n,i+1)},Yc=A([h_,La],Hc),Gc=(e,t,r)=>t?.dataKey!=null?e.map(n=>({value:X(n,t.dataKey)})):r.length>0?r.map(n=>n.dataKey).flatMap(n=>e.map(i=>({value:X(i,n)}))):e.map(n=>({value:n})),Ua=A([Yc,ue,qn],Gc);function dg(e,t){switch(e){case"xAxis":return t.direction==="x";case"yAxis":return t.direction==="y";default:return!1}}function gi(e){if(bt(e)||e instanceof Date){var t=Number(e);if(se(t))return t}}function Lv(e){if(Array.isArray(e)){var t=[gi(e[0]),gi(e[1])];return Yt(t)?t:void 0}var r=gi(e);if(r!=null)return[r,r]}function Nt(e){return e.map(gi).filter(lw)}function p_(e,t,r){return!r||typeof t!="number"||dt(t)?[]:r.length?Nt(r.flatMap(n=>{var i=X(e,n.dataKey),a,o;if(Array.isArray(i)?[a,o]=i:a=o=i,!(!se(a)||!se(o)))return[t-a,t+o]})):[]}var we=e=>{var t=be(e),r=Wr(e);return Kn(e,t,r)},Wn=A([we],e=>e?.dataKey),m_=A([sg,La,we],og),vg=(e,t,r,n)=>{var i={},a=t.reduce((o,u)=>(u.stackId==null||(o[u.stackId]==null&&(o[u.stackId]=[]),o[u.stackId].push(u)),o),i);return Object.fromEntries(Object.entries(a).map(o=>{var[u,l]=o,s=n?[...l].reverse():l,c=s.map(Fc);return[u,{stackedData:CP(e,c,r),graphicalItems:s}]}))},xl=A([m_,sg,Bn,Jy],vg),hg=(e,t,r,n)=>{var{dataStartIndex:i,dataEndIndex:a}=t;if(n==null&&r!=="zAxis"){var o=NP(e,i,a);if(!(o!=null&&o[0]===0&&o[1]===0))return o}},y_=A([ue],e=>e.allowDataOverflow),Vc=e=>{var t;if(e==null||!("domain"in e))return wl;if(e.domain!=null)return e.domain;if(e.ticks!=null){if(e.type==="number"){var r=Nt(e.ticks);return[Math.min(...r),Math.max(...r)]}if(e.type==="category")return e.ticks.map(String)}return(t=e?.domain)!==null&&t!==void 0?t:wl},Xc=A([ue],Vc),Zc=A([Xc,y_],Ry),g_=A([xl,rr,oe,Zc],hg,{memoizeOptions:{resultEqualityCheck:Ka}}),Ha=e=>e.errorBars,b_=(e,t,r)=>e.flatMap(n=>t[n.id]).filter(Boolean).filter(n=>dg(r,n)),Ji=function(){for(var t=arguments.length,r=new Array(t),n=0;n{var a,o;if(r.length>0&&e.forEach(u=>{r.forEach(l=>{var s,c,f=(s=n[l.id])===null||s===void 0?void 0:s.filter(g=>dg(i,g)),d=X(u,(c=t.dataKey)!==null&&c!==void 0?c:l.dataKey),v=p_(u,d,f);if(v.length>=2){var p=Math.min(...v),y=Math.max(...v);(a==null||po)&&(o=y)}var m=Lv(d);m!=null&&(a=a==null?m[0]:Math.min(a,m[0]),o=o==null?m[1]:Math.max(o,m[1]))})}),t?.dataKey!=null&&e.forEach(u=>{var l=Lv(X(u,t.dataKey));l!=null&&(a=a==null?l[0]:Math.min(a,l[0]),o=o==null?l[1]:Math.max(o,l[1]))}),se(a)&&se(o))return[a,o]},w_=A([Yc,ue,v_,Ha,oe],Qc,{memoizeOptions:{resultEqualityCheck:Ka}});function x_(e){var{value:t}=e;if(bt(t)||t instanceof Date)return t}var P_=(e,t,r)=>{var n=e.map(x_).filter(i=>i!=null);return r&&(t.dataKey==null||t.allowDuplicatedCategory&&jp(n))?ey(0,e.length):t.allowDuplicatedCategory?n:Array.from(new Set(n))},pg=e=>e.referenceElements.dots,Ur=(e,t,r)=>e.filter(n=>n.ifOverflow==="extendDomain").filter(n=>t==="xAxis"?n.xAxisId===r:n.yAxisId===r),O_=A([pg,oe,Fn],Ur),mg=e=>e.referenceElements.areas,A_=A([mg,oe,Fn],Ur),yg=e=>e.referenceElements.lines,S_=A([yg,oe,Fn],Ur),gg=(e,t)=>{var r=Nt(e.map(n=>t==="xAxis"?n.x:n.y));if(r.length!==0)return[Math.min(...r),Math.max(...r)]},E_=A(O_,oe,gg),bg=(e,t)=>{var r=Nt(e.flatMap(n=>[t==="xAxis"?n.x1:n.y1,t==="xAxis"?n.x2:n.y2]));if(r.length!==0)return[Math.min(...r),Math.max(...r)]},__=A([A_,oe],bg);function k_(e){var t;if(e.x!=null)return Nt([e.x]);var r=(t=e.segment)===null||t===void 0?void 0:t.map(n=>n.x);return r==null||r.length===0?[]:Nt(r)}function j_(e){var t;if(e.y!=null)return Nt([e.y]);var r=(t=e.segment)===null||t===void 0?void 0:t.map(n=>n.y);return r==null||r.length===0?[]:Nt(r)}var wg=(e,t)=>{var r=e.flatMap(n=>t==="xAxis"?k_(n):j_(n));if(r.length!==0)return[Math.min(...r),Math.max(...r)]},C_=A([S_,oe],wg),I_=A(E_,C_,__,(e,t,r)=>Ji(e,r,t)),Jc=(e,t,r,n,i,a,o,u)=>{if(r!=null)return r;var l=o==="vertical"&&u==="xAxis"||o==="horizontal"&&u==="yAxis",s=l?Ji(n,a,i):Ji(a,i);return KE(t,s,e.allowDataOverflow)},M_=A([ue,Xc,Zc,g_,w_,I_,q,oe],Jc,{memoizeOptions:{resultEqualityCheck:Ka}}),T_=[0,1],es=(e,t,r,n,i,a,o)=>{if(!((e==null||r==null||r.length===0)&&o===void 0)){var{dataKey:u,type:l}=e,s=Jt(t,a);if(s&&u==null){var c;return ey(0,(c=r?.length)!==null&&c!==void 0?c:0)}return l==="category"?P_(n,e,s):i==="expand"?T_:o}},ts=A([ue,q,Yc,Ua,Bn,oe,M_],es),xg=(e,t,r,n,i)=>{if(e!=null){var{scale:a,type:o}=e;if(a==="auto")return t==="radial"&&i==="radiusAxis"?"band":t==="radial"&&i==="angleAxis"?"linear":o==="category"&&n&&(n.indexOf("LineChart")>=0||n.indexOf("AreaChart")>=0||n.indexOf("ComposedChart")>=0&&!r)?"point":o==="category"?"band":"linear";if(typeof a=="string"){var u="scale".concat(An(a));return u in un?u:"point"}}},Hr=A([ue,q,cg,Nc,oe],xg);function D_(e){if(e!=null){if(e in un)return un[e]();var t="scale".concat(An(e));if(t in un)return un[t]()}}function rs(e,t,r,n){if(!(r==null||n==null)){if(typeof e.scale=="function")return e.scale.copy().domain(r).range(n);var i=D_(t);if(i!=null){var a=i.domain(r).range(n);return SP(a),a}}}var ns=(e,t,r)=>{var n=Vc(t);if(!(r!=="auto"&&r!=="linear")){if(t!=null&&t.tickCount&&Array.isArray(n)&&(n[0]==="auto"||n[1]==="auto")&&Yt(e))return ZE(e,t.tickCount,t.allowDecimals);if(t!=null&&t.tickCount&&t.type==="number"&&Yt(e))return QE(e,t.tickCount,t.allowDecimals)}},is=A([ts,Kn,Hr],ns),as=(e,t,r,n)=>{if(n!=="angleAxis"&&e?.type==="number"&&Yt(t)&&Array.isArray(r)&&r.length>0){var i=t[0],a=r[0],o=t[1],u=r[r.length-1];return[Math.min(i,a),Math.max(o,u)]}return t},N_=A([ue,ts,is,oe],as),$_=A(Ua,ue,(e,t)=>{if(!(!t||t.type!=="number")){var r=1/0,n=Array.from(Nt(e.map(u=>u.value))).sort((u,l)=>u-l);if(n.length<2)return 1/0;var i=n[n.length-1]-n[0];if(i===0)return 1/0;for(var a=0;an,(e,t,r,n,i)=>{if(!se(e))return 0;var a=t==="vertical"?n.height:n.width;if(i==="gap")return e*a/2;if(i==="no-gap"){var o=Ie(r,e*a),u=e*a/2;return u-o-(u-o)/a*o}return 0}),R_=(e,t)=>{var r=Bt(e,t);return r==null||typeof r.padding!="string"?0:Pg(e,"xAxis",t,r.padding)},L_=(e,t)=>{var r=Ft(e,t);return r==null||typeof r.padding!="string"?0:Pg(e,"yAxis",t,r.padding)},z_=A(Bt,R_,(e,t)=>{var r,n;if(e==null)return{left:0,right:0};var{padding:i}=e;return typeof i=="string"?{left:t,right:t}:{left:((r=i.left)!==null&&r!==void 0?r:0)+t,right:((n=i.right)!==null&&n!==void 0?n:0)+t}}),B_=A(Ft,L_,(e,t)=>{var r,n;if(e==null)return{top:0,bottom:0};var{padding:i}=e;return typeof i=="string"?{top:t,bottom:t}:{top:((r=i.top)!==null&&r!==void 0?r:0)+t,bottom:((n=i.bottom)!==null&&n!==void 0?n:0)+t}}),F_=A([ye,z_,Ea,Sa,(e,t,r)=>r],(e,t,r,n,i)=>{var{padding:a}=n;return i?[a.left,r.width-a.right]:[e.left+t.left,e.left+e.width-t.right]}),K_=A([ye,q,B_,Ea,Sa,(e,t,r)=>r],(e,t,r,n,i,a)=>{var{padding:o}=i;return a?[n.height-o.bottom,o.top]:t==="horizontal"?[e.top+e.height-r.bottom,e.top+r.top]:[e.top+r.top,e.top+e.height-r.bottom]}),Un=(e,t,r,n)=>{var i;switch(t){case"xAxis":return F_(e,r,n);case"yAxis":return K_(e,r,n);case"zAxis":return(i=Kc(e,r))===null||i===void 0?void 0:i.range;case"angleAxis":return ng(e);case"radiusAxis":return ig(e,r);default:return}},Og=A([ue,Un],za),Yr=A([ue,Hr,N_,Og],rs);A([qn,Ha,oe],b_);function Ag(e,t){return e.idt.id?1:0}var Ya=(e,t)=>t,Ga=(e,t,r)=>r,q_=A(Oa,Ya,Ga,(e,t,r)=>e.filter(n=>n.orientation===t).filter(n=>n.mirror===r).sort(Ag)),W_=A(Aa,Ya,Ga,(e,t,r)=>e.filter(n=>n.orientation===t).filter(n=>n.mirror===r).sort(Ag)),Sg=(e,t)=>({width:e.width,height:t.height}),U_=(e,t)=>{var r=typeof t.width=="number"?t.width:Cn;return{width:r,height:e.height}},Eg=A(ye,Bt,Sg),H_=(e,t,r)=>{switch(t){case"top":return e.top;case"bottom":return r-e.bottom;default:return 0}},Y_=(e,t,r)=>{switch(t){case"left":return e.left;case"right":return r-e.right;default:return 0}},G_=A(Lt,ye,q_,Ya,Ga,(e,t,r,n,i)=>{var a={},o;return r.forEach(u=>{var l=Sg(t,u);o==null&&(o=H_(t,n,e));var s=n==="top"&&!i||n==="bottom"&&i;a[u.id]=o-Number(s)*l.height,o+=(s?-1:1)*l.height}),a}),V_=A(Rt,ye,W_,Ya,Ga,(e,t,r,n,i)=>{var a={},o;return r.forEach(u=>{var l=U_(t,u);o==null&&(o=Y_(t,n,e));var s=n==="left"&&!i||n==="right"&&i;a[u.id]=o-Number(s)*l.width,o+=(s?-1:1)*l.width}),a}),X_=(e,t)=>{var r=Bt(e,t);if(r!=null)return G_(e,r.orientation,r.mirror)},Z_=A([ye,Bt,X_,(e,t)=>t],(e,t,r,n)=>{if(t!=null){var i=r?.[n];return i==null?{x:e.left,y:0}:{x:e.left,y:i}}}),Q_=(e,t)=>{var r=Ft(e,t);if(r!=null)return V_(e,r.orientation,r.mirror)},J_=A([ye,Ft,Q_,(e,t)=>t],(e,t,r,n)=>{if(t!=null){var i=r?.[n];return i==null?{x:0,y:e.top}:{x:i,y:e.top}}}),_g=A(ye,Ft,(e,t)=>{var r=typeof t.width=="number"?t.width:Cn;return{width:r,height:e.height}}),zv=(e,t,r)=>{switch(t){case"xAxis":return Eg(e,r).width;case"yAxis":return _g(e,r).height;default:return}},kg=(e,t,r,n)=>{if(r!=null){var{allowDuplicatedCategory:i,type:a,dataKey:o}=r,u=Jt(e,n),l=t.map(s=>s.value);if(o&&u&&a==="category"&&i&&jp(l))return l}},os=A([q,Ua,ue,oe],kg),jg=(e,t,r,n)=>{if(!(r==null||r.dataKey==null)){var{type:i,scale:a}=r,o=Jt(e,n);if(o&&(i==="number"||a!=="auto"))return t.map(u=>u.value)}},us=A([q,Ua,Kn,oe],jg),Bv=A([q,f_,Hr,Yr,os,us,Un,is,oe],(e,t,r,n,i,a,o,u,l)=>{if(t!=null){var s=Jt(e,l);return{angle:t.angle,interval:t.interval,minTickGap:t.minTickGap,orientation:t.orientation,tick:t.tick,tickCount:t.tickCount,tickFormatter:t.tickFormatter,ticks:t.ticks,type:t.type,unit:t.unit,axisType:l,categoricalDomain:a,duplicateDomain:i,isCategorical:s,niceTicks:u,range:o,realScaleType:r,scale:n}}}),ek=(e,t,r,n,i,a,o,u,l)=>{if(!(t==null||n==null)){var s=Jt(e,l),{type:c,ticks:f,tickCount:d}=t,v=r==="scaleBand"&&typeof n.bandwidth=="function"?n.bandwidth()/2:2,p=c==="category"&&n.bandwidth?n.bandwidth()/v:0;p=l==="angleAxis"&&a!=null&&a.length>=2?Ae(a[0]-a[1])*2*p:p;var y=f||i;if(y){var m=y.map((g,x)=>{var w=o?o.indexOf(g):g;return{index:x,coordinate:n(w)+p,value:g,offset:p}});return m.filter(g=>se(g.coordinate))}return s&&u?u.map((g,x)=>({coordinate:n(g)+p,value:g,index:x,offset:p})).filter(g=>se(g.coordinate)):n.ticks?n.ticks(d).map(g=>({coordinate:n(g)+p,value:g,offset:p})):n.domain().map((g,x)=>({coordinate:n(g)+p,value:o?o[g]:g,index:x,offset:p}))}},Cg=A([q,Kn,Hr,Yr,is,Un,os,us,oe],ek),tk=(e,t,r,n,i,a,o)=>{if(!(t==null||r==null||n==null||n[0]===n[1])){var u=Jt(e,o),{tickCount:l}=t,s=0;return s=o==="angleAxis"&&n?.length>=2?Ae(n[0]-n[1])*2*s:s,u&&a?a.map((c,f)=>({coordinate:r(c)+s,value:c,index:f,offset:s})):r.ticks?r.ticks(l).map(c=>({coordinate:r(c)+s,value:c,offset:s})):r.domain().map((c,f)=>({coordinate:r(c)+s,value:i?i[c]:c,index:f,offset:s}))}},Gt=A([q,Kn,Yr,Un,os,us,oe],tk),Vt=A(ue,Yr,(e,t)=>{if(!(e==null||t==null))return Qi(Qi({},e),{},{scale:t})}),rk=A([ue,Hr,ts,Og],rs);A((e,t,r)=>Kc(e,r),rk,(e,t)=>{if(!(e==null||t==null))return Qi(Qi({},e),{},{scale:t})});var nk=A([q,Oa,Aa],(e,t,r)=>{switch(e){case"horizontal":return t.some(n=>n.reversed)?"right-to-left":"left-to-right";case"vertical":return r.some(n=>n.reversed)?"bottom-to-top":"top-to-bottom";case"centric":case"radial":return"left-to-right";default:return}}),Ig=e=>e.options.defaultTooltipEventType,Mg=e=>e.options.validateTooltipEventTypes;function Tg(e,t,r){if(e==null)return t;var n=e?"axis":"item";return r==null?t:r.includes(n)?n:t}function ls(e,t){var r=Ig(e),n=Mg(e);return Tg(t,r,n)}function ik(e){return T(t=>ls(t,e))}var Dg=(e,t)=>{var r,n=Number(t);if(!(dt(n)||t==null))return n>=0?e==null||(r=e[n])===null||r===void 0?void 0:r.value:void 0},ak=e=>e.tooltip.settings,Ut={active:!1,index:null,dataKey:void 0,graphicalItemId:void 0,coordinate:void 0},ok={itemInteraction:{click:Ut,hover:Ut},axisInteraction:{click:Ut,hover:Ut},keyboardInteraction:Ut,syncInteraction:{active:!1,index:null,dataKey:void 0,label:void 0,coordinate:void 0,sourceViewBox:void 0,graphicalItemId:void 0},tooltipItemPayloads:[],settings:{shared:void 0,trigger:"hover",axisId:0,active:!1,defaultIndex:void 0}},Ng=qe({name:"tooltip",initialState:ok,reducers:{addTooltipEntrySettings:{reducer(e,t){e.tooltipItemPayloads.push(t.payload)},prepare:re()},replaceTooltipEntrySettings:{reducer(e,t){var{prev:r,next:n}=t.payload,i=ft(e).tooltipItemPayloads.indexOf(r);i>-1&&(e.tooltipItemPayloads[i]=n)},prepare:re()},removeTooltipEntrySettings:{reducer(e,t){var r=ft(e).tooltipItemPayloads.indexOf(t.payload);r>-1&&e.tooltipItemPayloads.splice(r,1)},prepare:re()},setTooltipSettingsState(e,t){e.settings=t.payload},setActiveMouseOverItemIndex(e,t){e.syncInteraction.active=!1,e.keyboardInteraction.active=!1,e.itemInteraction.hover.active=!0,e.itemInteraction.hover.index=t.payload.activeIndex,e.itemInteraction.hover.dataKey=t.payload.activeDataKey,e.itemInteraction.hover.graphicalItemId=t.payload.activeGraphicalItemId,e.itemInteraction.hover.coordinate=t.payload.activeCoordinate},mouseLeaveChart(e){e.itemInteraction.hover.active=!1,e.axisInteraction.hover.active=!1},mouseLeaveItem(e){e.itemInteraction.hover.active=!1},setActiveClickItemIndex(e,t){e.syncInteraction.active=!1,e.itemInteraction.click.active=!0,e.keyboardInteraction.active=!1,e.itemInteraction.click.index=t.payload.activeIndex,e.itemInteraction.click.dataKey=t.payload.activeDataKey,e.itemInteraction.click.graphicalItemId=t.payload.activeGraphicalItemId,e.itemInteraction.click.coordinate=t.payload.activeCoordinate},setMouseOverAxisIndex(e,t){e.syncInteraction.active=!1,e.axisInteraction.hover.active=!0,e.keyboardInteraction.active=!1,e.axisInteraction.hover.index=t.payload.activeIndex,e.axisInteraction.hover.dataKey=t.payload.activeDataKey,e.axisInteraction.hover.coordinate=t.payload.activeCoordinate},setMouseClickAxisIndex(e,t){e.syncInteraction.active=!1,e.keyboardInteraction.active=!1,e.axisInteraction.click.active=!0,e.axisInteraction.click.index=t.payload.activeIndex,e.axisInteraction.click.dataKey=t.payload.activeDataKey,e.axisInteraction.click.coordinate=t.payload.activeCoordinate},setSyncInteraction(e,t){e.syncInteraction=t.payload},setKeyboardInteraction(e,t){e.keyboardInteraction.active=t.payload.active,e.keyboardInteraction.index=t.payload.activeIndex,e.keyboardInteraction.coordinate=t.payload.activeCoordinate,e.keyboardInteraction.dataKey=t.payload.activeDataKey}}}),{addTooltipEntrySettings:uk,replaceTooltipEntrySettings:lk,removeTooltipEntrySettings:ck,setTooltipSettingsState:sk,setActiveMouseOverItemIndex:$g,mouseLeaveItem:fk,mouseLeaveChart:Rg,setActiveClickItemIndex:dk,setMouseOverAxisIndex:Lg,setMouseClickAxisIndex:vk,setSyncInteraction:Pl,setKeyboardInteraction:Ol}=Ng.actions,hk=Ng.reducer;function Fv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function fi(e){for(var t=1;t{if(t==null)return Ut;var i=gk(e,t,r);if(i==null)return Ut;if(i.active)return i;if(e.keyboardInteraction.active)return e.keyboardInteraction;if(e.syncInteraction.active&&e.syncInteraction.index!=null)return e.syncInteraction;var a=e.settings.active===!0;if(bk(i)){if(a)return fi(fi({},i),{},{active:!0})}else if(n!=null)return{active:!0,coordinate:void 0,dataKey:void 0,index:n,graphicalItemId:void 0};return fi(fi({},Ut),{},{coordinate:i.coordinate})};function wk(e){if(typeof e=="number")return Number.isFinite(e)?e:void 0;if(e instanceof Date){var t=e.valueOf();return Number.isFinite(t)?t:void 0}var r=Number(e);return Number.isFinite(r)?r:void 0}function xk(e,t){var r=wk(e),n=t[0],i=t[1];if(r===void 0)return!1;var a=Math.min(n,i),o=Math.max(n,i);return r>=a&&r<=o}function Pk(e,t,r){if(r==null||t==null)return!0;var n=X(e,t);return n==null||!Yt(r)?!0:xk(n,r)}var cs=(e,t,r,n)=>{var i=e?.index;if(i==null)return null;var a=Number(i);if(!se(a))return i;var o=0,u=1/0;t.length>0&&(u=t.length-1);var l=Math.max(o,Math.min(a,u)),s=t[l];return s==null||Pk(s,r,n)?String(l):null},Bg=(e,t,r,n,i,a,o,u)=>{if(!(a==null||u==null)){var l=o[0],s=l==null?void 0:u(l.positions,a);if(s!=null)return s;var c=i?.[Number(a)];if(c)switch(r){case"horizontal":return{x:c.coordinate,y:(n.top+t)/2};default:return{x:(n.left+e)/2,y:c.coordinate}}}},Fg=(e,t,r,n)=>{if(t==="axis")return e.tooltipItemPayloads;if(e.tooltipItemPayloads.length===0)return[];var i;return r==="hover"?i=e.itemInteraction.hover.dataKey:i=e.itemInteraction.click.dataKey,i==null&&n!=null?[e.tooltipItemPayloads[0]]:e.tooltipItemPayloads.filter(a=>{var o;return((o=a.settings)===null||o===void 0?void 0:o.dataKey)===i})},Hn=e=>e.options.tooltipPayloadSearcher,Gr=e=>e.tooltip;function Kv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function qv(e){for(var t=1;t{if(!(t==null||a==null)){var{chartData:u,computedData:l,dataStartIndex:s,dataEndIndex:c}=r,f=[];return e.reduce((d,v)=>{var p,{dataDefinedOnItem:y,settings:m}=v,g=Ek(y,u),x=Array.isArray(g)?Om(g,s,c):g,w=(p=m?.dataKey)!==null&&p!==void 0?p:n,P=m?.nameKey,b;if(n&&Array.isArray(x)&&!Array.isArray(x[0])&&o==="axis"?b=Cp(x,n,i):b=a(x,t,l,P),Array.isArray(b))b.forEach(S=>{var _=qv(qv({},m),{},{name:S.name,unit:S.unit,color:void 0,fill:void 0});d.push(ud({tooltipEntrySettings:_,dataKey:S.dataKey,payload:S.payload,value:X(S.payload,S.dataKey),name:S.name}))});else{var O;d.push(ud({tooltipEntrySettings:m,dataKey:w,payload:b,value:X(b,w),name:(O=X(b,P))!==null&&O!==void 0?O:m?.name}))}return d},f)}},ss=A([we,q,cg,Nc,be],xg),_k=A([e=>e.graphicalItems.cartesianItems,e=>e.graphicalItems.polarItems],(e,t)=>[...e,...t]),kk=A([be,Wr],qc),Yn=A([_k,we,kk],Wc,{memoizeOptions:{resultEqualityCheck:qa}}),jk=A([Yn],e=>e.filter(Fa)),Ck=A([Yn],Uc,{memoizeOptions:{resultEqualityCheck:qa}}),Vr=A([Ck,rr],Hc),Ik=A([jk,rr,we],og),fs=A([Vr,we,Yn],Gc),qg=A([we],Vc),Mk=A([we],e=>e.allowDataOverflow),Wg=A([qg,Mk],Ry),Tk=A([Yn],e=>e.filter(Fa)),Dk=A([Ik,Tk,Bn,Jy],vg),Nk=A([Dk,rr,be,Wg],hg),$k=A([Yn],fg),Rk=A([Vr,we,$k,Ha,be],Qc,{memoizeOptions:{resultEqualityCheck:Ka}}),Lk=A([pg,be,Wr],Ur),zk=A([Lk,be],gg),Bk=A([mg,be,Wr],Ur),Fk=A([Bk,be],bg),Kk=A([yg,be,Wr],Ur),qk=A([Kk,be],wg),Wk=A([zk,qk,Fk],Ji),Uk=A([we,qg,Wg,Nk,Rk,Wk,q,be],Jc),Gn=A([we,q,Vr,fs,Bn,be,Uk],es),Hk=A([Gn,we,ss],ns),Yk=A([we,Gn,Hk,be],as),Ug=e=>{var t=be(e),r=Wr(e),n=!1;return Un(e,t,r,n)},Hg=A([we,Ug],za),Yg=A([we,ss,Yk,Hg],rs),Gk=A([q,fs,we,be],kg),Vk=A([q,fs,we,be],jg),Xk=(e,t,r,n,i,a,o,u)=>{if(t){var{type:l}=t,s=Jt(e,u);if(n){var c=r==="scaleBand"&&n.bandwidth?n.bandwidth()/2:2,f=l==="category"&&n.bandwidth?n.bandwidth()/c:0;return f=u==="angleAxis"&&i!=null&&i?.length>=2?Ae(i[0]-i[1])*2*f:f,s&&o?o.map((d,v)=>({coordinate:n(d)+f,value:d,index:v,offset:f})):n.domain().map((d,v)=>({coordinate:n(d)+f,value:a?a[d]:d,index:v,offset:f}))}}},Kt=A([q,we,ss,Yg,Ug,Gk,Vk,be],Xk),ds=A([Ig,Mg,ak],(e,t,r)=>Tg(r.shared,e,t)),Gg=e=>e.tooltip.settings.trigger,vs=e=>e.tooltip.settings.defaultIndex,Vn=A([Gr,ds,Gg,vs],zg),Xt=A([Vn,Vr,Wn,Gn],cs),Vg=A([Kt,Xt],Dg),hs=A([Vn],e=>{if(e)return e.dataKey}),Zk=A([Vn],e=>{if(e)return e.graphicalItemId}),Xg=A([Gr,ds,Gg,vs],Fg),Qk=A([Rt,Lt,q,ye,Kt,vs,Xg,Hn],Bg),Jk=A([Vn,Qk],(e,t)=>e!=null&&e.coordinate?e.coordinate:t),ej=A([Vn],e=>e.active),tj=A([Xg,Xt,rr,Wn,Vg,Hn,ds],Kg),rj=A([tj],e=>{if(e!=null){var t=e.map(r=>r.payload).filter(r=>r!=null);return Array.from(new Set(t))}});function Wv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Uv(e){for(var t=1;tT(we),uj=()=>{var e=oj(),t=T(Kt),r=T(Yg);return Dr(!e||!r?void 0:Uv(Uv({},e),{},{scale:r}),t)};function Hv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Ar(e){for(var t=1;t{var i=t.find(a=>a&&a.index===r);if(i){if(e==="horizontal")return{x:i.coordinate,y:n.chartY};if(e==="vertical")return{x:n.chartX,y:i.coordinate}}return{x:0,y:0}},dj=(e,t,r,n)=>{var i=t.find(s=>s&&s.index===r);if(i){if(e==="centric"){var a=i.coordinate,{radius:o}=n;return Ar(Ar(Ar({},n),de(n.cx,n.cy,o,a)),{},{angle:a,radius:o})}var u=i.coordinate,{angle:l}=n;return Ar(Ar(Ar({},n),de(n.cx,n.cy,u,l)),{},{angle:l,radius:u})}return{angle:0,clockWise:!1,cx:0,cy:0,endAngle:0,innerRadius:0,outerRadius:0,radius:0,startAngle:0,x:0,y:0}};function vj(e,t){var{chartX:r,chartY:n}=e;return r>=t.left&&r<=t.left+t.width&&n>=t.top&&n<=t.top+t.height}var Zg=(e,t,r,n,i)=>{var a,o=-1,u=(a=t?.length)!==null&&a!==void 0?a:0;if(u<=1||e==null)return 0;if(n==="angleAxis"&&i!=null&&Math.abs(Math.abs(i[1]-i[0])-360)<=1e-6)for(var l=0;l0?r[l-1].coordinate:r[u-1].coordinate,c=r[l].coordinate,f=l>=u-1?r[0].coordinate:r[l+1].coordinate,d=void 0;if(Ae(c-s)!==Ae(f-c)){var v=[];if(Ae(f-c)===Ae(i[1]-i[0])){d=f;var p=c+i[1]-i[0];v[0]=Math.min(p,(p+s)/2),v[1]=Math.max(p,(p+s)/2)}else{d=s;var y=f+i[1]-i[0];v[0]=Math.min(c,(y+c)/2),v[1]=Math.max(c,(y+c)/2)}var m=[Math.min(c,(d+c)/2),Math.max(c,(d+c)/2)];if(e>m[0]&&e<=m[1]||e>=v[0]&&e<=v[1]){({index:o}=r[l]);break}}else{var g=Math.min(s,f),x=Math.max(s,f);if(e>(g+c)/2&&e<=(x+c)/2){({index:o}=r[l]);break}}}else if(t){for(var w=0;w0&&w(t[w].coordinate+t[w-1].coordinate)/2&&e<=(t[w].coordinate+t[w+1].coordinate)/2||w===u-1&&e>(t[w].coordinate+t[w-1].coordinate)/2){({index:o}=t[w]);break}}return o},hj=()=>T(Nc),ps=(e,t)=>t,Qg=(e,t,r)=>r,ms=(e,t,r,n)=>n,pj=A(Kt,e=>ha(e,t=>t.coordinate)),ys=A([Gr,ps,Qg,ms],zg),gs=A([ys,Vr,Wn,Gn],cs),mj=(e,t,r)=>{if(t!=null){var n=Gr(e);return t==="axis"?r==="hover"?n.axisInteraction.hover.dataKey:n.axisInteraction.click.dataKey:r==="hover"?n.itemInteraction.hover.dataKey:n.itemInteraction.click.dataKey}},Jg=A([Gr,ps,Qg,ms],Fg),ea=A([Rt,Lt,q,ye,Kt,ms,Jg,Hn],Bg),yj=A([ys,ea],(e,t)=>{var r;return(r=e.coordinate)!==null&&r!==void 0?r:t}),e0=A([Kt,gs],Dg),gj=A([Jg,gs,rr,Wn,e0,Hn,ps],Kg),bj=A([ys,gs],(e,t)=>({isActive:e.active&&t!=null,activeIndex:t})),wj=(e,t,r,n,i,a,o)=>{if(!(!e||!r||!n||!i)&&vj(e,o)){var u=$P(e,t),l=Zg(u,a,i,r,n),s=fj(t,i,l,e);return{activeIndex:String(l),activeCoordinate:s}}},xj=(e,t,r,n,i,a,o)=>{if(!(!e||!n||!i||!a||!r)){var u=J1(e,r);if(u){var l=RP(u,t),s=Zg(l,o,a,n,i),c=dj(t,a,s,u);return{activeIndex:String(s),activeCoordinate:c}}}},Pj=(e,t,r,n,i,a,o,u)=>{if(!(!e||!t||!n||!i||!a))return t==="horizontal"||t==="vertical"?wj(e,t,n,i,a,o,u):xj(e,t,r,n,i,a,o)},Oj=A(e=>e.zIndex.zIndexMap,(e,t)=>t,(e,t,r)=>r,(e,t,r)=>{if(t!=null){var n=e[t];if(n!=null)return r?n.panoramaElementId:n.elementId}}),Aj=A(e=>e.zIndex.zIndexMap,e=>{var t=Object.keys(e).map(n=>parseInt(n,10)).concat(Object.values(ve)),r=Array.from(new Set(t));return r.sort((n,i)=>n-i)},{memoizeOptions:{resultEqualityCheck:o_}});function Yv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Gv(e){for(var t=1;tGv(Gv({},e),{},{[t]:{elementId:void 0,panoramaElementId:void 0,consumers:0}}),kj)},Cj=new Set(Object.values(ve));function Ij(e){return Cj.has(e)}var t0=qe({name:"zIndex",initialState:jj,reducers:{registerZIndexPortal:{reducer:(e,t)=>{var{zIndex:r}=t.payload;e.zIndexMap[r]?e.zIndexMap[r].consumers+=1:e.zIndexMap[r]={consumers:1,elementId:void 0,panoramaElementId:void 0}},prepare:re()},unregisterZIndexPortal:{reducer:(e,t)=>{var{zIndex:r}=t.payload;e.zIndexMap[r]&&(e.zIndexMap[r].consumers-=1,e.zIndexMap[r].consumers<=0&&!Ij(r)&&delete e.zIndexMap[r])},prepare:re()},registerZIndexPortalId:{reducer:(e,t)=>{var{zIndex:r,elementId:n,isPanorama:i}=t.payload;e.zIndexMap[r]?i?e.zIndexMap[r].panoramaElementId=n:e.zIndexMap[r].elementId=n:e.zIndexMap[r]={consumers:0,elementId:i?void 0:n,panoramaElementId:i?n:void 0}},prepare:re()},unregisterZIndexPortalId:{reducer:(e,t)=>{var{zIndex:r}=t.payload;e.zIndexMap[r]&&(t.payload.isPanorama?e.zIndexMap[r].panoramaElementId=void 0:e.zIndexMap[r].elementId=void 0)},prepare:re()}}}),{registerZIndexPortal:Mj,unregisterZIndexPortal:Tj,registerZIndexPortalId:Dj,unregisterZIndexPortalId:Nj}=t0.actions,$j=t0.reducer;function We(e){var{zIndex:t,children:r}=e,n=hO(),i=n&&t!==void 0&&t!==0,a=Me(),o=ee();h.useLayoutEffect(()=>i?(o(Mj({zIndex:t})),()=>{o(Tj({zIndex:t}))}):Sn,[o,t,i]);var u=T(s=>Oj(s,t,a));if(!i)return r;if(!u)return null;var l=document.getElementById(u);return l?Nl.createPortal(r,l):null}function Al(){return Al=Object.assign?Object.assign.bind():function(e){for(var t=1;th.useContext(r0),yu={exports:{}},Xv;function Wj(){return Xv||(Xv=1,(function(e){var t=Object.prototype.hasOwnProperty,r="~";function n(){}Object.create&&(n.prototype=Object.create(null),new n().__proto__||(r=!1));function i(l,s,c){this.fn=l,this.context=s,this.once=c||!1}function a(l,s,c,f,d){if(typeof c!="function")throw new TypeError("The listener must be a function");var v=new i(c,f||l,d),p=r?r+s:s;return l._events[p]?l._events[p].fn?l._events[p]=[l._events[p],v]:l._events[p].push(v):(l._events[p]=v,l._eventsCount++),l}function o(l,s){--l._eventsCount===0?l._events=new n:delete l._events[s]}function u(){this._events=new n,this._eventsCount=0}u.prototype.eventNames=function(){var s=[],c,f;if(this._eventsCount===0)return s;for(f in c=this._events)t.call(c,f)&&s.push(r?f.slice(1):f);return Object.getOwnPropertySymbols?s.concat(Object.getOwnPropertySymbols(c)):s},u.prototype.listeners=function(s){var c=r?r+s:s,f=this._events[c];if(!f)return[];if(f.fn)return[f.fn];for(var d=0,v=f.length,p=new Array(v);d{e.eventEmitter==null&&(e.eventEmitter=Symbol("rechartsEventEmitter"))}}}),Gj=n0.reducer,{createEventEmitter:Vj}=n0.actions;function Xj(e){return e.tooltip.syncInteraction}var Zj={chartData:void 0,computedData:void 0,dataStartIndex:0,dataEndIndex:0},i0=qe({name:"chartData",initialState:Zj,reducers:{setChartData(e,t){if(e.chartData=t.payload,t.payload==null){e.dataStartIndex=0,e.dataEndIndex=0;return}t.payload.length>0&&e.dataEndIndex!==t.payload.length-1&&(e.dataEndIndex=t.payload.length-1)},setComputedData(e,t){e.computedData=t.payload},setDataStartEndIndexes(e,t){var{startIndex:r,endIndex:n}=t.payload;r!=null&&(e.dataStartIndex=r),n!=null&&(e.dataEndIndex=n)}}}),{setChartData:Qv,setDataStartEndIndexes:Qj,setComputedData:N$}=i0.actions,Jj=i0.reducer,eC=["x","y"];function Jv(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Sr(e){for(var t=1;tl.rootProps.className);h.useEffect(()=>{if(e==null)return Sn;var l=(s,c,f)=>{if(t!==f&&e===s){if(n==="index"){var d;if(o&&c!==null&&c!==void 0&&(d=c.payload)!==null&&d!==void 0&&d.coordinate&&c.payload.sourceViewBox){var v=c.payload.coordinate,{x:p,y}=v,m=iC(v,eC),{x:g,y:x,width:w,height:P}=c.payload.sourceViewBox,b=Sr(Sr({},m),{},{x:o.x+(w?(p-g)/w:0)*o.width,y:o.y+(P?(y-x)/P:0)*o.height});r(Sr(Sr({},c),{},{payload:Sr(Sr({},c.payload),{},{coordinate:b})}))}else r(c);return}if(i!=null){var O;if(typeof n=="function"){var S={activeTooltipIndex:c.payload.index==null?void 0:Number(c.payload.index),isTooltipActive:c.payload.active,activeIndex:c.payload.index==null?void 0:Number(c.payload.index),activeLabel:c.payload.label,activeDataKey:c.payload.dataKey,activeCoordinate:c.payload.coordinate},_=n(i,S);O=i[_]}else n==="value"&&(O=i.find(K=>String(K.value)===c.payload.label));var{coordinate:I}=c.payload;if(O==null||c.payload.active===!1||I==null||o==null){r(Pl({active:!1,coordinate:void 0,dataKey:void 0,index:null,label:void 0,sourceViewBox:void 0,graphicalItemId:void 0}));return}var{x:M,y:E}=I,j=Math.min(M,o.x+o.width),$=Math.min(E,o.y+o.height),L={x:a==="horizontal"?O.coordinate:j,y:a==="horizontal"?$:O.coordinate},z=Pl({active:c.payload.active,coordinate:L,dataKey:c.payload.dataKey,index:String(O.index),label:c.payload.label,sourceViewBox:c.payload.sourceViewBox,graphicalItemId:c.payload.graphicalItemId});r(z)}}};return Pn.on(Sl,l),()=>{Pn.off(Sl,l)}},[u,r,t,e,n,i,a,o])}function uC(){var e=T($c),t=T(Rc),r=ee();h.useEffect(()=>{if(e==null)return Sn;var n=(i,a,o)=>{t!==o&&e===i&&r(Qj(a))};return Pn.on(Zv,n),()=>{Pn.off(Zv,n)}},[r,t,e])}function lC(){var e=ee();h.useEffect(()=>{e(Vj())},[e]),oC(),uC()}function cC(e,t,r,n,i,a){var o=T(v=>mj(v,e,t)),u=T(Rc),l=T($c),s=T(eg),c=T(Xj),f=c?.active,d=_a();h.useEffect(()=>{if(!f&&l!=null&&u!=null){var v=Pl({active:a,coordinate:r,dataKey:o,index:i,label:typeof n=="number"?String(n):n,sourceViewBox:d,graphicalItemId:void 0});Pn.emit(Sl,l,v,u)}},[f,r,o,i,n,u,l,s,a,d])}function eh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function th(e){for(var t=1;t{S(sk({shared:x,trigger:w,axisId:O,active:i,defaultIndex:_}))},[S,x,w,O,i,_]);var I=_a(),M=Wm(),E=ik(x),{activeIndex:j,isActive:$}=(t=T(ze=>bj(ze,E,w,_)))!==null&&t!==void 0?t:{},L=T(ze=>gj(ze,E,w,_)),z=T(ze=>e0(ze,E,w,_)),K=T(ze=>yj(ze,E,w,_)),B=L,W=qj(),R=(r=i??$)!==null&&r!==void 0?r:!1,[ke,Te]=Yp([B,R]),Le=E==="axis"?z:void 0;cC(E,w,K,Le,j,R);var Pt=b??W;if(Pt==null||I==null||E==null)return null;var Je=B??rh;R||(Je=rh),s&&Je.length&&(Je=Kp(Je.filter(ze=>ze.value!=null&&(ze.hide!==!0||n.includeHidden)),d,vC));var nr=Je.length>0,Xr=h.createElement(e1,{allowEscapeViewBox:a,animationDuration:o,animationEasing:u,isAnimationActive:c,active:R,coordinate:K,hasPayload:nr,offset:f,position:v,reverseDirection:p,useTranslate3d:y,viewBox:I,wrapperStyle:m,lastBoundingBox:ke,innerRef:Te,hasPortalFromProps:!!b},hC(l,th(th({},n),{},{payload:Je,label:Le,active:R,activeIndex:j,coordinate:K,accessibilityLayer:M})));return h.createElement(h.Fragment,null,Nl.createPortal(Xr,Pt),R&&h.createElement(Kj,{cursor:g,tooltipEventType:E,coordinate:K,payload:Je,index:j}))}var Va=e=>null;Va.displayName="Cell";function mC(e,t,r){return(t=yC(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function yC(e){var t=gC(e,"string");return typeof t=="symbol"?t:t+""}function gC(e,t){if(typeof e!="object"||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var n=r.call(e,t);if(typeof n!="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}class bC{constructor(t){mC(this,"cache",new Map),this.maxSize=t}get(t){var r=this.cache.get(t);return r!==void 0&&(this.cache.delete(t),this.cache.set(t,r)),r}set(t,r){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.maxSize){var n=this.cache.keys().next().value;n!=null&&this.cache.delete(n)}this.cache.set(t,r)}clear(){this.cache.clear()}size(){return this.cache.size}}function nh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function wC(e){for(var t=1;t{try{var r=document.getElementById(ah);r||(r=document.createElement("span"),r.setAttribute("id",ah),r.setAttribute("aria-hidden","true"),document.body.appendChild(r)),Object.assign(r.style,SC,t),r.textContent="".concat(e);var n=r.getBoundingClientRect();return{width:n.width,height:n.height}}catch{return{width:0,height:0}}},ln=function(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(t==null||Tn.isSsr)return{width:0,height:0};if(!a0.enableCache)return oh(t,r);var n=EC(t,r),i=ih.get(n);if(i)return i;var a=oh(t,r);return ih.set(n,a),a},uh=/(-?\d+(?:\.\d+)?[a-zA-Z%]*)([*/])(-?\d+(?:\.\d+)?[a-zA-Z%]*)/,lh=/(-?\d+(?:\.\d+)?[a-zA-Z%]*)([+-])(-?\d+(?:\.\d+)?[a-zA-Z%]*)/,_C=/^px|cm|vh|vw|em|rem|%|mm|in|pt|pc|ex|ch|vmin|vmax|Q$/,kC=/(-?\d+(?:\.\d+)?)([a-zA-Z%]+)?/,o0={cm:96/2.54,mm:96/25.4,pt:96/72,pc:96/6,in:96,Q:96/(2.54*40),px:1},jC=Object.keys(o0),kr="NaN";function CC(e,t){return e*o0[t]}class Fe{static parse(t){var r,[,n,i]=(r=kC.exec(t))!==null&&r!==void 0?r:[];return new Fe(parseFloat(n),i??"")}constructor(t,r){this.num=t,this.unit=r,this.num=t,this.unit=r,dt(t)&&(this.unit=""),r!==""&&!_C.test(r)&&(this.num=NaN,this.unit=""),jC.includes(r)&&(this.num=CC(t,r),this.unit="px")}add(t){return this.unit!==t.unit?new Fe(NaN,""):new Fe(this.num+t.num,this.unit)}subtract(t){return this.unit!==t.unit?new Fe(NaN,""):new Fe(this.num-t.num,this.unit)}multiply(t){return this.unit!==""&&t.unit!==""&&this.unit!==t.unit?new Fe(NaN,""):new Fe(this.num*t.num,this.unit||t.unit)}divide(t){return this.unit!==""&&t.unit!==""&&this.unit!==t.unit?new Fe(NaN,""):new Fe(this.num/t.num,this.unit||t.unit)}toString(){return"".concat(this.num).concat(this.unit)}isNaN(){return dt(this.num)}}function u0(e){if(e.includes(kr))return kr;for(var t=e;t.includes("*")||t.includes("/");){var r,[,n,i,a]=(r=uh.exec(t))!==null&&r!==void 0?r:[],o=Fe.parse(n??""),u=Fe.parse(a??""),l=i==="*"?o.multiply(u):o.divide(u);if(l.isNaN())return kr;t=t.replace(uh,l.toString())}for(;t.includes("+")||/.-\d+(?:\.\d+)?/.test(t);){var s,[,c,f,d]=(s=lh.exec(t))!==null&&s!==void 0?s:[],v=Fe.parse(c??""),p=Fe.parse(d??""),y=f==="+"?v.add(p):v.subtract(p);if(y.isNaN())return kr;t=t.replace(lh,y.toString())}return t}var ch=/\(([^()]*)\)/;function IC(e){for(var t=e,r;(r=ch.exec(t))!=null;){var[,n]=r;t=t.replace(ch,u0(n))}return t}function MC(e){var t=e.replace(/\s+/g,"");return t=IC(t),t=u0(t),t}function TC(e){try{return MC(e)}catch{return kr}}function gu(e){var t=TC(e.slice(5,-1));return t===kr?"":t}var DC=["x","y","lineHeight","capHeight","fill","scaleToFit","textAnchor","verticalAnchor"],NC=["dx","dy","angle","className","breakAll"];function El(){return El=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var{children:t,breakAll:r,style:n}=e;try{var i=[];ae(t)||(r?i=t.toString().split(""):i=t.toString().split(l0));var a=i.map(u=>({word:u,width:ln(u,n).width})),o=r?0:ln(" ",n).width;return{wordsWithComputedWidth:a,spaceWidth:o}}catch{return null}};function RC(e){return e==="start"||e==="middle"||e==="end"||e==="inherit"}var s0=(e,t,r,n)=>e.reduce((i,a)=>{var{word:o,width:u}=a,l=i[i.length-1];if(l&&u!=null&&(t==null||n||l.width+u+re.reduce((t,r)=>t.width>r.width?t:r),LC="…",fh=(e,t,r,n,i,a,o,u)=>{var l=e.slice(0,t),s=c0({breakAll:r,style:n,children:l+LC});if(!s)return[!1,[]];var c=s0(s.wordsWithComputedWidth,a,o,u),f=c.length>i||f0(c).width>Number(a);return[f,c]},zC=(e,t,r,n,i)=>{var{maxLines:a,children:o,style:u,breakAll:l}=e,s=N(a),c=String(o),f=s0(t,n,r,i);if(!s||i)return f;var d=f.length>a||f0(f).width>Number(n);if(!d)return f;for(var v=0,p=c.length-1,y=0,m;v<=p&&y<=c.length-1;){var g=Math.floor((v+p)/2),x=g-1,[w,P]=fh(c,x,l,u,a,n,r,i),[b]=fh(c,g,l,u,a,n,r,i);if(!w&&!b&&(v=g+1),w&&b&&(p=g-1),!w&&b){m=P;break}y++}return m||f},dh=e=>{var t=ae(e)?[]:e.toString().split(l0);return[{words:t,width:void 0}]},BC=e=>{var{width:t,scaleToFit:r,children:n,style:i,breakAll:a,maxLines:o}=e;if((t||r)&&!Tn.isSsr){var u,l,s=c0({breakAll:a,children:n,style:i});if(s){var{wordsWithComputedWidth:c,spaceWidth:f}=s;u=c,l=f}else return dh(n);return zC({breakAll:a,children:n,maxLines:o,style:i},u,l,t,!!r)}return dh(n)},d0="#808080",FC={angle:0,breakAll:!1,capHeight:"0.71em",fill:d0,lineHeight:"1em",scaleToFit:!1,textAnchor:"start",verticalAnchor:"end",x:0,y:0},Xa=h.forwardRef((e,t)=>{var r=pe(e,FC),{x:n,y:i,lineHeight:a,capHeight:o,fill:u,scaleToFit:l,textAnchor:s,verticalAnchor:c}=r,f=sh(r,DC),d=h.useMemo(()=>BC({breakAll:f.breakAll,children:f.children,maxLines:f.maxLines,scaleToFit:l,style:f.style,width:f.width}),[f.breakAll,f.children,f.maxLines,l,f.style,f.width]),{dx:v,dy:p,angle:y,className:m,breakAll:g}=f,x=sh(f,NC);if(!bt(n)||!bt(i)||d.length===0)return null;var w=Number(n)+(N(v)?v:0),P=Number(i)+(N(p)?p:0);if(!se(w)||!se(P))return null;var b;switch(c){case"start":b=gu("calc(".concat(o,")"));break;case"middle":b=gu("calc(".concat((d.length-1)/2," * -").concat(a," + (").concat(o," / 2))"));break;default:b=gu("calc(".concat(d.length-1," * -").concat(a,")"));break}var O=[];if(l){var S=d[0].width,{width:_}=f;O.push("scale(".concat(N(_)&&N(S)?_/S:1,")"))}return y&&O.push("rotate(".concat(y,", ").concat(w,", ").concat(P,")")),O.length&&(x.transform=O.join(" ")),h.createElement("text",El({},$e(x),{ref:t,x:w,y:P,className:H("recharts-text",m),textAnchor:s,fill:u.includes("url")?d0:u}),d.map((I,M)=>{var E=I.words.join(g?"":" ");return h.createElement("tspan",{x:w,dy:M===0?b:a,key:"".concat(E,"-").concat(M)},E)}))});Xa.displayName="Text";var KC=["labelRef"];function qC(e,t){if(e==null)return{};var r,n,i=WC(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n{var{x:t,y:r,upperWidth:n,lowerWidth:i,width:a,height:o,children:u}=e,l=h.useMemo(()=>({x:t,y:r,upperWidth:n,lowerWidth:i,width:a,height:o}),[t,r,n,i,a,o]);return h.createElement(v0.Provider,{value:l},u)},h0=()=>{var e=h.useContext(v0),t=_a();return e||Mm(t)},VC=h.createContext(null),XC=()=>{var e=h.useContext(VC),t=T(ag);return e||t},ZC=e=>{var{value:t,formatter:r}=e,n=ae(e.children)?t:e.children;return typeof r=="function"?r(n):n},ws=e=>e!=null&&typeof e=="function",QC=(e,t)=>{var r=Ae(t-e),n=Math.min(Math.abs(t-e),360);return r*n},JC=(e,t,r,n,i)=>{var{offset:a,className:o}=e,{cx:u,cy:l,innerRadius:s,outerRadius:c,startAngle:f,endAngle:d,clockWise:v}=i,p=(s+c)/2,y=QC(f,d),m=y>=0?1:-1,g,x;switch(t){case"insideStart":g=f+m*a,x=v;break;case"insideEnd":g=d-m*a,x=!v;break;case"end":g=d+m*a,x=v;break;default:throw new Error("Unsupported position ".concat(t))}x=y<=0?x:!x;var w=de(u,l,p,g),P=de(u,l,p,g+(x?1:-1)*359),b="M".concat(w.x,",").concat(w.y,` + A`).concat(p,",").concat(p,",0,1,").concat(x?0:1,`, + `).concat(P.x,",").concat(P.y),O=ae(e.id)?cn("recharts-radial-line-"):e.id;return h.createElement("text",St({},n,{dominantBaseline:"central",className:H("recharts-radial-bar-label",o)}),h.createElement("defs",null,h.createElement("path",{id:O,d:b})),h.createElement("textPath",{xlinkHref:"#".concat(O)},r))},eI=(e,t,r)=>{var{cx:n,cy:i,innerRadius:a,outerRadius:o,startAngle:u,endAngle:l}=e,s=(u+l)/2;if(r==="outside"){var{x:c,y:f}=de(n,i,o+t,s);return{x:c,y:f,textAnchor:c>=n?"start":"end",verticalAnchor:"middle"}}if(r==="center")return{x:n,y:i,textAnchor:"middle",verticalAnchor:"middle"};if(r==="centerTop")return{x:n,y:i,textAnchor:"middle",verticalAnchor:"start"};if(r==="centerBottom")return{x:n,y:i,textAnchor:"middle",verticalAnchor:"end"};var d=(a+o)/2,{x:v,y:p}=de(n,i,d,s);return{x:v,y:p,textAnchor:"middle",verticalAnchor:"middle"}},_l=e=>"cx"in e&&N(e.cx),tI=(e,t)=>{var{parentViewBox:r,offset:n,position:i}=e,a;r!=null&&!_l(r)&&(a=r);var{x:o,y:u,upperWidth:l,lowerWidth:s,height:c}=t,f=o,d=o+(l-s)/2,v=(f+d)/2,p=(l+s)/2,y=f+l/2,m=c>=0?1:-1,g=m*n,x=m>0?"end":"start",w=m>0?"start":"end",P=l>=0?1:-1,b=P*n,O=P>0?"end":"start",S=P>0?"start":"end";if(i==="top"){var _={x:f+l/2,y:u-g,textAnchor:"middle",verticalAnchor:x};return ce(ce({},_),a?{height:Math.max(u-a.y,0),width:l}:{})}if(i==="bottom"){var I={x:d+s/2,y:u+c+g,textAnchor:"middle",verticalAnchor:w};return ce(ce({},I),a?{height:Math.max(a.y+a.height-(u+c),0),width:s}:{})}if(i==="left"){var M={x:v-b,y:u+c/2,textAnchor:O,verticalAnchor:"middle"};return ce(ce({},M),a?{width:Math.max(M.x-a.x,0),height:c}:{})}if(i==="right"){var E={x:v+p+b,y:u+c/2,textAnchor:S,verticalAnchor:"middle"};return ce(ce({},E),a?{width:Math.max(a.x+a.width-E.x,0),height:c}:{})}var j=a?{width:p,height:c}:{};return i==="insideLeft"?ce({x:v+b,y:u+c/2,textAnchor:S,verticalAnchor:"middle"},j):i==="insideRight"?ce({x:v+p-b,y:u+c/2,textAnchor:O,verticalAnchor:"middle"},j):i==="insideTop"?ce({x:f+l/2,y:u+g,textAnchor:"middle",verticalAnchor:w},j):i==="insideBottom"?ce({x:d+s/2,y:u+c-g,textAnchor:"middle",verticalAnchor:x},j):i==="insideTopLeft"?ce({x:f+b,y:u+g,textAnchor:S,verticalAnchor:w},j):i==="insideTopRight"?ce({x:f+l-b,y:u+g,textAnchor:O,verticalAnchor:w},j):i==="insideBottomLeft"?ce({x:d+b,y:u+c-g,textAnchor:S,verticalAnchor:x},j):i==="insideBottomRight"?ce({x:d+s-b,y:u+c-g,textAnchor:O,verticalAnchor:x},j):i&&typeof i=="object"&&(N(i.x)||Ct(i.x))&&(N(i.y)||Ct(i.y))?ce({x:o+Ie(i.x,p),y:u+Ie(i.y,c),textAnchor:"end",verticalAnchor:"end"},j):ce({x:y,y:u+c/2,textAnchor:"middle",verticalAnchor:"middle"},j)},rI={angle:0,offset:5,zIndex:ve.label,position:"middle",textBreakAll:!1};function Wt(e){var t=pe(e,rI),{viewBox:r,position:n,value:i,children:a,content:o,className:u="",textBreakAll:l,labelRef:s}=t,c=XC(),f=h0(),d=n==="center"?f:c??f,v,p,y;if(r==null?v=d:_l(r)?v=r:v=Mm(r),!v||ae(i)&&ae(a)&&!h.isValidElement(o)&&typeof o!="function")return null;var m=ce(ce({},t),{},{viewBox:v});if(h.isValidElement(o)){var{labelRef:g}=m,x=qC(m,KC);return h.cloneElement(o,x)}if(typeof o=="function"){if(p=h.createElement(o,m),h.isValidElement(p))return p}else p=ZC(t);var w=$e(t);if(_l(v)){if(n==="insideStart"||n==="insideEnd"||n==="end")return JC(t,n,p,w,v);y=eI(v,t.offset,t.position)}else y=tI(t,v);return h.createElement(We,{zIndex:t.zIndex},h.createElement(Xa,St({ref:s,className:H("recharts-label",u)},w,y,{textAnchor:RC(w.textAnchor)?w.textAnchor:y.textAnchor,breakAll:l}),p))}Wt.displayName="Label";var nI=(e,t,r)=>{if(!e)return null;var n={viewBox:t,labelRef:r};return e===!0?h.createElement(Wt,St({key:"label-implicit"},n)):bt(e)?h.createElement(Wt,St({key:"label-implicit",value:e},n)):h.isValidElement(e)?e.type===Wt?h.cloneElement(e,ce({key:"label-implicit"},n)):h.createElement(Wt,St({key:"label-implicit",content:e},n)):ws(e)?h.createElement(Wt,St({key:"label-implicit",content:e},n)):e&&typeof e=="object"?h.createElement(Wt,St({},e,{key:"label-implicit"},n)):null};function iI(e){var{label:t,labelRef:r}=e,n=h0();return nI(t,n,r)||null}var bu={},wu={},hh;function aI(){return hh||(hh=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return r[r.length-1]}e.last=t})(wu)),wu}var xu={},ph;function oI(){return ph||(ph=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){return Array.isArray(r)?r:Array.from(r)}e.toArray=t})(xu)),xu}var mh;function uI(){return mh||(mh=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});const t=aI(),r=oI(),n=Hl();function i(a){if(n.isArrayLike(a))return t.last(r.toArray(a))}e.last=i})(bu)),bu}var Pu,yh;function lI(){return yh||(yh=1,Pu=uI().last),Pu}var cI=lI();const sI=Qt(cI);var fI=["valueAccessor"],dI=["dataKey","clockWise","id","textBreakAll","zIndex"];function ta(){return ta=Object.assign?Object.assign.bind():function(e){for(var t=1;tArray.isArray(e.value)?sI(e.value):e.value,p0=h.createContext(void 0),m0=p0.Provider,y0=h.createContext(void 0),pI=y0.Provider;function mI(){return h.useContext(p0)}function yI(){return h.useContext(y0)}function bi(e){var{valueAccessor:t=hI}=e,r=gh(e,fI),{dataKey:n,clockWise:i,id:a,textBreakAll:o,zIndex:u}=r,l=gh(r,dI),s=mI(),c=yI(),f=s||c;return!f||!f.length?null:h.createElement(We,{zIndex:u??ve.label},h.createElement(Se,{className:"recharts-label-list"},f.map((d,v)=>{var p,y=ae(n)?t(d,v):X(d&&d.payload,n),m=ae(a)?{}:{id:"".concat(a,"-").concat(v)};return h.createElement(Wt,ta({key:"label-".concat(v)},$e(d),l,m,{fill:(p=r.fill)!==null&&p!==void 0?p:d.fill,parentViewBox:d.parentViewBox,value:y,textBreakAll:o,viewBox:d.viewBox,index:v,zIndex:0}))})))}bi.displayName="LabelList";function xs(e){var{label:t}=e;return t?t===!0?h.createElement(bi,{key:"labelList-implicit"}):h.isValidElement(t)||ws(t)?h.createElement(bi,{key:"labelList-implicit",content:t}):typeof t=="object"?h.createElement(bi,ta({key:"labelList-implicit"},t,{type:String(t.type)})):null:null}function kl(){return kl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var{cx:t,cy:r,r:n,className:i}=e,a=H("recharts-dot",i);return N(t)&&N(r)&&N(n)?h.createElement("circle",kl({},Ze(e),Ul(e),{className:a,cx:t,cy:r,r:n})):null},b0=e=>e.graphicalItems.polarItems,gI=A([oe,Fn],qc),Za=A([b0,ue,gI],Wc),bI=A([Za],Uc),Qa=A([bI,Mc],Hc),wI=A([Qa,ue,Za],Gc);A([Qa,ue,Za],(e,t,r)=>r.length>0?e.flatMap(n=>r.flatMap(i=>{var a,o=X(n,(a=t.dataKey)!==null&&a!==void 0?a:i.dataKey);return{value:o,errorDomain:[]}})).filter(Boolean):t?.dataKey!=null?e.map(n=>({value:X(n,t.dataKey),errorDomain:[]})):e.map(n=>({value:n,errorDomain:[]})));var bh=()=>{},xI=A([Qa,ue,Za,Ha,oe],Qc),PI=A([ue,Xc,Zc,bh,xI,bh,q,oe],Jc),w0=A([ue,q,Qa,wI,Bn,oe,PI],es),OI=A([w0,ue,Hr],ns);A([ue,w0,OI,oe],as);var AI={radiusAxis:{},angleAxis:{}},x0=qe({name:"polarAxis",initialState:AI,reducers:{addRadiusAxis(e,t){e.radiusAxis[t.payload.id]=t.payload},removeRadiusAxis(e,t){delete e.radiusAxis[t.payload.id]},addAngleAxis(e,t){e.angleAxis[t.payload.id]=t.payload},removeAngleAxis(e,t){delete e.angleAxis[t.payload.id]}}}),{addRadiusAxis:R$,removeRadiusAxis:L$,addAngleAxis:z$,removeAngleAxis:B$}=x0.actions,SI=x0.reducer;function wh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function xh(e){for(var t=1;tt,Ps=A([b0,jI],(e,t)=>e.filter(r=>r.type==="pie").find(r=>r.id===t)),CI=[],Os=(e,t,r)=>r?.length===0?CI:r,P0=A([Mc,Ps,Os],(e,t,r)=>{var{chartData:n}=e;if(t!=null){var i;if(t?.data!=null&&t.data.length>0?i=t.data:i=n,(!i||!i.length)&&r!=null&&(i=r.map(a=>xh(xh({},t.presentationProps),a.props))),i!=null)return i}}),II=A([P0,Ps,Os],(e,t,r)=>{if(!(e==null||t==null))return e.map((n,i)=>{var a,o=X(n,t.nameKey,t.name),u;return r!=null&&(a=r[i])!==null&&a!==void 0&&(a=a.props)!==null&&a!==void 0&&a.fill?u=r[i].props.fill:typeof n=="object"&&n!=null&&"fill"in n?u=n.fill:u=t.fill,{value:Br(o,t.dataKey),color:u,payload:n,type:t.legendType}})}),MI=A([P0,Ps,Os,ye],(e,t,r,n)=>{if(!(t==null||e==null))return TM({offset:n,pieSettings:t,displayedData:e,cells:r})}),Ou={exports:{}},G={};var Ph;function TI(){if(Ph)return G;Ph=1;var e=typeof Symbol=="function"&&Symbol.for,t=e?Symbol.for("react.element"):60103,r=e?Symbol.for("react.portal"):60106,n=e?Symbol.for("react.fragment"):60107,i=e?Symbol.for("react.strict_mode"):60108,a=e?Symbol.for("react.profiler"):60114,o=e?Symbol.for("react.provider"):60109,u=e?Symbol.for("react.context"):60110,l=e?Symbol.for("react.async_mode"):60111,s=e?Symbol.for("react.concurrent_mode"):60111,c=e?Symbol.for("react.forward_ref"):60112,f=e?Symbol.for("react.suspense"):60113,d=e?Symbol.for("react.suspense_list"):60120,v=e?Symbol.for("react.memo"):60115,p=e?Symbol.for("react.lazy"):60116,y=e?Symbol.for("react.block"):60121,m=e?Symbol.for("react.fundamental"):60117,g=e?Symbol.for("react.responder"):60118,x=e?Symbol.for("react.scope"):60119;function w(b){if(typeof b=="object"&&b!==null){var O=b.$$typeof;switch(O){case t:switch(b=b.type,b){case l:case s:case n:case a:case i:case f:return b;default:switch(b=b&&b.$$typeof,b){case u:case c:case p:case v:case o:return b;default:return O}}case r:return O}}}function P(b){return w(b)===s}return G.AsyncMode=l,G.ConcurrentMode=s,G.ContextConsumer=u,G.ContextProvider=o,G.Element=t,G.ForwardRef=c,G.Fragment=n,G.Lazy=p,G.Memo=v,G.Portal=r,G.Profiler=a,G.StrictMode=i,G.Suspense=f,G.isAsyncMode=function(b){return P(b)||w(b)===l},G.isConcurrentMode=P,G.isContextConsumer=function(b){return w(b)===u},G.isContextProvider=function(b){return w(b)===o},G.isElement=function(b){return typeof b=="object"&&b!==null&&b.$$typeof===t},G.isForwardRef=function(b){return w(b)===c},G.isFragment=function(b){return w(b)===n},G.isLazy=function(b){return w(b)===p},G.isMemo=function(b){return w(b)===v},G.isPortal=function(b){return w(b)===r},G.isProfiler=function(b){return w(b)===a},G.isStrictMode=function(b){return w(b)===i},G.isSuspense=function(b){return w(b)===f},G.isValidElementType=function(b){return typeof b=="string"||typeof b=="function"||b===n||b===s||b===a||b===i||b===f||b===d||typeof b=="object"&&b!==null&&(b.$$typeof===p||b.$$typeof===v||b.$$typeof===o||b.$$typeof===u||b.$$typeof===c||b.$$typeof===m||b.$$typeof===g||b.$$typeof===x||b.$$typeof===y)},G.typeOf=w,G}var Oh;function DI(){return Oh||(Oh=1,Ou.exports=TI()),Ou.exports}var NI=DI(),Ah=e=>typeof e=="string"?e:e?e.displayName||e.name||"Component":"",Sh=null,Au=null,O0=e=>{if(e===Sh&&Array.isArray(Au))return Au;var t=[];return h.Children.forEach(e,r=>{ae(r)||(NI.isFragment(r)?t=t.concat(O0(r.props.children)):t.push(r))}),Au=t,Sh=e,t};function As(e,t){var r=[],n=[];return Array.isArray(t)?n=t.map(i=>Ah(i)):n=[Ah(t)],O0(e).forEach(i=>{var a=pr(i,"type.displayName")||pr(i,"type.name");a&&n.indexOf(a)!==-1&&r.push(i)}),r}var A0=e=>e&&typeof e=="object"&&"clipDot"in e?!!e.clipDot:!0,Su={},Eh;function $I(){return Eh||(Eh=1,(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function t(r){if(typeof r!="object"||r==null)return!1;if(Object.getPrototypeOf(r)===null)return!0;if(Object.prototype.toString.call(r)!=="[object Object]"){const i=r[Symbol.toStringTag];return i==null||!Object.getOwnPropertyDescriptor(r,Symbol.toStringTag)?.writable?!1:r.toString()===`[object ${i}]`}let n=r;for(;Object.getPrototypeOf(n)!==null;)n=Object.getPrototypeOf(n);return Object.getPrototypeOf(r)===n}e.isPlainObject=t})(Su)),Su}var Eu,_h;function RI(){return _h||(_h=1,Eu=$I().isPlainObject),Eu}var LI=RI();const zI=Qt(LI);function kh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function jh(e){for(var t=1;t{var a=r-n,o;return o="M ".concat(e,",").concat(t),o+="L ".concat(e+r,",").concat(t),o+="L ".concat(e+r-a/2,",").concat(t+i),o+="L ".concat(e+r-a/2-n,",").concat(t+i),o+="L ".concat(e,",").concat(t," Z"),o},qI={x:0,y:0,upperWidth:0,lowerWidth:0,height:0,isUpdateAnimationActive:!1,animationBegin:0,animationDuration:1500,animationEasing:"ease"},WI=e=>{var t=pe(e,qI),{x:r,y:n,upperWidth:i,lowerWidth:a,height:o,className:u}=t,{animationEasing:l,animationDuration:s,animationBegin:c,isUpdateAnimationActive:f}=t,d=h.useRef(null),[v,p]=h.useState(-1),y=h.useRef(i),m=h.useRef(a),g=h.useRef(o),x=h.useRef(r),w=h.useRef(n),P=Nn(e,"trapezoid-");if(h.useEffect(()=>{if(d.current&&d.current.getTotalLength)try{var L=d.current.getTotalLength();L&&p(L)}catch{}},[]),r!==+r||n!==+n||i!==+i||a!==+a||o!==+o||i===0&&a===0||o===0)return null;var b=H("recharts-trapezoid",u);if(!f)return h.createElement("g",null,h.createElement("path",ra({},$e(t),{className:b,d:Ch(r,n,i,a,o)})));var O=y.current,S=m.current,_=g.current,I=x.current,M=w.current,E="0px ".concat(v===-1?1:v,"px"),j="".concat(v,"px 0px"),$=Um(["strokeDasharray"],s,l);return h.createElement(Dn,{animationId:P,key:P,canBegin:v>0,duration:s,easing:l,isActive:f,begin:c},L=>{var z=ne(O,i,L),K=ne(S,a,L),B=ne(_,o,L),W=ne(I,r,L),R=ne(M,n,L);d.current&&(y.current=z,m.current=K,g.current=B,x.current=W,w.current=R);var ke=L>0?{transition:$,strokeDasharray:j}:{strokeDasharray:E};return h.createElement("path",ra({},$e(t),{className:b,d:Ch(W,R,z,K,B),ref:d,style:jh(jh({},ke),t.style)}))})},UI=["option","shapeType","propTransformer","activeClassName"];function HI(e,t){if(e==null)return{};var r,n,i=YI(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n{var n=ee();return(i,a)=>o=>{e?.(i,a,o),n($g({activeIndex:String(a),activeDataKey:t,activeCoordinate:i.tooltipPosition,activeGraphicalItemId:r}))}},_s=e=>{var t=ee();return(r,n)=>i=>{e?.(r,n,i),t(fk())}},ks=(e,t,r)=>{var n=ee();return(i,a)=>o=>{e?.(i,a,o),n(dk({activeIndex:String(a),activeDataKey:t,activeCoordinate:i.tooltipPosition,activeGraphicalItemId:r}))}};function js(e){var{tooltipEntrySettings:t}=e,r=ee(),n=Me(),i=h.useRef(null);return h.useLayoutEffect(()=>{n||(i.current===null?r(uk(t)):i.current!==t&&r(lk({prev:i.current,next:t})),i.current=t)},[t,r,n]),h.useLayoutEffect(()=>()=>{i.current&&(r(ck(i.current)),i.current=null)},[r]),null}function S0(e){var{legendPayload:t}=e,r=ee(),n=Me(),i=h.useRef(null);return h.useLayoutEffect(()=>{n||(i.current===null?r(Fm(t)):i.current!==t&&r(Km({prev:i.current,next:t})),i.current=t)},[r,n,t]),h.useLayoutEffect(()=>()=>{i.current&&(r(qm(i.current)),i.current=null)},[r]),null}function eM(e){var{legendPayload:t}=e,r=ee(),n=T(q),i=h.useRef(null);return h.useLayoutEffect(()=>{n!=="centric"&&n!=="radial"||(i.current===null?r(Fm(t)):i.current!==t&&r(Km({prev:i.current,next:t})),i.current=t)},[r,n,t]),h.useLayoutEffect(()=>()=>{i.current&&(r(qm(i.current)),i.current=null)},[r]),null}var _u,tM=()=>{var[e]=h.useState(()=>cn("uid-"));return e},rM=(_u=sb.useId)!==null&&_u!==void 0?_u:tM;function E0(e,t){var r=rM();return t||(e?"".concat(e,"-").concat(r):r)}var nM=h.createContext(void 0),Cs=e=>{var{id:t,type:r,children:n}=e,i=E0("recharts-".concat(r),t);return h.createElement(nM.Provider,{value:i},n(i))},iM={cartesianItems:[],polarItems:[]},_0=qe({name:"graphicalItems",initialState:iM,reducers:{addCartesianGraphicalItem:{reducer(e,t){e.cartesianItems.push(t.payload)},prepare:re()},replaceCartesianGraphicalItem:{reducer(e,t){var{prev:r,next:n}=t.payload,i=ft(e).cartesianItems.indexOf(r);i>-1&&(e.cartesianItems[i]=n)},prepare:re()},removeCartesianGraphicalItem:{reducer(e,t){var r=ft(e).cartesianItems.indexOf(t.payload);r>-1&&e.cartesianItems.splice(r,1)},prepare:re()},addPolarGraphicalItem:{reducer(e,t){e.polarItems.push(t.payload)},prepare:re()},removePolarGraphicalItem:{reducer(e,t){var r=ft(e).polarItems.indexOf(t.payload);r>-1&&e.polarItems.splice(r,1)},prepare:re()}}}),{addCartesianGraphicalItem:aM,replaceCartesianGraphicalItem:oM,removeCartesianGraphicalItem:uM,addPolarGraphicalItem:lM,removePolarGraphicalItem:cM}=_0.actions,sM=_0.reducer,fM=e=>{var t=ee(),r=h.useRef(null);return h.useLayoutEffect(()=>{r.current===null?t(aM(e)):r.current!==e&&t(oM({prev:r.current,next:e})),r.current=e},[t,e]),h.useLayoutEffect(()=>()=>{r.current&&(t(uM(r.current)),r.current=null)},[t]),null},k0=h.memo(fM);function dM(e){var t=ee();return h.useLayoutEffect(()=>(t(lM(e)),()=>{t(cM(e))}),[t,e]),null}var vM=["key"],hM=["onMouseEnter","onClick","onMouseLeave"],pM=["id"],mM=["id"];function Th(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function le(e){for(var t=1;tAs(e.children,Va),[e.children]),r=T(n=>II(n,e.id,t));return r==null?null:h.createElement(eM,{legendPayload:r})}var PM=h.memo(e=>{var{dataKey:t,nameKey:r,sectors:n,stroke:i,strokeWidth:a,fill:o,name:u,hide:l,tooltipType:s}=e,c={dataDefinedOnItem:n.map(f=>f.tooltipPayload),positions:n.map(f=>f.tooltipPosition),settings:{stroke:i,strokeWidth:a,fill:o,dataKey:t,nameKey:r,name:Br(u,t),hide:l,type:s,color:o,unit:""}};return h.createElement(js,{tooltipEntrySettings:c})}),OM=(e,t)=>e>t?"start":eIe(typeof t=="function"?t(e):t,r,r*.8),SM=(e,t,r)=>{var{top:n,left:i,width:a,height:o}=t,u=Xm(a,o),l=i+Ie(e.cx,a,a/2),s=n+Ie(e.cy,o,o/2),c=Ie(e.innerRadius,u,0),f=AM(r,e.outerRadius,u),d=e.maxRadius||Math.sqrt(a*a+o*o)/2;return{cx:l,cy:s,innerRadius:c,outerRadius:f,maxRadius:d}},EM=(e,t)=>{var r=Ae(t-e),n=Math.min(Math.abs(t-e),360);return r*n};function _M(e){return e&&typeof e=="object"&&"className"in e&&typeof e.className=="string"?e.className:""}var kM=(e,t)=>{if(h.isValidElement(e))return h.cloneElement(e,t);if(typeof e=="function")return e(t);var r=H("recharts-pie-label-line",typeof e!="boolean"?e.className:""),{key:n}=t,i=Ja(t,vM);return h.createElement(lc,Zt({},i,{type:"linear",className:r}))},jM=(e,t,r)=>{if(h.isValidElement(e))return h.cloneElement(e,t);var n=r;if(typeof e=="function"&&(n=e(t),h.isValidElement(n)))return n;var i=H("recharts-pie-label-text",_M(e));return h.createElement(Xa,Zt({},t,{alignmentBaseline:"middle",className:i}),n)};function CM(e){var{sectors:t,props:r,showLabels:n}=e,{label:i,labelLine:a,dataKey:o}=r;if(!n||!i||!t)return null;var u=Ze(r),l=hr(i),s=hr(a),c=typeof i=="object"&&"offsetRadius"in i&&typeof i.offsetRadius=="number"&&i.offsetRadius||20,f=t.map((d,v)=>{var p=(d.startAngle+d.endAngle)/2,y=de(d.cx,d.cy,d.outerRadius+c,p),m=le(le(le(le({},u),d),{},{stroke:"none"},l),{},{index:v,textAnchor:OM(y.x,d.cx)},y),g=le(le(le(le({},u),d),{},{fill:"none",stroke:d.fill},s),{},{index:v,points:[de(d.cx,d.cy,d.outerRadius,p),y],key:"line"});return h.createElement(We,{zIndex:ve.label,key:"label-".concat(d.startAngle,"-").concat(d.endAngle,"-").concat(d.midAngle,"-").concat(v)},h.createElement(Se,null,a&&kM(a,g),jM(i,m,X(d,o))))});return h.createElement(Se,{className:"recharts-pie-labels"},f)}function IM(e){var{sectors:t,props:r,showLabels:n}=e,{label:i}=r;return typeof i=="object"&&i!=null&&"position"in i?h.createElement(xs,{label:i}):h.createElement(CM,{sectors:t,props:r,showLabels:n})}function MM(e){var{sectors:t,activeShape:r,inactiveShape:n,allOtherPieProps:i,shape:a,id:o}=e,u=T(Xt),l=T(hs),s=T(Zk),{onMouseEnter:c,onClick:f,onMouseLeave:d}=i,v=Ja(i,hM),p=Es(c,i.dataKey,o),y=_s(d),m=ks(f,i.dataKey,o);return t==null||t.length===0?null:h.createElement(h.Fragment,null,t.map((g,x)=>{if(g?.startAngle===0&&g?.endAngle===0&&t.length!==1)return null;var w=s==null||s===o,P=String(x)===u&&(l==null||i.dataKey===l)&&w,b=u?n:null,O=r&&P?r:b,S=le(le({},g),{},{stroke:g.stroke,tabIndex:-1,[_m]:x,[km]:i.dataKey});return h.createElement(Se,Zt({key:"sector-".concat(g?.startAngle,"-").concat(g?.endAngle,"-").concat(g.midAngle,"-").concat(x),tabIndex:-1,className:"recharts-pie-sector"},En(v,g,x),{onMouseEnter:p(g,x),onMouseLeave:y(g,x),onClick:m(g,x)}),h.createElement(Ss,Zt({option:a??O,index:x,shapeType:"sector",isActive:P},S)))}))}function TM(e){var t,{pieSettings:r,displayedData:n,cells:i,offset:a}=e,{cornerRadius:o,startAngle:u,endAngle:l,dataKey:s,nameKey:c,tooltipType:f}=r,d=Math.abs(r.minAngle),v=EM(u,l),p=Math.abs(v),y=n.length<=1?0:(t=r.paddingAngle)!==null&&t!==void 0?t:0,m=n.filter(O=>X(O,s,0)!==0).length,g=(p>=360?m:m-1)*y,x=p-m*d-g,w=n.reduce((O,S)=>{var _=X(S,s,0);return O+(N(_)?_:0)},0),P;if(w>0){var b;P=n.map((O,S)=>{var _=X(O,s,0),I=X(O,c,S),M=SM(r,a,O),E=(N(_)?_:0)/w,j,$=le(le({},O),i&&i[S]&&i[S].props);S?j=b.endAngle+Ae(v)*y*(_!==0?1:0):j=u;var L=j+Ae(v)*((_!==0?d:0)+E*x),z=(j+L)/2,K=(M.innerRadius+M.outerRadius)/2,B=[{name:I,value:_,payload:$,dataKey:s,type:f}],W=de(M.cx,M.cy,K,z);return b=le(le(le(le({},r.presentationProps),{},{percent:E,cornerRadius:typeof o=="string"?parseFloat(o):o,name:I,tooltipPayload:B,midAngle:z,middleRadius:K,tooltipPosition:W},$),M),{},{value:_,dataKey:s,startAngle:j,endAngle:L,payload:$,paddingAngle:Ae(v)*y}),b})}return P}function DM(e){var{showLabels:t,sectors:r,children:n}=e,i=h.useMemo(()=>!t||!r?[]:r.map(a=>({value:a.value,payload:a.payload,clockWise:!1,parentViewBox:void 0,viewBox:{cx:a.cx,cy:a.cy,innerRadius:a.innerRadius,outerRadius:a.outerRadius,startAngle:a.startAngle,endAngle:a.endAngle,clockWise:!1},fill:a.fill})),[r,t]);return h.createElement(pI,{value:t?i:void 0},n)}function NM(e){var{props:t,previousSectorsRef:r,id:n}=e,{sectors:i,isAnimationActive:a,animationBegin:o,animationDuration:u,animationEasing:l,activeShape:s,inactiveShape:c,onAnimationStart:f,onAnimationEnd:d}=t,v=Nn(t,"recharts-pie-"),p=r.current,[y,m]=h.useState(!1),g=h.useCallback(()=>{typeof d=="function"&&d(),m(!1)},[d]),x=h.useCallback(()=>{typeof f=="function"&&f(),m(!0)},[f]);return h.createElement(DM,{showLabels:!y,sectors:i},h.createElement(Dn,{animationId:v,begin:o,duration:u,isActive:a,easing:l,onAnimationStart:x,onAnimationEnd:g,key:v},w=>{var P=[],b=i&&i[0],O=b?.startAngle;return i?.forEach((S,_)=>{var I=p&&p[_],M=_>0?pr(S,"paddingAngle",0):0;if(I){var E=ne(I.endAngle-I.startAngle,S.endAngle-S.startAngle,w),j=le(le({},S),{},{startAngle:O+M,endAngle:O+E+M});P.push(j),O=j.endAngle}else{var{endAngle:$,startAngle:L}=S,z=ne(0,$-L,w),K=le(le({},S),{},{startAngle:O+M,endAngle:O+z+M});P.push(K),O=K.endAngle}}),r.current=P,h.createElement(Se,null,h.createElement(MM,{sectors:P,activeShape:s,inactiveShape:c,allOtherPieProps:t,shape:t.shape,id:n}))}),h.createElement(IM,{showLabels:!y,sectors:i,props:t}),t.children)}var $M={animationBegin:400,animationDuration:1500,animationEasing:"ease",cx:"50%",cy:"50%",dataKey:"value",endAngle:360,fill:"#808080",hide:!1,innerRadius:0,isAnimationActive:"auto",label:!1,labelLine:!0,legendType:"rect",minAngle:0,nameKey:"name",outerRadius:"80%",paddingAngle:0,rootTabIndex:0,startAngle:0,stroke:"#fff",zIndex:ve.area};function RM(e){var{id:t}=e,r=Ja(e,pM),{hide:n,className:i,rootTabIndex:a}=e,o=h.useMemo(()=>As(e.children,Va),[e.children]),u=T(c=>MI(c,t,o)),l=h.useRef(null),s=H("recharts-pie",i);return n||u==null?(l.current=null,h.createElement(Se,{tabIndex:a,className:s})):h.createElement(We,{zIndex:e.zIndex},h.createElement(PM,{dataKey:e.dataKey,nameKey:e.nameKey,sectors:u,stroke:e.stroke,strokeWidth:e.strokeWidth,fill:e.fill,name:e.name,hide:e.hide,tooltipType:e.tooltipType}),h.createElement(Se,{tabIndex:a,className:s},h.createElement(NM,{props:le(le({},r),{},{sectors:u}),previousSectorsRef:l,id:t})))}function LM(e){var t=pe(e,$M),{id:r}=t,n=Ja(t,mM),i=Ze(n);return h.createElement(Cs,{id:r,type:"pie"},a=>h.createElement(h.Fragment,null,h.createElement(dM,{type:"pie",id:a,data:n.data,dataKey:n.dataKey,hide:n.hide,angleAxisId:0,radiusAxisId:0,name:n.name,nameKey:n.nameKey,tooltipType:n.tooltipType,legendType:n.legendType,fill:n.fill,cx:n.cx,cy:n.cy,startAngle:n.startAngle,endAngle:n.endAngle,paddingAngle:n.paddingAngle,minAngle:n.minAngle,innerRadius:n.innerRadius,outerRadius:n.outerRadius,cornerRadius:n.cornerRadius,presentationProps:i,maxRadius:t.maxRadius}),h.createElement(xM,Zt({},n,{id:a})),h.createElement(RM,Zt({},n,{id:a}))))}LM.displayName="Pie";var zM=["points"];function Dh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function ku(e){for(var t=1;t{var m,g,x=ku(ku(ku({r:3},o),f),{},{index:y,cx:(m=p.x)!==null&&m!==void 0?m:void 0,cy:(g=p.y)!==null&&g!==void 0?g:void 0,dataKey:a,value:p.value,payload:p.payload,points:t});return h.createElement(UM,{key:"dot-".concat(y),option:r,dotProps:x,className:i})}),v={};return u&&l!=null&&(v.clipPath="url(#clipPath-".concat(c?"":"dots-").concat(l,")")),h.createElement(We,{zIndex:s},h.createElement(Se,ia({className:n},v),d))}function Nh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function $h(e){for(var t=1;t({top:e.top,bottom:e.bottom,left:e.left,right:e.right})),uT=A([oT,Rt,Lt],(e,t,r)=>{if(!(!e||t==null||r==null))return{x:e.left,y:e.top,width:Math.max(0,t-e.left-e.right),height:Math.max(0,r-e.top-e.bottom)}}),Is=()=>T(uT),lT=()=>T(rj);function Rh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function ju(e){for(var t=1;t{var{point:t,childIndex:r,mainColor:n,activeDot:i,dataKey:a,clipPath:o}=e;if(i===!1||t.x==null||t.y==null)return null;var u={index:r,dataKey:a,cx:t.x,cy:t.y,r:4,fill:n??"none",strokeWidth:2,stroke:"#fff",payload:t.payload,value:t.value},l=ju(ju(ju({},u),hr(i)),Ul(i)),s;return h.isValidElement(i)?s=h.cloneElement(i,l):typeof i=="function"?s=i(l):s=h.createElement(g0,l),h.createElement(Se,{className:"recharts-active-dot",clipPath:o},s)};function vT(e){var{points:t,mainColor:r,activeDot:n,itemDataKey:i,clipPath:a,zIndex:o=ve.activeDot}=e,u=T(Xt),l=lT();if(t==null||l==null)return null;var s=t.find(c=>l.includes(c.payload));return ae(s)?null:h.createElement(We,{zIndex:o},h.createElement(dT,{point:s,childIndex:Number(u),mainColor:r,dataKey:i,activeDot:n,clipPath:a}))}var hT=["x","y"];function jl(){return jl=Object.assign?Object.assign.bind():function(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:0;return(n,i)=>{if(N(t))return t;var a=N(n)||ae(n);return a?t(n,i):(a||fb(!1),r)}},PT={},C0=qe({name:"errorBars",initialState:PT,reducers:{addErrorBar:(e,t)=>{var{itemId:r,errorBar:n}=t.payload;e[r]||(e[r]=[]),e[r].push(n)},replaceErrorBar:(e,t)=>{var{itemId:r,prev:n,next:i}=t.payload;e[r]&&(e[r]=e[r].map(a=>a.dataKey===n.dataKey&&a.direction===n.direction?i:a))},removeErrorBar:(e,t)=>{var{itemId:r,errorBar:n}=t.payload;e[r]&&(e[r]=e[r].filter(i=>i.dataKey!==n.dataKey||i.direction!==n.direction))}}}),{addErrorBar:W$,replaceErrorBar:U$,removeErrorBar:H$}=C0.actions,OT=C0.reducer,AT=["children"];function ST(e,t){if(e==null)return{};var r,n,i=ET(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n({x:0,y:0,value:0}),errorBarOffset:0},kT=h.createContext(_T);function I0(e){var{children:t}=e,r=ST(e,AT);return h.createElement(kT.Provider,{value:r},t)}function Ms(e,t){var r,n,i=T(s=>Bt(s,e)),a=T(s=>Ft(s,t)),o=(r=i?.allowDataOverflow)!==null&&r!==void 0?r:xe.allowDataOverflow,u=(n=a?.allowDataOverflow)!==null&&n!==void 0?n:Pe.allowDataOverflow,l=o||u;return{needClip:l,needClipX:o,needClipY:u}}function M0(e){var{xAxisId:t,yAxisId:r,clipPathId:n}=e,i=Is(),{needClipX:a,needClipY:o,needClip:u}=Ms(t,r);if(!u||!i)return null;var{x:l,y:s,width:c,height:f}=i;return h.createElement("clipPath",{id:"clipPath-".concat(n)},h.createElement("rect",{x:a?l:l-c/2,y:o?s:s-f/2,width:a?c:c*2,height:o?f:f*2}))}function jT(e,t){return e&&typeof e=="object"&&"zIndex"in e&&typeof e.zIndex=="number"&&se(e.zIndex)?e.zIndex:t}var Cu={exports:{}},Iu={};var zh;function CT(){if(zh)return Iu;zh=1;var e=db();function t(l,s){return l===s&&(l!==0||1/l===1/s)||l!==l&&s!==s}var r=typeof Object.is=="function"?Object.is:t,n=e.useSyncExternalStore,i=e.useRef,a=e.useEffect,o=e.useMemo,u=e.useDebugValue;return Iu.useSyncExternalStoreWithSelector=function(l,s,c,f,d){var v=i(null);if(v.current===null){var p={hasValue:!1,value:null};v.current=p}else p=v.current;v=o(function(){function m(b){if(!g){if(g=!0,x=b,b=f(b),d!==void 0&&p.hasValue){var O=p.value;if(d(O,b))return w=O}return w=b}if(O=w,r(x,b))return O;var S=f(b);return d!==void 0&&d(O,S)?(x=b,O):(x=b,w=S)}var g=!1,x,w,P=c===void 0?null:c;return[function(){return m(s())},P===null?void 0:function(){return m(P())}]},[s,c,f,d]);var y=n(l,v[0],v[1]);return a(function(){p.hasValue=!0,p.value=y},[y]),u(y),y},Iu}var Bh;function IT(){return Bh||(Bh=1,Cu.exports=CT()),Cu.exports}IT();function MT(e){e()}function TT(){let e=null,t=null;return{clear(){e=null,t=null},notify(){MT(()=>{let r=e;for(;r;)r.callback(),r=r.next})},get(){const r=[];let n=e;for(;n;)r.push(n),n=n.next;return r},subscribe(r){let n=!0;const i=t={callback:r,next:null,prev:t};return i.prev?i.prev.next=i:e=i,function(){!n||e===null||(n=!1,i.next?i.next.prev=i.prev:t=i.prev,i.prev?i.prev.next=i.next:e=i.next)}}}}var Fh={notify(){},get:()=>[]};function DT(e,t){let r,n=Fh,i=0,a=!1;function o(y){c();const m=n.subscribe(y);let g=!1;return()=>{g||(g=!0,m(),f())}}function u(){n.notify()}function l(){p.onStateChange&&p.onStateChange()}function s(){return a}function c(){i++,r||(r=e.subscribe(l),n=TT())}function f(){i--,r&&i===0&&(r(),r=void 0,n.clear(),n=Fh)}function d(){a||(a=!0,c())}function v(){a&&(a=!1,f())}const p={addNestedSub:o,notifyNestedSubs:u,handleChangeWrapper:l,isSubscribed:s,trySubscribe:d,tryUnsubscribe:v,getListeners:()=>n};return p}var NT=()=>typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",$T=NT(),RT=()=>typeof navigator<"u"&&navigator.product==="ReactNative",LT=RT(),zT=()=>$T||LT?h.useLayoutEffect:h.useEffect,BT=zT();function Kh(e,t){return e===t?e!==0||t!==0||1/e===1/t:e!==e&&t!==t}function FT(e,t){if(Kh(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;const r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let i=0;i{const l=DT(i);return{store:i,subscription:l,getServerState:n?()=>n:void 0}},[i,n]),o=h.useMemo(()=>i.getState(),[i]);BT(()=>{const{subscription:l}=a;return l.onStateChange=l.notifyNestedSubs,l.trySubscribe(),o!==i.getState()&&l.notifyNestedSubs(),()=>{l.tryUnsubscribe(),l.onStateChange=void 0}},[a,o]);const u=r||UT;return h.createElement(u.Provider,{value:a},t)}var YT=HT,GT=new Set(["axisLine","tickLine","activeBar","activeDot","activeLabel","activeShape","allowEscapeViewBox","background","cursor","dot","label","line","margin","padding","position","shape","style","tick","wrapperStyle"]);function VT(e,t){return e==null&&t==null?!0:typeof e=="number"&&typeof t=="number"?e===t||e!==e&&t!==t:e===t}function eo(e,t){var r=new Set([...Object.keys(e),...Object.keys(t)]);for(var n of r)if(GT.has(n)){if(e[n]==null&&t[n]==null)continue;if(!FT(e[n],t[n]))return!1}else if(!VT(e[n],t[n]))return!1;return!0}var XT=["onMouseEnter","onMouseLeave","onClick"],ZT=["value","background","tooltipPosition"],QT=["id"],JT=["onMouseEnter","onClick","onMouseLeave"];function $t(){return $t=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var{dataKey:t,name:r,fill:n,legendType:i,hide:a}=e;return[{inactive:a,dataKey:t,type:i,color:n,value:Br(r,t),payload:e}]},aD=h.memo(e=>{var{dataKey:t,stroke:r,strokeWidth:n,fill:i,name:a,hide:o,unit:u,tooltipType:l}=e,s={dataDefinedOnItem:void 0,positions:void 0,settings:{stroke:r,strokeWidth:n,fill:i,dataKey:t,nameKey:void 0,name:Br(a,t),hide:o,type:l,color:i,unit:u}};return h.createElement(js,{tooltipEntrySettings:s})});function oD(e){var t=T(Xt),{data:r,dataKey:n,background:i,allOtherBarProps:a}=e,{onMouseEnter:o,onMouseLeave:u,onClick:l}=a,s=oa(a,XT),c=Es(o,n),f=_s(u),d=ks(l,n);if(!i||r==null)return null;var v=hr(i);return h.createElement(We,{zIndex:jT(i,ve.barBackground)},r.map((p,y)=>{var{value:m,background:g,tooltipPosition:x}=p,w=oa(p,ZT);if(!g)return null;var P=c(p,y),b=f(p,y),O=d(p,y),S=De(De(De(De(De({option:i,isActive:String(y)===t},w),{},{fill:"#eee"},g),v),En(s,p,y)),{},{onMouseEnter:P,onMouseLeave:b,onClick:O,dataKey:n,index:y,className:"recharts-bar-background-rectangle"});return h.createElement(aa,$t({key:"background-bar-".concat(y)},S))}))}function uD(e){var{showLabels:t,children:r,rects:n}=e,i=n?.map(a=>{var o={x:a.x,y:a.y,width:a.width,lowerWidth:a.width,upperWidth:a.width,height:a.height};return De(De({},o),{},{value:a.value,payload:a.payload,parentViewBox:a.parentViewBox,viewBox:o,fill:a.fill})});return h.createElement(m0,{value:t?i:void 0},r)}function lD(e){var{shape:t,activeBar:r,baseProps:n,entry:i,index:a,dataKey:o}=e,u=T(Xt),l=T(hs),s=r&&String(a)===u&&(l==null||o===l),c=s?r:t;return s?h.createElement(We,{zIndex:ve.activeBar},h.createElement(aa,$t({},n,{name:String(n.name)},i,{isActive:s,option:c,index:a,dataKey:o}))):h.createElement(aa,$t({},n,{name:String(n.name)},i,{isActive:s,option:c,index:a,dataKey:o}))}function cD(e){var{shape:t,baseProps:r,entry:n,index:i,dataKey:a}=e;return h.createElement(aa,$t({},r,{name:String(r.name)},n,{isActive:!1,option:t,index:i,dataKey:a}))}function sD(e){var t,{data:r,props:n}=e,i=(t=Ze(n))!==null&&t!==void 0?t:{},{id:a}=i,o=oa(i,QT),{shape:u,dataKey:l,activeBar:s}=n,{onMouseEnter:c,onClick:f,onMouseLeave:d}=n,v=oa(n,JT),p=Es(c,l),y=_s(d),m=ks(f,l);return r?h.createElement(h.Fragment,null,r.map((g,x)=>h.createElement(Se,$t({key:"rectangle-".concat(g?.x,"-").concat(g?.y,"-").concat(g?.value,"-").concat(x),className:"recharts-bar-rectangle"},En(v,g,x),{onMouseEnter:p(g,x),onMouseLeave:y(g,x),onClick:m(g,x)}),s?h.createElement(lD,{shape:u,activeBar:s,baseProps:o,entry:g,index:x,dataKey:l}):h.createElement(cD,{shape:u,baseProps:o,entry:g,index:x,dataKey:l})))):null}function fD(e){var{props:t,previousRectanglesRef:r}=e,{data:n,layout:i,isAnimationActive:a,animationBegin:o,animationDuration:u,animationEasing:l,onAnimationEnd:s,onAnimationStart:c}=t,f=r.current,d=Nn(t,"recharts-bar-"),[v,p]=h.useState(!1),y=!v,m=h.useCallback(()=>{typeof s=="function"&&s(),p(!1)},[s]),g=h.useCallback(()=>{typeof c=="function"&&c(),p(!0)},[c]);return h.createElement(uD,{showLabels:y,rects:n},h.createElement(Dn,{animationId:d,begin:o,duration:u,isActive:a,easing:l,onAnimationEnd:m,onAnimationStart:g,key:d},x=>{var w=x===1?n:n?.map((P,b)=>{var O=f&&f[b];if(O)return De(De({},P),{},{x:ne(O.x,P.x,x),y:ne(O.y,P.y,x),width:ne(O.width,P.width,x),height:ne(O.height,P.height,x)});if(i==="horizontal"){var S=ne(0,P.height,x),_=ne(P.stackedBarStart,P.y,x);return De(De({},P),{},{y:_,height:S})}var I=ne(0,P.width,x),M=ne(P.stackedBarStart,P.x,x);return De(De({},P),{},{width:I,x:M})});return x>0&&(r.current=w??null),w==null?null:h.createElement(Se,null,h.createElement(sD,{props:t,data:w}))}),h.createElement(xs,{label:t.label}),t.children)}function dD(e){var t=h.useRef(null);return h.createElement(fD,{previousRectanglesRef:t,props:e})}var T0=0,vD=(e,t)=>{var r=Array.isArray(e.value)?e.value[1]:e.value;return{x:e.x,y:e.y,value:r,errorVal:X(e,t)}};class hD extends h.PureComponent{render(){var{hide:t,data:r,dataKey:n,className:i,xAxisId:a,yAxisId:o,needClip:u,background:l,id:s}=this.props;if(t||r==null)return null;var c=H("recharts-bar",i),f=s;return h.createElement(Se,{className:c,id:s},u&&h.createElement("defs",null,h.createElement(M0,{clipPathId:f,xAxisId:a,yAxisId:o})),h.createElement(Se,{className:"recharts-bar-rectangles",clipPath:u?"url(#clipPath-".concat(f,")"):void 0},h.createElement(oD,{data:r,dataKey:n,background:l,allOtherBarProps:this.props}),h.createElement(dD,this.props)))}}var pD={activeBar:!1,animationBegin:0,animationDuration:400,animationEasing:"ease",background:!1,hide:!1,isAnimationActive:"auto",label:!1,legendType:"rect",minPointSize:T0,xAxisId:0,yAxisId:0,zIndex:ve.bar};function mD(e){var{xAxisId:t,yAxisId:r,hide:n,legendType:i,minPointSize:a,activeBar:o,animationBegin:u,animationDuration:l,animationEasing:s,isAnimationActive:c}=e,{needClip:f}=Ms(t,r),d=In(),v=Me(),p=As(e.children,Va),y=T(x=>UD(x,t,r,v,e.id,p));if(d!=="vertical"&&d!=="horizontal")return null;var m,g=y?.[0];return g==null||g.height==null||g.width==null?m=0:m=d==="vertical"?g.height/2:g.width/2,h.createElement(I0,{xAxisId:t,yAxisId:r,data:y,dataPointFormatter:vD,errorBarOffset:m},h.createElement(hD,$t({},e,{layout:d,needClip:f,data:y,xAxisId:t,yAxisId:r,hide:n,legendType:i,minPointSize:a,activeBar:o,animationBegin:u,animationDuration:l,animationEasing:s,isAnimationActive:c})))}function yD(e){var{layout:t,barSettings:{dataKey:r,minPointSize:n},pos:i,bandSize:a,xAxis:o,yAxis:u,xAxisTicks:l,yAxisTicks:s,stackedData:c,displayedData:f,offset:d,cells:v,parentViewBox:p,dataStartIndex:y}=e,m=t==="horizontal"?u:o,g=c?m.scale.domain():null,x=MP({numericAxis:m}),w=m.scale(x);return f.map((P,b)=>{var O,S,_,I,M,E;c?O=EP(c[b+y],g):(O=X(P,r),Array.isArray(O)||(O=[x,O]));var j=xT(n,T0)(O[1],b);if(t==="horizontal"){var $,[L,z]=[u.scale(O[0]),u.scale(O[1])];S=id({axis:o,ticks:l,bandSize:a,offset:i.offset,entry:P,index:b}),_=($=z??L)!==null&&$!==void 0?$:void 0,I=i.size;var K=L-z;if(M=dt(K)?0:K,E={x:S,y:d.top,width:I,height:d.height},Math.abs(j)>0&&Math.abs(M)0&&Math.abs(I)h.createElement(h.Fragment,null,h.createElement(S0,{legendPayload:iD(t)}),h.createElement(aD,{dataKey:t.dataKey,stroke:t.stroke,strokeWidth:t.strokeWidth,fill:t.fill,name:t.name,hide:t.hide,unit:t.unit,tooltipType:t.tooltipType}),h.createElement(k0,{type:"bar",id:n,data:void 0,xAxisId:t.xAxisId,yAxisId:t.yAxisId,zAxisId:0,dataKey:t.dataKey,stackId:IP(t.stackId),hide:t.hide,barSize:t.barSize,minPointSize:t.minPointSize,maxBarSize:t.maxBarSize,isPanorama:r}),h.createElement(We,{zIndex:t.zIndex},h.createElement(mD,$t({},t,{id:n})))))}var bD=h.memo(gD,eo);bD.displayName="Bar";function Wh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function vi(e){for(var t=1;tt,AD=(e,t,r)=>r,SD=(e,t,r,n)=>n,ED=(e,t,r,n,i)=>i,Xn=A([Wa,ED],(e,t)=>e.filter(r=>r.type==="bar").find(r=>r.id===t)),_D=A([Xn],e=>e?.maxBarSize),kD=(e,t,r,n,i,a)=>a,Uh=(e,t,r)=>{var n=r??e;if(!ae(n))return Ie(n,t,0)},jD=A([q,Wa,OD,AD,SD],(e,t,r,n,i)=>t.filter(a=>e==="horizontal"?a.xAxisId===r:a.yAxisId===n).filter(a=>a.isPanorama===i).filter(a=>a.hide===!1).filter(a=>a.type==="bar")),CD=(e,t,r,n)=>{var i=q(e);return i==="horizontal"?xl(e,"yAxis",r,n):xl(e,"xAxis",t,n)},ID=(e,t,r)=>{var n=q(e);return n==="horizontal"?zv(e,"xAxis",t):zv(e,"yAxis",r)},MD=(e,t,r)=>{var n={},i=e.filter(Fa),a=e.filter(s=>s.stackId==null),o=i.reduce((s,c)=>(s[c.stackId]||(s[c.stackId]=[]),s[c.stackId].push(c),s),n),u=Object.entries(o).map(s=>{var[c,f]=s,d=f.map(p=>p.dataKey),v=Uh(t,r,f[0].barSize);return{stackId:c,dataKeys:d,barSize:v}}),l=a.map(s=>{var c=[s.dataKey].filter(d=>d!=null),f=Uh(t,r,s.barSize);return{stackId:void 0,dataKeys:c,barSize:f}});return[...u,...l]},TD=A([jD,e_,ID],MD),DD=(e,t,r,n,i)=>{var a,o,u=Xn(e,t,r,n,i);if(u!=null){var l=q(e),s=Zy(e),{maxBarSize:c}=u,f=ae(c)?s:c,d,v;return l==="horizontal"?(d=Vt(e,"xAxis",t,n),v=Gt(e,"xAxis",t,n)):(d=Vt(e,"yAxis",r,n),v=Gt(e,"yAxis",r,n)),(a=(o=Dr(d,v,!0))!==null&&o!==void 0?o:f)!==null&&a!==void 0?a:0}},D0=(e,t,r,n)=>{var i=q(e),a,o;return i==="horizontal"?(a=Vt(e,"xAxis",t,n),o=Gt(e,"xAxis",t,n)):(a=Vt(e,"yAxis",r,n),o=Gt(e,"yAxis",r,n)),Dr(a,o)};function ND(e,t,r,n,i){var a=n.length;if(!(a<1)){var o=Ie(e,r,0,!0),u,l=[];if(se(n[0].barSize)){var s=!1,c=r/a,f=n.reduce((g,x)=>g+(x.barSize||0),0);f+=(a-1)*o,f>=r&&(f-=(a-1)*o,o=0),f>=r&&c>0&&(s=!0,c*=.9,f=a*c);var d=(r-f)/2>>0,v={offset:d-o,size:0};u=n.reduce((g,x)=>{var w,P={stackId:x.stackId,dataKeys:x.dataKeys,position:{offset:v.offset+v.size+o,size:s?c:(w=x.barSize)!==null&&w!==void 0?w:0}},b=[...g,P];return v=b[b.length-1].position,b},l)}else{var p=Ie(t,r,0,!0);r-2*p-(a-1)*o<=0&&(o=0);var y=(r-2*p-(a-1)*o)/a;y>1&&(y>>=0);var m=se(i)?Math.min(y,i):y;u=n.reduce((g,x,w)=>[...g,{stackId:x.stackId,dataKeys:x.dataKeys,position:{offset:p+(y+o)*w+(y-m)/2,size:m}}],l)}return u}}var $D=(e,t,r,n,i,a,o)=>{var u=ae(o)?t:o,l=ND(r,n,i!==a?i:a,e,u);return i!==a&&l!=null&&(l=l.map(s=>vi(vi({},s),{},{position:vi(vi({},s.position),{},{offset:s.position.offset-i/2})}))),l},RD=A([TD,Zy,JE,Qy,DD,D0,_D],$D),LD=(e,t,r,n)=>Vt(e,"xAxis",t,n),zD=(e,t,r,n)=>Vt(e,"yAxis",r,n),BD=(e,t,r,n)=>Gt(e,"xAxis",t,n),FD=(e,t,r,n)=>Gt(e,"yAxis",r,n),KD=A([RD,Xn],(e,t)=>{if(!(e==null||t==null)){var r=e.find(n=>n.stackId===t.stackId&&t.dataKey!=null&&n.dataKeys.includes(t.dataKey));if(r!=null)return r.position}}),qD=(e,t)=>{var r=Fc(t);if(!(!e||r==null||t==null)){var{stackId:n}=t;if(n!=null){var i=e[n];if(i){var{stackedData:a}=i;if(a)return a.find(o=>o.key===r)}}}},WD=A([CD,Xn],qD),UD=A([ye,rc,LD,zD,BD,FD,KD,q,La,D0,WD,Xn,kD],(e,t,r,n,i,a,o,u,l,s,c,f,d)=>{var{chartData:v,dataStartIndex:p,dataEndIndex:y}=l;if(!(f==null||o==null||t==null||u!=="horizontal"&&u!=="vertical"||r==null||n==null||i==null||a==null||s==null)){var{data:m}=f,g;if(m!=null&&m.length>0?g=m:g=v?.slice(p,y+1),g!=null)return yD({layout:u,barSettings:f,pos:o,parentViewBox:t,bandSize:s,xAxis:r,yAxis:n,xAxisTicks:i,yAxisTicks:a,stackedData:c,displayedData:g,offset:e,cells:d,dataStartIndex:p})}}),N0=e=>{var{chartData:t}=e,r=ee(),n=Me();return h.useEffect(()=>n?()=>{}:(r(Qv(t)),()=>{r(Qv(void 0))}),[t,r,n]),null},Hh={x:0,y:0,width:0,height:0,padding:{top:0,right:0,bottom:0,left:0}},$0=qe({name:"brush",initialState:Hh,reducers:{setBrushSettings(e,t){return t.payload==null?Hh:t.payload}}}),{setBrushSettings:Y$}=$0.actions,HD=$0.reducer;function YD(e,t,r){return(t=GD(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function GD(e){var t=VD(e,"string");return typeof t=="symbol"?t:t+""}function VD(e,t){if(typeof e!="object"||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var n=r.call(e,t);if(typeof n!="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}class Ts{static create(t){return new Ts(t)}constructor(t){this.scale=t}get domain(){return this.scale.domain}get range(){return this.scale.range}get rangeMin(){return this.range()[0]}get rangeMax(){return this.range()[1]}get bandwidth(){return this.scale.bandwidth}apply(t){var{bandAware:r,position:n}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(t!==void 0){if(n)switch(n){case"start":return this.scale(t);case"middle":{var i=this.bandwidth?this.bandwidth()/2:0;return this.scale(t)+i}case"end":{var a=this.bandwidth?this.bandwidth():0;return this.scale(t)+a}default:return this.scale(t)}if(r){var o=this.bandwidth?this.bandwidth()/2:0;return this.scale(t)+o}return this.scale(t)}}isInRange(t){var r=this.range(),n=r[0],i=r[r.length-1];return n<=i?t>=n&&t<=i:t>=i&&t<=n}}YD(Ts,"EPS",1e-4);function XD(e){return(e%180+180)%180}var ZD=function(t){var{width:r,height:n}=t,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,a=XD(i),o=a*Math.PI/180,u=Math.atan(n/r),l=o>u&&o{e.dots.push(t.payload)},removeDot:(e,t)=>{var r=ft(e).dots.findIndex(n=>n===t.payload);r!==-1&&e.dots.splice(r,1)},addArea:(e,t)=>{e.areas.push(t.payload)},removeArea:(e,t)=>{var r=ft(e).areas.findIndex(n=>n===t.payload);r!==-1&&e.areas.splice(r,1)},addLine:(e,t)=>{e.lines.push(t.payload)},removeLine:(e,t)=>{var r=ft(e).lines.findIndex(n=>n===t.payload);r!==-1&&e.lines.splice(r,1)}}}),{addDot:G$,removeDot:V$,addArea:X$,removeArea:Z$,addLine:Q$,removeLine:J$}=R0.actions,JD=R0.reducer,eN=h.createContext(void 0),tN=e=>{var{children:t}=e,[r]=h.useState("".concat(cn("recharts"),"-clip")),n=Is();if(n==null)return null;var{x:i,y:a,width:o,height:u}=n;return h.createElement(eN.Provider,{value:r},h.createElement("defs",null,h.createElement("clipPath",{id:r},h.createElement("rect",{x:i,y:a,height:u,width:o}))),t)};function L0(e,t){if(t<1)return[];if(t===1)return e;for(var r=[],n=0;ne*i)return!1;var a=r();return e*(t-e*a/2-n)>=0&&e*(t+e*a/2-i)<=0}function iN(e,t){return L0(e,t+1)}function aN(e,t,r,n,i){for(var a=(n||[]).slice(),{start:o,end:u}=t,l=0,s=1,c=o,f=function(){var p=n?.[l];if(p===void 0)return{v:L0(n,s)};var y=l,m,g=()=>(m===void 0&&(m=r(p,y)),m),x=p.coordinate,w=l===0||ua(e,x,g,c,u);w||(l=0,c=o,s+=1),w&&(c=x+e*(g()/2+i),l+=s)},d;s<=a.length;)if(d=f(),d)return d.v;return[]}function Yh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function je(e){for(var t=1;t(p===void 0&&(p=r(v,d)),p);if(d===o-1){var m=e*(v.coordinate+e*y()/2-l);a[d]=v=je(je({},v),{},{tickCoord:m>0?v.coordinate-m*e:v.coordinate})}else a[d]=v=je(je({},v),{},{tickCoord:v.coordinate});if(v.tickCoord!=null){var g=ua(e,v.tickCoord,y,u,l);g&&(l=v.tickCoord-e*(y()/2+i),a[d]=je(je({},v),{},{isShow:!0}))}},c=o-1;c>=0;c--)s(c);return a}function sN(e,t,r,n,i,a){var o=(n||[]).slice(),u=o.length,{start:l,end:s}=t;if(a){var c=n[u-1],f=r(c,u-1),d=e*(c.coordinate+e*f/2-s);if(o[u-1]=c=je(je({},c),{},{tickCoord:d>0?c.coordinate-d*e:c.coordinate}),c.tickCoord!=null){var v=ua(e,c.tickCoord,()=>f,l,s);v&&(s=c.tickCoord-e*(f/2+i),o[u-1]=je(je({},c),{},{isShow:!0}))}}for(var p=a?u-1:u,y=function(x){var w=o[x],P,b=()=>(P===void 0&&(P=r(w,x)),P);if(x===0){var O=e*(w.coordinate-e*b()/2-l);o[x]=w=je(je({},w),{},{tickCoord:O<0?w.coordinate-O*e:w.coordinate})}else o[x]=w=je(je({},w),{},{tickCoord:w.coordinate});if(w.tickCoord!=null){var S=ua(e,w.tickCoord,b,l,s);S&&(l=w.tickCoord+e*(b()/2+i),o[x]=je(je({},w),{},{isShow:!0}))}},m=0;m{var b=typeof s=="function"?s(w.value,P):w.value;return p==="width"?rN(ln(b,{fontSize:t,letterSpacing:r}),y,f):ln(b,{fontSize:t,letterSpacing:r})[p]},g=i.length>=2?Ae(i[1].coordinate-i[0].coordinate):1,x=nN(a,g,p);return l==="equidistantPreserveStart"?aN(g,x,m,i,o):(l==="preserveStart"||l==="preserveStartEnd"?v=sN(g,x,m,i,o,l==="preserveStartEnd"):v=cN(g,x,m,i,o),v.filter(w=>w.isShow))}var fN=e=>{var{ticks:t,label:r,labelGapWithTick:n=5,tickSize:i=0,tickMargin:a=0}=e,o=0;if(t){Array.from(t).forEach(c=>{if(c){var f=c.getBoundingClientRect();f.width>o&&(o=f.width)}});var u=r?r.getBoundingClientRect().width:0,l=i+a,s=o+l+u+(r?n:0);return Math.round(s)}return 0},dN=["axisLine","width","height","className","hide","ticks","axisType"];function vN(e,t){if(e==null)return{};var r,n,i=hN(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n{var{ticks:r=[],tick:n,tickLine:i,stroke:a,tickFormatter:o,unit:u,padding:l,tickTextProps:s,orientation:c,mirror:f,x:d,y:v,width:p,height:y,tickSize:m,tickMargin:g,fontSize:x,letterSpacing:w,getTicksConfig:P,events:b,axisType:O}=e,S=Ds(fe(fe({},P),{},{ticks:r}),x,w),_=wN(c,f),I=xN(c,f),M=Ze(P),E=hr(n),j={};typeof i=="object"&&(j=i);var $=fe(fe({},M),{},{fill:"none"},j),L=S.map(B=>fe({entry:B},bN(B,d,v,p,y,c,m,f,g))),z=L.map(B=>{var{entry:W,line:R}=B;return h.createElement(Se,{className:"recharts-cartesian-axis-tick",key:"tick-".concat(W.value,"-").concat(W.coordinate,"-").concat(W.tickCoord)},i&&h.createElement("line",br({},$,R,{className:H("recharts-cartesian-axis-tick-line",pr(i,"className"))})))}),K=L.map((B,W)=>{var{entry:R,tick:ke}=B,Te=fe(fe(fe(fe({textAnchor:_,verticalAnchor:I},M),{},{stroke:"none",fill:a},E),ke),{},{index:W,payload:R,visibleTicksCount:S.length,tickFormatter:o,padding:l},s);return h.createElement(Se,br({className:"recharts-cartesian-axis-tick-label",key:"tick-label-".concat(R.value,"-").concat(R.coordinate,"-").concat(R.tickCoord)},En(b,R,W)),n&&h.createElement(PN,{option:n,tickProps:Te,value:"".concat(typeof o=="function"?o(R.value,W):R.value).concat(u||"")}))});return h.createElement("g",{className:"recharts-cartesian-axis-ticks recharts-".concat(O,"-ticks")},K.length>0&&h.createElement(We,{zIndex:ve.label},h.createElement("g",{className:"recharts-cartesian-axis-tick-labels recharts-".concat(O,"-tick-labels"),ref:t},K)),z.length>0&&h.createElement("g",{className:"recharts-cartesian-axis-tick-lines recharts-".concat(O,"-tick-lines")},z))}),AN=h.forwardRef((e,t)=>{var{axisLine:r,width:n,height:i,className:a,hide:o,ticks:u,axisType:l}=e,s=vN(e,dN),[c,f]=h.useState(""),[d,v]=h.useState(""),p=h.useRef(null);h.useImperativeHandle(t,()=>({getCalculatedWidth:()=>{var m;return fN({ticks:p.current,label:(m=e.labelRef)===null||m===void 0?void 0:m.current,labelGapWithTick:5,tickSize:e.tickSize,tickMargin:e.tickMargin})}}));var y=h.useCallback(m=>{if(m){var g=m.getElementsByClassName("recharts-cartesian-axis-tick-value");p.current=g;var x=g[0];if(x){var w=window.getComputedStyle(x),P=w.fontSize,b=w.letterSpacing;(P!==c||b!==d)&&(f(P),v(b))}}},[c,d]);return o||n!=null&&n<=0||i!=null&&i<=0?null:h.createElement(We,{zIndex:e.zIndex},h.createElement(Se,{className:H("recharts-cartesian-axis",a)},h.createElement(gN,{x:e.x,y:e.y,width:n,height:i,orientation:e.orientation,mirror:e.mirror,axisLine:r,otherSvgProps:Ze(e)}),h.createElement(ON,{ref:y,axisType:l,events:s,fontSize:c,getTicksConfig:e,height:e.height,letterSpacing:d,mirror:e.mirror,orientation:e.orientation,padding:e.padding,stroke:e.stroke,tick:e.tick,tickFormatter:e.tickFormatter,tickLine:e.tickLine,tickMargin:e.tickMargin,tickSize:e.tickSize,tickTextProps:e.tickTextProps,ticks:u,unit:e.unit,width:e.width,x:e.x,y:e.y}),h.createElement(GC,{x:e.x,y:e.y,width:e.width,height:e.height,lowerWidth:e.width,upperWidth:e.width},h.createElement(iI,{label:e.label,labelRef:e.labelRef}),e.children)))}),Ns=h.forwardRef((e,t)=>{var r=pe(e,jt);return h.createElement(AN,br({},r,{ref:t}))});Ns.displayName="CartesianAxis";var SN=["x1","y1","x2","y2","key"],EN=["offset"],_N=["xAxisId","yAxisId"],kN=["xAxisId","yAxisId"];function Vh(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Ce(e){for(var t=1;t{var{fill:t}=e;if(!t||t==="none")return null;var{fillOpacity:r,x:n,y:i,width:a,height:o,ry:u}=e;return h.createElement("rect",{x:n,y:i,ry:u,width:a,height:o,stroke:"none",fill:t,fillOpacity:r,className:"recharts-cartesian-grid-bg"})};function z0(e){var{option:t,lineItemProps:r}=e,n;if(h.isValidElement(t))n=h.cloneElement(t,r);else if(typeof t=="function")n=t(r);else{var i,{x1:a,y1:o,x2:u,y2:l,key:s}=r,c=la(r,SN),f=(i=Ze(c))!==null&&i!==void 0?i:{},{offset:d}=f,v=la(f,EN);n=h.createElement("line",sr({},v,{x1:a,y1:o,x2:u,y2:l,fill:"none",key:s}))}return n}function DN(e){var{x:t,width:r,horizontal:n=!0,horizontalPoints:i}=e;if(!n||!i||!i.length)return null;var{xAxisId:a,yAxisId:o}=e,u=la(e,_N),l=i.map((s,c)=>{var f=Ce(Ce({},u),{},{x1:t,y1:s,x2:t+r,y2:s,key:"line-".concat(c),index:c});return h.createElement(z0,{key:"line-".concat(c),option:n,lineItemProps:f})});return h.createElement("g",{className:"recharts-cartesian-grid-horizontal"},l)}function NN(e){var{y:t,height:r,vertical:n=!0,verticalPoints:i}=e;if(!n||!i||!i.length)return null;var{xAxisId:a,yAxisId:o}=e,u=la(e,kN),l=i.map((s,c)=>{var f=Ce(Ce({},u),{},{x1:s,y1:t,x2:s,y2:t+r,key:"line-".concat(c),index:c});return h.createElement(z0,{option:n,lineItemProps:f,key:"line-".concat(c)})});return h.createElement("g",{className:"recharts-cartesian-grid-vertical"},l)}function $N(e){var{horizontalFill:t,fillOpacity:r,x:n,y:i,width:a,height:o,horizontalPoints:u,horizontal:l=!0}=e;if(!l||!t||!t.length||u==null)return null;var s=u.map(f=>Math.round(f+i-i)).sort((f,d)=>f-d);i!==s[0]&&s.unshift(0);var c=s.map((f,d)=>{var v=!s[d+1],p=v?i+o-f:s[d+1]-f;if(p<=0)return null;var y=d%t.length;return h.createElement("rect",{key:"react-".concat(d),y:f,x:n,height:p,width:a,stroke:"none",fill:t[y],fillOpacity:r,className:"recharts-cartesian-grid-bg"})});return h.createElement("g",{className:"recharts-cartesian-gridstripes-horizontal"},c)}function RN(e){var{vertical:t=!0,verticalFill:r,fillOpacity:n,x:i,y:a,width:o,height:u,verticalPoints:l}=e;if(!t||!r||!r.length)return null;var s=l.map(f=>Math.round(f+i-i)).sort((f,d)=>f-d);i!==s[0]&&s.unshift(0);var c=s.map((f,d)=>{var v=!s[d+1],p=v?i+o-f:s[d+1]-f;if(p<=0)return null;var y=d%r.length;return h.createElement("rect",{key:"react-".concat(d),x:f,y:a,width:p,height:u,stroke:"none",fill:r[y],fillOpacity:n,className:"recharts-cartesian-grid-bg"})});return h.createElement("g",{className:"recharts-cartesian-gridstripes-vertical"},c)}var LN=(e,t)=>{var{xAxis:r,width:n,height:i,offset:a}=e;return Am(Ds(Ce(Ce(Ce({},jt),r),{},{ticks:Sm(r),viewBox:{x:0,y:0,width:n,height:i}})),a.left,a.left+a.width,t)},zN=(e,t)=>{var{yAxis:r,width:n,height:i,offset:a}=e;return Am(Ds(Ce(Ce(Ce({},jt),r),{},{ticks:Sm(r),viewBox:{x:0,y:0,width:n,height:i}})),a.top,a.top+a.height,t)},BN={horizontal:!0,vertical:!0,horizontalPoints:[],verticalPoints:[],stroke:"#ccc",fill:"none",verticalFill:[],horizontalFill:[],xAxisId:0,yAxisId:0,syncWithTicks:!1,zIndex:ve.grid};function FN(e){var t=ic(),r=ac(),n=Tm(),i=Ce(Ce({},pe(e,BN)),{},{x:N(e.x)?e.x:n.left,y:N(e.y)?e.y:n.top,width:N(e.width)?e.width:n.width,height:N(e.height)?e.height:n.height}),{xAxisId:a,yAxisId:o,x:u,y:l,width:s,height:c,syncWithTicks:f,horizontalValues:d,verticalValues:v}=i,p=Me(),y=T(I=>Bv(I,"xAxis",a,p)),m=T(I=>Bv(I,"yAxis",o,p));if(!wt(s)||!wt(c)||!N(u)||!N(l))return null;var g=i.verticalCoordinatesGenerator||LN,x=i.horizontalCoordinatesGenerator||zN,{horizontalPoints:w,verticalPoints:P}=i;if((!w||!w.length)&&typeof x=="function"){var b=d&&d.length,O=x({yAxis:m?Ce(Ce({},m),{},{ticks:b?d:m.ticks}):void 0,width:t??s,height:r??c,offset:n},b?!0:f);Di(Array.isArray(O),"horizontalCoordinatesGenerator should return Array but instead it returned [".concat(typeof O,"]")),Array.isArray(O)&&(w=O)}if((!P||!P.length)&&typeof g=="function"){var S=v&&v.length,_=g({xAxis:y?Ce(Ce({},y),{},{ticks:S?v:y.ticks}):void 0,width:t??s,height:r??c,offset:n},S?!0:f);Di(Array.isArray(_),"verticalCoordinatesGenerator should return Array but instead it returned [".concat(typeof _,"]")),Array.isArray(_)&&(P=_)}return h.createElement(We,{zIndex:i.zIndex},h.createElement("g",{className:"recharts-cartesian-grid"},h.createElement(TN,{fill:i.fill,fillOpacity:i.fillOpacity,x:i.x,y:i.y,width:i.width,height:i.height,ry:i.ry}),h.createElement($N,sr({},i,{horizontalPoints:w})),h.createElement(RN,sr({},i,{verticalPoints:P})),h.createElement(DN,sr({},i,{offset:n,horizontalPoints:w,xAxis:y,yAxis:m})),h.createElement(NN,sr({},i,{offset:n,verticalPoints:P,xAxis:y,yAxis:m}))))}FN.displayName="CartesianGrid";var B0=(e,t,r,n)=>Vt(e,"xAxis",t,n),F0=(e,t,r,n)=>Gt(e,"xAxis",t,n),K0=(e,t,r,n)=>Vt(e,"yAxis",r,n),q0=(e,t,r,n)=>Gt(e,"yAxis",r,n),KN=A([q,B0,K0,F0,q0],(e,t,r,n,i)=>Jt(e,"xAxis")?Dr(t,n,!1):Dr(r,i,!1)),qN=(e,t,r,n,i)=>i;function WN(e){return e.type==="line"}var UN=A([Wa,qN],(e,t)=>e.filter(WN).find(r=>r.id===t)),HN=A([q,B0,K0,F0,q0,UN,KN,La],(e,t,r,n,i,a,o,u)=>{var{chartData:l,dataStartIndex:s,dataEndIndex:c}=u;if(!(a==null||t==null||r==null||n==null||i==null||n.length===0||i.length===0||o==null||e!=="horizontal"&&e!=="vertical")){var{dataKey:f,data:d}=a,v;if(d!=null&&d.length>0?v=d:v=l?.slice(s,c+1),v!=null)return v2({layout:e,xAxis:t,yAxis:r,xAxisTicks:n,yAxisTicks:i,dataKey:f,bandSize:o,displayedData:v})}});function YN(e){var t=hr(e),r=3,n=2;if(t!=null){var{r:i,strokeWidth:a}=t,o=Number(i),u=Number(a);return(Number.isNaN(o)||o<0)&&(o=r),(Number.isNaN(u)||u<0)&&(u=n),{r:o,strokeWidth:u}}return{r,strokeWidth:n}}var GN=["id"],VN=["type","layout","connectNulls","needClip","shape"],XN=["activeDot","animateNewValues","animationBegin","animationDuration","animationEasing","connectNulls","dot","hide","isAnimationActive","label","legendType","xAxisId","yAxisId","id"];function On(){return On=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var{dataKey:t,name:r,stroke:n,legendType:i,hide:a}=e;return[{inactive:a,dataKey:t,type:i,color:n,value:Br(r,t),payload:e}]},r2=h.memo(e=>{var{dataKey:t,data:r,stroke:n,strokeWidth:i,fill:a,name:o,hide:u,unit:l,tooltipType:s}=e,c={dataDefinedOnItem:r,positions:void 0,settings:{stroke:n,strokeWidth:i,fill:a,dataKey:t,nameKey:void 0,name:Br(o,t),hide:u,type:s,color:n,unit:l}};return h.createElement(js,{tooltipEntrySettings:c})}),W0=(e,t)=>"".concat(t,"px ").concat(e-t,"px");function n2(e,t){for(var r=e.length%2!==0?[...e,0]:e,n=[],i=0;i{var n=r.reduce((f,d)=>f+d);if(!n)return W0(t,e);for(var i=Math.floor(e/n),a=e%n,o=t-e,u=[],l=0,s=0;la){u=[...r.slice(0,l),a-s];break}var c=u.length%2===0?[0,o]:[o];return[...n2(r,i),...u,...c].map(f=>"".concat(f,"px")).join(", ")};function a2(e){var{clipPathId:t,points:r,props:n}=e,{dot:i,dataKey:a,needClip:o}=n,{id:u}=n,l=$s(n,GN),s=Ze(l);return h.createElement(YM,{points:r,dot:i,className:"recharts-line-dots",dotClassName:"recharts-line-dot",dataKey:a,baseProps:s,needClip:o,clipPathId:t})}function o2(e){var{showLabels:t,children:r,points:n}=e,i=h.useMemo(()=>n?.map(a=>{var o,u,l={x:(o=a.x)!==null&&o!==void 0?o:0,y:(u=a.y)!==null&&u!==void 0?u:0,width:0,lowerWidth:0,upperWidth:0,height:0};return mt(mt({},l),{},{value:a.value,payload:a.payload,viewBox:l,parentViewBox:void 0,fill:void 0})}),[n]);return h.createElement(m0,{value:t?i:void 0},r)}function Zh(e){var{clipPathId:t,pathRef:r,points:n,strokeDasharray:i,props:a}=e,{type:o,layout:u,connectNulls:l,needClip:s,shape:c}=a,f=$s(a,VN),d=mt(mt({},$e(f)),{},{fill:"none",className:"recharts-line-curve",clipPath:s?"url(#clipPath-".concat(t,")"):void 0,points:n,type:o,layout:u,connectNulls:l,strokeDasharray:i??a.strokeDasharray});return h.createElement(h.Fragment,null,n?.length>1&&h.createElement(Ss,On({shapeType:"curve",option:c},d,{pathRef:r})),h.createElement(a2,{points:n,clipPathId:t,props:a}))}function u2(e){try{return e&&e.getTotalLength&&e.getTotalLength()||0}catch{return 0}}function l2(e){var{clipPathId:t,props:r,pathRef:n,previousPointsRef:i,longestAnimatedLengthRef:a}=e,{points:o,strokeDasharray:u,isAnimationActive:l,animationBegin:s,animationDuration:c,animationEasing:f,animateNewValues:d,width:v,height:p,onAnimationEnd:y,onAnimationStart:m}=r,g=i.current,x=Nn(o,"recharts-line-"),w=h.useRef(x),[P,b]=h.useState(!1),O=!P,S=h.useCallback(()=>{typeof y=="function"&&y(),b(!1)},[y]),_=h.useCallback(()=>{typeof m=="function"&&m(),b(!0)},[m]),I=u2(n.current),M=h.useRef(0);w.current!==x&&(M.current=a.current,w.current=x);var E=M.current;return h.createElement(o2,{points:o,showLabels:O},r.children,h.createElement(Dn,{animationId:x,begin:s,duration:c,isActive:l,easing:f,onAnimationEnd:S,onAnimationStart:_,key:x},j=>{var $=ne(E,I+E,j),L=Math.min($,I),z;if(l)if(u){var K="".concat(u).split(/[,\s]+/gim).map(R=>parseFloat(R));z=i2(L,I,K)}else z=W0(I,L);else z=u==null?void 0:String(u);if(j>0&&I>0&&(i.current=o,a.current=Math.max(a.current,L)),g){var B=g.length/o.length,W=j===1?o:o.map((R,ke)=>{var Te=Math.floor(ke*B);if(g[Te]){var Le=g[Te];return mt(mt({},R),{},{x:ne(Le.x,R.x,j),y:ne(Le.y,R.y,j)})}return d?mt(mt({},R),{},{x:ne(v*2,R.x,j),y:ne(p/2,R.y,j)}):mt(mt({},R),{},{x:R.x,y:R.y})});return i.current=W,h.createElement(Zh,{props:r,points:W,clipPathId:t,pathRef:n,strokeDasharray:z})}return h.createElement(Zh,{props:r,points:o,clipPathId:t,pathRef:n,strokeDasharray:z})}),h.createElement(xs,{label:r.label}))}function c2(e){var{clipPathId:t,props:r}=e,n=h.useRef(null),i=h.useRef(0),a=h.useRef(null);return h.createElement(l2,{props:r,clipPathId:t,previousPointsRef:n,longestAnimatedLengthRef:i,pathRef:a})}var s2=(e,t)=>{var r,n;return{x:(r=e.x)!==null&&r!==void 0?r:void 0,y:(n=e.y)!==null&&n!==void 0?n:void 0,value:e.value,errorVal:X(e.payload,t)}};class f2 extends h.Component{render(){var{hide:t,dot:r,points:n,className:i,xAxisId:a,yAxisId:o,top:u,left:l,width:s,height:c,id:f,needClip:d,zIndex:v}=this.props;if(t)return null;var p=H("recharts-line",i),y=f,{r:m,strokeWidth:g}=YN(r),x=A0(r),w=m*2+g,P=d?"url(#clipPath-".concat(x?"":"dots-").concat(y,")"):void 0;return h.createElement(We,{zIndex:v},h.createElement(Se,{className:p},d&&h.createElement("defs",null,h.createElement(M0,{clipPathId:y,xAxisId:a,yAxisId:o}),!x&&h.createElement("clipPath",{id:"clipPath-dots-".concat(y)},h.createElement("rect",{x:l-w/2,y:u-w/2,width:s+w,height:c+w}))),h.createElement(I0,{xAxisId:a,yAxisId:o,data:n,dataPointFormatter:s2,errorBarOffset:0},h.createElement(c2,{props:this.props,clipPathId:y}))),h.createElement(vT,{activeDot:this.props.activeDot,points:n,mainColor:this.props.stroke,itemDataKey:this.props.dataKey,clipPath:P}))}}var U0={activeDot:!0,animateNewValues:!0,animationBegin:0,animationDuration:1500,animationEasing:"ease",connectNulls:!1,dot:!0,fill:"#fff",hide:!1,isAnimationActive:"auto",label:!1,legendType:"line",stroke:"#3182bd",strokeWidth:1,xAxisId:0,yAxisId:0,zIndex:ve.line,type:"linear"};function d2(e){var t=pe(e,U0),{activeDot:r,animateNewValues:n,animationBegin:i,animationDuration:a,animationEasing:o,connectNulls:u,dot:l,hide:s,isAnimationActive:c,label:f,legendType:d,xAxisId:v,yAxisId:p,id:y}=t,m=$s(t,XN),{needClip:g}=Ms(v,p),x=Is(),w=In(),P=Me(),b=T(M=>HN(M,v,p,P,y));if(w!=="horizontal"&&w!=="vertical"||b==null||x==null)return null;var{height:O,width:S,x:_,y:I}=x;return h.createElement(f2,On({},m,{id:y,connectNulls:u,dot:l,activeDot:r,animateNewValues:n,animationBegin:i,animationDuration:a,animationEasing:o,isAnimationActive:c,hide:s,label:f,legendType:d,xAxisId:v,yAxisId:p,points:b,layout:w,height:O,width:S,left:_,top:I,needClip:g}))}function v2(e){var{layout:t,xAxis:r,yAxis:n,xAxisTicks:i,yAxisTicks:a,dataKey:o,bandSize:u,displayedData:l}=e;return l.map((s,c)=>{var f=X(s,o);if(t==="horizontal"){var d=nd({axis:r,ticks:i,bandSize:u,entry:s,index:c}),v=ae(f)?null:n.scale(f);return{x:d,y:v,value:f,payload:s}}var p=ae(f)?null:r.scale(f),y=nd({axis:n,ticks:a,bandSize:u,entry:s,index:c});return p==null||y==null?null:{x:p,y,value:f,payload:s}}).filter(Boolean)}function h2(e){var t=pe(e,U0),r=Me();return h.createElement(Cs,{id:t.id,type:"line"},n=>h.createElement(h.Fragment,null,h.createElement(S0,{legendPayload:t2(t)}),h.createElement(r2,{dataKey:t.dataKey,data:t.data,stroke:t.stroke,strokeWidth:t.strokeWidth,fill:t.fill,name:t.name,hide:t.hide,unit:t.unit,tooltipType:t.tooltipType}),h.createElement(k0,{type:"line",id:n,data:t.data,xAxisId:t.xAxisId,yAxisId:t.yAxisId,zAxisId:0,dataKey:t.dataKey,hide:t.hide,isPanorama:r}),h.createElement(d2,On({},t,{id:n}))))}var p2=h.memo(h2,eo);p2.displayName="Line";var m2=["domain","range"],y2=["domain","range"];function Qh(e,t){if(e==null)return{};var r,n,i=g2(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n{r.current===null?t(QM(e)):r.current!==e&&t(JM({prev:r.current,next:e})),r.current=e},[e,t]),h.useLayoutEffect(()=>()=>{r.current&&(t(eT(r.current)),r.current=null)},[t]),null}var O2=e=>{var{xAxisId:t,className:r}=e,n=T(rc),i=Me(),a="xAxis",o=T(m=>Yr(m,a,t,i)),u=T(m=>Cg(m,a,t,i)),l=T(m=>Eg(m,t)),s=T(m=>Z_(m,t)),c=T(m=>ug(m,t));if(l==null||s==null||c==null)return null;var{dangerouslySetInnerHTML:f,ticks:d}=e,v=ep(e,b2),{id:p}=c,y=ep(c,w2);return h.createElement(Ns,Cl({},v,y,{scale:o,x:s.x,y:s.y,width:l.width,height:l.height,className:H("recharts-".concat(a," ").concat(a),r),viewBox:n,ticks:u,axisType:a}))},A2={allowDataOverflow:xe.allowDataOverflow,allowDecimals:xe.allowDecimals,allowDuplicatedCategory:xe.allowDuplicatedCategory,angle:xe.angle,axisLine:jt.axisLine,height:xe.height,hide:!1,includeHidden:xe.includeHidden,interval:xe.interval,minTickGap:xe.minTickGap,mirror:xe.mirror,orientation:xe.orientation,padding:xe.padding,reversed:xe.reversed,scale:xe.scale,tick:xe.tick,tickCount:xe.tickCount,tickLine:jt.tickLine,tickSize:jt.tickSize,type:xe.type,xAxisId:0},S2=e=>{var t=pe(e,A2);return h.createElement(h.Fragment,null,h.createElement(P2,{allowDataOverflow:t.allowDataOverflow,allowDecimals:t.allowDecimals,allowDuplicatedCategory:t.allowDuplicatedCategory,angle:t.angle,dataKey:t.dataKey,domain:t.domain,height:t.height,hide:t.hide,id:t.xAxisId,includeHidden:t.includeHidden,interval:t.interval,minTickGap:t.minTickGap,mirror:t.mirror,name:t.name,orientation:t.orientation,padding:t.padding,reversed:t.reversed,scale:t.scale,tick:t.tick,tickCount:t.tickCount,tickFormatter:t.tickFormatter,ticks:t.ticks,type:t.type,unit:t.unit}),h.createElement(O2,t))},E2=h.memo(S2,H0);E2.displayName="XAxis";var _2=["dangerouslySetInnerHTML","ticks"],k2=["id"];function Il(){return Il=Object.assign?Object.assign.bind():function(e){for(var t=1;t{r.current===null?t(tT(e)):r.current!==e&&t(rT({prev:r.current,next:e})),r.current=e},[e,t]),h.useLayoutEffect(()=>()=>{r.current&&(t(nT(r.current)),r.current=null)},[t]),null}var I2=e=>{var{yAxisId:t,className:r,width:n,label:i}=e,a=h.useRef(null),o=h.useRef(null),u=T(rc),l=Me(),s=ee(),c="yAxis",f=T(b=>Yr(b,c,t,l)),d=T(b=>_g(b,t)),v=T(b=>J_(b,t)),p=T(b=>Cg(b,c,t,l)),y=T(b=>lg(b,t));if(h.useLayoutEffect(()=>{if(!(n!=="auto"||!d||ws(i)||h.isValidElement(i)||y==null)){var b=a.current;if(b){var O=b.getCalculatedWidth();Math.round(d.width)!==Math.round(O)&&s(iT({id:t,width:O}))}}},[p,d,s,i,t,n,y]),d==null||v==null||y==null)return null;var{dangerouslySetInnerHTML:m,ticks:g}=e,x=tp(e,_2),{id:w}=y,P=tp(y,k2);return h.createElement(Ns,Il({},x,P,{ref:a,labelRef:o,scale:f,x:v.x,y:v.y,tickTextProps:n==="auto"?{width:void 0}:{width:n},width:d.width,height:d.height,className:H("recharts-".concat(c," ").concat(c),r),viewBox:u,ticks:p,axisType:c}))},M2={allowDataOverflow:Pe.allowDataOverflow,allowDecimals:Pe.allowDecimals,allowDuplicatedCategory:Pe.allowDuplicatedCategory,angle:Pe.angle,axisLine:jt.axisLine,hide:!1,includeHidden:Pe.includeHidden,interval:Pe.interval,minTickGap:Pe.minTickGap,mirror:Pe.mirror,orientation:Pe.orientation,padding:Pe.padding,reversed:Pe.reversed,scale:Pe.scale,tick:Pe.tick,tickCount:Pe.tickCount,tickLine:jt.tickLine,tickSize:jt.tickSize,type:Pe.type,width:Pe.width,yAxisId:0},T2=e=>{var t=pe(e,M2);return h.createElement(h.Fragment,null,h.createElement(C2,{interval:t.interval,id:t.yAxisId,scale:t.scale,type:t.type,domain:t.domain,allowDataOverflow:t.allowDataOverflow,dataKey:t.dataKey,allowDuplicatedCategory:t.allowDuplicatedCategory,allowDecimals:t.allowDecimals,tickCount:t.tickCount,padding:t.padding,includeHidden:t.includeHidden,reversed:t.reversed,ticks:t.ticks,width:t.width,orientation:t.orientation,mirror:t.mirror,hide:t.hide,unit:t.unit,name:t.name,angle:t.angle,minTickGap:t.minTickGap,tick:t.tick,tickFormatter:t.tickFormatter}),h.createElement(I2,t))},D2=h.memo(T2,H0);D2.displayName="YAxis";var N2=(e,t)=>t,Rs=A([N2,q,ag,be,Hg,Kt,pj,ye],Pj),Ls=e=>{var t=e.currentTarget.getBoundingClientRect(),r=t.width/e.currentTarget.offsetWidth,n=t.height/e.currentTarget.offsetHeight;return{chartX:Math.round((e.clientX-t.left)/r),chartY:Math.round((e.clientY-t.top)/n)}},Y0=at("mouseClick"),G0=jn();G0.startListening({actionCreator:Y0,effect:(e,t)=>{var r=e.payload,n=Rs(t.getState(),Ls(r));n?.activeIndex!=null&&t.dispatch(vk({activeIndex:n.activeIndex,activeDataKey:void 0,activeCoordinate:n.activeCoordinate}))}});var Ml=at("mouseMove"),V0=jn(),hi=null;V0.startListening({actionCreator:Ml,effect:(e,t)=>{var r=e.payload;hi!==null&&cancelAnimationFrame(hi);var n=Ls(r);hi=requestAnimationFrame(()=>{var i=t.getState(),a=ls(i,i.tooltip.settings.shared);if(a==="axis"){var o=Rs(i,n);o?.activeIndex!=null?t.dispatch(Lg({activeIndex:o.activeIndex,activeDataKey:void 0,activeCoordinate:o.activeCoordinate})):t.dispatch(Rg())}hi=null})}});var rp={accessibilityLayer:!0,barCategoryGap:"10%",barGap:4,barSize:void 0,className:void 0,maxBarSize:void 0,stackOffset:"none",syncId:void 0,syncMethod:"index",baseValue:void 0,reverseStackOrder:!1},X0=qe({name:"rootProps",initialState:rp,reducers:{updateOptions:(e,t)=>{var r;e.accessibilityLayer=t.payload.accessibilityLayer,e.barCategoryGap=t.payload.barCategoryGap,e.barGap=(r=t.payload.barGap)!==null&&r!==void 0?r:rp.barGap,e.barSize=t.payload.barSize,e.maxBarSize=t.payload.maxBarSize,e.stackOffset=t.payload.stackOffset,e.syncId=t.payload.syncId,e.syncMethod=t.payload.syncMethod,e.className=t.payload.className,e.baseValue=t.payload.baseValue,e.reverseStackOrder=t.payload.reverseStackOrder}}}),$2=X0.reducer,{updateOptions:R2}=X0.actions,Z0=qe({name:"polarOptions",initialState:null,reducers:{updatePolarOptions:(e,t)=>t.payload}}),{updatePolarOptions:L2}=Z0.actions,z2=Z0.reducer,Q0=at("keyDown"),J0=at("focus"),zs=jn();zs.startListening({actionCreator:Q0,effect:(e,t)=>{var r=t.getState(),n=r.rootProps.accessibilityLayer!==!1;if(n){var{keyboardInteraction:i}=r.tooltip,a=e.payload;if(!(a!=="ArrowRight"&&a!=="ArrowLeft"&&a!=="Enter")){var o=cs(i,Vr(r),Wn(r),Gn(r)),u=o==null?-1:Number(o);if(!(!Number.isFinite(u)||u<0)){var l=Kt(r);if(a==="Enter"){var s=ea(r,"axis","hover",String(i.index));t.dispatch(Ol({active:!i.active,activeIndex:i.index,activeDataKey:i.dataKey,activeCoordinate:s}));return}var c=nk(r),f=c==="left-to-right"?1:-1,d=a==="ArrowRight"?1:-1,v=u+d*f;if(!(l==null||v>=l.length||v<0)){var p=ea(r,"axis","hover",String(v));t.dispatch(Ol({active:!0,activeIndex:v.toString(),activeDataKey:void 0,activeCoordinate:p}))}}}}}});zs.startListening({actionCreator:J0,effect:(e,t)=>{var r=t.getState(),n=r.rootProps.accessibilityLayer!==!1;if(n){var{keyboardInteraction:i}=r.tooltip;if(!i.active&&i.index==null){var a="0",o=ea(r,"axis","hover",String(a));t.dispatch(Ol({activeDataKey:void 0,active:!0,activeIndex:a,activeCoordinate:o}))}}}});var rt=at("externalEvent"),eb=jn(),Mu=new Map;eb.startListening({actionCreator:rt,effect:(e,t)=>{var{handler:r,reactEvent:n}=e.payload;if(r!=null){n.persist();var i=n.type,a=Mu.get(i);a!==void 0&&cancelAnimationFrame(a);var o=requestAnimationFrame(()=>{try{var u=t.getState(),l={activeCoordinate:Jk(u),activeDataKey:hs(u),activeIndex:Xt(u),activeLabel:Vg(u),activeTooltipIndex:Xt(u),isTooltipActive:ej(u)};r(l,n)}finally{Mu.delete(i)}});Mu.set(i,o)}}});var B2=A([Gr],e=>e.tooltipItemPayloads),F2=A([B2,Hn,(e,t,r)=>t,(e,t,r)=>r],(e,t,r,n)=>{var i=e.find(u=>u.settings.dataKey===n);if(i!=null){var{positions:a}=i;if(a!=null){var o=t(a,r);return o}}}),tb=at("touchMove"),rb=jn();rb.startListening({actionCreator:tb,effect:(e,t)=>{var r=e.payload;if(!(r.touches==null||r.touches.length===0)){var n=t.getState(),i=ls(n,n.tooltip.settings.shared);if(i==="axis"){var a=Rs(n,Ls({clientX:r.touches[0].clientX,clientY:r.touches[0].clientY,currentTarget:r.currentTarget}));a?.activeIndex!=null&&t.dispatch(Lg({activeIndex:a.activeIndex,activeDataKey:void 0,activeCoordinate:a.activeCoordinate}))}else if(i==="item"){var o,u=r.touches[0];if(document.elementFromPoint==null)return;var l=document.elementFromPoint(u.clientX,u.clientY);if(!l||!l.getAttribute)return;var s=l.getAttribute(_m),c=(o=l.getAttribute(km))!==null&&o!==void 0?o:void 0,f=F2(t.getState(),s,c);t.dispatch($g({activeDataKey:c,activeIndex:s,activeCoordinate:f}))}}}});var K2=Vp({brush:HD,cartesianAxis:aT,chartData:Jj,errorBars:OT,graphicalItems:sM,layout:wP,legend:kO,options:Gj,polarAxis:SI,polarOptions:z2,referenceElements:JD,rootProps:$2,tooltip:hk,zIndex:$j}),q2=function(t){return Ux({reducer:K2,preloadedState:t,middleware:r=>{var n;return r({serializableCheck:!1,immutableCheck:!["commonjs","es6","production"].includes((n="es6")!==null&&n!==void 0?n:"")}).concat([G0.middleware,V0.middleware,zs.middleware,eb.middleware,rb.middleware])},enhancers:r=>{var n=r;return typeof r=="function"&&(n=r()),n.concat(sm({type:"raf"}))},devTools:Tn.devToolsEnabled})};function nb(e){var{preloadedState:t,children:r,reduxStoreName:n}=e,i=Me(),a=h.useRef(null);if(i)return r;a.current==null&&(a.current=q2(t));var o=Yl;return h.createElement(YT,{context:o,store:a.current},r)}function W2(e){var{layout:t,margin:r}=e,n=ee(),i=Me();return h.useEffect(()=>{i||(n(yP(t)),n(mP(r)))},[n,i,t,r]),null}var ib=h.memo(W2,eo);function ab(e){var t=ee();return h.useEffect(()=>{t(R2(e))},[t,e]),null}function np(e){var{zIndex:t,isPanorama:r}=e,n=r?"recharts-zindex-panorama-":"recharts-zindex-",i=E0("".concat(n).concat(t)),a=ee();return h.useLayoutEffect(()=>(a(Dj({zIndex:t,elementId:i,isPanorama:r})),()=>{a(Nj({zIndex:t,isPanorama:r}))}),[a,t,i,r]),h.createElement("g",{tabIndex:-1,id:i})}function ip(e){var{children:t,isPanorama:r}=e,n=T(Aj);if(!n||n.length===0)return t;var i=n.filter(o=>o<0),a=n.filter(o=>o>0);return h.createElement(h.Fragment,null,i.map(o=>h.createElement(np,{key:o,zIndex:o,isPanorama:r})),t,a.map(o=>h.createElement(np,{key:o,zIndex:o,isPanorama:r})))}var U2=["children"];function H2(e,t){if(e==null)return{};var r,n,i=Y2(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n{var r=ic(),n=ac(),i=Wm();if(!wt(r)||!wt(n))return null;var{children:a,otherAttributes:o,title:u,desc:l}=e,s,c;return o!=null&&(typeof o.tabIndex=="number"?s=o.tabIndex:s=i?0:void 0,typeof o.role=="string"?c=o.role:c=i?"application":void 0),h.createElement(Rl,ca({},o,{title:u,desc:l,role:c,tabIndex:s,width:r,height:n,style:G2,ref:t}),a)}),X2=e=>{var{children:t}=e,r=T(Ea);if(!r)return null;var{width:n,height:i,y:a,x:o}=r;return h.createElement(Rl,{width:n,height:i,x:o,y:a},t)},ap=h.forwardRef((e,t)=>{var{children:r}=e,n=H2(e,U2),i=Me();return i?h.createElement(X2,null,h.createElement(ip,{isPanorama:!0},r)):h.createElement(V2,ca({ref:t},n),h.createElement(ip,{isPanorama:!1},r))});function Z2(){var e=ee(),[t,r]=h.useState(null),n=T(LP);return h.useEffect(()=>{if(t!=null){var i=t.getBoundingClientRect(),a=i.width/t.offsetWidth;se(a)&&a!==n&&e(bP(a))}},[t,e,n]),r}function op(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Q2(e){for(var t=1;t(lC(),null);function sa(e){if(typeof e=="number")return e;if(typeof e=="string"){var t=parseFloat(e);if(!Number.isNaN(t))return t}return 0}var n$=h.forwardRef((e,t)=>{var r,n,i=h.useRef(null),[a,o]=h.useState({containerWidth:sa((r=e.style)===null||r===void 0?void 0:r.width),containerHeight:sa((n=e.style)===null||n===void 0?void 0:n.height)}),u=h.useCallback((s,c)=>{o(f=>{var d=Math.round(s),v=Math.round(c);return f.containerWidth===d&&f.containerHeight===v?f:{containerWidth:d,containerHeight:v}})},[]),l=h.useCallback(s=>{if(typeof t=="function"&&t(s),s!=null&&typeof ResizeObserver<"u"){var{width:c,height:f}=s.getBoundingClientRect();u(c,f);var d=p=>{var{width:y,height:m}=p[0].contentRect;u(y,m)},v=new ResizeObserver(d);v.observe(s),i.current=v}},[t,u]);return h.useEffect(()=>()=>{var s=i.current;s?.disconnect()},[u]),h.createElement(h.Fragment,null,h.createElement(ka,{width:a.containerWidth,height:a.containerHeight}),h.createElement("div",wr({ref:l},e)))}),i$=h.forwardRef((e,t)=>{var{width:r,height:n}=e,[i,a]=h.useState({containerWidth:sa(r),containerHeight:sa(n)}),o=h.useCallback((l,s)=>{a(c=>{var f=Math.round(l),d=Math.round(s);return c.containerWidth===f&&c.containerHeight===d?c:{containerWidth:f,containerHeight:d}})},[]),u=h.useCallback(l=>{if(typeof t=="function"&&t(l),l!=null){var{width:s,height:c}=l.getBoundingClientRect();o(s,c)}},[t,o]);return h.createElement(h.Fragment,null,h.createElement(ka,{width:i.containerWidth,height:i.containerHeight}),h.createElement("div",wr({ref:u},e)))}),a$=h.forwardRef((e,t)=>{var{width:r,height:n}=e;return h.createElement(h.Fragment,null,h.createElement(ka,{width:r,height:n}),h.createElement("div",wr({ref:t},e)))}),o$=h.forwardRef((e,t)=>{var{width:r,height:n}=e;return Ct(r)||Ct(n)?h.createElement(i$,wr({},e,{ref:t})):h.createElement(a$,wr({},e,{ref:t}))});function u$(e){return e===!0?n$:o$}var l$=h.forwardRef((e,t)=>{var{children:r,className:n,height:i,onClick:a,onContextMenu:o,onDoubleClick:u,onMouseDown:l,onMouseEnter:s,onMouseLeave:c,onMouseMove:f,onMouseUp:d,onTouchEnd:v,onTouchMove:p,onTouchStart:y,style:m,width:g,responsive:x,dispatchTouchEvents:w=!0}=e,P=h.useRef(null),b=ee(),[O,S]=h.useState(null),[_,I]=h.useState(null),M=Z2(),E=nc(),j=E?.width>0?E.width:g,$=E?.height>0?E.height:i,L=h.useCallback(k=>{M(k),typeof t=="function"&&t(k),S(k),I(k),k!=null&&(P.current=k)},[M,t,S,I]),z=h.useCallback(k=>{b(Y0(k)),b(rt({handler:a,reactEvent:k}))},[b,a]),K=h.useCallback(k=>{b(Ml(k)),b(rt({handler:s,reactEvent:k}))},[b,s]),B=h.useCallback(k=>{b(Rg()),b(rt({handler:c,reactEvent:k}))},[b,c]),W=h.useCallback(k=>{b(Ml(k)),b(rt({handler:f,reactEvent:k}))},[b,f]),R=h.useCallback(()=>{b(J0())},[b]),ke=h.useCallback(k=>{b(Q0(k.key))},[b]),Te=h.useCallback(k=>{b(rt({handler:o,reactEvent:k}))},[b,o]),Le=h.useCallback(k=>{b(rt({handler:u,reactEvent:k}))},[b,u]),Pt=h.useCallback(k=>{b(rt({handler:l,reactEvent:k}))},[b,l]),Je=h.useCallback(k=>{b(rt({handler:d,reactEvent:k}))},[b,d]),nr=h.useCallback(k=>{b(rt({handler:y,reactEvent:k}))},[b,y]),Xr=h.useCallback(k=>{w&&b(tb(k)),b(rt({handler:p,reactEvent:k}))},[b,w,p]),ze=h.useCallback(k=>{b(rt({handler:v,reactEvent:k}))},[b,v]),to=u$(x);return h.createElement(r0.Provider,{value:O},h.createElement(fp.Provider,{value:_},h.createElement(to,{width:j??m?.width,height:$??m?.height,className:H("recharts-wrapper",n),style:Q2({position:"relative",cursor:"default",width:j,height:$},m),onClick:z,onContextMenu:Te,onDoubleClick:Le,onFocus:R,onKeyDown:ke,onMouseDown:Pt,onMouseEnter:K,onMouseLeave:B,onMouseMove:W,onMouseUp:Je,onTouchEnd:ze,onTouchMove:Xr,onTouchStart:nr,ref:L},h.createElement(r$,null),r)))}),c$=["width","height","responsive","children","className","style","compact","title","desc"];function s$(e,t){if(e==null)return{};var r,n,i=f$(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n{var{width:r,height:n,responsive:i,children:a,className:o,style:u,compact:l,title:s,desc:c}=e,f=s$(e,c$),d=Ze(f);return l?h.createElement(h.Fragment,null,h.createElement(ka,{width:r,height:n}),h.createElement(ap,{otherAttributes:d,title:s,desc:c},a)):h.createElement(l$,{className:o,style:u,width:r,height:n,responsive:i??!1,onClick:e.onClick,onMouseLeave:e.onMouseLeave,onMouseEnter:e.onMouseEnter,onMouseMove:e.onMouseMove,onMouseDown:e.onMouseDown,onMouseUp:e.onMouseUp,onContextMenu:e.onContextMenu,onDoubleClick:e.onDoubleClick,onTouchStart:e.onTouchStart,onTouchMove:e.onTouchMove,onTouchEnd:e.onTouchEnd},h.createElement(ap,{otherAttributes:d,title:s,desc:c,ref:t},h.createElement(tN,null,a)))});function Tl(){return Tl=Object.assign?Object.assign.bind():function(e){for(var t=1;th.createElement(ub,{chartName:"LineChart",defaultTooltipEventType:"axis",validateTooltipEventTypes:h$,tooltipPayloadSearcher:bs,categoricalChartProps:e,ref:t})),p$=["axis","item"],tR=h.forwardRef((e,t)=>h.createElement(ub,{chartName:"BarChart",defaultTooltipEventType:"axis",validateTooltipEventTypes:p$,tooltipPayloadSearcher:bs,categoricalChartProps:e,ref:t}));function m$(e){var t=ee();return h.useEffect(()=>{t(L2(e))},[t,e]),null}var y$=["layout"];function Dl(){return Dl=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var r=pe(e,E$);return h.createElement(x$,{chartName:"PieChart",defaultTooltipEventType:"item",validateTooltipEventTypes:S$,tooltipPayloadSearcher:bs,categoricalChartProps:r,ref:t})});export{tR as B,FN as C,KO as L,rR as P,I$ as R,$$ as T,E2 as X,D2 as Y,ov as a,HA as b,bn as c,T$ as d,M$ as e,D$ as f,eR as g,p2 as h,pt as i,bD as j,LM as k,Va as l}; diff --git a/webui/dist/assets/codemirror-TZqPU532.js b/webui/dist/assets/codemirror-TZqPU532.js new file mode 100644 index 00000000..cfe8cb2f --- /dev/null +++ b/webui/dist/assets/codemirror-TZqPU532.js @@ -0,0 +1,16 @@ +import{r as Se,j as zu}from"./router-9vIXuQkh.js";function xr(){return xr=Object.assign?Object.assign.bind():function(n){for(var e=1;e{let n="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,t=0;e>1;if(n=bh[i])e=i+1;else return!0;if(e==t)return!1}}function hl(n){return n>=127462&&n<=127487}const cl=8205;function Nu(n,e,t=!0,i=!0){return(t?Sh:Xu)(n,e,i)}function Sh(n,e,t){if(e==n.length)return e;e&&xh(n.charCodeAt(e))&&kh(n.charCodeAt(e-1))&&e--;let i=zs(n,e);for(e+=fl(i);e=0&&hl(zs(n,o));)r++,o-=2;if(r%2==0)break;e+=2}else break}return e}function Xu(n,e,t){for(;e>0;){let i=Sh(n,e-2,t);if(i=56320&&n<57344}function kh(n){return n>=55296&&n<56320}function fl(n){return n<65536?1:2}class V{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,i){[e,t]=li(this,e,t);let s=[];return this.decompose(0,e,s,2),i.length&&i.decompose(0,i.length,s,3),this.decompose(t,this.length,s,1),Ze.from(s,this.length-(t-e)+i.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=li(this,e,t);let i=[];return this.decompose(e,t,i,0),Ze.from(i,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),s=new Ai(this),r=new Ai(e);for(let o=t,l=t;;){if(s.next(o),r.next(o),o=0,s.lineBreak!=r.lineBreak||s.done!=r.done||s.value!=r.value)return!1;if(l+=s.value.length,s.done||l>=i)return!0}}iter(e=1){return new Ai(this,e)}iterRange(e,t=this.length){return new wh(this,e,t)}iterLines(e,t){let i;if(e==null)i=this.iter();else{t==null&&(t=this.lines+1);let s=this.line(e).from;i=this.iterRange(s,Math.max(s,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new vh(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?V.empty:e.length<=32?new K(e):Ze.from(K.split(e,[]))}}class K extends V{constructor(e,t=Fu(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.text[r],l=s+o.length;if((t?i:l)>=e)return new _u(s,l,i,o);s=l+1,i++}}decompose(e,t,i,s){let r=e<=0&&t>=this.length?this:new K(ul(this.text,e,t),Math.min(t,this.length)-Math.max(0,e));if(s&1){let o=i.pop(),l=Xn(r.text,o.text.slice(),0,r.length);if(l.length<=32)i.push(new K(l,o.length+r.length));else{let a=l.length>>1;i.push(new K(l.slice(0,a)),new K(l.slice(a)))}}else i.push(r)}replace(e,t,i){if(!(i instanceof K))return super.replace(e,t,i);[e,t]=li(this,e,t);let s=Xn(this.text,Xn(i.text,ul(this.text,0,e)),t),r=this.length+i.length-(t-e);return s.length<=32?new K(s,r):Ze.from(K.split(s,[]),r)}sliceString(e,t=this.length,i=` +`){[e,t]=li(this,e,t);let s="";for(let r=0,o=0;r<=t&&oe&&o&&(s+=i),er&&(s+=l.slice(Math.max(0,e-r),t-r)),r=a+1}return s}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(e,t){let i=[],s=-1;for(let r of e)i.push(r),s+=r.length+1,i.length==32&&(t.push(new K(i,s)),i=[],s=-1);return s>-1&&t.push(new K(i,s)),t}}class Ze extends V{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let i of e)this.lines+=i.lines}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.children[r],l=s+o.length,a=i+o.lines-1;if((t?a:l)>=e)return o.lineInner(e,t,i,s);s=l+1,i=a+1}}decompose(e,t,i,s){for(let r=0,o=0;o<=t&&r=o){let h=s&((o<=e?1:0)|(a>=t?2:0));o>=e&&a<=t&&!h?i.push(l):l.decompose(e-o,t-o,i,h)}o=a+1}}replace(e,t,i){if([e,t]=li(this,e,t),i.lines=r&&t<=l){let a=o.replace(e-r,t-r,i),h=this.lines-o.lines+a.lines;if(a.lines>4&&a.lines>h>>6){let c=this.children.slice();return c[s]=a,new Ze(c,this.length-(t-e)+i.length)}return super.replace(r,l,a)}r=l+1}return super.replace(e,t,i)}sliceString(e,t=this.length,i=` +`){[e,t]=li(this,e,t);let s="";for(let r=0,o=0;re&&r&&(s+=i),eo&&(s+=l.sliceString(e-o,t-o,i)),o=a+1}return s}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(e,t){if(!(e instanceof Ze))return 0;let i=0,[s,r,o,l]=t>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=t,r+=t){if(s==o||r==l)return i;let a=this.children[s],h=e.children[r];if(a!=h)return i+a.scanIdentical(h,t);i+=a.length+1}}static from(e,t=e.reduce((i,s)=>i+s.length+1,-1)){let i=0;for(let d of e)i+=d.lines;if(i<32){let d=[];for(let p of e)p.flatten(d);return new K(d,t)}let s=Math.max(32,i>>5),r=s<<1,o=s>>1,l=[],a=0,h=-1,c=[];function f(d){let p;if(d.lines>r&&d instanceof Ze)for(let m of d.children)f(m);else d.lines>o&&(a>o||!a)?(u(),l.push(d)):d instanceof K&&a&&(p=c[c.length-1])instanceof K&&d.lines+p.lines<=32?(a+=d.lines,h+=d.length+1,c[c.length-1]=new K(p.text.concat(d.text),p.length+1+d.length)):(a+d.lines>s&&u(),a+=d.lines,h+=d.length+1,c.push(d))}function u(){a!=0&&(l.push(c.length==1?c[0]:Ze.from(c,h)),h=-1,a=c.length=0)}for(let d of e)f(d);return u(),l.length==1?l[0]:new Ze(l,t)}}V.empty=new K([""],0);function Fu(n){let e=-1;for(let t of n)e+=t.length+1;return e}function Xn(n,e,t=0,i=1e9){for(let s=0,r=0,o=!0;r=t&&(a>i&&(l=l.slice(0,i-s)),s0?1:(e instanceof K?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let i=this.nodes.length-1,s=this.nodes[i],r=this.offsets[i],o=r>>1,l=s instanceof K?s.text.length:s.children.length;if(o==(t>0?l:0)){if(i==0)return this.done=!0,this.value="",this;t>0&&this.offsets[i-1]++,this.nodes.pop(),this.offsets.pop()}else if((r&1)==(t>0?0:1)){if(this.offsets[i]+=t,e==0)return this.lineBreak=!0,this.value=` +`,this;e--}else if(s instanceof K){let a=s.text[o+(t<0?-1:0)];if(this.offsets[i]+=t,a.length>Math.max(0,e))return this.value=e==0?a:t>0?a.slice(e):a.slice(0,a.length-e),this;e-=a.length}else{let a=s.children[o+(t<0?-1:0)];e>a.length?(e-=a.length,this.offsets[i]+=t):(t<0&&this.offsets[i]--,this.nodes.push(a),this.offsets.push(t>0?1:(a instanceof K?a.text.length:a.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class wh{constructor(e,t,i){this.value="",this.done=!1,this.cursor=new Ai(e,t>i?-1:1),this.pos=t>i?e.length:0,this.from=Math.min(t,i),this.to=Math.max(t,i)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let i=t<0?this.pos-this.from:this.to-this.pos;e>i&&(e=i),i-=e;let{value:s}=this.cursor.next(e);return this.pos+=(s.length+e)*t,this.value=s.length<=i?s:t<0?s.slice(s.length-i):s.slice(0,i),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class vh{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:t,lineBreak:i,value:s}=this.inner.next(e);return t&&this.afterBreak?(this.value="",this.afterBreak=!1):t?(this.done=!0,this.value=""):i?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=s,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(V.prototype[Symbol.iterator]=function(){return this.iter()},Ai.prototype[Symbol.iterator]=wh.prototype[Symbol.iterator]=vh.prototype[Symbol.iterator]=function(){return this});class _u{constructor(e,t,i,s){this.from=e,this.to=t,this.number=i,this.text=s}get length(){return this.to-this.from}}function li(n,e,t){return e=Math.max(0,Math.min(n.length,e)),[e,Math.max(e,Math.min(n.length,t))]}function pe(n,e,t=!0,i=!0){return Nu(n,e,t,i)}function Uu(n){return n>=56320&&n<57344}function Hu(n){return n>=55296&&n<56320}function Te(n,e){let t=n.charCodeAt(e);if(!Hu(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return Uu(i)?(t-55296<<10)+(i-56320)+65536:t}function So(n){return n<=65535?String.fromCharCode(n):(n-=65536,String.fromCharCode((n>>10)+55296,(n&1023)+56320))}function Ye(n){return n<65536?1:2}const wr=/\r\n?|\n/;var de=(function(n){return n[n.Simple=0]="Simple",n[n.TrackDel=1]="TrackDel",n[n.TrackBefore=2]="TrackBefore",n[n.TrackAfter=3]="TrackAfter",n})(de||(de={}));class it{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;te)return r+(e-s);r+=l}else{if(i!=de.Simple&&h>=e&&(i==de.TrackDel&&se||i==de.TrackBefore&&se))return null;if(h>e||h==e&&t<0&&!l)return e==s||t<0?r:r+a;r+=a}s=h}if(e>s)throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`);return r}touchesRange(e,t=e){for(let i=0,s=0;i=0&&s<=t&&l>=e)return st?"cover":!0;s=l}return!1}toString(){let e="";for(let t=0;t=0?":"+s:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some(t=>typeof t!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new it(e)}static create(e){return new it(e)}}class se extends it{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return vr(this,(t,i,s,r,o)=>e=e.replace(s,s+(i-t),o),!1),e}mapDesc(e,t=!1){return Tr(this,e,t,!0)}invert(e){let t=this.sections.slice(),i=[];for(let s=0,r=0;s=0){t[s]=l,t[s+1]=o;let a=s>>1;for(;i.length0&&kt(i,t,r.text),r.forward(c),l+=c}let h=e[o++];for(;l>1].toJSON()))}return e}static of(e,t,i){let s=[],r=[],o=0,l=null;function a(c=!1){if(!c&&!s.length)return;ou||f<0||u>t)throw new RangeError(`Invalid change range ${f} to ${u} (in doc of length ${t})`);let p=d?typeof d=="string"?V.of(d.split(i||wr)):d:V.empty,m=p.length;if(f==u&&m==0)return;fo&&Oe(s,f-o,-1),Oe(s,u-f,m),kt(r,s,p),o=u}}return h(e),a(!l),l}static empty(e){return new se(e?[e,-1]:[],[])}static fromJSON(e){if(!Array.isArray(e))throw new RangeError("Invalid JSON representation of ChangeSet");let t=[],i=[];for(let s=0;sl&&typeof o!="string"))throw new RangeError("Invalid JSON representation of ChangeSet");if(r.length==1)t.push(r[0],0);else{for(;i.length=0&&t<=0&&t==n[s+1]?n[s]+=e:s>=0&&e==0&&n[s]==0?n[s+1]+=t:i?(n[s]+=e,n[s+1]+=t):n.push(e,t)}function kt(n,e,t){if(t.length==0)return;let i=e.length-2>>1;if(i>1])),!(t||o==n.sections.length||n.sections[o+1]<0);)l=n.sections[o++],a=n.sections[o++];e(s,h,r,c,f),s=h,r=c}}}function Tr(n,e,t,i=!1){let s=[],r=i?[]:null,o=new Bi(n),l=new Bi(e);for(let a=-1;;){if(o.done&&l.len||l.done&&o.len)throw new Error("Mismatched change set lengths");if(o.ins==-1&&l.ins==-1){let h=Math.min(o.len,l.len);Oe(s,h,-1),o.forward(h),l.forward(h)}else if(l.ins>=0&&(o.ins<0||a==o.i||o.off==0&&(l.len=0&&a=0){let h=0,c=o.len;for(;c;)if(l.ins==-1){let f=Math.min(c,l.len);h+=f,c-=f,l.forward(f)}else if(l.ins==0&&l.lena||o.ins>=0&&o.len>a)&&(l||i.length>h),r.forward2(a),o.forward(a)}}}}class Bi{constructor(e){this.set=e,this.i=0,this.next()}next(){let{sections:e}=this.set;this.i>1;return t>=e.length?V.empty:e[t]}textBit(e){let{inserted:t}=this.set,i=this.i-2>>1;return i>=t.length&&!e?V.empty:t[i].slice(this.off,e==null?void 0:this.off+e)}forward(e){e==this.len?this.next():(this.len-=e,this.off+=e)}forward2(e){this.ins==-1?this.forward(e):e==this.ins?this.next():(this.ins-=e,this.off+=e)}}class Wt{constructor(e,t,i){this.from=e,this.to=t,this.flags=i}get anchor(){return this.flags&32?this.to:this.from}get head(){return this.flags&32?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return this.flags&8?-1:this.flags&16?1:0}get bidiLevel(){let e=this.flags&7;return e==7?null:e}get goalColumn(){let e=this.flags>>6;return e==16777215?void 0:e}map(e,t=-1){let i,s;return this.empty?i=s=e.mapPos(this.from,t):(i=e.mapPos(this.from,1),s=e.mapPos(this.to,-1)),i==this.from&&s==this.to?this:new Wt(i,s,this.flags)}extend(e,t=e){if(e<=this.anchor&&t>=this.anchor)return b.range(e,t);let i=Math.abs(e-this.anchor)>Math.abs(t-this.anchor)?e:t;return b.range(this.anchor,i)}eq(e,t=!1){return this.anchor==e.anchor&&this.head==e.head&&(!t||!this.empty||this.assoc==e.assoc)}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(e){if(!e||typeof e.anchor!="number"||typeof e.head!="number")throw new RangeError("Invalid JSON representation for SelectionRange");return b.range(e.anchor,e.head)}static create(e,t,i){return new Wt(e,t,i)}}class b{constructor(e,t){this.ranges=e,this.mainIndex=t}map(e,t=-1){return e.empty?this:b.create(this.ranges.map(i=>i.map(e,t)),this.mainIndex)}eq(e,t=!1){if(this.ranges.length!=e.ranges.length||this.mainIndex!=e.mainIndex)return!1;for(let i=0;ie.toJSON()),main:this.mainIndex}}static fromJSON(e){if(!e||!Array.isArray(e.ranges)||typeof e.main!="number"||e.main>=e.ranges.length)throw new RangeError("Invalid JSON representation for EditorSelection");return new b(e.ranges.map(t=>Wt.fromJSON(t)),e.main)}static single(e,t=e){return new b([b.range(e,t)],0)}static create(e,t=0){if(e.length==0)throw new RangeError("A selection needs at least one range");for(let i=0,s=0;se?8:0)|r)}static normalized(e,t=0){let i=e[t];e.sort((s,r)=>s.from-r.from),t=e.indexOf(i);for(let s=1;sr.head?b.range(a,l):b.range(l,a))}}return new b(e,t)}}function Ch(n,e){for(let t of n.ranges)if(t.to>e)throw new RangeError("Selection points outside of document")}let xo=0;class A{constructor(e,t,i,s,r){this.combine=e,this.compareInput=t,this.compare=i,this.isStatic=s,this.id=xo++,this.default=e([]),this.extensions=typeof r=="function"?r(this):r}get reader(){return this}static define(e={}){return new A(e.combine||(t=>t),e.compareInput||((t,i)=>t===i),e.compare||(e.combine?(t,i)=>t===i:ko),!!e.static,e.enables)}of(e){return new Fn([],this,0,e)}compute(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new Fn(e,this,1,t)}computeN(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new Fn(e,this,2,t)}from(e,t){return t||(t=i=>i),this.compute([e],i=>t(i.field(e)))}}function ko(n,e){return n==e||n.length==e.length&&n.every((t,i)=>t===e[i])}class Fn{constructor(e,t,i,s){this.dependencies=e,this.facet=t,this.type=i,this.value=s,this.id=xo++}dynamicSlot(e){var t;let i=this.value,s=this.facet.compareInput,r=this.id,o=e[r]>>1,l=this.type==2,a=!1,h=!1,c=[];for(let f of this.dependencies)f=="doc"?a=!0:f=="selection"?h=!0:(((t=e[f.id])!==null&&t!==void 0?t:1)&1)==0&&c.push(e[f.id]);return{create(f){return f.values[o]=i(f),1},update(f,u){if(a&&u.docChanged||h&&(u.docChanged||u.selection)||Cr(f,c)){let d=i(f);if(l?!dl(d,f.values[o],s):!s(d,f.values[o]))return f.values[o]=d,1}return 0},reconfigure:(f,u)=>{let d,p=u.config.address[r];if(p!=null){let m=ns(u,p);if(this.dependencies.every(g=>g instanceof A?u.facet(g)===f.facet(g):g instanceof he?u.field(g,!1)==f.field(g,!1):!0)||(l?dl(d=i(f),m,s):s(d=i(f),m)))return f.values[o]=m,0}else d=i(f);return f.values[o]=d,1}}}}function dl(n,e,t){if(n.length!=e.length)return!1;for(let i=0;in[a.id]),s=t.map(a=>a.type),r=i.filter(a=>!(a&1)),o=n[e.id]>>1;function l(a){let h=[];for(let c=0;ci===s),e);return e.provide&&(t.provides=e.provide(t)),t}create(e){let t=e.facet(On).find(i=>i.field==this);return(t?.create||this.createF)(e)}slot(e){let t=e[this.id]>>1;return{create:i=>(i.values[t]=this.create(i),1),update:(i,s)=>{let r=i.values[t],o=this.updateF(r,s);return this.compareF(r,o)?0:(i.values[t]=o,1)},reconfigure:(i,s)=>{let r=i.facet(On),o=s.facet(On),l;return(l=r.find(a=>a.field==this))&&l!=o.find(a=>a.field==this)?(i.values[t]=l.create(i),1):s.config.address[this.id]!=null?(i.values[t]=s.field(this),0):(i.values[t]=this.create(i),1)}}}init(e){return[this,On.of({field:this,create:e})]}get extension(){return this}}const $t={lowest:4,low:3,default:2,high:1,highest:0};function Si(n){return e=>new Ph(e,n)}const Mt={highest:Si($t.highest),high:Si($t.high),default:Si($t.default),low:Si($t.low),lowest:Si($t.lowest)};class Ph{constructor(e,t){this.inner=e,this.prec=t}}class vs{of(e){return new Pr(this,e)}reconfigure(e){return vs.reconfigure.of({compartment:this,extension:e})}get(e){return e.config.compartments.get(this)}}class Pr{constructor(e,t){this.compartment=e,this.inner=t}}class is{constructor(e,t,i,s,r,o){for(this.base=e,this.compartments=t,this.dynamicSlots=i,this.address=s,this.staticValues=r,this.facets=o,this.statusTemplate=[];this.statusTemplate.length>1]}static resolve(e,t,i){let s=[],r=Object.create(null),o=new Map;for(let u of Gu(e,t,o))u instanceof he?s.push(u):(r[u.facet.id]||(r[u.facet.id]=[])).push(u);let l=Object.create(null),a=[],h=[];for(let u of s)l[u.id]=h.length<<1,h.push(d=>u.slot(d));let c=i?.config.facets;for(let u in r){let d=r[u],p=d[0].facet,m=c&&c[u]||[];if(d.every(g=>g.type==0))if(l[p.id]=a.length<<1|1,ko(m,d))a.push(i.facet(p));else{let g=p.combine(d.map(y=>y.value));a.push(i&&p.compare(g,i.facet(p))?i.facet(p):g)}else{for(let g of d)g.type==0?(l[g.id]=a.length<<1|1,a.push(g.value)):(l[g.id]=h.length<<1,h.push(y=>g.dynamicSlot(y)));l[p.id]=h.length<<1,h.push(g=>ju(g,p,d))}}let f=h.map(u=>u(l));return new is(e,o,f,l,a,r)}}function Gu(n,e,t){let i=[[],[],[],[],[]],s=new Map;function r(o,l){let a=s.get(o);if(a!=null){if(a<=l)return;let h=i[a].indexOf(o);h>-1&&i[a].splice(h,1),o instanceof Pr&&t.delete(o.compartment)}if(s.set(o,l),Array.isArray(o))for(let h of o)r(h,l);else if(o instanceof Pr){if(t.has(o.compartment))throw new RangeError("Duplicate use of compartment in extensions");let h=e.get(o.compartment)||o.inner;t.set(o.compartment,h),r(h,l)}else if(o instanceof Ph)r(o.inner,o.prec);else if(o instanceof he)i[l].push(o),o.provides&&r(o.provides,l);else if(o instanceof Fn)i[l].push(o),o.facet.extensions&&r(o.facet.extensions,$t.default);else{let h=o.extension;if(!h)throw new Error(`Unrecognized extension value in extension set (${o}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);r(h,l)}}return r(n,$t.default),i.reduce((o,l)=>o.concat(l))}function Mi(n,e){if(e&1)return 2;let t=e>>1,i=n.status[t];if(i==4)throw new Error("Cyclic dependency between fields and/or facets");if(i&2)return i;n.status[t]=4;let s=n.computeSlot(n,n.config.dynamicSlots[t]);return n.status[t]=2|s}function ns(n,e){return e&1?n.config.staticValues[e>>1]:n.values[e>>1]}const Qh=A.define(),Qr=A.define({combine:n=>n.some(e=>e),static:!0}),Ah=A.define({combine:n=>n.length?n[0]:void 0,static:!0}),Mh=A.define(),Rh=A.define(),Dh=A.define(),Eh=A.define({combine:n=>n.length?n[0]:!1});class st{constructor(e,t){this.type=e,this.value=t}static define(){return new Zu}}class Zu{of(e){return new st(this,e)}}class Yu{constructor(e){this.map=e}of(e){return new q(this,e)}}class q{constructor(e,t){this.type=e,this.value=t}map(e){let t=this.type.map(this.value,e);return t===void 0?void 0:t==this.value?this:new q(this.type,t)}is(e){return this.type==e}static define(e={}){return new Yu(e.map||(t=>t))}static mapEffects(e,t){if(!e.length)return e;let i=[];for(let s of e){let r=s.map(t);r&&i.push(r)}return i}}q.reconfigure=q.define();q.appendConfig=q.define();class ie{constructor(e,t,i,s,r,o){this.startState=e,this.changes=t,this.selection=i,this.effects=s,this.annotations=r,this.scrollIntoView=o,this._doc=null,this._state=null,i&&Ch(i,t.newLength),r.some(l=>l.type==ie.time)||(this.annotations=r.concat(ie.time.of(Date.now())))}static create(e,t,i,s,r,o){return new ie(e,t,i,s,r,o)}get newDoc(){return this._doc||(this._doc=this.changes.apply(this.startState.doc))}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(e){for(let t of this.annotations)if(t.type==e)return t.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(e){let t=this.annotation(ie.userEvent);return!!(t&&(t==e||t.length>e.length&&t.slice(0,e.length)==e&&t[e.length]=="."))}}ie.time=st.define();ie.userEvent=st.define();ie.addToHistory=st.define();ie.remote=st.define();function Ku(n,e){let t=[];for(let i=0,s=0;;){let r,o;if(i=n[i]))r=n[i++],o=n[i++];else if(s=0;s--){let r=i[s](n);r instanceof ie?n=r:Array.isArray(r)&&r.length==1&&r[0]instanceof ie?n=r[0]:n=$h(e,ti(r),!1)}return n}function ed(n){let e=n.startState,t=e.facet(Dh),i=n;for(let s=t.length-1;s>=0;s--){let r=t[s](n);r&&Object.keys(r).length&&(i=qh(i,Ar(e,r,n.changes.newLength),!0))}return i==n?n:ie.create(e,n.changes,n.selection,i.effects,i.annotations,i.scrollIntoView)}const td=[];function ti(n){return n==null?td:Array.isArray(n)?n:[n]}var Y=(function(n){return n[n.Word=0]="Word",n[n.Space=1]="Space",n[n.Other=2]="Other",n})(Y||(Y={}));const id=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;let Mr;try{Mr=new RegExp("[\\p{Alphabetic}\\p{Number}_]","u")}catch{}function nd(n){if(Mr)return Mr.test(n);for(let e=0;e"€"&&(t.toUpperCase()!=t.toLowerCase()||id.test(t)))return!0}return!1}function sd(n){return e=>{if(!/\S/.test(e))return Y.Space;if(nd(e))return Y.Word;for(let t=0;t-1)return Y.Word;return Y.Other}}class I{constructor(e,t,i,s,r,o){this.config=e,this.doc=t,this.selection=i,this.values=s,this.status=e.statusTemplate.slice(),this.computeSlot=r,o&&(o._state=this);for(let l=0;ls.set(h,a)),t=null),s.set(l.value.compartment,l.value.extension)):l.is(q.reconfigure)?(t=null,i=l.value):l.is(q.appendConfig)&&(t=null,i=ti(i).concat(l.value));let r;t?r=e.startState.values.slice():(t=is.resolve(i,s,this),r=new I(t,this.doc,this.selection,t.dynamicSlots.map(()=>null),(a,h)=>h.reconfigure(a,this),null).values);let o=e.startState.facet(Qr)?e.newSelection:e.newSelection.asSingle();new I(t,e.newDoc,o,r,(l,a)=>a.update(l,e),e)}replaceSelection(e){return typeof e=="string"&&(e=this.toText(e)),this.changeByRange(t=>({changes:{from:t.from,to:t.to,insert:e},range:b.cursor(t.from+e.length)}))}changeByRange(e){let t=this.selection,i=e(t.ranges[0]),s=this.changes(i.changes),r=[i.range],o=ti(i.effects);for(let l=1;lo.spec.fromJSON(l,a)))}}return I.create({doc:e.doc,selection:b.fromJSON(e.selection),extensions:t.extensions?s.concat([t.extensions]):s})}static create(e={}){let t=is.resolve(e.extensions||[],new Map),i=e.doc instanceof V?e.doc:V.of((e.doc||"").split(t.staticFacet(I.lineSeparator)||wr)),s=e.selection?e.selection instanceof b?e.selection:b.single(e.selection.anchor,e.selection.head):b.single(0);return Ch(s,i.length),t.staticFacet(Qr)||(s=s.asSingle()),new I(t,i,s,t.dynamicSlots.map(()=>null),(r,o)=>o.create(r),null)}get tabSize(){return this.facet(I.tabSize)}get lineBreak(){return this.facet(I.lineSeparator)||` +`}get readOnly(){return this.facet(Eh)}phrase(e,...t){for(let i of this.facet(I.phrases))if(Object.prototype.hasOwnProperty.call(i,e)){e=i[e];break}return t.length&&(e=e.replace(/\$(\$|\d*)/g,(i,s)=>{if(s=="$")return"$";let r=+(s||1);return!r||r>t.length?i:t[r-1]})),e}languageDataAt(e,t,i=-1){let s=[];for(let r of this.facet(Qh))for(let o of r(this,t,i))Object.prototype.hasOwnProperty.call(o,e)&&s.push(o[e]);return s}charCategorizer(e){return sd(this.languageDataAt("wordChars",e).join(""))}wordAt(e){let{text:t,from:i,length:s}=this.doc.lineAt(e),r=this.charCategorizer(e),o=e-i,l=e-i;for(;o>0;){let a=pe(t,o,!1);if(r(t.slice(a,o))!=Y.Word)break;o=a}for(;ln.length?n[0]:4});I.lineSeparator=Ah;I.readOnly=Eh;I.phrases=A.define({compare(n,e){let t=Object.keys(n),i=Object.keys(e);return t.length==i.length&&t.every(s=>n[s]==e[s])}});I.languageData=Qh;I.changeFilter=Mh;I.transactionFilter=Rh;I.transactionExtender=Dh;vs.reconfigure=q.define();function rt(n,e,t={}){let i={};for(let s of n)for(let r of Object.keys(s)){let o=s[r],l=i[r];if(l===void 0)i[r]=o;else if(!(l===o||o===void 0))if(Object.hasOwnProperty.call(t,r))i[r]=t[r](l,o);else throw new Error("Config merge conflict for field "+r)}for(let s in e)i[s]===void 0&&(i[s]=e[s]);return i}class Nt{eq(e){return this==e}range(e,t=e){return Rr.create(e,t,this)}}Nt.prototype.startSide=Nt.prototype.endSide=0;Nt.prototype.point=!1;Nt.prototype.mapMode=de.TrackDel;let Rr=class Bh{constructor(e,t,i){this.from=e,this.to=t,this.value=i}static create(e,t,i){return new Bh(e,t,i)}};function Dr(n,e){return n.from-e.from||n.value.startSide-e.value.startSide}class wo{constructor(e,t,i,s){this.from=e,this.to=t,this.value=i,this.maxPoint=s}get length(){return this.to[this.to.length-1]}findIndex(e,t,i,s=0){let r=i?this.to:this.from;for(let o=s,l=r.length;;){if(o==l)return o;let a=o+l>>1,h=r[a]-e||(i?this.value[a].endSide:this.value[a].startSide)-t;if(a==o)return h>=0?o:l;h>=0?l=a:o=a+1}}between(e,t,i,s){for(let r=this.findIndex(t,-1e9,!0),o=this.findIndex(i,1e9,!1,r);rd||u==d&&h.startSide>0&&h.endSide<=0)continue;(d-u||h.endSide-h.startSide)<0||(o<0&&(o=u),h.point&&(l=Math.max(l,d-u)),i.push(h),s.push(u-o),r.push(d-o))}return{mapped:i.length?new wo(s,r,i,l):null,pos:o}}}class N{constructor(e,t,i,s){this.chunkPos=e,this.chunk=t,this.nextLayer=i,this.maxPoint=s}static create(e,t,i,s){return new N(e,t,i,s)}get length(){let e=this.chunk.length-1;return e<0?0:Math.max(this.chunkEnd(e),this.nextLayer.length)}get size(){if(this.isEmpty)return 0;let e=this.nextLayer.size;for(let t of this.chunk)e+=t.value.length;return e}chunkEnd(e){return this.chunkPos[e]+this.chunk[e].length}update(e){let{add:t=[],sort:i=!1,filterFrom:s=0,filterTo:r=this.length}=e,o=e.filter;if(t.length==0&&!o)return this;if(i&&(t=t.slice().sort(Dr)),this.isEmpty)return t.length?N.of(t):this;let l=new Wh(this,null,-1).goto(0),a=0,h=[],c=new gt;for(;l.value||a=0){let f=t[a++];c.addInner(f.from,f.to,f.value)||h.push(f)}else l.rangeIndex==1&&l.chunkIndexthis.chunkEnd(l.chunkIndex)||rl.to||r=r&&e<=r+o.length&&o.between(r,e-r,t-r,i)===!1)return}this.nextLayer.between(e,t,i)}}iter(e=0){return Wi.from([this]).goto(e)}get isEmpty(){return this.nextLayer==this}static iter(e,t=0){return Wi.from(e).goto(t)}static compare(e,t,i,s,r=-1){let o=e.filter(f=>f.maxPoint>0||!f.isEmpty&&f.maxPoint>=r),l=t.filter(f=>f.maxPoint>0||!f.isEmpty&&f.maxPoint>=r),a=pl(o,l,i),h=new xi(o,a,r),c=new xi(l,a,r);i.iterGaps((f,u,d)=>ml(h,f,c,u,d,s)),i.empty&&i.length==0&&ml(h,0,c,0,0,s)}static eq(e,t,i=0,s){s==null&&(s=999999999);let r=e.filter(c=>!c.isEmpty&&t.indexOf(c)<0),o=t.filter(c=>!c.isEmpty&&e.indexOf(c)<0);if(r.length!=o.length)return!1;if(!r.length)return!0;let l=pl(r,o),a=new xi(r,l,0).goto(i),h=new xi(o,l,0).goto(i);for(;;){if(a.to!=h.to||!Er(a.active,h.active)||a.point&&(!h.point||!a.point.eq(h.point)))return!1;if(a.to>s)return!0;a.next(),h.next()}}static spans(e,t,i,s,r=-1){let o=new xi(e,null,r).goto(t),l=t,a=o.openStart;for(;;){let h=Math.min(o.to,i);if(o.point){let c=o.activeForPoint(o.to),f=o.pointFroml&&(s.span(l,h,o.active,a),a=o.openEnd(h));if(o.to>i)return a+(o.point&&o.to>i?1:0);l=o.to,o.next()}}static of(e,t=!1){let i=new gt;for(let s of e instanceof Rr?[e]:t?rd(e):e)i.add(s.from,s.to,s.value);return i.finish()}static join(e){if(!e.length)return N.empty;let t=e[e.length-1];for(let i=e.length-2;i>=0;i--)for(let s=e[i];s!=N.empty;s=s.nextLayer)t=new N(s.chunkPos,s.chunk,t,Math.max(s.maxPoint,t.maxPoint));return t}}N.empty=new N([],[],null,-1);function rd(n){if(n.length>1)for(let e=n[0],t=1;t0)return n.slice().sort(Dr);e=i}return n}N.empty.nextLayer=N.empty;class gt{finishChunk(e){this.chunks.push(new wo(this.from,this.to,this.value,this.maxPoint)),this.chunkPos.push(this.chunkStart),this.chunkStart=-1,this.setMaxPoint=Math.max(this.setMaxPoint,this.maxPoint),this.maxPoint=-1,e&&(this.from=[],this.to=[],this.value=[])}constructor(){this.chunks=[],this.chunkPos=[],this.chunkStart=-1,this.last=null,this.lastFrom=-1e9,this.lastTo=-1e9,this.from=[],this.to=[],this.value=[],this.maxPoint=-1,this.setMaxPoint=-1,this.nextLayer=null}add(e,t,i){this.addInner(e,t,i)||(this.nextLayer||(this.nextLayer=new gt)).add(e,t,i)}addInner(e,t,i){let s=e-this.lastTo||i.startSide-this.last.endSide;if(s<=0&&(e-this.lastFrom||i.startSide-this.last.startSide)<0)throw new Error("Ranges must be added sorted by `from` position and `startSide`");return s<0?!1:(this.from.length==250&&this.finishChunk(!0),this.chunkStart<0&&(this.chunkStart=e),this.from.push(e-this.chunkStart),this.to.push(t-this.chunkStart),this.last=i,this.lastFrom=e,this.lastTo=t,this.value.push(i),i.point&&(this.maxPoint=Math.max(this.maxPoint,t-e)),!0)}addChunk(e,t){if((e-this.lastTo||t.value[0].startSide-this.last.endSide)<0)return!1;this.from.length&&this.finishChunk(!0),this.setMaxPoint=Math.max(this.setMaxPoint,t.maxPoint),this.chunks.push(t),this.chunkPos.push(e);let i=t.value.length-1;return this.last=t.value[i],this.lastFrom=t.from[i]+e,this.lastTo=t.to[i]+e,!0}finish(){return this.finishInner(N.empty)}finishInner(e){if(this.from.length&&this.finishChunk(!1),this.chunks.length==0)return e;let t=N.create(this.chunkPos,this.chunks,this.nextLayer?this.nextLayer.finishInner(e):e,this.setMaxPoint);return this.from=null,t}}function pl(n,e,t){let i=new Map;for(let r of n)for(let o=0;o=this.minPoint)break}}setRangeIndex(e){if(e==this.layer.chunk[this.chunkIndex].value.length){if(this.chunkIndex++,this.skip)for(;this.chunkIndex=i&&s.push(new Wh(o,t,i,r));return s.length==1?s[0]:new Wi(s)}get startSide(){return this.value?this.value.startSide:0}goto(e,t=-1e9){for(let i of this.heap)i.goto(e,t);for(let i=this.heap.length>>1;i>=0;i--)Is(this.heap,i);return this.next(),this}forward(e,t){for(let i of this.heap)i.forward(e,t);for(let i=this.heap.length>>1;i>=0;i--)Is(this.heap,i);(this.to-e||this.value.endSide-t)<0&&this.next()}next(){if(this.heap.length==0)this.from=this.to=1e9,this.value=null,this.rank=-1;else{let e=this.heap[0];this.from=e.from,this.to=e.to,this.value=e.value,this.rank=e.rank,e.value&&e.next(),Is(this.heap,0)}}}function Is(n,e){for(let t=n[e];;){let i=(e<<1)+1;if(i>=n.length)break;let s=n[i];if(i+1=0&&(s=n[i+1],i++),t.compare(s)<0)break;n[i]=t,n[e]=s,e=i}}class xi{constructor(e,t,i){this.minPoint=i,this.active=[],this.activeTo=[],this.activeRank=[],this.minActive=-1,this.point=null,this.pointFrom=0,this.pointRank=0,this.to=-1e9,this.endSide=0,this.openStart=-1,this.cursor=Wi.from(e,t,i)}goto(e,t=-1e9){return this.cursor.goto(e,t),this.active.length=this.activeTo.length=this.activeRank.length=0,this.minActive=-1,this.to=e,this.endSide=t,this.openStart=-1,this.next(),this}forward(e,t){for(;this.minActive>-1&&(this.activeTo[this.minActive]-e||this.active[this.minActive].endSide-t)<0;)this.removeActive(this.minActive);this.cursor.forward(e,t)}removeActive(e){yn(this.active,e),yn(this.activeTo,e),yn(this.activeRank,e),this.minActive=gl(this.active,this.activeTo)}addActive(e){let t=0,{value:i,to:s,rank:r}=this.cursor;for(;t0;)t++;bn(this.active,t,i),bn(this.activeTo,t,s),bn(this.activeRank,t,r),e&&bn(e,t,this.cursor.from),this.minActive=gl(this.active,this.activeTo)}next(){let e=this.to,t=this.point;this.point=null;let i=this.openStart<0?[]:null;for(;;){let s=this.minActive;if(s>-1&&(this.activeTo[s]-this.cursor.from||this.active[s].endSide-this.cursor.startSide)<0){if(this.activeTo[s]>e){this.to=this.activeTo[s],this.endSide=this.active[s].endSide;break}this.removeActive(s),i&&yn(i,s)}else if(this.cursor.value)if(this.cursor.from>e){this.to=this.cursor.from,this.endSide=this.cursor.startSide;break}else{let r=this.cursor.value;if(!r.point)this.addActive(i),this.cursor.next();else if(t&&this.cursor.to==this.to&&this.cursor.from=0&&i[s]=0&&!(this.activeRank[i]e||this.activeTo[i]==e&&this.active[i].endSide>=this.point.endSide)&&t.push(this.active[i]);return t.reverse()}openEnd(e){let t=0;for(let i=this.activeTo.length-1;i>=0&&this.activeTo[i]>e;i--)t++;return t}}function ml(n,e,t,i,s,r){n.goto(e),t.goto(i);let o=i+s,l=i,a=i-e;for(;;){let h=n.to+a-t.to,c=h||n.endSide-t.endSide,f=c<0?n.to+a:t.to,u=Math.min(f,o);if(n.point||t.point?n.point&&t.point&&(n.point==t.point||n.point.eq(t.point))&&Er(n.activeForPoint(n.to),t.activeForPoint(t.to))||r.comparePoint(l,u,n.point,t.point):u>l&&!Er(n.active,t.active)&&r.compareRange(l,u,n.active,t.active),f>o)break;(h||n.openEnd!=t.openEnd)&&r.boundChange&&r.boundChange(f),l=f,c<=0&&n.next(),c>=0&&t.next()}}function Er(n,e){if(n.length!=e.length)return!1;for(let t=0;t=e;i--)n[i+1]=n[i];n[e]=t}function gl(n,e){let t=-1,i=1e9;for(let s=0;s=e)return s;if(s==n.length)break;r+=n.charCodeAt(s)==9?t-r%t:1,s=pe(n,s)}return i===!0?-1:n.length}const $r="ͼ",Ol=typeof Symbol>"u"?"__"+$r:Symbol.for($r),Br=typeof Symbol>"u"?"__styleSet"+Math.floor(Math.random()*1e8):Symbol("styleSet"),yl=typeof globalThis<"u"?globalThis:typeof window<"u"?window:{};class Tt{constructor(e,t){this.rules=[];let{finish:i}=t||{};function s(o){return/^@/.test(o)?[o]:o.split(/,\s*/)}function r(o,l,a,h){let c=[],f=/^@(\w+)\b/.exec(o[0]),u=f&&f[1]=="keyframes";if(f&&l==null)return a.push(o[0]+";");for(let d in l){let p=l[d];if(/&/.test(d))r(d.split(/,\s*/).map(m=>o.map(g=>m.replace(/&/,g))).reduce((m,g)=>m.concat(g)),p,a);else if(p&&typeof p=="object"){if(!f)throw new RangeError("The value of a property ("+d+") should be a primitive value.");r(s(d),p,c,u)}else p!=null&&c.push(d.replace(/_.*/,"").replace(/[A-Z]/g,m=>"-"+m.toLowerCase())+": "+p+";")}(c.length||u)&&a.push((i&&!f&&!h?o.map(i):o).join(", ")+" {"+c.join(" ")+"}")}for(let o in e)r(s(o),e[o],this.rules)}getRules(){return this.rules.join(` +`)}static newName(){let e=yl[Ol]||1;return yl[Ol]=e+1,$r+e.toString(36)}static mount(e,t,i){let s=e[Br],r=i&&i.nonce;s?r&&s.setNonce(r):s=new od(e,r),s.mount(Array.isArray(t)?t:[t],e)}}let bl=new Map;class od{constructor(e,t){let i=e.ownerDocument||e,s=i.defaultView;if(!e.head&&e.adoptedStyleSheets&&s.CSSStyleSheet){let r=bl.get(i);if(r)return e[Br]=r;this.sheet=new s.CSSStyleSheet,bl.set(i,this)}else this.styleTag=i.createElement("style"),t&&this.styleTag.setAttribute("nonce",t);this.modules=[],e[Br]=this}mount(e,t){let i=this.sheet,s=0,r=0;for(let o=0;o-1&&(this.modules.splice(a,1),r--,a=-1),a==-1){if(this.modules.splice(r++,0,l),i)for(let h=0;h",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},ld=typeof navigator<"u"&&/Mac/.test(navigator.platform),ad=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);for(var ue=0;ue<10;ue++)Ct[48+ue]=Ct[96+ue]=String(ue);for(var ue=1;ue<=24;ue++)Ct[ue+111]="F"+ue;for(var ue=65;ue<=90;ue++)Ct[ue]=String.fromCharCode(ue+32),Li[ue]=String.fromCharCode(ue);for(var Vs in Ct)Li.hasOwnProperty(Vs)||(Li[Vs]=Ct[Vs]);function hd(n){var e=ld&&n.metaKey&&n.shiftKey&&!n.ctrlKey&&!n.altKey||ad&&n.shiftKey&&n.key&&n.key.length==1||n.key=="Unidentified",t=!e&&n.key||(n.shiftKey?Li:Ct)[n.keyCode]||n.key||"Unidentified";return t=="Esc"&&(t="Escape"),t=="Del"&&(t="Delete"),t=="Left"&&(t="ArrowLeft"),t=="Up"&&(t="ArrowUp"),t=="Right"&&(t="ArrowRight"),t=="Down"&&(t="ArrowDown"),t}function U(){var n=arguments[0];typeof n=="string"&&(n=document.createElement(n));var e=1,t=arguments[1];if(t&&typeof t=="object"&&t.nodeType==null&&!Array.isArray(t)){for(var i in t)if(Object.prototype.hasOwnProperty.call(t,i)){var s=t[i];typeof s=="string"?n.setAttribute(i,s):s!=null&&(n[i]=s)}e++}for(;e2);var Q={mac:xl||/Mac/.test(xe.platform),windows:/Win/.test(xe.platform),linux:/Linux|X11/.test(xe.platform),ie:Ts,ie_version:zh?Wr.documentMode||6:zr?+zr[1]:Lr?+Lr[1]:0,gecko:Sl,gecko_version:Sl?+(/Firefox\/(\d+)/.exec(xe.userAgent)||[0,0])[1]:0,chrome:!!Ns,chrome_version:Ns?+Ns[1]:0,ios:xl,android:/Android\b/.test(xe.userAgent),webkit_version:cd?+(/\bAppleWebKit\/(\d+)/.exec(xe.userAgent)||[0,0])[1]:0,safari:Ir,safari_version:Ir?+(/\bVersion\/(\d+(\.\d+)?)/.exec(xe.userAgent)||[0,0])[1]:0,tabSize:Wr.documentElement.style.tabSize!=null?"tab-size":"-moz-tab-size"};function zi(n){let e;return n.nodeType==11?e=n.getSelection?n:n.ownerDocument:e=n,e.getSelection()}function Vr(n,e){return e?n==e||n.contains(e.nodeType!=1?e.parentNode:e):!1}function _n(n,e){if(!e.anchorNode)return!1;try{return Vr(n,e.anchorNode)}catch{return!1}}function ai(n){return n.nodeType==3?Ft(n,0,n.nodeValue.length).getClientRects():n.nodeType==1?n.getClientRects():[]}function Ri(n,e,t,i){return t?kl(n,e,t,i,-1)||kl(n,e,t,i,1):!1}function Xt(n){for(var e=0;;e++)if(n=n.previousSibling,!n)return e}function ss(n){return n.nodeType==1&&/^(DIV|P|LI|UL|OL|BLOCKQUOTE|DD|DT|H\d|SECTION|PRE)$/.test(n.nodeName)}function kl(n,e,t,i,s){for(;;){if(n==t&&e==i)return!0;if(e==(s<0?0:nt(n))){if(n.nodeName=="DIV")return!1;let r=n.parentNode;if(!r||r.nodeType!=1)return!1;e=Xt(n)+(s<0?0:1),n=r}else if(n.nodeType==1){if(n=n.childNodes[e+(s<0?-1:0)],n.nodeType==1&&n.contentEditable=="false")return!1;e=s<0?nt(n):0}else return!1}}function nt(n){return n.nodeType==3?n.nodeValue.length:n.childNodes.length}function sn(n,e){let t=e?n.left:n.right;return{left:t,right:t,top:n.top,bottom:n.bottom}}function fd(n){let e=n.visualViewport;return e?{left:0,right:e.width,top:0,bottom:e.height}:{left:0,right:n.innerWidth,top:0,bottom:n.innerHeight}}function Ih(n,e){let t=e.width/n.offsetWidth,i=e.height/n.offsetHeight;return(t>.995&&t<1.005||!isFinite(t)||Math.abs(e.width-n.offsetWidth)<1)&&(t=1),(i>.995&&i<1.005||!isFinite(i)||Math.abs(e.height-n.offsetHeight)<1)&&(i=1),{scaleX:t,scaleY:i}}function ud(n,e,t,i,s,r,o,l){let a=n.ownerDocument,h=a.defaultView||window;for(let c=n,f=!1;c&&!f;)if(c.nodeType==1){let u,d=c==a.body,p=1,m=1;if(d)u=fd(h);else{if(/^(fixed|sticky)$/.test(getComputedStyle(c).position)&&(f=!0),c.scrollHeight<=c.clientHeight&&c.scrollWidth<=c.clientWidth){c=c.assignedSlot||c.parentNode;continue}let S=c.getBoundingClientRect();({scaleX:p,scaleY:m}=Ih(c,S)),u={left:S.left,right:S.left+c.clientWidth*p,top:S.top,bottom:S.top+c.clientHeight*m}}let g=0,y=0;if(s=="nearest")e.top0&&e.bottom>u.bottom+y&&(y=e.bottom-u.bottom+o)):e.bottom>u.bottom&&(y=e.bottom-u.bottom+o,t<0&&e.top-y0&&e.right>u.right+g&&(g=e.right-u.right+r)):e.right>u.right&&(g=e.right-u.right+r,t<0&&e.leftu.bottom||e.leftu.right)&&(e={left:Math.max(e.left,u.left),right:Math.min(e.right,u.right),top:Math.max(e.top,u.top),bottom:Math.min(e.bottom,u.bottom)}),c=c.assignedSlot||c.parentNode}else if(c.nodeType==11)c=c.host;else break}function dd(n){let e=n.ownerDocument,t,i;for(let s=n.parentNode;s&&!(s==e.body||t&&i);)if(s.nodeType==1)!i&&s.scrollHeight>s.clientHeight&&(i=s),!t&&s.scrollWidth>s.clientWidth&&(t=s),s=s.assignedSlot||s.parentNode;else if(s.nodeType==11)s=s.host;else break;return{x:t,y:i}}class pd{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}eq(e){return this.anchorNode==e.anchorNode&&this.anchorOffset==e.anchorOffset&&this.focusNode==e.focusNode&&this.focusOffset==e.focusOffset}setRange(e){let{anchorNode:t,focusNode:i}=e;this.set(t,Math.min(e.anchorOffset,t?nt(t):0),i,Math.min(e.focusOffset,i?nt(i):0))}set(e,t,i,s){this.anchorNode=e,this.anchorOffset=t,this.focusNode=i,this.focusOffset=s}}let qt=null;Q.safari&&Q.safari_version>=26&&(qt=!1);function Vh(n){if(n.setActive)return n.setActive();if(qt)return n.focus(qt);let e=[];for(let t=n;t&&(e.push(t,t.scrollTop,t.scrollLeft),t!=t.ownerDocument);t=t.parentNode);if(n.focus(qt==null?{get preventScroll(){return qt={preventScroll:!0},!0}}:void 0),!qt){qt=!1;for(let t=0;tMath.max(1,n.scrollHeight-n.clientHeight-4)}function Fh(n,e){for(let t=n,i=e;;){if(t.nodeType==3&&i>0)return{node:t,offset:i};if(t.nodeType==1&&i>0){if(t.contentEditable=="false")return null;t=t.childNodes[i-1],i=nt(t)}else if(t.parentNode&&!ss(t))i=Xt(t),t=t.parentNode;else return null}}function _h(n,e){for(let t=n,i=e;;){if(t.nodeType==3&&it)return f.domBoundsAround(e,t,h);if(u>=e&&s==-1&&(s=a,r=h),h>t&&f.dom.parentNode==this.dom){o=a,l=c;break}c=u,h=u+f.breakAfter}return{from:r,to:l<0?i+this.length:l,startDOM:(s?this.children[s-1].dom.nextSibling:null)||this.dom.firstChild,endDOM:o=0?this.children[o].dom:null}}markDirty(e=!1){this.flags|=2,this.markParentsDirty(e)}markParentsDirty(e){for(let t=this.parent;t;t=t.parent){if(e&&(t.flags|=2),t.flags&1)return;t.flags|=1,e=!1}}setParent(e){this.parent!=e&&(this.parent=e,this.flags&7&&this.markParentsDirty(!0))}setDOM(e){this.dom!=e&&(this.dom&&(this.dom.cmView=null),this.dom=e,e.cmView=this)}get rootView(){for(let e=this;;){let t=e.parent;if(!t)return e;e=t}}replaceChildren(e,t,i=vo){this.markDirty();for(let s=e;sthis.pos||e==this.pos&&(t>0||this.i==0||this.children[this.i-1].breakAfter))return this.off=e-this.pos,this;let i=this.children[--this.i];this.pos-=i.length+i.breakAfter}}}function Hh(n,e,t,i,s,r,o,l,a){let{children:h}=n,c=h.length?h[e]:null,f=r.length?r[r.length-1]:null,u=f?f.breakAfter:o;if(!(e==i&&c&&!o&&!u&&r.length<2&&c.merge(t,s,r.length?f:null,t==0,l,a))){if(i0&&(!o&&r.length&&c.merge(t,c.length,r[0],!1,l,0)?c.breakAfter=r.shift().breakAfter:(tOd||i.flags&8)?!1:(this.text=this.text.slice(0,e)+(i?i.text:"")+this.text.slice(t),this.markDirty(),!0)}split(e){let t=new Ve(this.text.slice(e));return this.text=this.text.slice(0,e),this.markDirty(),t.flags|=this.flags&8,t}localPosFromDOM(e,t){return e==this.dom?t:t?this.text.length:0}domAtPos(e){return new ye(this.dom,e)}domBoundsAround(e,t,i){return{from:i,to:i+this.length,startDOM:this.dom,endDOM:this.dom.nextSibling}}coordsAt(e,t){return yd(this.dom,e,t)}}class Ot extends _{constructor(e,t=[],i=0){super(),this.mark=e,this.children=t,this.length=i;for(let s of t)s.setParent(this)}setAttrs(e){if(Nh(e),this.mark.class&&(e.className=this.mark.class),this.mark.attrs)for(let t in this.mark.attrs)e.setAttribute(t,this.mark.attrs[t]);return e}canReuseDOM(e){return super.canReuseDOM(e)&&!((this.flags|e.flags)&8)}reuseDOM(e){e.nodeName==this.mark.tagName.toUpperCase()&&(this.setDOM(e),this.flags|=6)}sync(e,t){this.dom?this.flags&4&&this.setAttrs(this.dom):this.setDOM(this.setAttrs(document.createElement(this.mark.tagName))),super.sync(e,t)}merge(e,t,i,s,r,o){return i&&(!(i instanceof Ot&&i.mark.eq(this.mark))||e&&r<=0||te&&t.push(i=e&&(s=r),i=a,r++}let o=this.length-e;return this.length=e,s>-1&&(this.children.length=s,this.markDirty()),new Ot(this.mark,t,o)}domAtPos(e){return Gh(this,e)}coordsAt(e,t){return Yh(this,e,t)}}function yd(n,e,t){let i=n.nodeValue.length;e>i&&(e=i);let s=e,r=e,o=0;e==0&&t<0||e==i&&t>=0?Q.chrome||Q.gecko||(e?(s--,o=1):r=0)?0:l.length-1];return Q.safari&&!o&&a.width==0&&(a=Array.prototype.find.call(l,h=>h.width)||a),o?sn(a,o<0):a||null}class pt extends _{static create(e,t,i){return new pt(e,t,i)}constructor(e,t,i){super(),this.widget=e,this.length=t,this.side=i,this.prevWidget=null}split(e){let t=pt.create(this.widget,this.length-e,this.side);return this.length-=e,t}sync(e){(!this.dom||!this.widget.updateDOM(this.dom,e))&&(this.dom&&this.prevWidget&&this.prevWidget.destroy(this.dom),this.prevWidget=null,this.setDOM(this.widget.toDOM(e)),this.widget.editable||(this.dom.contentEditable="false"))}getSide(){return this.side}merge(e,t,i,s,r,o){return i&&(!(i instanceof pt)||!this.widget.compare(i.widget)||e>0&&r<=0||t0)?ye.before(this.dom):ye.after(this.dom,e==this.length)}domBoundsAround(){return null}coordsAt(e,t){let i=this.widget.coordsAt(this.dom,e,t);if(i)return i;let s=this.dom.getClientRects(),r=null;if(!s.length)return null;let o=this.side?this.side<0:e>0;for(let l=o?s.length-1:0;r=s[l],!(e>0?l==0:l==s.length-1||r.top0?ye.before(this.dom):ye.after(this.dom)}localPosFromDOM(){return 0}domBoundsAround(){return null}coordsAt(e){return this.dom.getBoundingClientRect()}get overrideDOMText(){return V.empty}get isHidden(){return!0}}Ve.prototype.children=pt.prototype.children=hi.prototype.children=vo;function Gh(n,e){let t=n.dom,{children:i}=n,s=0;for(let r=0;sr&&e0;r--){let o=i[r-1];if(o.dom.parentNode==t)return o.domAtPos(o.length)}for(let r=s;r0&&e instanceof Ot&&s.length&&(i=s[s.length-1])instanceof Ot&&i.mark.eq(e.mark)?Zh(i,e.children[0],t-1):(s.push(e),e.setParent(n)),n.length+=e.length}function Yh(n,e,t){let i=null,s=-1,r=null,o=-1;function l(h,c){for(let f=0,u=0;f=c&&(d.children.length?l(d,c-u):(!r||r.isHidden&&(t>0||Sd(r,d)))&&(p>c||u==p&&d.getSide()>0)?(r=d,o=c-u):(u-1?1:0)!=s.length-(t&&s.indexOf(t)>-1?1:0))return!1;for(let r of i)if(r!=t&&(s.indexOf(r)==-1||n[r]!==e[r]))return!1;return!0}function Xr(n,e,t){let i=!1;if(e)for(let s in e)t&&s in t||(i=!0,s=="style"?n.style.cssText="":n.removeAttribute(s));if(t)for(let s in t)e&&e[s]==t[s]||(i=!0,s=="style"?n.style.cssText=t[s]:n.setAttribute(s,t[s]));return i}function xd(n){let e=Object.create(null);for(let t=0;t0?3e8:-4e8:t>0?1e8:-1e8,new Pt(e,t,t,i,e.widget||null,!1)}static replace(e){let t=!!e.block,i,s;if(e.isBlockGap)i=-5e8,s=4e8;else{let{start:r,end:o}=Kh(e,t);i=(r?t?-3e8:-1:5e8)-1,s=(o?t?2e8:1:-6e8)+1}return new Pt(e,i,s,t,e.widget||null,!0)}static line(e){return new on(e)}static set(e,t=!1){return N.of(e,t)}hasHeight(){return this.widget?this.widget.estimatedHeight>-1:!1}}R.none=N.empty;class rn extends R{constructor(e){let{start:t,end:i}=Kh(e);super(t?-1:5e8,i?1:-6e8,null,e),this.tagName=e.tagName||"span",this.class=e.class||"",this.attrs=e.attributes||null}eq(e){var t,i;return this==e||e instanceof rn&&this.tagName==e.tagName&&(this.class||((t=this.attrs)===null||t===void 0?void 0:t.class))==(e.class||((i=e.attrs)===null||i===void 0?void 0:i.class))&&rs(this.attrs,e.attrs,"class")}range(e,t=e){if(e>=t)throw new RangeError("Mark decorations may not be empty");return super.range(e,t)}}rn.prototype.point=!1;class on extends R{constructor(e){super(-2e8,-2e8,null,e)}eq(e){return e instanceof on&&this.spec.class==e.spec.class&&rs(this.spec.attributes,e.spec.attributes)}range(e,t=e){if(t!=e)throw new RangeError("Line decoration ranges must be zero-length");return super.range(e,t)}}on.prototype.mapMode=de.TrackBefore;on.prototype.point=!0;class Pt extends R{constructor(e,t,i,s,r,o){super(t,i,r,e),this.block=s,this.isReplace=o,this.mapMode=s?t<=0?de.TrackBefore:de.TrackAfter:de.TrackDel}get type(){return this.startSide!=this.endSide?ke.WidgetRange:this.startSide<=0?ke.WidgetBefore:ke.WidgetAfter}get heightRelevant(){return this.block||!!this.widget&&(this.widget.estimatedHeight>=5||this.widget.lineBreaks>0)}eq(e){return e instanceof Pt&&kd(this.widget,e.widget)&&this.block==e.block&&this.startSide==e.startSide&&this.endSide==e.endSide}range(e,t=e){if(this.isReplace&&(e>t||e==t&&this.startSide>0&&this.endSide<=0))throw new RangeError("Invalid range for replacement decoration");if(!this.isReplace&&t!=e)throw new RangeError("Widget decorations can only have zero-length ranges");return super.range(e,t)}}Pt.prototype.point=!0;function Kh(n,e=!1){let{inclusiveStart:t,inclusiveEnd:i}=n;return t==null&&(t=n.inclusive),i==null&&(i=n.inclusive),{start:t??e,end:i??e}}function kd(n,e){return n==e||!!(n&&e&&n.compare(e))}function Un(n,e,t,i=0){let s=t.length-1;s>=0&&t[s]+i>=n?t[s]=Math.max(t[s],e):t.push(n,e)}class te extends _{constructor(){super(...arguments),this.children=[],this.length=0,this.prevAttrs=void 0,this.attrs=null,this.breakAfter=0}merge(e,t,i,s,r,o){if(i){if(!(i instanceof te))return!1;this.dom||i.transferDOM(this)}return s&&this.setDeco(i?i.attrs:null),jh(this,e,t,i?i.children.slice():[],r,o),!0}split(e){let t=new te;if(t.breakAfter=this.breakAfter,this.length==0)return t;let{i,off:s}=this.childPos(e);s&&(t.append(this.children[i].split(s),0),this.children[i].merge(s,this.children[i].length,null,!1,0,0),i++);for(let r=i;r0&&this.children[i-1].length==0;)this.children[--i].destroy();return this.children.length=i,this.markDirty(),this.length=e,t}transferDOM(e){this.dom&&(this.markDirty(),e.setDOM(this.dom),e.prevAttrs=this.prevAttrs===void 0?this.attrs:this.prevAttrs,this.prevAttrs=void 0,this.dom=null)}setDeco(e){rs(this.attrs,e)||(this.dom&&(this.prevAttrs=this.attrs,this.markDirty()),this.attrs=e)}append(e,t){Zh(this,e,t)}addLineDeco(e){let t=e.spec.attributes,i=e.spec.class;t&&(this.attrs=Nr(t,this.attrs||{})),i&&(this.attrs=Nr({class:i},this.attrs||{}))}domAtPos(e){return Gh(this,e)}reuseDOM(e){e.nodeName=="DIV"&&(this.setDOM(e),this.flags|=6)}sync(e,t){var i;this.dom?this.flags&4&&(Nh(this.dom),this.dom.className="cm-line",this.prevAttrs=this.attrs?null:void 0):(this.setDOM(document.createElement("div")),this.dom.className="cm-line",this.prevAttrs=this.attrs?null:void 0),this.prevAttrs!==void 0&&(Xr(this.dom,this.prevAttrs,this.attrs),this.dom.classList.add("cm-line"),this.prevAttrs=void 0),super.sync(e,t);let s=this.dom.lastChild;for(;s&&_.get(s)instanceof Ot;)s=s.lastChild;if(!s||!this.length||s.nodeName!="BR"&&((i=_.get(s))===null||i===void 0?void 0:i.isEditable)==!1&&(!Q.ios||!this.children.some(r=>r instanceof Ve))){let r=document.createElement("BR");r.cmIgnore=!0,this.dom.appendChild(r)}}measureTextSize(){if(this.children.length==0||this.length>20)return null;let e=0,t;for(let i of this.children){if(!(i instanceof Ve)||/[^ -~]/.test(i.text))return null;let s=ai(i.dom);if(s.length!=1)return null;e+=s[0].width,t=s[0].height}return e?{lineHeight:this.dom.getBoundingClientRect().height,charWidth:e/this.length,textHeight:t}:null}coordsAt(e,t){let i=Yh(this,e,t);if(!this.children.length&&i&&this.parent){let{heightOracle:s}=this.parent.view.viewState,r=i.bottom-i.top;if(Math.abs(r-s.lineHeight)<2&&s.textHeight=t){if(r instanceof te)return r;if(o>t)break}s=o+r.breakAfter}return null}}class mt extends _{constructor(e,t,i){super(),this.widget=e,this.length=t,this.deco=i,this.breakAfter=0,this.prevWidget=null}merge(e,t,i,s,r,o){return i&&(!(i instanceof mt)||!this.widget.compare(i.widget)||e>0&&r<=0||t0}}class Fr extends ot{constructor(e){super(),this.height=e}toDOM(){let e=document.createElement("div");return e.className="cm-gap",this.updateDOM(e),e}eq(e){return e.height==this.height}updateDOM(e){return e.style.height=this.height+"px",!0}get editable(){return!0}get estimatedHeight(){return this.height}ignoreEvent(){return!1}}class Di{constructor(e,t,i,s){this.doc=e,this.pos=t,this.end=i,this.disallowBlockEffectsFor=s,this.content=[],this.curLine=null,this.breakAtStart=0,this.pendingBuffer=0,this.bufferMarks=[],this.atCursorPos=!0,this.openStart=-1,this.openEnd=-1,this.text="",this.textOff=0,this.cursor=e.iter(),this.skip=t}posCovered(){if(this.content.length==0)return!this.breakAtStart&&this.doc.lineAt(this.pos).from!=this.pos;let e=this.content[this.content.length-1];return!(e.breakAfter||e instanceof mt&&e.deco.endSide<0)}getLine(){return this.curLine||(this.content.push(this.curLine=new te),this.atCursorPos=!0),this.curLine}flushBuffer(e=this.bufferMarks){this.pendingBuffer&&(this.curLine.append(Sn(new hi(-1),e),e.length),this.pendingBuffer=0)}addBlockWidget(e){this.flushBuffer(),this.curLine=null,this.content.push(e)}finish(e){this.pendingBuffer&&e<=this.bufferMarks.length?this.flushBuffer():this.pendingBuffer=0,!this.posCovered()&&!(e&&this.content.length&&this.content[this.content.length-1]instanceof mt)&&this.getLine()}buildText(e,t,i){for(;e>0;){if(this.textOff==this.text.length){let{value:o,lineBreak:l,done:a}=this.cursor.next(this.skip);if(this.skip=0,a)throw new Error("Ran out of text content when drawing inline views");if(l){this.posCovered()||this.getLine(),this.content.length?this.content[this.content.length-1].breakAfter=1:this.breakAtStart=1,this.flushBuffer(),this.curLine=null,this.atCursorPos=!0,e--;continue}else this.text=o,this.textOff=0}let s=Math.min(this.text.length-this.textOff,e),r=Math.min(s,512);this.flushBuffer(t.slice(t.length-i)),this.getLine().append(Sn(new Ve(this.text.slice(this.textOff,this.textOff+r)),t),i),this.atCursorPos=!0,this.textOff+=r,e-=r,i=s<=r?0:t.length}}span(e,t,i,s){this.buildText(t-e,i,s),this.pos=t,this.openStart<0&&(this.openStart=s)}point(e,t,i,s,r,o){if(this.disallowBlockEffectsFor[o]&&i instanceof Pt){if(i.block)throw new RangeError("Block decorations may not be specified via plugins");if(t>this.doc.lineAt(this.pos).to)throw new RangeError("Decorations that replace line breaks may not be specified via plugins")}let l=t-e;if(i instanceof Pt)if(i.block)i.startSide>0&&!this.posCovered()&&this.getLine(),this.addBlockWidget(new mt(i.widget||ci.block,l,i));else{let a=pt.create(i.widget||ci.inline,l,l?0:i.startSide),h=this.atCursorPos&&!a.isEditable&&r<=s.length&&(e0),c=!a.isEditable&&(es.length||i.startSide<=0),f=this.getLine();this.pendingBuffer==2&&!h&&!a.isEditable&&(this.pendingBuffer=0),this.flushBuffer(s),h&&(f.append(Sn(new hi(1),s),r),r=s.length+Math.max(0,r-s.length)),f.append(Sn(a,s),r),this.atCursorPos=c,this.pendingBuffer=c?es.length?1:2:0,this.pendingBuffer&&(this.bufferMarks=s.slice())}else this.doc.lineAt(this.pos).from==this.pos&&this.getLine().addLineDeco(i);l&&(this.textOff+l<=this.text.length?this.textOff+=l:(this.skip+=l-(this.text.length-this.textOff),this.text="",this.textOff=0),this.pos=t),this.openStart<0&&(this.openStart=r)}static build(e,t,i,s,r){let o=new Di(e,t,i,r);return o.openEnd=N.spans(s,t,i,o),o.openStart<0&&(o.openStart=o.openEnd),o.finish(o.openEnd),o}}function Sn(n,e){for(let t of e)n=new Ot(t,[n],n.length);return n}class ci extends ot{constructor(e){super(),this.tag=e}eq(e){return e.tag==this.tag}toDOM(){return document.createElement(this.tag)}updateDOM(e){return e.nodeName.toLowerCase()==this.tag}get isHidden(){return!0}}ci.inline=new ci("span");ci.block=new ci("div");var Z=(function(n){return n[n.LTR=0]="LTR",n[n.RTL=1]="RTL",n})(Z||(Z={}));const _t=Z.LTR,To=Z.RTL;function Jh(n){let e=[];for(let t=0;t=t){if(l.level==i)return o;(r<0||(s!=0?s<0?l.fromt:e[r].level>l.level))&&(r=o)}}if(r<0)throw new RangeError("Index out of range");return r}}function tc(n,e){if(n.length!=e.length)return!1;for(let t=0;t=0;m-=3)if(Ue[m+1]==-d){let g=Ue[m+2],y=g&2?s:g&4?g&1?r:s:0;y&&(H[f]=H[Ue[m]]=y),l=m;break}}else{if(Ue.length==189)break;Ue[l++]=f,Ue[l++]=u,Ue[l++]=a}else if((p=H[f])==2||p==1){let m=p==s;a=m?0:1;for(let g=l-3;g>=0;g-=3){let y=Ue[g+2];if(y&2)break;if(m)Ue[g+2]|=2;else{if(y&4)break;Ue[g+2]|=4}}}}}function Qd(n,e,t,i){for(let s=0,r=i;s<=t.length;s++){let o=s?t[s-1].to:n,l=sa;)p==g&&(p=t[--m].from,g=m?t[m-1].to:n),H[--p]=d;a=c}else r=h,a++}}}function Ur(n,e,t,i,s,r,o){let l=i%2?2:1;if(i%2==s%2)for(let a=e,h=0;aa&&o.push(new wt(a,m.from,d));let g=m.direction==_t!=!(d%2);Hr(n,g?i+1:i,s,m.inner,m.from,m.to,o),a=m.to}p=m.to}else{if(p==t||(c?H[p]!=l:H[p]==l))break;p++}u?Ur(n,a,p,i+1,s,u,o):ae;){let c=!0,f=!1;if(!h||a>r[h-1].to){let m=H[a-1];m!=l&&(c=!1,f=m==16)}let u=!c&&l==1?[]:null,d=c?i:i+1,p=a;e:for(;;)if(h&&p==r[h-1].to){if(f)break e;let m=r[--h];if(!c)for(let g=m.from,y=h;;){if(g==e)break e;if(y&&r[y-1].to==g)g=r[--y].from;else{if(H[g-1]==l)break e;break}}if(u)u.push(m);else{m.toH.length;)H[H.length]=256;let i=[],s=e==_t?0:1;return Hr(n,s,s,t,0,n.length,i),i}function ic(n){return[new wt(0,n,0)]}let nc="";function Md(n,e,t,i,s){var r;let o=i.head-n.from,l=wt.find(e,o,(r=i.bidiLevel)!==null&&r!==void 0?r:-1,i.assoc),a=e[l],h=a.side(s,t);if(o==h){let u=l+=s?1:-1;if(u<0||u>=e.length)return null;a=e[l=u],o=a.side(!s,t),h=a.side(s,t)}let c=pe(n.text,o,a.forward(s,t));(ca.to)&&(c=h),nc=n.text.slice(Math.min(o,c),Math.max(o,c));let f=l==(s?e.length-1:0)?null:e[l+(s?1:-1)];return f&&c==h&&f.level+(s?0:1)n.some(e=>e)}),fc=A.define({combine:n=>n.some(e=>e)}),uc=A.define();class ni{constructor(e,t="nearest",i="nearest",s=5,r=5,o=!1){this.range=e,this.y=t,this.x=i,this.yMargin=s,this.xMargin=r,this.isSnapshot=o}map(e){return e.empty?this:new ni(this.range.map(e),this.y,this.x,this.yMargin,this.xMargin,this.isSnapshot)}clip(e){return this.range.to<=e.doc.length?this:new ni(b.cursor(e.doc.length),this.y,this.x,this.yMargin,this.xMargin,this.isSnapshot)}}const xn=q.define({map:(n,e)=>n.map(e)}),dc=q.define();function Pe(n,e,t){let i=n.facet(lc);i.length?i[0](e):window.onerror&&window.onerror(String(e),t,void 0,void 0,e)||(t?console.error(t+":",e):console.error(e))}const dt=A.define({combine:n=>n.length?n[0]:!0});let Dd=0;const Kt=A.define({combine(n){return n.filter((e,t)=>{for(let i=0;i{let a=[];return o&&a.push(Ii.of(h=>{let c=h.plugin(l);return c?o(c):R.none})),r&&a.push(r(l)),a})}static fromClass(e,t){return J.define((i,s)=>new e(i,s),t)}}class Xs{constructor(e){this.spec=e,this.mustUpdate=null,this.value=null}get plugin(){return this.spec&&this.spec.plugin}update(e){if(this.value){if(this.mustUpdate){let t=this.mustUpdate;if(this.mustUpdate=null,this.value.update)try{this.value.update(t)}catch(i){if(Pe(t.state,i,"CodeMirror plugin crashed"),this.value.destroy)try{this.value.destroy()}catch{}this.deactivate()}}}else if(this.spec)try{this.value=this.spec.plugin.create(e,this.spec.arg)}catch(t){Pe(e.state,t,"CodeMirror plugin crashed"),this.deactivate()}return this}destroy(e){var t;if(!((t=this.value)===null||t===void 0)&&t.destroy)try{this.value.destroy()}catch(i){Pe(e.state,i,"CodeMirror plugin crashed")}}deactivate(){this.spec=this.value=null}}const pc=A.define(),Qo=A.define(),Ii=A.define(),mc=A.define(),ln=A.define(),gc=A.define();function Cl(n,e){let t=n.state.facet(gc);if(!t.length)return t;let i=t.map(r=>r instanceof Function?r(n):r),s=[];return N.spans(i,e.from,e.to,{point(){},span(r,o,l,a){let h=r-e.from,c=o-e.from,f=s;for(let u=l.length-1;u>=0;u--,a--){let d=l[u].spec.bidiIsolate,p;if(d==null&&(d=Rd(e.text,h,c)),a>0&&f.length&&(p=f[f.length-1]).to==h&&p.direction==d)p.to=c,f=p.inner;else{let m={from:h,to:c,direction:d,inner:[]};f.push(m),f=m.inner}}}}),s}const Oc=A.define();function Ao(n){let e=0,t=0,i=0,s=0;for(let r of n.state.facet(Oc)){let o=r(n);o&&(o.left!=null&&(e=Math.max(e,o.left)),o.right!=null&&(t=Math.max(t,o.right)),o.top!=null&&(i=Math.max(i,o.top)),o.bottom!=null&&(s=Math.max(s,o.bottom)))}return{left:e,right:t,top:i,bottom:s}}const Ti=A.define();class Le{constructor(e,t,i,s){this.fromA=e,this.toA=t,this.fromB=i,this.toB=s}join(e){return new Le(Math.min(this.fromA,e.fromA),Math.max(this.toA,e.toA),Math.min(this.fromB,e.fromB),Math.max(this.toB,e.toB))}addToSet(e){let t=e.length,i=this;for(;t>0;t--){let s=e[t-1];if(!(s.fromA>i.toA)){if(s.toAc)break;r+=2}if(!a)return i;new Le(a.fromA,a.toA,a.fromB,a.toB).addToSet(i),o=a.toA,l=a.toB}}}class os{constructor(e,t,i){this.view=e,this.state=t,this.transactions=i,this.flags=0,this.startState=e.state,this.changes=se.empty(this.startState.doc.length);for(let r of i)this.changes=this.changes.compose(r.changes);let s=[];this.changes.iterChangedRanges((r,o,l,a)=>s.push(new Le(r,o,l,a))),this.changedRanges=s}static create(e,t,i){return new os(e,t,i)}get viewportChanged(){return(this.flags&4)>0}get viewportMoved(){return(this.flags&8)>0}get heightChanged(){return(this.flags&2)>0}get geometryChanged(){return this.docChanged||(this.flags&18)>0}get focusChanged(){return(this.flags&1)>0}get docChanged(){return!this.changes.empty}get selectionSet(){return this.transactions.some(e=>e.selection)}get empty(){return this.flags==0&&this.transactions.length==0}}class Pl extends _{get length(){return this.view.state.doc.length}constructor(e){super(),this.view=e,this.decorations=[],this.dynamicDecorationMap=[!1],this.domChanged=null,this.hasComposition=null,this.markedForComposition=new Set,this.editContextFormatting=R.none,this.lastCompositionAfterCursor=!1,this.minWidth=0,this.minWidthFrom=0,this.minWidthTo=0,this.impreciseAnchor=null,this.impreciseHead=null,this.forceSelection=!1,this.lastUpdate=Date.now(),this.setDOM(e.contentDOM),this.children=[new te],this.children[0].setParent(this),this.updateDeco(),this.updateInner([new Le(0,0,0,e.state.doc.length)],0,null)}update(e){var t;let i=e.changedRanges;this.minWidth>0&&i.length&&(i.every(({fromA:h,toA:c})=>cthis.minWidthTo)?(this.minWidthFrom=e.changes.mapPos(this.minWidthFrom,1),this.minWidthTo=e.changes.mapPos(this.minWidthTo,1)):this.minWidth=this.minWidthFrom=this.minWidthTo=0),this.updateEditContextFormatting(e);let s=-1;this.view.inputState.composing>=0&&!this.view.observer.editContext&&(!((t=this.domChanged)===null||t===void 0)&&t.newSel?s=this.domChanged.newSel.head:!zd(e.changes,this.hasComposition)&&!e.selectionSet&&(s=e.state.selection.main.head));let r=s>-1?qd(this.view,e.changes,s):null;if(this.domChanged=null,this.hasComposition){this.markedForComposition.clear();let{from:h,to:c}=this.hasComposition;i=new Le(h,c,e.changes.mapPos(h,-1),e.changes.mapPos(c,1)).addToSet(i.slice())}this.hasComposition=r?{from:r.range.fromB,to:r.range.toB}:null,(Q.ie||Q.chrome)&&!r&&e&&e.state.doc.lines!=e.startState.doc.lines&&(this.forceSelection=!0);let o=this.decorations,l=this.updateDeco(),a=Wd(o,l,e.changes);return i=Le.extendWithRanges(i,a),!(this.flags&7)&&i.length==0?!1:(this.updateInner(i,e.startState.doc.length,r),e.transactions.length&&(this.lastUpdate=Date.now()),!0)}updateInner(e,t,i){this.view.viewState.mustMeasureContent=!0,this.updateChildren(e,t,i);let{observer:s}=this.view;s.ignore(()=>{this.dom.style.height=this.view.viewState.contentHeight/this.view.scaleY+"px",this.dom.style.flexBasis=this.minWidth?this.minWidth+"px":"";let o=Q.chrome||Q.ios?{node:s.selectionRange.focusNode,written:!1}:void 0;this.sync(this.view,o),this.flags&=-8,o&&(o.written||s.selectionRange.focusNode!=o.node)&&(this.forceSelection=!0),this.dom.style.height=""}),this.markedForComposition.forEach(o=>o.flags&=-9);let r=[];if(this.view.viewport.from||this.view.viewport.to=0?s[o]:null;if(!l)break;let{fromA:a,toA:h,fromB:c,toB:f}=l,u,d,p,m;if(i&&i.range.fromBc){let w=Di.build(this.view.state.doc,c,i.range.fromB,this.decorations,this.dynamicDecorationMap),k=Di.build(this.view.state.doc,i.range.toB,f,this.decorations,this.dynamicDecorationMap);d=w.breakAtStart,p=w.openStart,m=k.openEnd;let v=this.compositionView(i);k.breakAtStart?v.breakAfter=1:k.content.length&&v.merge(v.length,v.length,k.content[0],!1,k.openStart,0)&&(v.breakAfter=k.content[0].breakAfter,k.content.shift()),w.content.length&&v.merge(0,0,w.content[w.content.length-1],!0,0,w.openEnd)&&w.content.pop(),u=w.content.concat(v).concat(k.content)}else({content:u,breakAtStart:d,openStart:p,openEnd:m}=Di.build(this.view.state.doc,c,f,this.decorations,this.dynamicDecorationMap));let{i:g,off:y}=r.findPos(h,1),{i:S,off:x}=r.findPos(a,-1);Hh(this,S,x,g,y,u,d,p,m)}i&&this.fixCompositionDOM(i)}updateEditContextFormatting(e){this.editContextFormatting=this.editContextFormatting.map(e.changes);for(let t of e.transactions)for(let i of t.effects)i.is(dc)&&(this.editContextFormatting=i.value)}compositionView(e){let t=new Ve(e.text.nodeValue);t.flags|=8;for(let{deco:s}of e.marks)t=new Ot(s,[t],t.length);let i=new te;return i.append(t,0),i}fixCompositionDOM(e){let t=(r,o)=>{o.flags|=8|(o.children.some(a=>a.flags&7)?1:0),this.markedForComposition.add(o);let l=_.get(r);l&&l!=o&&(l.dom=null),o.setDOM(r)},i=this.childPos(e.range.fromB,1),s=this.children[i.i];t(e.line,s);for(let r=e.marks.length-1;r>=-1;r--)i=s.childPos(i.off,1),s=s.children[i.i],t(r>=0?e.marks[r].node:e.text,s)}updateSelection(e=!1,t=!1){(e||!this.view.observer.selectionRange.focusNode)&&this.view.observer.readSelectionRange();let i=this.view.root.activeElement,s=i==this.dom,r=!s&&!(this.view.state.facet(dt)||this.dom.tabIndex>-1)&&_n(this.dom,this.view.observer.selectionRange)&&!(i&&this.dom.contains(i));if(!(s||t||r))return;let o=this.forceSelection;this.forceSelection=!1;let l=this.view.state.selection.main,a=this.moveToLine(this.domAtPos(l.anchor)),h=l.empty?a:this.moveToLine(this.domAtPos(l.head));if(Q.gecko&&l.empty&&!this.hasComposition&&Ed(a)){let f=document.createTextNode("");this.view.observer.ignore(()=>a.node.insertBefore(f,a.node.childNodes[a.offset]||null)),a=h=new ye(f,0),o=!0}let c=this.view.observer.selectionRange;(o||!c.focusNode||(!Ri(a.node,a.offset,c.anchorNode,c.anchorOffset)||!Ri(h.node,h.offset,c.focusNode,c.focusOffset))&&!this.suppressWidgetCursorChange(c,l))&&(this.view.observer.ignore(()=>{Q.android&&Q.chrome&&this.dom.contains(c.focusNode)&&Ld(c.focusNode,this.dom)&&(this.dom.blur(),this.dom.focus({preventScroll:!0}));let f=zi(this.view.root);if(f)if(l.empty){if(Q.gecko){let u=$d(a.node,a.offset);if(u&&u!=3){let d=(u==1?Fh:_h)(a.node,a.offset);d&&(a=new ye(d.node,d.offset))}}f.collapse(a.node,a.offset),l.bidiLevel!=null&&f.caretBidiLevel!==void 0&&(f.caretBidiLevel=l.bidiLevel)}else if(f.extend){f.collapse(a.node,a.offset);try{f.extend(h.node,h.offset)}catch{}}else{let u=document.createRange();l.anchor>l.head&&([a,h]=[h,a]),u.setEnd(h.node,h.offset),u.setStart(a.node,a.offset),f.removeAllRanges(),f.addRange(u)}r&&this.view.root.activeElement==this.dom&&(this.dom.blur(),i&&i.focus())}),this.view.observer.setSelectionRange(a,h)),this.impreciseAnchor=a.precise?null:new ye(c.anchorNode,c.anchorOffset),this.impreciseHead=h.precise?null:new ye(c.focusNode,c.focusOffset)}suppressWidgetCursorChange(e,t){return this.hasComposition&&t.empty&&Ri(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset)&&this.posFromDOM(e.focusNode,e.focusOffset)==t.head}enforceCursorAssoc(){if(this.hasComposition)return;let{view:e}=this,t=e.state.selection.main,i=zi(e.root),{anchorNode:s,anchorOffset:r}=e.observer.selectionRange;if(!i||!t.empty||!t.assoc||!i.modify)return;let o=te.find(this,t.head);if(!o)return;let l=o.posAtStart;if(t.head==l||t.head==l+o.length)return;let a=this.coordsAt(t.head,-1),h=this.coordsAt(t.head,1);if(!a||!h||a.bottom>h.top)return;let c=this.domAtPos(t.head+t.assoc);i.collapse(c.node,c.offset),i.modify("move",t.assoc<0?"forward":"backward","lineboundary"),e.observer.readSelectionRange();let f=e.observer.selectionRange;e.docView.posFromDOM(f.anchorNode,f.anchorOffset)!=t.from&&i.collapse(s,r)}moveToLine(e){let t=this.dom,i;if(e.node!=t)return e;for(let s=e.offset;!i&&s=0;s--){let r=_.get(t.childNodes[s]);r instanceof te&&(i=r.domAtPos(r.length))}return i?new ye(i.node,i.offset,!0):e}nearest(e){for(let t=e;t;){let i=_.get(t);if(i&&i.rootView==this)return i;t=t.parentNode}return null}posFromDOM(e,t){let i=this.nearest(e);if(!i)throw new RangeError("Trying to find position for a DOM position outside of the document");return i.localPosFromDOM(e,t)+i.posAtStart}domAtPos(e){let{i:t,off:i}=this.childCursor().findPos(e,-1);for(;t=0;o--){let l=this.children[o],a=r-l.breakAfter,h=a-l.length;if(ae||l.covers(1))&&(!i||l instanceof te&&!(i instanceof te&&t>=0)))i=l,s=h;else if(i&&h==e&&a==e&&l instanceof mt&&Math.abs(t)<2){if(l.deco.startSide<0)break;o&&(i=null)}r=h}return i?i.coordsAt(e-s,t):null}coordsForChar(e){let{i:t,off:i}=this.childPos(e,1),s=this.children[t];if(!(s instanceof te))return null;for(;s.children.length;){let{i:l,off:a}=s.childPos(i,1);for(;;l++){if(l==s.children.length)return null;if((s=s.children[l]).length)break}i=a}if(!(s instanceof Ve))return null;let r=pe(s.text,i);if(r==i)return null;let o=Ft(s.dom,i,r).getClientRects();for(let l=0;lMath.max(this.view.scrollDOM.clientWidth,this.minWidth)+1,l=-1,a=this.view.textDirection==Z.LTR;for(let h=0,c=0;cs)break;if(h>=i){let d=f.dom.getBoundingClientRect();if(t.push(d.height),o){let p=f.dom.lastChild,m=p?ai(p):[];if(m.length){let g=m[m.length-1],y=a?g.right-d.left:d.right-g.left;y>l&&(l=y,this.minWidth=r,this.minWidthFrom=h,this.minWidthTo=u)}}}h=u+f.breakAfter}return t}textDirectionAt(e){let{i:t}=this.childPos(e,1);return getComputedStyle(this.children[t].dom).direction=="rtl"?Z.RTL:Z.LTR}measureTextSize(){for(let r of this.children)if(r instanceof te){let o=r.measureTextSize();if(o)return o}let e=document.createElement("div"),t,i,s;return e.className="cm-line",e.style.width="99999px",e.style.position="absolute",e.textContent="abc def ghi jkl mno pqr stu",this.view.observer.ignore(()=>{this.dom.appendChild(e);let r=ai(e.firstChild)[0];t=e.getBoundingClientRect().height,i=r?r.width/27:7,s=r?r.height:t,e.remove()}),{lineHeight:t,charWidth:i,textHeight:s}}childCursor(e=this.length){let t=this.children.length;return t&&(e-=this.children[--t].length),new Uh(this.children,e,t)}computeBlockGapDeco(){let e=[],t=this.view.viewState;for(let i=0,s=0;;s++){let r=s==t.viewports.length?null:t.viewports[s],o=r?r.from-1:this.length;if(o>i){let l=(t.lineBlockAt(o).bottom-t.lineBlockAt(i).top)/this.view.scaleY;e.push(R.replace({widget:new Fr(l),block:!0,inclusive:!0,isBlockGap:!0}).range(i,o))}if(!r)break;i=r.to+1}return R.set(e)}updateDeco(){let e=1,t=this.view.state.facet(Ii).map(r=>(this.dynamicDecorationMap[e++]=typeof r=="function")?r(this.view):r),i=!1,s=this.view.state.facet(mc).map((r,o)=>{let l=typeof r=="function";return l&&(i=!0),l?r(this.view):r});for(s.length&&(this.dynamicDecorationMap[e++]=i,t.push(N.join(s))),this.decorations=[this.editContextFormatting,...t,this.computeBlockGapDeco(),this.view.viewState.lineGapDeco];et.anchor?-1:1),s;if(!i)return;!t.empty&&(s=this.coordsAt(t.anchor,t.anchor>t.head?-1:1))&&(i={left:Math.min(i.left,s.left),top:Math.min(i.top,s.top),right:Math.max(i.right,s.right),bottom:Math.max(i.bottom,s.bottom)});let r=Ao(this.view),o={left:i.left-r.left,top:i.top-r.top,right:i.right+r.right,bottom:i.bottom+r.bottom},{offsetWidth:l,offsetHeight:a}=this.view.scrollDOM;ud(this.view.scrollDOM,o,t.heads instanceof pt||s.children.some(i);return i(this.children[t])}}function Ed(n){return n.node.nodeType==1&&n.node.firstChild&&(n.offset==0||n.node.childNodes[n.offset-1].contentEditable=="false")&&(n.offset==n.node.childNodes.length||n.node.childNodes[n.offset].contentEditable=="false")}function yc(n,e){let t=n.observer.selectionRange;if(!t.focusNode)return null;let i=Fh(t.focusNode,t.focusOffset),s=_h(t.focusNode,t.focusOffset),r=i||s;if(s&&i&&s.node!=i.node){let l=_.get(s.node);if(!l||l instanceof Ve&&l.text!=s.node.nodeValue)r=s;else if(n.docView.lastCompositionAfterCursor){let a=_.get(i.node);!a||a instanceof Ve&&a.text!=i.node.nodeValue||(r=s)}}if(n.docView.lastCompositionAfterCursor=r!=i,!r)return null;let o=e-r.offset;return{from:o,to:o+r.node.nodeValue.length,node:r.node}}function qd(n,e,t){let i=yc(n,t);if(!i)return null;let{node:s,from:r,to:o}=i,l=s.nodeValue;if(/[\n\r]/.test(l)||n.state.doc.sliceString(i.from,i.to)!=l)return null;let a=e.invertedDesc,h=new Le(a.mapPos(r),a.mapPos(o),r,o),c=[];for(let f=s.parentNode;;f=f.parentNode){let u=_.get(f);if(u instanceof Ot)c.push({node:f,deco:u.mark});else{if(u instanceof te||f.nodeName=="DIV"&&f.parentNode==n.contentDOM)return{range:h,text:s,marks:c,line:f};if(f!=n.contentDOM)c.push({node:f,deco:new rn({inclusive:!0,attributes:xd(f),tagName:f.tagName.toLowerCase()})});else return null}}}function $d(n,e){return n.nodeType!=1?0:(e&&n.childNodes[e-1].contentEditable=="false"?1:0)|(e{ie.from&&(t=!0)}),t}function Id(n,e,t=1){let i=n.charCategorizer(e),s=n.doc.lineAt(e),r=e-s.from;if(s.length==0)return b.cursor(e);r==0?t=1:r==s.length&&(t=-1);let o=r,l=r;t<0?o=pe(s.text,r,!1):l=pe(s.text,r);let a=i(s.text.slice(o,l));for(;o>0;){let h=pe(s.text,o,!1);if(i(s.text.slice(h,o))!=a)break;o=h}for(;ln?e.left-n:Math.max(0,n-e.right)}function Nd(n,e){return e.top>n?e.top-n:Math.max(0,n-e.bottom)}function Fs(n,e){return n.tope.top+1}function Ql(n,e){return en.bottom?{top:n.top,left:n.left,right:n.right,bottom:e}:n}function Gr(n,e,t){let i,s,r,o,l=!1,a,h,c,f;for(let p=n.firstChild;p;p=p.nextSibling){let m=ai(p);for(let g=0;gx||o==x&&r>S)&&(i=p,s=y,r=S,o=x,l=S?e0:gy.bottom&&(!c||c.bottomy.top)&&(h=p,f=y):c&&Fs(c,y)?c=Al(c,y.bottom):f&&Fs(f,y)&&(f=Ql(f,y.top))}}if(c&&c.bottom>=t?(i=a,s=c):f&&f.top<=t&&(i=h,s=f),!i)return{node:n,offset:0};let u=Math.max(s.left,Math.min(s.right,e));if(i.nodeType==3)return Ml(i,u,t);if(l&&i.contentEditable!="false")return Gr(i,u,t);let d=Array.prototype.indexOf.call(n.childNodes,i)+(e>=(s.left+s.right)/2?1:0);return{node:n,offset:d}}function Ml(n,e,t){let i=n.nodeValue.length,s=-1,r=1e9,o=0;for(let l=0;lt?c.top-t:t-c.bottom)-1;if(c.left-1<=e&&c.right+1>=e&&f=(c.left+c.right)/2,d=u;if(Q.chrome||Q.gecko){let p=Ft(n,l).getBoundingClientRect();Math.abs(p.left-c.right)<.1&&(d=!u)}if(f<=0)return{node:n,offset:l+(d?1:0)};s=l+(d?1:0),r=f}}}return{node:n,offset:s>-1?s:o>0?n.nodeValue.length:0}}function bc(n,e,t,i=-1){var s,r;let o=n.contentDOM.getBoundingClientRect(),l=o.top+n.viewState.paddingTop,a,{docHeight:h}=n.viewState,{x:c,y:f}=e,u=f-l;if(u<0)return 0;if(u>h)return n.state.doc.length;for(let w=n.viewState.heightOracle.textHeight/2,k=!1;a=n.elementAtHeight(u),a.type!=ke.Text;)for(;u=i>0?a.bottom+w:a.top-w,!(u>=0&&u<=h);){if(k)return t?null:0;k=!0,i=-i}f=l+u;let d=a.from;if(dn.viewport.to)return n.viewport.to==n.state.doc.length?n.state.doc.length:t?null:Rl(n,o,a,c,f);let p=n.dom.ownerDocument,m=n.root.elementFromPoint?n.root:p,g=m.elementFromPoint(c,f);g&&!n.contentDOM.contains(g)&&(g=null),g||(c=Math.max(o.left+1,Math.min(o.right-1,c)),g=m.elementFromPoint(c,f),g&&!n.contentDOM.contains(g)&&(g=null));let y,S=-1;if(g&&((s=n.docView.nearest(g))===null||s===void 0?void 0:s.isEditable)!=!1){if(p.caretPositionFromPoint){let w=p.caretPositionFromPoint(c,f);w&&({offsetNode:y,offset:S}=w)}else if(p.caretRangeFromPoint){let w=p.caretRangeFromPoint(c,f);w&&({startContainer:y,startOffset:S}=w)}y&&(!n.contentDOM.contains(y)||Q.safari&&Xd(y,S,c)||Q.chrome&&Fd(y,S,c))&&(y=void 0),y&&(S=Math.min(nt(y),S))}if(!y||!n.docView.dom.contains(y)){let w=te.find(n.docView,d);if(!w)return u>a.top+a.height/2?a.to:a.from;({node:y,offset:S}=Gr(w.dom,c,f))}let x=n.docView.nearest(y);if(!x)return null;if(x.isWidget&&((r=x.dom)===null||r===void 0?void 0:r.nodeType)==1){let w=x.dom.getBoundingClientRect();return e.yn.defaultLineHeight*1.5){let l=n.viewState.heightOracle.textHeight,a=Math.floor((s-t.top-(n.defaultLineHeight-l)*.5)/l);r+=a*n.viewState.heightOracle.lineLength}let o=n.state.sliceDoc(t.from,t.to);return t.from+qr(o,r,n.state.tabSize)}function Sc(n,e,t){let i,s=n;if(n.nodeType!=3||e!=(i=n.nodeValue.length))return!1;for(;;){let r=s.nextSibling;if(r){if(r.nodeName=="BR")break;return!1}else{let o=s.parentNode;if(!o||o.nodeName=="DIV")break;s=o}}return Ft(n,i-1,i).getBoundingClientRect().right>t}function Xd(n,e,t){return Sc(n,e,t)}function Fd(n,e,t){if(e!=0)return Sc(n,e,t);for(let s=n;;){let r=s.parentNode;if(!r||r.nodeType!=1||r.firstChild!=s)return!1;if(r.classList.contains("cm-line"))break;s=r}let i=n.nodeType==1?n.getBoundingClientRect():Ft(n,0,Math.max(n.nodeValue.length,1)).getBoundingClientRect();return t-i.left>5}function Zr(n,e,t){let i=n.lineBlockAt(e);if(Array.isArray(i.type)){let s;for(let r of i.type){if(r.from>e)break;if(!(r.toe)return r;(!s||r.type==ke.Text&&(s.type!=r.type||(t<0?r.frome)))&&(s=r)}}return s||i}return i}function _d(n,e,t,i){let s=Zr(n,e.head,e.assoc||-1),r=!i||s.type!=ke.Text||!(n.lineWrapping||s.widgetLineBreaks)?null:n.coordsAtPos(e.assoc<0&&e.head>s.from?e.head-1:e.head);if(r){let o=n.dom.getBoundingClientRect(),l=n.textDirectionAt(s.from),a=n.posAtCoords({x:t==(l==Z.LTR)?o.right-1:o.left+1,y:(r.top+r.bottom)/2});if(a!=null)return b.cursor(a,t?-1:1)}return b.cursor(t?s.to:s.from,t?-1:1)}function Dl(n,e,t,i){let s=n.state.doc.lineAt(e.head),r=n.bidiSpans(s),o=n.textDirectionAt(s.from);for(let l=e,a=null;;){let h=Md(s,r,o,l,t),c=nc;if(!h){if(s.number==(t?n.state.doc.lines:1))return l;c=` +`,s=n.state.doc.line(s.number+(t?1:-1)),r=n.bidiSpans(s),h=n.visualLineSide(s,!t)}if(a){if(!a(c))return l}else{if(!i)return h;a=i(c)}l=h}}function Ud(n,e,t){let i=n.state.charCategorizer(e),s=i(t);return r=>{let o=i(r);return s==Y.Space&&(s=o),s==o}}function Hd(n,e,t,i){let s=e.head,r=t?1:-1;if(s==(t?n.state.doc.length:0))return b.cursor(s,e.assoc);let o=e.goalColumn,l,a=n.contentDOM.getBoundingClientRect(),h=n.coordsAtPos(s,e.assoc||-1),c=n.documentTop;if(h)o==null&&(o=h.left-a.left),l=r<0?h.top:h.bottom;else{let d=n.viewState.lineBlockAt(s);o==null&&(o=Math.min(a.right-a.left,n.defaultCharacterWidth*(s-d.from))),l=(r<0?d.top:d.bottom)+c}let f=a.left+o,u=i??n.viewState.heightOracle.textHeight>>1;for(let d=0;;d+=10){let p=l+(u+d)*r,m=bc(n,{x:f,y:p},!1,r);if(pa.bottom||(r<0?ms)){let g=n.docView.coordsForChar(m),y=!g||p{if(e>r&&es(n)),t.from,e.head>t.from?-1:1);return i==t.from?t:b.cursor(i,ir)&&!Zd(o,t)&&this.lineBreak(),s=o}return this.findPointBefore(i,t),this}readTextNode(e){let t=e.nodeValue;for(let i of this.points)i.node==e&&(i.pos=this.text.length+Math.min(i.offset,t.length));for(let i=0,s=this.lineSeparator?null:/\r\n?|\n/g;;){let r=-1,o=1,l;if(this.lineSeparator?(r=t.indexOf(this.lineSeparator,i),o=this.lineSeparator.length):(l=s.exec(t))&&(r=l.index,o=l[0].length),this.append(t.slice(i,r<0?t.length:r)),r<0)break;if(this.lineBreak(),o>1)for(let a of this.points)a.node==e&&a.pos>this.text.length&&(a.pos-=o-1);i=r+o}}readNode(e){if(e.cmIgnore)return;let t=_.get(e),i=t&&t.overrideDOMText;if(i!=null){this.findPointInside(e,i.length);for(let s=i.iter();!s.next().done;)s.lineBreak?this.lineBreak():this.append(s.value)}else e.nodeType==3?this.readTextNode(e):e.nodeName=="BR"?e.nextSibling&&this.lineBreak():e.nodeType==1&&this.readRange(e.firstChild,null)}findPointBefore(e,t){for(let i of this.points)i.node==e&&e.childNodes[i.offset]==t&&(i.pos=this.text.length)}findPointInside(e,t){for(let i of this.points)(e.nodeType==3?i.node==e:e.contains(i.node))&&(i.pos=this.text.length+(Gd(e,i.node,i.offset)?t:0))}}function Gd(n,e,t){for(;;){if(!e||t-1;let{impreciseHead:r,impreciseAnchor:o}=e.docView;if(e.state.readOnly&&t>-1)this.newSel=null;else if(t>-1&&(this.bounds=e.docView.domBoundsAround(t,i,0))){let l=r||o?[]:Jd(e),a=new jd(l,e.state);a.readRange(this.bounds.startDOM,this.bounds.endDOM),this.text=a.text,this.newSel=ep(l,this.bounds.from)}else{let l=e.observer.selectionRange,a=r&&r.node==l.focusNode&&r.offset==l.focusOffset||!Vr(e.contentDOM,l.focusNode)?e.state.selection.main.head:e.docView.posFromDOM(l.focusNode,l.focusOffset),h=o&&o.node==l.anchorNode&&o.offset==l.anchorOffset||!Vr(e.contentDOM,l.anchorNode)?e.state.selection.main.anchor:e.docView.posFromDOM(l.anchorNode,l.anchorOffset),c=e.viewport;if((Q.ios||Q.chrome)&&e.state.selection.main.empty&&a!=h&&(c.from>0||c.to-1&&e.state.selection.ranges.length>1?this.newSel=e.state.selection.replaceRange(b.range(h,a)):this.newSel=b.single(h,a)}}}function kc(n,e){let t,{newSel:i}=e,s=n.state.selection.main,r=n.inputState.lastKeyTime>Date.now()-100?n.inputState.lastKeyCode:-1;if(e.bounds){let{from:o,to:l}=e.bounds,a=s.from,h=null;(r===8||Q.android&&e.text.length=s.from&&t.to<=s.to&&(t.from!=s.from||t.to!=s.to)&&s.to-s.from-(t.to-t.from)<=4?t={from:s.from,to:s.to,insert:n.state.doc.slice(s.from,t.from).append(t.insert).append(n.state.doc.slice(t.to,s.to))}:n.state.doc.lineAt(s.from).toDate.now()-50?t={from:s.from,to:s.to,insert:n.state.toText(n.inputState.insertingText)}:Q.chrome&&t&&t.from==t.to&&t.from==s.head&&t.insert.toString()==` + `&&n.lineWrapping&&(i&&(i=b.single(i.main.anchor-1,i.main.head-1)),t={from:s.from,to:s.to,insert:V.of([" "])}),t)return Mo(n,t,i,r);if(i&&!i.main.eq(s)){let o=!1,l="select";return n.inputState.lastSelectionTime>Date.now()-50&&(n.inputState.lastSelectionOrigin=="select"&&(o=!0),l=n.inputState.lastSelectionOrigin,l=="select.pointer"&&(i=xc(n.state.facet(ln).map(a=>a(n)),i))),n.dispatch({selection:i,scrollIntoView:o,userEvent:l}),!0}else return!1}function Mo(n,e,t,i=-1){if(Q.ios&&n.inputState.flushIOSKey(e))return!0;let s=n.state.selection.main;if(Q.android&&(e.to==s.to&&(e.from==s.from||e.from==s.from-1&&n.state.sliceDoc(e.from,s.from)==" ")&&e.insert.length==1&&e.insert.lines==2&&ii(n.contentDOM,"Enter",13)||(e.from==s.from-1&&e.to==s.to&&e.insert.length==0||i==8&&e.insert.lengths.head)&&ii(n.contentDOM,"Backspace",8)||e.from==s.from&&e.to==s.to+1&&e.insert.length==0&&ii(n.contentDOM,"Delete",46)))return!0;let r=e.insert.toString();n.inputState.composing>=0&&n.inputState.composing++;let o,l=()=>o||(o=Kd(n,e,t));return n.state.facet(ac).some(a=>a(n,e.from,e.to,r,l))||n.dispatch(l()),!0}function Kd(n,e,t){let i,s=n.state,r=s.selection.main,o=-1;if(e.from==e.to&&e.fromr.to){let a=e.fromf(n)),h,a);e.from==c&&(o=c)}if(o>-1)i={changes:e,selection:b.cursor(e.from+e.insert.length,-1)};else if(e.from>=r.from&&e.to<=r.to&&e.to-e.from>=(r.to-r.from)/3&&(!t||t.main.empty&&t.main.from==e.from+e.insert.length)&&n.inputState.composing<0){let a=r.frome.to?s.sliceDoc(e.to,r.to):"";i=s.replaceSelection(n.state.toText(a+e.insert.sliceString(0,void 0,n.state.lineBreak)+h))}else{let a=s.changes(e),h=t&&t.main.to<=a.newLength?t.main:void 0;if(s.selection.ranges.length>1&&(n.inputState.composing>=0||n.inputState.compositionPendingChange)&&e.to<=r.to+10&&e.to>=r.to-10){let c=n.state.sliceDoc(e.from,e.to),f,u=t&&yc(n,t.main.head);if(u){let p=e.insert.length-(e.to-e.from);f={from:u.from,to:u.to-p}}else f=n.state.doc.lineAt(r.head);let d=r.to-e.to;i=s.changeByRange(p=>{if(p.from==r.from&&p.to==r.to)return{changes:a,range:h||p.map(a)};let m=p.to-d,g=m-c.length;if(n.state.sliceDoc(g,m)!=c||m>=f.from&&g<=f.to)return{range:p};let y=s.changes({from:g,to:m,insert:e.insert}),S=p.to-r.to;return{changes:y,range:h?b.range(Math.max(0,h.anchor+S),Math.max(0,h.head+S)):p.map(y)}})}else i={changes:a,selection:h&&s.selection.replaceRange(h)}}let l="input.type";return(n.composing||n.inputState.compositionPendingChange&&n.inputState.compositionEndedAt>Date.now()-50)&&(n.inputState.compositionPendingChange=!1,l+=".compose",n.inputState.compositionFirstChange&&(l+=".start",n.inputState.compositionFirstChange=!1)),s.update(i,{userEvent:l,scrollIntoView:!0})}function wc(n,e,t,i){let s=Math.min(n.length,e.length),r=0;for(;r0&&l>0&&n.charCodeAt(o-1)==e.charCodeAt(l-1);)o--,l--;if(i=="end"){let a=Math.max(0,r-Math.min(o,l));t-=o+a-r}if(o=o?r-t:0;r-=a,l=r+(l-o),o=r}else if(l=l?r-t:0;r-=a,o=r+(o-l),l=r}return{from:r,toA:o,toB:l}}function Jd(n){let e=[];if(n.root.activeElement!=n.contentDOM)return e;let{anchorNode:t,anchorOffset:i,focusNode:s,focusOffset:r}=n.observer.selectionRange;return t&&(e.push(new El(t,i)),(s!=t||r!=i)&&e.push(new El(s,r))),e}function ep(n,e){if(n.length==0)return null;let t=n[0].pos,i=n.length==2?n[1].pos:t;return t>-1&&i>-1?b.single(t+e,i+e):null}class tp{setSelectionOrigin(e){this.lastSelectionOrigin=e,this.lastSelectionTime=Date.now()}constructor(e){this.view=e,this.lastKeyCode=0,this.lastKeyTime=0,this.lastTouchTime=0,this.lastFocusTime=0,this.lastScrollTop=0,this.lastScrollLeft=0,this.pendingIOSKey=void 0,this.tabFocusMode=-1,this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastContextMenu=0,this.scrollHandlers=[],this.handlers=Object.create(null),this.composing=-1,this.compositionFirstChange=null,this.compositionEndedAt=0,this.compositionPendingKey=!1,this.compositionPendingChange=!1,this.insertingText="",this.insertingTextAt=0,this.mouseSelection=null,this.draggedContent=null,this.handleEvent=this.handleEvent.bind(this),this.notifiedFocused=e.hasFocus,Q.safari&&e.contentDOM.addEventListener("input",()=>null),Q.gecko&&Op(e.contentDOM.ownerDocument)}handleEvent(e){!hp(this.view,e)||this.ignoreDuringComposition(e)||e.type=="keydown"&&this.keydown(e)||(this.view.updateState!=0?Promise.resolve().then(()=>this.runHandlers(e.type,e)):this.runHandlers(e.type,e))}runHandlers(e,t){let i=this.handlers[e];if(i){for(let s of i.observers)s(this.view,t);for(let s of i.handlers){if(t.defaultPrevented)break;if(s(this.view,t)){t.preventDefault();break}}}}ensureHandlers(e){let t=ip(e),i=this.handlers,s=this.view.contentDOM;for(let r in t)if(r!="scroll"){let o=!t[r].handlers.length,l=i[r];l&&o!=!l.handlers.length&&(s.removeEventListener(r,this.handleEvent),l=null),l||s.addEventListener(r,this.handleEvent,{passive:o})}for(let r in i)r!="scroll"&&!t[r]&&s.removeEventListener(r,this.handleEvent);this.handlers=t}keydown(e){if(this.lastKeyCode=e.keyCode,this.lastKeyTime=Date.now(),e.keyCode==9&&this.tabFocusMode>-1&&(!this.tabFocusMode||Date.now()<=this.tabFocusMode))return!0;if(this.tabFocusMode>0&&e.keyCode!=27&&Tc.indexOf(e.keyCode)<0&&(this.tabFocusMode=-1),Q.android&&Q.chrome&&!e.synthetic&&(e.keyCode==13||e.keyCode==8))return this.view.observer.delayAndroidKey(e.key,e.keyCode),!0;let t;return Q.ios&&!e.synthetic&&!e.altKey&&!e.metaKey&&((t=vc.find(i=>i.keyCode==e.keyCode))&&!e.ctrlKey||np.indexOf(e.key)>-1&&e.ctrlKey&&!e.shiftKey)?(this.pendingIOSKey=t||e,setTimeout(()=>this.flushIOSKey(),250),!0):(e.keyCode!=229&&this.view.observer.forceFlush(),!1)}flushIOSKey(e){let t=this.pendingIOSKey;return!t||t.key=="Enter"&&e&&e.from0?!0:Q.safari&&!Q.ios&&this.compositionPendingKey&&Date.now()-this.compositionEndedAt<100?(this.compositionPendingKey=!1,!0):!1}startMouseSelection(e){this.mouseSelection&&this.mouseSelection.destroy(),this.mouseSelection=e}update(e){this.view.observer.update(e),this.mouseSelection&&this.mouseSelection.update(e),this.draggedContent&&e.docChanged&&(this.draggedContent=this.draggedContent.map(e.changes)),e.transactions.length&&(this.lastKeyCode=this.lastSelectionTime=0)}destroy(){this.mouseSelection&&this.mouseSelection.destroy()}}function ql(n,e){return(t,i)=>{try{return e.call(n,i,t)}catch(s){Pe(t.state,s)}}}function ip(n){let e=Object.create(null);function t(i){return e[i]||(e[i]={observers:[],handlers:[]})}for(let i of n){let s=i.spec,r=s&&s.plugin.domEventHandlers,o=s&&s.plugin.domEventObservers;if(r)for(let l in r){let a=r[l];a&&t(l).handlers.push(ql(i.value,a))}if(o)for(let l in o){let a=o[l];a&&t(l).observers.push(ql(i.value,a))}}for(let i in Ne)t(i).handlers.push(Ne[i]);for(let i in ze)t(i).observers.push(ze[i]);return e}const vc=[{key:"Backspace",keyCode:8,inputType:"deleteContentBackward"},{key:"Enter",keyCode:13,inputType:"insertParagraph"},{key:"Enter",keyCode:13,inputType:"insertLineBreak"},{key:"Delete",keyCode:46,inputType:"deleteContentForward"}],np="dthko",Tc=[16,17,18,20,91,92,224,225],kn=6;function wn(n){return Math.max(0,n)*.7+8}function sp(n,e){return Math.max(Math.abs(n.clientX-e.clientX),Math.abs(n.clientY-e.clientY))}class rp{constructor(e,t,i,s){this.view=e,this.startEvent=t,this.style=i,this.mustSelect=s,this.scrollSpeed={x:0,y:0},this.scrolling=-1,this.lastEvent=t,this.scrollParents=dd(e.contentDOM),this.atoms=e.state.facet(ln).map(o=>o(e));let r=e.contentDOM.ownerDocument;r.addEventListener("mousemove",this.move=this.move.bind(this)),r.addEventListener("mouseup",this.up=this.up.bind(this)),this.extend=t.shiftKey,this.multiple=e.state.facet(I.allowMultipleSelections)&&op(e,t),this.dragging=ap(e,t)&&Qc(t)==1?null:!1}start(e){this.dragging===!1&&this.select(e)}move(e){if(e.buttons==0)return this.destroy();if(this.dragging||this.dragging==null&&sp(this.startEvent,e)<10)return;this.select(this.lastEvent=e);let t=0,i=0,s=0,r=0,o=this.view.win.innerWidth,l=this.view.win.innerHeight;this.scrollParents.x&&({left:s,right:o}=this.scrollParents.x.getBoundingClientRect()),this.scrollParents.y&&({top:r,bottom:l}=this.scrollParents.y.getBoundingClientRect());let a=Ao(this.view);e.clientX-a.left<=s+kn?t=-wn(s-e.clientX):e.clientX+a.right>=o-kn&&(t=wn(e.clientX-o)),e.clientY-a.top<=r+kn?i=-wn(r-e.clientY):e.clientY+a.bottom>=l-kn&&(i=wn(e.clientY-l)),this.setScrollSpeed(t,i)}up(e){this.dragging==null&&this.select(this.lastEvent),this.dragging||e.preventDefault(),this.destroy()}destroy(){this.setScrollSpeed(0,0);let e=this.view.contentDOM.ownerDocument;e.removeEventListener("mousemove",this.move),e.removeEventListener("mouseup",this.up),this.view.inputState.mouseSelection=this.view.inputState.draggedContent=null}setScrollSpeed(e,t){this.scrollSpeed={x:e,y:t},e||t?this.scrolling<0&&(this.scrolling=setInterval(()=>this.scroll(),50)):this.scrolling>-1&&(clearInterval(this.scrolling),this.scrolling=-1)}scroll(){let{x:e,y:t}=this.scrollSpeed;e&&this.scrollParents.x&&(this.scrollParents.x.scrollLeft+=e,e=0),t&&this.scrollParents.y&&(this.scrollParents.y.scrollTop+=t,t=0),(e||t)&&this.view.win.scrollBy(e,t),this.dragging===!1&&this.select(this.lastEvent)}select(e){let{view:t}=this,i=xc(this.atoms,this.style.get(e,this.extend,this.multiple));(this.mustSelect||!i.eq(t.state.selection,this.dragging===!1))&&this.view.dispatch({selection:i,userEvent:"select.pointer"}),this.mustSelect=!1}update(e){e.transactions.some(t=>t.isUserEvent("input.type"))?this.destroy():this.style.update(e)&&setTimeout(()=>this.select(this.lastEvent),20)}}function op(n,e){let t=n.state.facet(sc);return t.length?t[0](e):Q.mac?e.metaKey:e.ctrlKey}function lp(n,e){let t=n.state.facet(rc);return t.length?t[0](e):Q.mac?!e.altKey:!e.ctrlKey}function ap(n,e){let{main:t}=n.state.selection;if(t.empty)return!1;let i=zi(n.root);if(!i||i.rangeCount==0)return!0;let s=i.getRangeAt(0).getClientRects();for(let r=0;r=e.clientX&&o.top<=e.clientY&&o.bottom>=e.clientY)return!0}return!1}function hp(n,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let t=e.target,i;t!=n.contentDOM;t=t.parentNode)if(!t||t.nodeType==11||(i=_.get(t))&&i.ignoreEvent(e))return!1;return!0}const Ne=Object.create(null),ze=Object.create(null),Cc=Q.ie&&Q.ie_version<15||Q.ios&&Q.webkit_version<604;function cp(n){let e=n.dom.parentNode;if(!e)return;let t=e.appendChild(document.createElement("textarea"));t.style.cssText="position: fixed; left: -10000px; top: 10px",t.focus(),setTimeout(()=>{n.focus(),t.remove(),Pc(n,t.value)},50)}function Cs(n,e,t){for(let i of n.facet(e))t=i(t,n);return t}function Pc(n,e){e=Cs(n.state,Co,e);let{state:t}=n,i,s=1,r=t.toText(e),o=r.lines==t.selection.ranges.length;if(Yr!=null&&t.selection.ranges.every(a=>a.empty)&&Yr==r.toString()){let a=-1;i=t.changeByRange(h=>{let c=t.doc.lineAt(h.from);if(c.from==a)return{range:h};a=c.from;let f=t.toText((o?r.line(s++).text:e)+t.lineBreak);return{changes:{from:c.from,insert:f},range:b.cursor(h.from+f.length)}})}else o?i=t.changeByRange(a=>{let h=r.line(s++);return{changes:{from:a.from,to:a.to,insert:h.text},range:b.cursor(a.from+h.length)}}):i=t.replaceSelection(r);n.dispatch(i,{userEvent:"input.paste",scrollIntoView:!0})}ze.scroll=n=>{n.inputState.lastScrollTop=n.scrollDOM.scrollTop,n.inputState.lastScrollLeft=n.scrollDOM.scrollLeft};Ne.keydown=(n,e)=>(n.inputState.setSelectionOrigin("select"),e.keyCode==27&&n.inputState.tabFocusMode!=0&&(n.inputState.tabFocusMode=Date.now()+2e3),!1);ze.touchstart=(n,e)=>{n.inputState.lastTouchTime=Date.now(),n.inputState.setSelectionOrigin("select.pointer")};ze.touchmove=n=>{n.inputState.setSelectionOrigin("select.pointer")};Ne.mousedown=(n,e)=>{if(n.observer.flush(),n.inputState.lastTouchTime>Date.now()-2e3)return!1;let t=null;for(let i of n.state.facet(oc))if(t=i(n,e),t)break;if(!t&&e.button==0&&(t=dp(n,e)),t){let i=!n.hasFocus;n.inputState.startMouseSelection(new rp(n,e,t,i)),i&&n.observer.ignore(()=>{Vh(n.contentDOM);let r=n.root.activeElement;r&&!r.contains(n.contentDOM)&&r.blur()});let s=n.inputState.mouseSelection;if(s)return s.start(e),s.dragging===!1}else n.inputState.setSelectionOrigin("select.pointer");return!1};function $l(n,e,t,i){if(i==1)return b.cursor(e,t);if(i==2)return Id(n.state,e,t);{let s=te.find(n.docView,e),r=n.state.doc.lineAt(s?s.posAtEnd:e),o=s?s.posAtStart:r.from,l=s?s.posAtEnd:r.to;return le>=t.top&&e<=t.bottom&&n>=t.left&&n<=t.right;function fp(n,e,t,i){let s=te.find(n.docView,e);if(!s)return 1;let r=e-s.posAtStart;if(r==0)return 1;if(r==s.length)return-1;let o=s.coordsAt(r,-1);if(o&&Bl(t,i,o))return-1;let l=s.coordsAt(r,1);return l&&Bl(t,i,l)?1:o&&o.bottom>=i?-1:1}function Wl(n,e){let t=n.posAtCoords({x:e.clientX,y:e.clientY},!1);return{pos:t,bias:fp(n,t,e.clientX,e.clientY)}}const up=Q.ie&&Q.ie_version<=11;let Ll=null,zl=0,Il=0;function Qc(n){if(!up)return n.detail;let e=Ll,t=Il;return Ll=n,Il=Date.now(),zl=!e||t>Date.now()-400&&Math.abs(e.clientX-n.clientX)<2&&Math.abs(e.clientY-n.clientY)<2?(zl+1)%3:1}function dp(n,e){let t=Wl(n,e),i=Qc(e),s=n.state.selection;return{update(r){r.docChanged&&(t.pos=r.changes.mapPos(t.pos),s=s.map(r.changes))},get(r,o,l){let a=Wl(n,r),h,c=$l(n,a.pos,a.bias,i);if(t.pos!=a.pos&&!o){let f=$l(n,t.pos,t.bias,i),u=Math.min(f.from,c.from),d=Math.max(f.to,c.to);c=u1&&(h=pp(s,a.pos))?h:l?s.addRange(c):b.create([c])}}}function pp(n,e){for(let t=0;t=e)return b.create(n.ranges.slice(0,t).concat(n.ranges.slice(t+1)),n.mainIndex==t?0:n.mainIndex-(n.mainIndex>t?1:0))}return null}Ne.dragstart=(n,e)=>{let{selection:{main:t}}=n.state;if(e.target.draggable){let s=n.docView.nearest(e.target);if(s&&s.isWidget){let r=s.posAtStart,o=r+s.length;(r>=t.to||o<=t.from)&&(t=b.range(r,o))}}let{inputState:i}=n;return i.mouseSelection&&(i.mouseSelection.dragging=!0),i.draggedContent=t,e.dataTransfer&&(e.dataTransfer.setData("Text",Cs(n.state,Po,n.state.sliceDoc(t.from,t.to))),e.dataTransfer.effectAllowed="copyMove"),!1};Ne.dragend=n=>(n.inputState.draggedContent=null,!1);function Vl(n,e,t,i){if(t=Cs(n.state,Co,t),!t)return;let s=n.posAtCoords({x:e.clientX,y:e.clientY},!1),{draggedContent:r}=n.inputState,o=i&&r&&lp(n,e)?{from:r.from,to:r.to}:null,l={from:s,insert:t},a=n.state.changes(o?[o,l]:l);n.focus(),n.dispatch({changes:a,selection:{anchor:a.mapPos(s,-1),head:a.mapPos(s,1)},userEvent:o?"move.drop":"input.drop"}),n.inputState.draggedContent=null}Ne.drop=(n,e)=>{if(!e.dataTransfer)return!1;if(n.state.readOnly)return!0;let t=e.dataTransfer.files;if(t&&t.length){let i=Array(t.length),s=0,r=()=>{++s==t.length&&Vl(n,e,i.filter(o=>o!=null).join(n.state.lineBreak),!1)};for(let o=0;o{/[\x00-\x08\x0e-\x1f]{2}/.test(l.result)||(i[o]=l.result),r()},l.readAsText(t[o])}return!0}else{let i=e.dataTransfer.getData("Text");if(i)return Vl(n,e,i,!0),!0}return!1};Ne.paste=(n,e)=>{if(n.state.readOnly)return!0;n.observer.flush();let t=Cc?null:e.clipboardData;return t?(Pc(n,t.getData("text/plain")||t.getData("text/uri-list")),!0):(cp(n),!1)};function mp(n,e){let t=n.dom.parentNode;if(!t)return;let i=t.appendChild(document.createElement("textarea"));i.style.cssText="position: fixed; left: -10000px; top: 10px",i.value=e,i.focus(),i.selectionEnd=e.length,i.selectionStart=0,setTimeout(()=>{i.remove(),n.focus()},50)}function gp(n){let e=[],t=[],i=!1;for(let s of n.selection.ranges)s.empty||(e.push(n.sliceDoc(s.from,s.to)),t.push(s));if(!e.length){let s=-1;for(let{from:r}of n.selection.ranges){let o=n.doc.lineAt(r);o.number>s&&(e.push(o.text),t.push({from:o.from,to:Math.min(n.doc.length,o.to+1)})),s=o.number}i=!0}return{text:Cs(n,Po,e.join(n.lineBreak)),ranges:t,linewise:i}}let Yr=null;Ne.copy=Ne.cut=(n,e)=>{let{text:t,ranges:i,linewise:s}=gp(n.state);if(!t&&!s)return!1;Yr=s?t:null,e.type=="cut"&&!n.state.readOnly&&n.dispatch({changes:i,scrollIntoView:!0,userEvent:"delete.cut"});let r=Cc?null:e.clipboardData;return r?(r.clearData(),r.setData("text/plain",t),!0):(mp(n,t),!1)};const Ac=st.define();function Mc(n,e){let t=[];for(let i of n.facet(hc)){let s=i(n,e);s&&t.push(s)}return t.length?n.update({effects:t,annotations:Ac.of(!0)}):null}function Rc(n){setTimeout(()=>{let e=n.hasFocus;if(e!=n.inputState.notifiedFocused){let t=Mc(n.state,e);t?n.dispatch(t):n.update([])}},10)}ze.focus=n=>{n.inputState.lastFocusTime=Date.now(),!n.scrollDOM.scrollTop&&(n.inputState.lastScrollTop||n.inputState.lastScrollLeft)&&(n.scrollDOM.scrollTop=n.inputState.lastScrollTop,n.scrollDOM.scrollLeft=n.inputState.lastScrollLeft),Rc(n)};ze.blur=n=>{n.observer.clearSelectionRange(),Rc(n)};ze.compositionstart=ze.compositionupdate=n=>{n.observer.editContext||(n.inputState.compositionFirstChange==null&&(n.inputState.compositionFirstChange=!0),n.inputState.composing<0&&(n.inputState.composing=0))};ze.compositionend=n=>{n.observer.editContext||(n.inputState.composing=-1,n.inputState.compositionEndedAt=Date.now(),n.inputState.compositionPendingKey=!0,n.inputState.compositionPendingChange=n.observer.pendingRecords().length>0,n.inputState.compositionFirstChange=null,Q.chrome&&Q.android?n.observer.flushSoon():n.inputState.compositionPendingChange?Promise.resolve().then(()=>n.observer.flush()):setTimeout(()=>{n.inputState.composing<0&&n.docView.hasComposition&&n.update([])},50))};ze.contextmenu=n=>{n.inputState.lastContextMenu=Date.now()};Ne.beforeinput=(n,e)=>{var t,i;if((e.inputType=="insertText"||e.inputType=="insertCompositionText")&&(n.inputState.insertingText=e.data,n.inputState.insertingTextAt=Date.now()),e.inputType=="insertReplacementText"&&n.observer.editContext){let r=(t=e.dataTransfer)===null||t===void 0?void 0:t.getData("text/plain"),o=e.getTargetRanges();if(r&&o.length){let l=o[0],a=n.posAtDOM(l.startContainer,l.startOffset),h=n.posAtDOM(l.endContainer,l.endOffset);return Mo(n,{from:a,to:h,insert:n.state.toText(r)},null),!0}}let s;if(Q.chrome&&Q.android&&(s=vc.find(r=>r.inputType==e.inputType))&&(n.observer.delayAndroidKey(s.key,s.keyCode),s.key=="Backspace"||s.key=="Delete")){let r=((i=window.visualViewport)===null||i===void 0?void 0:i.height)||0;setTimeout(()=>{var o;(((o=window.visualViewport)===null||o===void 0?void 0:o.height)||0)>r+10&&n.hasFocus&&(n.contentDOM.blur(),n.focus())},100)}return Q.ios&&e.inputType=="deleteContentForward"&&n.observer.flushSoon(),Q.safari&&e.inputType=="insertText"&&n.inputState.composing>=0&&setTimeout(()=>ze.compositionend(n,e),20),!1};const Nl=new Set;function Op(n){Nl.has(n)||(Nl.add(n),n.addEventListener("copy",()=>{}),n.addEventListener("cut",()=>{}))}const Xl=["pre-wrap","normal","pre-line","break-spaces"];let fi=!1;function Fl(){fi=!1}class yp{constructor(e){this.lineWrapping=e,this.doc=V.empty,this.heightSamples={},this.lineHeight=14,this.charWidth=7,this.textHeight=14,this.lineLength=30}heightForGap(e,t){let i=this.doc.lineAt(t).number-this.doc.lineAt(e).number+1;return this.lineWrapping&&(i+=Math.max(0,Math.ceil((t-e-i*this.lineLength*.5)/this.lineLength))),this.lineHeight*i}heightForLine(e){return this.lineWrapping?(1+Math.max(0,Math.ceil((e-this.lineLength)/Math.max(1,this.lineLength-5))))*this.lineHeight:this.lineHeight}setDoc(e){return this.doc=e,this}mustRefreshForWrapping(e){return Xl.indexOf(e)>-1!=this.lineWrapping}mustRefreshForHeights(e){let t=!1;for(let i=0;i-1,a=Math.round(t)!=Math.round(this.lineHeight)||this.lineWrapping!=l;if(this.lineWrapping=l,this.lineHeight=t,this.charWidth=i,this.textHeight=s,this.lineLength=r,a){this.heightSamples={};for(let h=0;h0}set outdated(e){this.flags=(e?2:0)|this.flags&-3}setHeight(e){this.height!=e&&(Math.abs(this.height-e)>Hn&&(fi=!0),this.height=e)}replace(e,t,i){return we.of(i)}decomposeLeft(e,t){t.push(this)}decomposeRight(e,t){t.push(this)}applyChanges(e,t,i,s){let r=this,o=i.doc;for(let l=s.length-1;l>=0;l--){let{fromA:a,toA:h,fromB:c,toB:f}=s[l],u=r.lineAt(a,G.ByPosNoHeight,i.setDoc(t),0,0),d=u.to>=h?u:r.lineAt(h,G.ByPosNoHeight,i,0,0);for(f+=d.to-h,h=d.to;l>0&&u.from<=s[l-1].toA;)a=s[l-1].fromA,c=s[l-1].fromB,l--,ar*2){let l=e[t-1];l.break?e.splice(--t,1,l.left,null,l.right):e.splice(--t,1,l.left,l.right),i+=1+l.break,s-=l.size}else if(r>s*2){let l=e[i];l.break?e.splice(i,1,l.left,null,l.right):e.splice(i,1,l.left,l.right),i+=2+l.break,r-=l.size}else break;else if(s=r&&o(this.blockAt(0,i,s,r))}updateHeight(e,t=0,i=!1,s){return s&&s.from<=t&&s.more&&this.setHeight(s.heights[s.index++]),this.outdated=!1,this}toString(){return`block(${this.length})`}}class De extends Dc{constructor(e,t){super(e,t,null),this.collapsed=0,this.widgetHeight=0,this.breaks=0}blockAt(e,t,i,s){return new Ke(s,this.length,i,this.height,this.breaks)}replace(e,t,i){let s=i[0];return i.length==1&&(s instanceof De||s instanceof fe&&s.flags&4)&&Math.abs(this.length-s.length)<10?(s instanceof fe?s=new De(s.length,this.height):s.height=this.height,this.outdated||(s.outdated=!1),s):we.of(i)}updateHeight(e,t=0,i=!1,s){return s&&s.from<=t&&s.more?this.setHeight(s.heights[s.index++]):(i||this.outdated)&&this.setHeight(Math.max(this.widgetHeight,e.heightForLine(this.length-this.collapsed))+this.breaks*e.lineHeight),this.outdated=!1,this}toString(){return`line(${this.length}${this.collapsed?-this.collapsed:""}${this.widgetHeight?":"+this.widgetHeight:""})`}}class fe extends we{constructor(e){super(e,0)}heightMetrics(e,t){let i=e.doc.lineAt(t).number,s=e.doc.lineAt(t+this.length).number,r=s-i+1,o,l=0;if(e.lineWrapping){let a=Math.min(this.height,e.lineHeight*r);o=a/r,this.length>r+1&&(l=(this.height-a)/(this.length-r-1))}else o=this.height/r;return{firstLine:i,lastLine:s,perLine:o,perChar:l}}blockAt(e,t,i,s){let{firstLine:r,lastLine:o,perLine:l,perChar:a}=this.heightMetrics(t,s);if(t.lineWrapping){let h=s+(e0){let r=i[i.length-1];r instanceof fe?i[i.length-1]=new fe(r.length+s):i.push(null,new fe(s-1))}if(e>0){let r=i[0];r instanceof fe?i[0]=new fe(e+r.length):i.unshift(new fe(e-1),null)}return we.of(i)}decomposeLeft(e,t){t.push(new fe(e-1),null)}decomposeRight(e,t){t.push(null,new fe(this.length-e-1))}updateHeight(e,t=0,i=!1,s){let r=t+this.length;if(s&&s.from<=t+this.length&&s.more){let o=[],l=Math.max(t,s.from),a=-1;for(s.from>t&&o.push(new fe(s.from-t-1).updateHeight(e,t));l<=r&&s.more;){let c=e.doc.lineAt(l).length;o.length&&o.push(null);let f=s.heights[s.index++];a==-1?a=f:Math.abs(f-a)>=Hn&&(a=-2);let u=new De(c,f);u.outdated=!1,o.push(u),l+=c+1}l<=r&&o.push(null,new fe(r-l).updateHeight(e,l));let h=we.of(o);return(a<0||Math.abs(h.height-this.height)>=Hn||Math.abs(a-this.heightMetrics(e,t).perLine)>=Hn)&&(fi=!0),ls(this,h)}else(i||this.outdated)&&(this.setHeight(e.heightForGap(t,t+this.length)),this.outdated=!1);return this}toString(){return`gap(${this.length})`}}class Sp extends we{constructor(e,t,i){super(e.length+t+i.length,e.height+i.height,t|(e.outdated||i.outdated?2:0)),this.left=e,this.right=i,this.size=e.size+i.size}get break(){return this.flags&1}blockAt(e,t,i,s){let r=i+this.left.height;return el))return h;let c=t==G.ByPosNoHeight?G.ByPosNoHeight:G.ByPos;return a?h.join(this.right.lineAt(l,c,i,o,l)):this.left.lineAt(l,c,i,s,r).join(h)}forEachLine(e,t,i,s,r,o){let l=s+this.left.height,a=r+this.left.length+this.break;if(this.break)e=a&&this.right.forEachLine(e,t,i,l,a,o);else{let h=this.lineAt(a,G.ByPos,i,s,r);e=e&&h.from<=t&&o(h),t>h.to&&this.right.forEachLine(h.to+1,t,i,l,a,o)}}replace(e,t,i){let s=this.left.length+this.break;if(tthis.left.length)return this.balanced(this.left,this.right.replace(e-s,t-s,i));let r=[];e>0&&this.decomposeLeft(e,r);let o=r.length;for(let l of i)r.push(l);if(e>0&&_l(r,o-1),t=i&&t.push(null)),e>i&&this.right.decomposeLeft(e-i,t)}decomposeRight(e,t){let i=this.left.length,s=i+this.break;if(e>=s)return this.right.decomposeRight(e-s,t);e2*t.size||t.size>2*e.size?we.of(this.break?[e,null,t]:[e,t]):(this.left=ls(this.left,e),this.right=ls(this.right,t),this.setHeight(e.height+t.height),this.outdated=e.outdated||t.outdated,this.size=e.size+t.size,this.length=e.length+this.break+t.length,this)}updateHeight(e,t=0,i=!1,s){let{left:r,right:o}=this,l=t+r.length+this.break,a=null;return s&&s.from<=t+r.length&&s.more?a=r=r.updateHeight(e,t,i,s):r.updateHeight(e,t,i),s&&s.from<=l+o.length&&s.more?a=o=o.updateHeight(e,l,i,s):o.updateHeight(e,l,i),a?this.balanced(r,o):(this.height=this.left.height+this.right.height,this.outdated=!1,this)}toString(){return this.left+(this.break?" ":"-")+this.right}}function _l(n,e){let t,i;n[e]==null&&(t=n[e-1])instanceof fe&&(i=n[e+1])instanceof fe&&n.splice(e-1,3,new fe(t.length+1+i.length))}const xp=5;class Ro{constructor(e,t){this.pos=e,this.oracle=t,this.nodes=[],this.lineStart=-1,this.lineEnd=-1,this.covering=null,this.writtenTo=e}get isCovered(){return this.covering&&this.nodes[this.nodes.length-1]==this.covering}span(e,t){if(this.lineStart>-1){let i=Math.min(t,this.lineEnd),s=this.nodes[this.nodes.length-1];s instanceof De?s.length+=i-this.pos:(i>this.pos||!this.isCovered)&&this.nodes.push(new De(i-this.pos,-1)),this.writtenTo=i,t>i&&(this.nodes.push(null),this.writtenTo++,this.lineStart=-1)}this.pos=t}point(e,t,i){if(e=xp)&&this.addLineDeco(s,r,o)}else t>e&&this.span(e,t);this.lineEnd>-1&&this.lineEnd-1)return;let{from:e,to:t}=this.oracle.doc.lineAt(this.pos);this.lineStart=e,this.lineEnd=t,this.writtenToe&&this.nodes.push(new De(this.pos-e,-1)),this.writtenTo=this.pos}blankContent(e,t){let i=new fe(t-e);return this.oracle.doc.lineAt(e).to==t&&(i.flags|=4),i}ensureLine(){this.enterLine();let e=this.nodes.length?this.nodes[this.nodes.length-1]:null;if(e instanceof De)return e;let t=new De(0,-1);return this.nodes.push(t),t}addBlock(e){this.enterLine();let t=e.deco;t&&t.startSide>0&&!this.isCovered&&this.ensureLine(),this.nodes.push(e),this.writtenTo=this.pos=this.pos+e.length,t&&t.endSide>0&&(this.covering=e)}addLineDeco(e,t,i){let s=this.ensureLine();s.length+=i,s.collapsed+=i,s.widgetHeight=Math.max(s.widgetHeight,e),s.breaks+=t,this.writtenTo=this.pos=this.pos+i}finish(e){let t=this.nodes.length==0?null:this.nodes[this.nodes.length-1];this.lineStart>-1&&!(t instanceof De)&&!this.isCovered?this.nodes.push(new De(0,-1)):(this.writtenToc.clientHeight||c.scrollWidth>c.clientWidth)&&f.overflow!="visible"){let u=c.getBoundingClientRect();r=Math.max(r,u.left),o=Math.min(o,u.right),l=Math.max(l,u.top),a=Math.min(h==n.parentNode?s.innerHeight:a,u.bottom)}h=f.position=="absolute"||f.position=="fixed"?c.offsetParent:c.parentNode}else if(h.nodeType==11)h=h.host;else break;return{left:r-t.left,right:Math.max(r,o)-t.left,top:l-(t.top+e),bottom:Math.max(l,a)-(t.top+e)}}function Tp(n){let e=n.getBoundingClientRect(),t=n.ownerDocument.defaultView||window;return e.left0&&e.top0}function Cp(n,e){let t=n.getBoundingClientRect();return{left:0,right:t.right-t.left,top:e,bottom:t.bottom-(t.top+e)}}class Us{constructor(e,t,i,s){this.from=e,this.to=t,this.size=i,this.displaySize=s}static same(e,t){if(e.length!=t.length)return!1;for(let i=0;itypeof i!="function"&&i.class=="cm-lineWrapping");this.heightOracle=new yp(t),this.stateDeco=e.facet(Ii).filter(i=>typeof i!="function"),this.heightMap=we.empty().applyChanges(this.stateDeco,V.empty,this.heightOracle.setDoc(e.doc),[new Le(0,0,0,e.doc.length)]);for(let i=0;i<2&&(this.viewport=this.getViewport(0,null),!!this.updateForViewport());i++);this.updateViewportLines(),this.lineGaps=this.ensureLineGaps([]),this.lineGapDeco=R.set(this.lineGaps.map(i=>i.draw(this,!1))),this.computeVisibleRanges()}updateForViewport(){let e=[this.viewport],{main:t}=this.state.selection;for(let i=0;i<=1;i++){let s=i?t.head:t.anchor;if(!e.some(({from:r,to:o})=>s>=r&&s<=o)){let{from:r,to:o}=this.lineBlockAt(s);e.push(new vn(r,o))}}return this.viewports=e.sort((i,s)=>i.from-s.from),this.updateScaler()}updateScaler(){let e=this.scaler;return this.scaler=this.heightMap.height<=7e6?Hl:new Do(this.heightOracle,this.heightMap,this.viewports),e.eq(this.scaler)?0:2}updateViewportLines(){this.viewportLines=[],this.heightMap.forEachLine(this.viewport.from,this.viewport.to,this.heightOracle.setDoc(this.state.doc),0,0,e=>{this.viewportLines.push(Pi(e,this.scaler))})}update(e,t=null){this.state=e.state;let i=this.stateDeco;this.stateDeco=this.state.facet(Ii).filter(c=>typeof c!="function");let s=e.changedRanges,r=Le.extendWithRanges(s,kp(i,this.stateDeco,e?e.changes:se.empty(this.state.doc.length))),o=this.heightMap.height,l=this.scrolledToBottom?null:this.scrollAnchorAt(this.scrollTop);Fl(),this.heightMap=this.heightMap.applyChanges(this.stateDeco,e.startState.doc,this.heightOracle.setDoc(this.state.doc),r),(this.heightMap.height!=o||fi)&&(e.flags|=2),l?(this.scrollAnchorPos=e.changes.mapPos(l.from,-1),this.scrollAnchorHeight=l.top):(this.scrollAnchorPos=-1,this.scrollAnchorHeight=o);let a=r.length?this.mapViewport(this.viewport,e.changes):this.viewport;(t&&(t.range.heada.to)||!this.viewportIsAppropriate(a))&&(a=this.getViewport(0,t));let h=a.from!=this.viewport.from||a.to!=this.viewport.to;this.viewport=a,e.flags|=this.updateForViewport(),(h||!e.changes.empty||e.flags&2)&&this.updateViewportLines(),(this.lineGaps.length||this.viewport.to-this.viewport.from>4e3)&&this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps,e.changes))),e.flags|=this.computeVisibleRanges(e.changes),t&&(this.scrollTarget=t),!this.mustEnforceCursorAssoc&&e.selectionSet&&e.view.lineWrapping&&e.state.selection.main.empty&&e.state.selection.main.assoc&&!e.state.facet(fc)&&(this.mustEnforceCursorAssoc=!0)}measure(e){let t=e.contentDOM,i=window.getComputedStyle(t),s=this.heightOracle,r=i.whiteSpace;this.defaultTextDirection=i.direction=="rtl"?Z.RTL:Z.LTR;let o=this.heightOracle.mustRefreshForWrapping(r),l=t.getBoundingClientRect(),a=o||this.mustMeasureContent||this.contentDOMHeight!=l.height;this.contentDOMHeight=l.height,this.mustMeasureContent=!1;let h=0,c=0;if(l.width&&l.height){let{scaleX:w,scaleY:k}=Ih(t,l);(w>.005&&Math.abs(this.scaleX-w)>.005||k>.005&&Math.abs(this.scaleY-k)>.005)&&(this.scaleX=w,this.scaleY=k,h|=16,o=a=!0)}let f=(parseInt(i.paddingTop)||0)*this.scaleY,u=(parseInt(i.paddingBottom)||0)*this.scaleY;(this.paddingTop!=f||this.paddingBottom!=u)&&(this.paddingTop=f,this.paddingBottom=u,h|=18),this.editorWidth!=e.scrollDOM.clientWidth&&(s.lineWrapping&&(a=!0),this.editorWidth=e.scrollDOM.clientWidth,h|=16);let d=e.scrollDOM.scrollTop*this.scaleY;this.scrollTop!=d&&(this.scrollAnchorHeight=-1,this.scrollTop=d),this.scrolledToBottom=Xh(e.scrollDOM);let p=(this.printing?Cp:vp)(t,this.paddingTop),m=p.top-this.pixelViewport.top,g=p.bottom-this.pixelViewport.bottom;this.pixelViewport=p;let y=this.pixelViewport.bottom>this.pixelViewport.top&&this.pixelViewport.right>this.pixelViewport.left;if(y!=this.inView&&(this.inView=y,y&&(a=!0)),!this.inView&&!this.scrollTarget&&!Tp(e.dom))return 0;let S=l.width;if((this.contentDOMWidth!=S||this.editorHeight!=e.scrollDOM.clientHeight)&&(this.contentDOMWidth=l.width,this.editorHeight=e.scrollDOM.clientHeight,h|=16),a){let w=e.docView.measureVisibleLineHeights(this.viewport);if(s.mustRefreshForHeights(w)&&(o=!0),o||s.lineWrapping&&Math.abs(S-this.contentDOMWidth)>s.charWidth){let{lineHeight:k,charWidth:v,textHeight:T}=e.docView.measureTextSize();o=k>0&&s.refresh(r,k,v,T,Math.max(5,S/v),w),o&&(e.docView.minWidth=0,h|=16)}m>0&&g>0?c=Math.max(m,g):m<0&&g<0&&(c=Math.min(m,g)),Fl();for(let k of this.viewports){let v=k.from==this.viewport.from?w:e.docView.measureVisibleLineHeights(k);this.heightMap=(o?we.empty().applyChanges(this.stateDeco,V.empty,this.heightOracle,[new Le(0,0,0,e.state.doc.length)]):this.heightMap).updateHeight(s,0,o,new bp(k.from,v))}fi&&(h|=2)}let x=!this.viewportIsAppropriate(this.viewport,c)||this.scrollTarget&&(this.scrollTarget.range.headthis.viewport.to);return x&&(h&2&&(h|=this.updateScaler()),this.viewport=this.getViewport(c,this.scrollTarget),h|=this.updateForViewport()),(h&2||x)&&this.updateViewportLines(),(this.lineGaps.length||this.viewport.to-this.viewport.from>4e3)&&this.updateLineGaps(this.ensureLineGaps(o?[]:this.lineGaps,e)),h|=this.computeVisibleRanges(),this.mustEnforceCursorAssoc&&(this.mustEnforceCursorAssoc=!1,e.docView.enforceCursorAssoc()),h}get visibleTop(){return this.scaler.fromDOM(this.pixelViewport.top)}get visibleBottom(){return this.scaler.fromDOM(this.pixelViewport.bottom)}getViewport(e,t){let i=.5-Math.max(-.5,Math.min(.5,e/1e3/2)),s=this.heightMap,r=this.heightOracle,{visibleTop:o,visibleBottom:l}=this,a=new vn(s.lineAt(o-i*1e3,G.ByHeight,r,0,0).from,s.lineAt(l+(1-i)*1e3,G.ByHeight,r,0,0).to);if(t){let{head:h}=t.range;if(ha.to){let c=Math.min(this.editorHeight,this.pixelViewport.bottom-this.pixelViewport.top),f=s.lineAt(h,G.ByPos,r,0,0),u;t.y=="center"?u=(f.top+f.bottom)/2-c/2:t.y=="start"||t.y=="nearest"&&h=l+Math.max(10,Math.min(i,250)))&&s>o-2*1e3&&r>1,o=s<<1;if(this.defaultTextDirection!=Z.LTR&&!i)return[];let l=[],a=(c,f,u,d)=>{if(f-cc&&yy.from>=u.from&&y.to<=u.to&&Math.abs(y.from-c)y.fromS));if(!g){if(fx.from<=f&&x.to>=f)){let x=t.moveToLineBoundary(b.cursor(f),!1,!0).head;x>c&&(f=x)}let y=this.gapSize(u,c,f,d),S=i||y<2e6?y:2e6;g=new Us(c,f,y,S)}l.push(g)},h=c=>{if(c.length2e6)for(let v of e)v.from>=c.from&&v.fromc.from&&a(c.from,d,c,f),pt.draw(this,this.heightOracle.lineWrapping))))}computeVisibleRanges(e){let t=this.stateDeco;this.lineGaps.length&&(t=t.concat(this.lineGapDeco));let i=[];N.spans(t,this.viewport.from,this.viewport.to,{span(r,o){i.push({from:r,to:o})},point(){}},20);let s=0;if(i.length!=this.visibleRanges.length)s=12;else for(let r=0;r=this.viewport.from&&e<=this.viewport.to&&this.viewportLines.find(t=>t.from<=e&&t.to>=e)||Pi(this.heightMap.lineAt(e,G.ByPos,this.heightOracle,0,0),this.scaler)}lineBlockAtHeight(e){return e>=this.viewportLines[0].top&&e<=this.viewportLines[this.viewportLines.length-1].bottom&&this.viewportLines.find(t=>t.top<=e&&t.bottom>=e)||Pi(this.heightMap.lineAt(this.scaler.fromDOM(e),G.ByHeight,this.heightOracle,0,0),this.scaler)}scrollAnchorAt(e){let t=this.lineBlockAtHeight(e+8);return t.from>=this.viewport.from||this.viewportLines[0].top-e>200?t:this.viewportLines[0]}elementAtHeight(e){return Pi(this.heightMap.blockAt(this.scaler.fromDOM(e),this.heightOracle,0,0),this.scaler)}get docHeight(){return this.scaler.toDOM(this.heightMap.height)}get contentHeight(){return this.docHeight+this.paddingTop+this.paddingBottom}}class vn{constructor(e,t){this.from=e,this.to=t}}function Qp(n,e,t){let i=[],s=n,r=0;return N.spans(t,n,e,{span(){},point(o,l){o>s&&(i.push({from:s,to:o}),r+=o-s),s=l}},20),s=1)return e[e.length-1].to;let i=Math.floor(n*t);for(let s=0;;s++){let{from:r,to:o}=e[s],l=o-r;if(i<=l)return r+i;i-=l}}function Cn(n,e){let t=0;for(let{from:i,to:s}of n.ranges){if(e<=s){t+=e-i;break}t+=s-i}return t/n.total}function Ap(n,e){for(let t of n)if(e(t))return t}const Hl={toDOM(n){return n},fromDOM(n){return n},scale:1,eq(n){return n==this}};class Do{constructor(e,t,i){let s=0,r=0,o=0;this.viewports=i.map(({from:l,to:a})=>{let h=t.lineAt(l,G.ByPos,e,0,0).top,c=t.lineAt(a,G.ByPos,e,0,0).bottom;return s+=c-h,{from:l,to:a,top:h,bottom:c,domTop:0,domBottom:0}}),this.scale=(7e6-s)/(t.height-s);for(let l of this.viewports)l.domTop=o+(l.top-r)*this.scale,o=l.domBottom=l.domTop+(l.bottom-l.top),r=l.bottom}toDOM(e){for(let t=0,i=0,s=0;;t++){let r=tt.from==e.viewports[i].from&&t.to==e.viewports[i].to):!1}}function Pi(n,e){if(e.scale==1)return n;let t=e.toDOM(n.top),i=e.toDOM(n.bottom);return new Ke(n.from,n.length,t,i-t,Array.isArray(n._content)?n._content.map(s=>Pi(s,e)):n._content)}const Pn=A.define({combine:n=>n.join(" ")}),Kr=A.define({combine:n=>n.indexOf(!0)>-1}),Jr=Tt.newName(),Ec=Tt.newName(),qc=Tt.newName(),$c={"&light":"."+Ec,"&dark":"."+qc};function eo(n,e,t){return new Tt(e,{finish(i){return/&/.test(i)?i.replace(/&\w*/,s=>{if(s=="&")return n;if(!t||!t[s])throw new RangeError(`Unsupported selector: ${s}`);return t[s]}):n+" "+i}})}const Mp=eo("."+Jr,{"&":{position:"relative !important",boxSizing:"border-box","&.cm-focused":{outline:"1px dotted #212121"},display:"flex !important",flexDirection:"column"},".cm-scroller":{display:"flex !important",alignItems:"flex-start !important",fontFamily:"monospace",lineHeight:1.4,height:"100%",overflowX:"auto",position:"relative",zIndex:0,overflowAnchor:"none"},".cm-content":{margin:0,flexGrow:2,flexShrink:0,display:"block",whiteSpace:"pre",wordWrap:"normal",boxSizing:"border-box",minHeight:"100%",padding:"4px 0",outline:"none","&[contenteditable=true]":{WebkitUserModify:"read-write-plaintext-only"}},".cm-lineWrapping":{whiteSpace_fallback:"pre-wrap",whiteSpace:"break-spaces",wordBreak:"break-word",overflowWrap:"anywhere",flexShrink:1},"&light .cm-content":{caretColor:"black"},"&dark .cm-content":{caretColor:"white"},".cm-line":{display:"block",padding:"0 2px 0 6px"},".cm-layer":{position:"absolute",left:0,top:0,contain:"size style","& > *":{position:"absolute"}},"&light .cm-selectionBackground":{background:"#d9d9d9"},"&dark .cm-selectionBackground":{background:"#222"},"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground":{background:"#d7d4f0"},"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground":{background:"#233"},".cm-cursorLayer":{pointerEvents:"none"},"&.cm-focused > .cm-scroller > .cm-cursorLayer":{animation:"steps(1) cm-blink 1.2s infinite"},"@keyframes cm-blink":{"0%":{},"50%":{opacity:0},"100%":{}},"@keyframes cm-blink2":{"0%":{},"50%":{opacity:0},"100%":{}},".cm-cursor, .cm-dropCursor":{borderLeft:"1.2px solid black",marginLeft:"-0.6px",pointerEvents:"none"},".cm-cursor":{display:"none"},"&dark .cm-cursor":{borderLeftColor:"#ddd"},".cm-dropCursor":{position:"absolute"},"&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor":{display:"block"},".cm-iso":{unicodeBidi:"isolate"},".cm-announced":{position:"fixed",top:"-10000px"},"@media print":{".cm-announced":{display:"none"}},"&light .cm-activeLine":{backgroundColor:"#cceeff44"},"&dark .cm-activeLine":{backgroundColor:"#99eeff33"},"&light .cm-specialChar":{color:"red"},"&dark .cm-specialChar":{color:"#f78"},".cm-gutters":{flexShrink:0,display:"flex",height:"100%",boxSizing:"border-box",zIndex:200},".cm-gutters-before":{insetInlineStart:0},".cm-gutters-after":{insetInlineEnd:0},"&light .cm-gutters":{backgroundColor:"#f5f5f5",color:"#6c6c6c",border:"0px solid #ddd","&.cm-gutters-before":{borderRightWidth:"1px"},"&.cm-gutters-after":{borderLeftWidth:"1px"}},"&dark .cm-gutters":{backgroundColor:"#333338",color:"#ccc"},".cm-gutter":{display:"flex !important",flexDirection:"column",flexShrink:0,boxSizing:"border-box",minHeight:"100%",overflow:"hidden"},".cm-gutterElement":{boxSizing:"border-box"},".cm-lineNumbers .cm-gutterElement":{padding:"0 3px 0 5px",minWidth:"20px",textAlign:"right",whiteSpace:"nowrap"},"&light .cm-activeLineGutter":{backgroundColor:"#e2f2ff"},"&dark .cm-activeLineGutter":{backgroundColor:"#222227"},".cm-panels":{boxSizing:"border-box",position:"sticky",left:0,right:0,zIndex:300},"&light .cm-panels":{backgroundColor:"#f5f5f5",color:"black"},"&light .cm-panels-top":{borderBottom:"1px solid #ddd"},"&light .cm-panels-bottom":{borderTop:"1px solid #ddd"},"&dark .cm-panels":{backgroundColor:"#333338",color:"white"},".cm-dialog":{padding:"2px 19px 4px 6px",position:"relative","& label":{fontSize:"80%"}},".cm-dialog-close":{position:"absolute",top:"3px",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",fontSize:"14px",padding:"0"},".cm-tab":{display:"inline-block",overflow:"hidden",verticalAlign:"bottom"},".cm-widgetBuffer":{verticalAlign:"text-top",height:"1em",width:0,display:"inline"},".cm-placeholder":{color:"#888",display:"inline-block",verticalAlign:"top",userSelect:"none"},".cm-highlightSpace":{backgroundImage:"radial-gradient(circle at 50% 55%, #aaa 20%, transparent 5%)",backgroundPosition:"center"},".cm-highlightTab":{backgroundImage:`url('data:image/svg+xml,')`,backgroundSize:"auto 100%",backgroundPosition:"right 90%",backgroundRepeat:"no-repeat"},".cm-trailingSpace":{backgroundColor:"#ff332255"},".cm-button":{verticalAlign:"middle",color:"inherit",fontSize:"70%",padding:".2em 1em",borderRadius:"1px"},"&light .cm-button":{backgroundImage:"linear-gradient(#eff1f5, #d9d9df)",border:"1px solid #888","&:active":{backgroundImage:"linear-gradient(#b4b4b4, #d0d3d6)"}},"&dark .cm-button":{backgroundImage:"linear-gradient(#393939, #111)",border:"1px solid #888","&:active":{backgroundImage:"linear-gradient(#111, #333)"}},".cm-textfield":{verticalAlign:"middle",color:"inherit",fontSize:"70%",border:"1px solid silver",padding:".2em .5em"},"&light .cm-textfield":{backgroundColor:"white"},"&dark .cm-textfield":{border:"1px solid #555",backgroundColor:"inherit"}},$c),Rp={childList:!0,characterData:!0,subtree:!0,attributes:!0,characterDataOldValue:!0},Hs=Q.ie&&Q.ie_version<=11;class Dp{constructor(e){this.view=e,this.active=!1,this.editContext=null,this.selectionRange=new pd,this.selectionChanged=!1,this.delayedFlush=-1,this.resizeTimeout=-1,this.queue=[],this.delayedAndroidKey=null,this.flushingAndroidKey=-1,this.lastChange=0,this.scrollTargets=[],this.intersection=null,this.resizeScroll=null,this.intersecting=!1,this.gapIntersection=null,this.gaps=[],this.printQuery=null,this.parentCheck=-1,this.dom=e.contentDOM,this.observer=new MutationObserver(t=>{for(let i of t)this.queue.push(i);(Q.ie&&Q.ie_version<=11||Q.ios&&e.composing)&&t.some(i=>i.type=="childList"&&i.removedNodes.length||i.type=="characterData"&&i.oldValue.length>i.target.nodeValue.length)?this.flushSoon():this.flush()}),window.EditContext&&Q.android&&e.constructor.EDIT_CONTEXT!==!1&&!(Q.chrome&&Q.chrome_version<126)&&(this.editContext=new qp(e),e.state.facet(dt)&&(e.contentDOM.editContext=this.editContext.editContext)),Hs&&(this.onCharData=t=>{this.queue.push({target:t.target,type:"characterData",oldValue:t.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this),this.onResize=this.onResize.bind(this),this.onPrint=this.onPrint.bind(this),this.onScroll=this.onScroll.bind(this),window.matchMedia&&(this.printQuery=window.matchMedia("print")),typeof ResizeObserver=="function"&&(this.resizeScroll=new ResizeObserver(()=>{var t;((t=this.view.docView)===null||t===void 0?void 0:t.lastUpdate){this.parentCheck<0&&(this.parentCheck=setTimeout(this.listenForScroll.bind(this),1e3)),t.length>0&&t[t.length-1].intersectionRatio>0!=this.intersecting&&(this.intersecting=!this.intersecting,this.intersecting!=this.view.inView&&this.onScrollChanged(document.createEvent("Event")))},{threshold:[0,.001]}),this.intersection.observe(this.dom),this.gapIntersection=new IntersectionObserver(t=>{t.length>0&&t[t.length-1].intersectionRatio>0&&this.onScrollChanged(document.createEvent("Event"))},{})),this.listenForScroll(),this.readSelectionRange()}onScrollChanged(e){this.view.inputState.runHandlers("scroll",e),this.intersecting&&this.view.measure()}onScroll(e){this.intersecting&&this.flush(!1),this.editContext&&this.view.requestMeasure(this.editContext.measureReq),this.onScrollChanged(e)}onResize(){this.resizeTimeout<0&&(this.resizeTimeout=setTimeout(()=>{this.resizeTimeout=-1,this.view.requestMeasure()},50))}onPrint(e){(e.type=="change"||!e.type)&&!e.matches||(this.view.viewState.printing=!0,this.view.measure(),setTimeout(()=>{this.view.viewState.printing=!1,this.view.requestMeasure()},500))}updateGaps(e){if(this.gapIntersection&&(e.length!=this.gaps.length||this.gaps.some((t,i)=>t!=e[i]))){this.gapIntersection.disconnect();for(let t of e)this.gapIntersection.observe(t);this.gaps=e}}onSelectionChange(e){let t=this.selectionChanged;if(!this.readSelectionRange()||this.delayedAndroidKey)return;let{view:i}=this,s=this.selectionRange;if(i.state.facet(dt)?i.root.activeElement!=this.dom:!_n(this.dom,s))return;let r=s.anchorNode&&i.docView.nearest(s.anchorNode);if(r&&r.ignoreEvent(e)){t||(this.selectionChanged=!1);return}(Q.ie&&Q.ie_version<=11||Q.android&&Q.chrome)&&!i.state.selection.main.empty&&s.focusNode&&Ri(s.focusNode,s.focusOffset,s.anchorNode,s.anchorOffset)?this.flushSoon():this.flush(!1)}readSelectionRange(){let{view:e}=this,t=zi(e.root);if(!t)return!1;let i=Q.safari&&e.root.nodeType==11&&e.root.activeElement==this.dom&&Ep(this.view,t)||t;if(!i||this.selectionRange.eq(i))return!1;let s=_n(this.dom,i);return s&&!this.selectionChanged&&e.inputState.lastFocusTime>Date.now()-200&&e.inputState.lastTouchTime{let r=this.delayedAndroidKey;r&&(this.clearDelayedAndroidKey(),this.view.inputState.lastKeyCode=r.keyCode,this.view.inputState.lastKeyTime=Date.now(),!this.flush()&&r.force&&ii(this.dom,r.key,r.keyCode))};this.flushingAndroidKey=this.view.win.requestAnimationFrame(s)}(!this.delayedAndroidKey||e=="Enter")&&(this.delayedAndroidKey={key:e,keyCode:t,force:this.lastChange{this.delayedFlush=-1,this.flush()}))}forceFlush(){this.delayedFlush>=0&&(this.view.win.cancelAnimationFrame(this.delayedFlush),this.delayedFlush=-1),this.flush()}pendingRecords(){for(let e of this.observer.takeRecords())this.queue.push(e);return this.queue}processRecords(){let e=this.pendingRecords();e.length&&(this.queue=[]);let t=-1,i=-1,s=!1;for(let r of e){let o=this.readMutation(r);o&&(o.typeOver&&(s=!0),t==-1?{from:t,to:i}=o:(t=Math.min(o.from,t),i=Math.max(o.to,i)))}return{from:t,to:i,typeOver:s}}readChange(){let{from:e,to:t,typeOver:i}=this.processRecords(),s=this.selectionChanged&&_n(this.dom,this.selectionRange);if(e<0&&!s)return null;e>-1&&(this.lastChange=Date.now()),this.view.inputState.lastFocusTime=0,this.selectionChanged=!1;let r=new Yd(this.view,e,t,i);return this.view.docView.domChanged={newSel:r.newSel?r.newSel.main:null},r}flush(e=!0){if(this.delayedFlush>=0||this.delayedAndroidKey)return!1;e&&this.readSelectionRange();let t=this.readChange();if(!t)return this.view.requestMeasure(),!1;let i=this.view.state,s=kc(this.view,t);return this.view.state==i&&(t.domChanged||t.newSel&&!t.newSel.main.eq(this.view.state.selection.main))&&this.view.update([]),s}readMutation(e){let t=this.view.docView.nearest(e.target);if(!t||t.ignoreMutation(e))return null;if(t.markDirty(e.type=="attributes"),e.type=="attributes"&&(t.flags|=4),e.type=="childList"){let i=jl(t,e.previousSibling||e.target.previousSibling,-1),s=jl(t,e.nextSibling||e.target.nextSibling,1);return{from:i?t.posAfter(i):t.posAtStart,to:s?t.posBefore(s):t.posAtEnd,typeOver:!1}}else return e.type=="characterData"?{from:t.posAtStart,to:t.posAtEnd,typeOver:e.target.nodeValue==e.oldValue}:null}setWindow(e){e!=this.win&&(this.removeWindowListeners(this.win),this.win=e,this.addWindowListeners(this.win))}addWindowListeners(e){e.addEventListener("resize",this.onResize),this.printQuery?this.printQuery.addEventListener?this.printQuery.addEventListener("change",this.onPrint):this.printQuery.addListener(this.onPrint):e.addEventListener("beforeprint",this.onPrint),e.addEventListener("scroll",this.onScroll),e.document.addEventListener("selectionchange",this.onSelectionChange)}removeWindowListeners(e){e.removeEventListener("scroll",this.onScroll),e.removeEventListener("resize",this.onResize),this.printQuery?this.printQuery.removeEventListener?this.printQuery.removeEventListener("change",this.onPrint):this.printQuery.removeListener(this.onPrint):e.removeEventListener("beforeprint",this.onPrint),e.document.removeEventListener("selectionchange",this.onSelectionChange)}update(e){this.editContext&&(this.editContext.update(e),e.startState.facet(dt)!=e.state.facet(dt)&&(e.view.contentDOM.editContext=e.state.facet(dt)?this.editContext.editContext:null))}destroy(){var e,t,i;this.stop(),(e=this.intersection)===null||e===void 0||e.disconnect(),(t=this.gapIntersection)===null||t===void 0||t.disconnect(),(i=this.resizeScroll)===null||i===void 0||i.disconnect();for(let s of this.scrollTargets)s.removeEventListener("scroll",this.onScroll);this.removeWindowListeners(this.win),clearTimeout(this.parentCheck),clearTimeout(this.resizeTimeout),this.win.cancelAnimationFrame(this.delayedFlush),this.win.cancelAnimationFrame(this.flushingAndroidKey),this.editContext&&(this.view.contentDOM.editContext=null,this.editContext.destroy())}}function jl(n,e,t){for(;e;){let i=_.get(e);if(i&&i.parent==n)return i;let s=e.parentNode;e=s!=n.dom?s:t>0?e.nextSibling:e.previousSibling}return null}function Gl(n,e){let t=e.startContainer,i=e.startOffset,s=e.endContainer,r=e.endOffset,o=n.docView.domAtPos(n.state.selection.main.anchor);return Ri(o.node,o.offset,s,r)&&([t,i,s,r]=[s,r,t,i]),{anchorNode:t,anchorOffset:i,focusNode:s,focusOffset:r}}function Ep(n,e){if(e.getComposedRanges){let s=e.getComposedRanges(n.root)[0];if(s)return Gl(n,s)}let t=null;function i(s){s.preventDefault(),s.stopImmediatePropagation(),t=s.getTargetRanges()[0]}return n.contentDOM.addEventListener("beforeinput",i,!0),n.dom.ownerDocument.execCommand("indent"),n.contentDOM.removeEventListener("beforeinput",i,!0),t?Gl(n,t):null}class qp{constructor(e){this.from=0,this.to=0,this.pendingContextChange=null,this.handlers=Object.create(null),this.composing=null,this.resetRange(e.state);let t=this.editContext=new window.EditContext({text:e.state.doc.sliceString(this.from,this.to),selectionStart:this.toContextPos(Math.max(this.from,Math.min(this.to,e.state.selection.main.anchor))),selectionEnd:this.toContextPos(e.state.selection.main.head)});this.handlers.textupdate=i=>{let s=e.state.selection.main,{anchor:r,head:o}=s,l=this.toEditorPos(i.updateRangeStart),a=this.toEditorPos(i.updateRangeEnd);e.inputState.composing>=0&&!this.composing&&(this.composing={contextBase:i.updateRangeStart,editorBase:l,drifted:!1});let h=a-l>i.text.length;l==this.from&&rthis.to&&(a=r);let c=wc(e.state.sliceDoc(l,a),i.text,(h?s.from:s.to)-l,h?"end":null);if(!c){let u=b.single(this.toEditorPos(i.selectionStart),this.toEditorPos(i.selectionEnd));u.main.eq(s)||e.dispatch({selection:u,userEvent:"select"});return}let f={from:c.from+l,to:c.toA+l,insert:V.of(i.text.slice(c.from,c.toB).split(` +`))};if((Q.mac||Q.android)&&f.from==o-1&&/^\. ?$/.test(i.text)&&e.contentDOM.getAttribute("autocorrect")=="off"&&(f={from:l,to:a,insert:V.of([i.text.replace("."," ")])}),this.pendingContextChange=f,!e.state.readOnly){let u=this.to-this.from+(f.to-f.from+f.insert.length);Mo(e,f,b.single(this.toEditorPos(i.selectionStart,u),this.toEditorPos(i.selectionEnd,u)))}this.pendingContextChange&&(this.revertPending(e.state),this.setSelection(e.state)),f.from=0&&!/[\\p{Alphabetic}\\p{Number}_]/.test(t.text.slice(Math.max(0,i.updateRangeStart-1),Math.min(t.text.length,i.updateRangeStart+1)))&&this.handlers.compositionend(i)},this.handlers.characterboundsupdate=i=>{let s=[],r=null;for(let o=this.toEditorPos(i.rangeStart),l=this.toEditorPos(i.rangeEnd);o{let s=[];for(let r of i.getTextFormats()){let o=r.underlineStyle,l=r.underlineThickness;if(!/none/i.test(o)&&!/none/i.test(l)){let a=this.toEditorPos(r.rangeStart),h=this.toEditorPos(r.rangeEnd);if(a{e.inputState.composing<0&&(e.inputState.composing=0,e.inputState.compositionFirstChange=!0)},this.handlers.compositionend=()=>{if(e.inputState.composing=-1,e.inputState.compositionFirstChange=null,this.composing){let{drifted:i}=this.composing;this.composing=null,i&&this.reset(e.state)}};for(let i in this.handlers)t.addEventListener(i,this.handlers[i]);this.measureReq={read:i=>{this.editContext.updateControlBounds(i.contentDOM.getBoundingClientRect());let s=zi(i.root);s&&s.rangeCount&&this.editContext.updateSelectionBounds(s.getRangeAt(0).getBoundingClientRect())}}}applyEdits(e){let t=0,i=!1,s=this.pendingContextChange;return e.changes.iterChanges((r,o,l,a,h)=>{if(i)return;let c=h.length-(o-r);if(s&&o>=s.to)if(s.from==r&&s.to==o&&s.insert.eq(h)){s=this.pendingContextChange=null,t+=c,this.to+=c;return}else s=null,this.revertPending(e.state);if(r+=t,o+=t,o<=this.from)this.from+=c,this.to+=c;else if(rthis.to||this.to-this.from+h.length>3e4){i=!0;return}this.editContext.updateText(this.toContextPos(r),this.toContextPos(o),h.toString()),this.to+=c}t+=c}),s&&!i&&this.revertPending(e.state),!i}update(e){let t=this.pendingContextChange,i=e.startState.selection.main;this.composing&&(this.composing.drifted||!e.changes.touchesRange(i.from,i.to)&&e.transactions.some(s=>!s.isUserEvent("input.type")&&s.changes.touchesRange(this.from,this.to)))?(this.composing.drifted=!0,this.composing.editorBase=e.changes.mapPos(this.composing.editorBase)):!this.applyEdits(e)||!this.rangeIsValid(e.state)?(this.pendingContextChange=null,this.reset(e.state)):(e.docChanged||e.selectionSet||t)&&this.setSelection(e.state),(e.geometryChanged||e.docChanged||e.selectionSet)&&e.view.requestMeasure(this.measureReq)}resetRange(e){let{head:t}=e.selection.main;this.from=Math.max(0,t-1e4),this.to=Math.min(e.doc.length,t+1e4)}reset(e){this.resetRange(e),this.editContext.updateText(0,this.editContext.text.length,e.doc.sliceString(this.from,this.to)),this.setSelection(e)}revertPending(e){let t=this.pendingContextChange;this.pendingContextChange=null,this.editContext.updateText(this.toContextPos(t.from),this.toContextPos(t.from+t.insert.length),e.doc.sliceString(t.from,t.to))}setSelection(e){let{main:t}=e.selection,i=this.toContextPos(Math.max(this.from,Math.min(this.to,t.anchor))),s=this.toContextPos(t.head);(this.editContext.selectionStart!=i||this.editContext.selectionEnd!=s)&&this.editContext.updateSelection(i,s)}rangeIsValid(e){let{head:t}=e.selection.main;return!(this.from>0&&t-this.from<500||this.to1e4*3)}toEditorPos(e,t=this.to-this.from){e=Math.min(e,t);let i=this.composing;return i&&i.drifted?i.editorBase+(e-i.contextBase):e+this.from}toContextPos(e){let t=this.composing;return t&&t.drifted?t.contextBase+(e-t.editorBase):e-this.from}destroy(){for(let e in this.handlers)this.editContext.removeEventListener(e,this.handlers[e])}}class P{get state(){return this.viewState.state}get viewport(){return this.viewState.viewport}get visibleRanges(){return this.viewState.visibleRanges}get inView(){return this.viewState.inView}get composing(){return!!this.inputState&&this.inputState.composing>0}get compositionStarted(){return!!this.inputState&&this.inputState.composing>=0}get root(){return this._root}get win(){return this.dom.ownerDocument.defaultView||window}constructor(e={}){var t;this.plugins=[],this.pluginMap=new Map,this.editorAttrs={},this.contentAttrs={},this.bidiCache=[],this.destroyed=!1,this.updateState=2,this.measureScheduled=-1,this.measureRequests=[],this.contentDOM=document.createElement("div"),this.scrollDOM=document.createElement("div"),this.scrollDOM.tabIndex=-1,this.scrollDOM.className="cm-scroller",this.scrollDOM.appendChild(this.contentDOM),this.announceDOM=document.createElement("div"),this.announceDOM.className="cm-announced",this.announceDOM.setAttribute("aria-live","polite"),this.dom=document.createElement("div"),this.dom.appendChild(this.announceDOM),this.dom.appendChild(this.scrollDOM),e.parent&&e.parent.appendChild(this.dom);let{dispatch:i}=e;this.dispatchTransactions=e.dispatchTransactions||i&&(s=>s.forEach(r=>i(r,this)))||(s=>this.update(s)),this.dispatch=this.dispatch.bind(this),this._root=e.root||md(e.parent)||document,this.viewState=new Ul(e.state||I.create(e)),e.scrollTo&&e.scrollTo.is(xn)&&(this.viewState.scrollTarget=e.scrollTo.value.clip(this.viewState.state)),this.plugins=this.state.facet(Kt).map(s=>new Xs(s));for(let s of this.plugins)s.update(this);this.observer=new Dp(this),this.inputState=new tp(this),this.inputState.ensureHandlers(this.plugins),this.docView=new Pl(this),this.mountStyles(),this.updateAttrs(),this.updateState=0,this.requestMeasure(),!((t=document.fonts)===null||t===void 0)&&t.ready&&document.fonts.ready.then(()=>this.requestMeasure())}dispatch(...e){let t=e.length==1&&e[0]instanceof ie?e:e.length==1&&Array.isArray(e[0])?e[0]:[this.state.update(...e)];this.dispatchTransactions(t,this)}update(e){if(this.updateState!=0)throw new Error("Calls to EditorView.update are not allowed while an update is in progress");let t=!1,i=!1,s,r=this.state;for(let u of e){if(u.startState!=r)throw new RangeError("Trying to update state with a transaction that doesn't start from the previous state.");r=u.state}if(this.destroyed){this.viewState.state=r;return}let o=this.hasFocus,l=0,a=null;e.some(u=>u.annotation(Ac))?(this.inputState.notifiedFocused=o,l=1):o!=this.inputState.notifiedFocused&&(this.inputState.notifiedFocused=o,a=Mc(r,o),a||(l=1));let h=this.observer.delayedAndroidKey,c=null;if(h?(this.observer.clearDelayedAndroidKey(),c=this.observer.readChange(),(c&&!this.state.doc.eq(r.doc)||!this.state.selection.eq(r.selection))&&(c=null)):this.observer.clear(),r.facet(I.phrases)!=this.state.facet(I.phrases))return this.setState(r);s=os.create(this,r,e),s.flags|=l;let f=this.viewState.scrollTarget;try{this.updateState=2;for(let u of e){if(f&&(f=f.map(u.changes)),u.scrollIntoView){let{main:d}=u.state.selection;f=new ni(d.empty?d:b.cursor(d.head,d.head>d.anchor?-1:1))}for(let d of u.effects)d.is(xn)&&(f=d.value.clip(this.state))}this.viewState.update(s,f),this.bidiCache=as.update(this.bidiCache,s.changes),s.empty||(this.updatePlugins(s),this.inputState.update(s)),t=this.docView.update(s),this.state.facet(Ti)!=this.styleModules&&this.mountStyles(),i=this.updateAttrs(),this.showAnnouncements(e),this.docView.updateSelection(t,e.some(u=>u.isUserEvent("select.pointer")))}finally{this.updateState=0}if(s.startState.facet(Pn)!=s.state.facet(Pn)&&(this.viewState.mustMeasureContent=!0),(t||i||f||this.viewState.mustEnforceCursorAssoc||this.viewState.mustMeasureContent)&&this.requestMeasure(),t&&this.docViewUpdate(),!s.empty)for(let u of this.state.facet(jr))try{u(s)}catch(d){Pe(this.state,d,"update listener")}(a||c)&&Promise.resolve().then(()=>{a&&this.state==a.startState&&this.dispatch(a),c&&!kc(this,c)&&h.force&&ii(this.contentDOM,h.key,h.keyCode)})}setState(e){if(this.updateState!=0)throw new Error("Calls to EditorView.setState are not allowed while an update is in progress");if(this.destroyed){this.viewState.state=e;return}this.updateState=2;let t=this.hasFocus;try{for(let i of this.plugins)i.destroy(this);this.viewState=new Ul(e),this.plugins=e.facet(Kt).map(i=>new Xs(i)),this.pluginMap.clear();for(let i of this.plugins)i.update(this);this.docView.destroy(),this.docView=new Pl(this),this.inputState.ensureHandlers(this.plugins),this.mountStyles(),this.updateAttrs(),this.bidiCache=[]}finally{this.updateState=0}t&&this.focus(),this.requestMeasure()}updatePlugins(e){let t=e.startState.facet(Kt),i=e.state.facet(Kt);if(t!=i){let s=[];for(let r of i){let o=t.indexOf(r);if(o<0)s.push(new Xs(r));else{let l=this.plugins[o];l.mustUpdate=e,s.push(l)}}for(let r of this.plugins)r.mustUpdate!=e&&r.destroy(this);this.plugins=s,this.pluginMap.clear()}else for(let s of this.plugins)s.mustUpdate=e;for(let s=0;s-1&&this.win.cancelAnimationFrame(this.measureScheduled),this.observer.delayedAndroidKey){this.measureScheduled=-1,this.requestMeasure();return}this.measureScheduled=0,e&&this.observer.forceFlush();let t=null,i=this.scrollDOM,s=i.scrollTop*this.scaleY,{scrollAnchorPos:r,scrollAnchorHeight:o}=this.viewState;Math.abs(s-this.viewState.scrollTop)>1&&(o=-1),this.viewState.scrollAnchorHeight=-1;try{for(let l=0;;l++){if(o<0)if(Xh(i))r=-1,o=this.viewState.heightMap.height;else{let d=this.viewState.scrollAnchorAt(s);r=d.from,o=d.top}this.updateState=1;let a=this.viewState.measure(this);if(!a&&!this.measureRequests.length&&this.viewState.scrollTarget==null)break;if(l>5){console.warn(this.measureRequests.length?"Measure loop restarted more than 5 times":"Viewport failed to stabilize");break}let h=[];a&4||([this.measureRequests,h]=[h,this.measureRequests]);let c=h.map(d=>{try{return d.read(this)}catch(p){return Pe(this.state,p),Zl}}),f=os.create(this,this.state,[]),u=!1;f.flags|=a,t?t.flags|=a:t=f,this.updateState=2,f.empty||(this.updatePlugins(f),this.inputState.update(f),this.updateAttrs(),u=this.docView.update(f),u&&this.docViewUpdate());for(let d=0;d1||p<-1){s=s+p,i.scrollTop=s/this.scaleY,o=-1;continue}}break}}}finally{this.updateState=0,this.measureScheduled=-1}if(t&&!t.empty)for(let l of this.state.facet(jr))l(t)}get themeClasses(){return Jr+" "+(this.state.facet(Kr)?qc:Ec)+" "+this.state.facet(Pn)}updateAttrs(){let e=Yl(this,pc,{class:"cm-editor"+(this.hasFocus?" cm-focused ":" ")+this.themeClasses}),t={spellcheck:"false",autocorrect:"off",autocapitalize:"off",writingsuggestions:"false",translate:"no",contenteditable:this.state.facet(dt)?"true":"false",class:"cm-content",style:`${Q.tabSize}: ${this.state.tabSize}`,role:"textbox","aria-multiline":"true"};this.state.readOnly&&(t["aria-readonly"]="true"),Yl(this,Qo,t);let i=this.observer.ignore(()=>{let s=Xr(this.contentDOM,this.contentAttrs,t),r=Xr(this.dom,this.editorAttrs,e);return s||r});return this.editorAttrs=e,this.contentAttrs=t,i}showAnnouncements(e){let t=!0;for(let i of e)for(let s of i.effects)if(s.is(P.announce)){t&&(this.announceDOM.textContent=""),t=!1;let r=this.announceDOM.appendChild(document.createElement("div"));r.textContent=s.value}}mountStyles(){this.styleModules=this.state.facet(Ti);let e=this.state.facet(P.cspNonce);Tt.mount(this.root,this.styleModules.concat(Mp).reverse(),e?{nonce:e}:void 0)}readMeasured(){if(this.updateState==2)throw new Error("Reading the editor layout isn't allowed during an update");this.updateState==0&&this.measureScheduled>-1&&this.measure(!1)}requestMeasure(e){if(this.measureScheduled<0&&(this.measureScheduled=this.win.requestAnimationFrame(()=>this.measure())),e){if(this.measureRequests.indexOf(e)>-1)return;if(e.key!=null){for(let t=0;ti.plugin==e)||null),t&&t.update(this).value}get documentTop(){return this.contentDOM.getBoundingClientRect().top+this.viewState.paddingTop}get documentPadding(){return{top:this.viewState.paddingTop,bottom:this.viewState.paddingBottom}}get scaleX(){return this.viewState.scaleX}get scaleY(){return this.viewState.scaleY}elementAtHeight(e){return this.readMeasured(),this.viewState.elementAtHeight(e)}lineBlockAtHeight(e){return this.readMeasured(),this.viewState.lineBlockAtHeight(e)}get viewportLineBlocks(){return this.viewState.viewportLines}lineBlockAt(e){return this.viewState.lineBlockAt(e)}get contentHeight(){return this.viewState.contentHeight}moveByChar(e,t,i){return _s(this,e,Dl(this,e,t,i))}moveByGroup(e,t){return _s(this,e,Dl(this,e,t,i=>Ud(this,e.head,i)))}visualLineSide(e,t){let i=this.bidiSpans(e),s=this.textDirectionAt(e.from),r=i[t?i.length-1:0];return b.cursor(r.side(t,s)+e.from,r.forward(!t,s)?1:-1)}moveToLineBoundary(e,t,i=!0){return _d(this,e,t,i)}moveVertically(e,t,i){return _s(this,e,Hd(this,e,t,i))}domAtPos(e){return this.docView.domAtPos(e)}posAtDOM(e,t=0){return this.docView.posFromDOM(e,t)}posAtCoords(e,t=!0){return this.readMeasured(),bc(this,e,t)}coordsAtPos(e,t=1){this.readMeasured();let i=this.docView.coordsAt(e,t);if(!i||i.left==i.right)return i;let s=this.state.doc.lineAt(e),r=this.bidiSpans(s),o=r[wt.find(r,e-s.from,-1,t)];return sn(i,o.dir==Z.LTR==t>0)}coordsForChar(e){return this.readMeasured(),this.docView.coordsForChar(e)}get defaultCharacterWidth(){return this.viewState.heightOracle.charWidth}get defaultLineHeight(){return this.viewState.heightOracle.lineHeight}get textDirection(){return this.viewState.defaultTextDirection}textDirectionAt(e){return!this.state.facet(cc)||ethis.viewport.to?this.textDirection:(this.readMeasured(),this.docView.textDirectionAt(e))}get lineWrapping(){return this.viewState.heightOracle.lineWrapping}bidiSpans(e){if(e.length>$p)return ic(e.length);let t=this.textDirectionAt(e.from),i;for(let r of this.bidiCache)if(r.from==e.from&&r.dir==t&&(r.fresh||tc(r.isolates,i=Cl(this,e))))return r.order;i||(i=Cl(this,e));let s=Ad(e.text,t,i);return this.bidiCache.push(new as(e.from,e.to,t,i,!0,s)),s}get hasFocus(){var e;return(this.dom.ownerDocument.hasFocus()||Q.safari&&((e=this.inputState)===null||e===void 0?void 0:e.lastContextMenu)>Date.now()-3e4)&&this.root.activeElement==this.contentDOM}focus(){this.observer.ignore(()=>{Vh(this.contentDOM),this.docView.updateSelection()})}setRoot(e){this._root!=e&&(this._root=e,this.observer.setWindow((e.nodeType==9?e:e.ownerDocument).defaultView||window),this.mountStyles())}destroy(){this.root.activeElement==this.contentDOM&&this.contentDOM.blur();for(let e of this.plugins)e.destroy(this);this.plugins=[],this.inputState.destroy(),this.docView.destroy(),this.dom.remove(),this.observer.destroy(),this.measureScheduled>-1&&this.win.cancelAnimationFrame(this.measureScheduled),this.destroyed=!0}static scrollIntoView(e,t={}){return xn.of(new ni(typeof e=="number"?b.cursor(e):e,t.y,t.x,t.yMargin,t.xMargin))}scrollSnapshot(){let{scrollTop:e,scrollLeft:t}=this.scrollDOM,i=this.viewState.scrollAnchorAt(e);return xn.of(new ni(b.cursor(i.from),"start","start",i.top-e,t,!0))}setTabFocusMode(e){e==null?this.inputState.tabFocusMode=this.inputState.tabFocusMode<0?0:-1:typeof e=="boolean"?this.inputState.tabFocusMode=e?0:-1:this.inputState.tabFocusMode!=0&&(this.inputState.tabFocusMode=Date.now()+e)}static domEventHandlers(e){return J.define(()=>({}),{eventHandlers:e})}static domEventObservers(e){return J.define(()=>({}),{eventObservers:e})}static theme(e,t){let i=Tt.newName(),s=[Pn.of(i),Ti.of(eo(`.${i}`,e))];return t&&t.dark&&s.push(Kr.of(!0)),s}static baseTheme(e){return Mt.lowest(Ti.of(eo("."+Jr,e,$c)))}static findFromDOM(e){var t;let i=e.querySelector(".cm-content"),s=i&&_.get(i)||_.get(e);return((t=s?.rootView)===null||t===void 0?void 0:t.view)||null}}P.styleModule=Ti;P.inputHandler=ac;P.clipboardInputFilter=Co;P.clipboardOutputFilter=Po;P.scrollHandler=uc;P.focusChangeEffect=hc;P.perLineTextDirection=cc;P.exceptionSink=lc;P.updateListener=jr;P.editable=dt;P.mouseSelectionStyle=oc;P.dragMovesSelection=rc;P.clickAddsSelectionRange=sc;P.decorations=Ii;P.outerDecorations=mc;P.atomicRanges=ln;P.bidiIsolatedRanges=gc;P.scrollMargins=Oc;P.darkTheme=Kr;P.cspNonce=A.define({combine:n=>n.length?n[0]:""});P.contentAttributes=Qo;P.editorAttributes=pc;P.lineWrapping=P.contentAttributes.of({class:"cm-lineWrapping"});P.announce=q.define();const $p=4096,Zl={};class as{constructor(e,t,i,s,r,o){this.from=e,this.to=t,this.dir=i,this.isolates=s,this.fresh=r,this.order=o}static update(e,t){if(t.empty&&!e.some(r=>r.fresh))return e;let i=[],s=e.length?e[e.length-1].dir:Z.LTR;for(let r=Math.max(0,e.length-10);r=0;s--){let r=i[s],o=typeof r=="function"?r(n):r;o&&Nr(o,t)}return t}const Bp=Q.mac?"mac":Q.windows?"win":Q.linux?"linux":"key";function Wp(n,e){const t=n.split(/-(?!$)/);let i=t[t.length-1];i=="Space"&&(i=" ");let s,r,o,l;for(let a=0;ai.concat(s),[]))),t}function zp(n,e,t){return Wc(Bc(n.state),e,n,t)}let xt=null;const Ip=4e3;function Vp(n,e=Bp){let t=Object.create(null),i=Object.create(null),s=(o,l)=>{let a=i[o];if(a==null)i[o]=l;else if(a!=l)throw new Error("Key binding "+o+" is used both as a regular binding and as a multi-stroke prefix")},r=(o,l,a,h,c)=>{var f,u;let d=t[o]||(t[o]=Object.create(null)),p=l.split(/ (?!$)/).map(y=>Wp(y,e));for(let y=1;y{let w=xt={view:x,prefix:S,scope:o};return setTimeout(()=>{xt==w&&(xt=null)},Ip),!0}]})}let m=p.join(" ");s(m,!1);let g=d[m]||(d[m]={preventDefault:!1,stopPropagation:!1,run:((u=(f=d._any)===null||f===void 0?void 0:f.run)===null||u===void 0?void 0:u.slice())||[]});a&&g.run.push(a),h&&(g.preventDefault=!0),c&&(g.stopPropagation=!0)};for(let o of n){let l=o.scope?o.scope.split(" "):["editor"];if(o.any)for(let h of l){let c=t[h]||(t[h]=Object.create(null));c._any||(c._any={preventDefault:!1,stopPropagation:!1,run:[]});let{any:f}=o;for(let u in c)c[u].run.push(d=>f(d,to))}let a=o[e]||o.key;if(a)for(let h of l)r(h,a,o.run,o.preventDefault,o.stopPropagation),o.shift&&r(h,"Shift-"+a,o.shift,o.preventDefault,o.stopPropagation)}return t}let to=null;function Wc(n,e,t,i){to=e;let s=hd(e),r=Te(s,0),o=Ye(r)==s.length&&s!=" ",l="",a=!1,h=!1,c=!1;xt&&xt.view==t&&xt.scope==i&&(l=xt.prefix+" ",Tc.indexOf(e.keyCode)<0&&(h=!0,xt=null));let f=new Set,u=g=>{if(g){for(let y of g.run)if(!f.has(y)&&(f.add(y),y(t)))return g.stopPropagation&&(c=!0),!0;g.preventDefault&&(g.stopPropagation&&(c=!0),h=!0)}return!1},d=n[i],p,m;return d&&(u(d[l+Qn(s,e,!o)])?a=!0:o&&(e.altKey||e.metaKey||e.ctrlKey)&&!(Q.windows&&e.ctrlKey&&e.altKey)&&!(Q.mac&&e.altKey&&!(e.ctrlKey||e.metaKey))&&(p=Ct[e.keyCode])&&p!=s?(u(d[l+Qn(p,e,!0)])||e.shiftKey&&(m=Li[e.keyCode])!=s&&m!=p&&u(d[l+Qn(m,e,!1)]))&&(a=!0):o&&e.shiftKey&&u(d[l+Qn(s,e,!0)])&&(a=!0),!a&&u(d._any)&&(a=!0)),h&&(a=!0),a&&c&&e.stopPropagation(),to=null,a}class hn{constructor(e,t,i,s,r){this.className=e,this.left=t,this.top=i,this.width=s,this.height=r}draw(){let e=document.createElement("div");return e.className=this.className,this.adjust(e),e}update(e,t){return t.className!=this.className?!1:(this.adjust(e),!0)}adjust(e){e.style.left=this.left+"px",e.style.top=this.top+"px",this.width!=null&&(e.style.width=this.width+"px"),e.style.height=this.height+"px"}eq(e){return this.left==e.left&&this.top==e.top&&this.width==e.width&&this.height==e.height&&this.className==e.className}static forRange(e,t,i){if(i.empty){let s=e.coordsAtPos(i.head,i.assoc||1);if(!s)return[];let r=Lc(e);return[new hn(t,s.left-r.left,s.top-r.top,null,s.bottom-s.top)]}else return Np(e,t,i)}}function Lc(n){let e=n.scrollDOM.getBoundingClientRect();return{left:(n.textDirection==Z.LTR?e.left:e.right-n.scrollDOM.clientWidth*n.scaleX)-n.scrollDOM.scrollLeft*n.scaleX,top:e.top-n.scrollDOM.scrollTop*n.scaleY}}function Jl(n,e,t,i){let s=n.coordsAtPos(e,t*2);if(!s)return i;let r=n.dom.getBoundingClientRect(),o=(s.top+s.bottom)/2,l=n.posAtCoords({x:r.left+1,y:o}),a=n.posAtCoords({x:r.right-1,y:o});return l==null||a==null?i:{from:Math.max(i.from,Math.min(l,a)),to:Math.min(i.to,Math.max(l,a))}}function Np(n,e,t){if(t.to<=n.viewport.from||t.from>=n.viewport.to)return[];let i=Math.max(t.from,n.viewport.from),s=Math.min(t.to,n.viewport.to),r=n.textDirection==Z.LTR,o=n.contentDOM,l=o.getBoundingClientRect(),a=Lc(n),h=o.querySelector(".cm-line"),c=h&&window.getComputedStyle(h),f=l.left+(c?parseInt(c.paddingLeft)+Math.min(0,parseInt(c.textIndent)):0),u=l.right-(c?parseInt(c.paddingRight):0),d=Zr(n,i,1),p=Zr(n,s,-1),m=d.type==ke.Text?d:null,g=p.type==ke.Text?p:null;if(m&&(n.lineWrapping||d.widgetLineBreaks)&&(m=Jl(n,i,1,m)),g&&(n.lineWrapping||p.widgetLineBreaks)&&(g=Jl(n,s,-1,g)),m&&g&&m.from==g.from&&m.to==g.to)return S(x(t.from,t.to,m));{let k=m?x(t.from,null,m):w(d,!1),v=g?x(null,t.to,g):w(p,!0),T=[];return(m||d).to<(g||p).from-(m&&g?1:0)||d.widgetLineBreaks>1&&k.bottom+n.defaultLineHeight/2D&&W.from=ne)break;ee>X&&$(Math.max(F,X),k==null&&F<=D,Math.min(ee,ne),v==null&&ee>=B,me.dir)}if(X=oe.to+1,X>=ne)break}return z.length==0&&$(D,k==null,B,v==null,n.textDirection),{top:E,bottom:M,horizontal:z}}function w(k,v){let T=l.top+(v?k.top:k.bottom);return{top:T,bottom:T,horizontal:[]}}}function Xp(n,e){return n.constructor==e.constructor&&n.eq(e)}class Fp{constructor(e,t){this.view=e,this.layer=t,this.drawn=[],this.scaleX=1,this.scaleY=1,this.measureReq={read:this.measure.bind(this),write:this.draw.bind(this)},this.dom=e.scrollDOM.appendChild(document.createElement("div")),this.dom.classList.add("cm-layer"),t.above&&this.dom.classList.add("cm-layer-above"),t.class&&this.dom.classList.add(t.class),this.scale(),this.dom.setAttribute("aria-hidden","true"),this.setOrder(e.state),e.requestMeasure(this.measureReq),t.mount&&t.mount(this.dom,e)}update(e){e.startState.facet(jn)!=e.state.facet(jn)&&this.setOrder(e.state),(this.layer.update(e,this.dom)||e.geometryChanged)&&(this.scale(),e.view.requestMeasure(this.measureReq))}docViewUpdate(e){this.layer.updateOnDocViewUpdate!==!1&&e.requestMeasure(this.measureReq)}setOrder(e){let t=0,i=e.facet(jn);for(;t!Xp(t,this.drawn[i]))){let t=this.dom.firstChild,i=0;for(let s of e)s.update&&t&&s.constructor&&this.drawn[i].constructor&&s.update(t,this.drawn[i])?(t=t.nextSibling,i++):this.dom.insertBefore(s.draw(),t);for(;t;){let s=t.nextSibling;t.remove(),t=s}this.drawn=e,Q.safari&&Q.safari_version>=26&&(this.dom.style.display=this.dom.firstChild?"":"none")}}destroy(){this.layer.destroy&&this.layer.destroy(this.dom,this.view),this.dom.remove()}}const jn=A.define();function zc(n){return[J.define(e=>new Fp(e,n)),jn.of(n)]}const Vi=A.define({combine(n){return rt(n,{cursorBlinkRate:1200,drawRangeCursor:!0},{cursorBlinkRate:(e,t)=>Math.min(e,t),drawRangeCursor:(e,t)=>e||t})}});function _p(n={}){return[Vi.of(n),Up,Hp,jp,fc.of(!0)]}function Ic(n){return n.startState.facet(Vi)!=n.state.facet(Vi)}const Up=zc({above:!0,markers(n){let{state:e}=n,t=e.facet(Vi),i=[];for(let s of e.selection.ranges){let r=s==e.selection.main;if(s.empty||t.drawRangeCursor){let o=r?"cm-cursor cm-cursor-primary":"cm-cursor cm-cursor-secondary",l=s.empty?s:b.cursor(s.head,s.head>s.anchor?-1:1);for(let a of hn.forRange(n,o,l))i.push(a)}}return i},update(n,e){n.transactions.some(i=>i.selection)&&(e.style.animationName=e.style.animationName=="cm-blink"?"cm-blink2":"cm-blink");let t=Ic(n);return t&&ea(n.state,e),n.docChanged||n.selectionSet||t},mount(n,e){ea(e.state,n)},class:"cm-cursorLayer"});function ea(n,e){e.style.animationDuration=n.facet(Vi).cursorBlinkRate+"ms"}const Hp=zc({above:!1,markers(n){return n.state.selection.ranges.map(e=>e.empty?[]:hn.forRange(n,"cm-selectionBackground",e)).reduce((e,t)=>e.concat(t))},update(n,e){return n.docChanged||n.selectionSet||n.viewportChanged||Ic(n)},class:"cm-selectionLayer"}),jp=Mt.highest(P.theme({".cm-line":{"& ::selection, &::selection":{backgroundColor:"transparent !important"},caretColor:"transparent !important"},".cm-content":{caretColor:"transparent !important","& :focus":{caretColor:"initial !important","&::selection, & ::selection":{backgroundColor:"Highlight !important"}}}})),Vc=q.define({map(n,e){return n==null?null:e.mapPos(n)}}),Qi=he.define({create(){return null},update(n,e){return n!=null&&(n=e.changes.mapPos(n)),e.effects.reduce((t,i)=>i.is(Vc)?i.value:t,n)}}),Gp=J.fromClass(class{constructor(n){this.view=n,this.cursor=null,this.measureReq={read:this.readPos.bind(this),write:this.drawCursor.bind(this)}}update(n){var e;let t=n.state.field(Qi);t==null?this.cursor!=null&&((e=this.cursor)===null||e===void 0||e.remove(),this.cursor=null):(this.cursor||(this.cursor=this.view.scrollDOM.appendChild(document.createElement("div")),this.cursor.className="cm-dropCursor"),(n.startState.field(Qi)!=t||n.docChanged||n.geometryChanged)&&this.view.requestMeasure(this.measureReq))}readPos(){let{view:n}=this,e=n.state.field(Qi),t=e!=null&&n.coordsAtPos(e);if(!t)return null;let i=n.scrollDOM.getBoundingClientRect();return{left:t.left-i.left+n.scrollDOM.scrollLeft*n.scaleX,top:t.top-i.top+n.scrollDOM.scrollTop*n.scaleY,height:t.bottom-t.top}}drawCursor(n){if(this.cursor){let{scaleX:e,scaleY:t}=this.view;n?(this.cursor.style.left=n.left/e+"px",this.cursor.style.top=n.top/t+"px",this.cursor.style.height=n.height/t+"px"):this.cursor.style.left="-100000px"}}destroy(){this.cursor&&this.cursor.remove()}setDropPos(n){this.view.state.field(Qi)!=n&&this.view.dispatch({effects:Vc.of(n)})}},{eventObservers:{dragover(n){this.setDropPos(this.view.posAtCoords({x:n.clientX,y:n.clientY}))},dragleave(n){(n.target==this.view.contentDOM||!this.view.contentDOM.contains(n.relatedTarget))&&this.setDropPos(null)},dragend(){this.setDropPos(null)},drop(){this.setDropPos(null)}}});function Zp(){return[Qi,Gp]}function ta(n,e,t,i,s){e.lastIndex=0;for(let r=n.iterRange(t,i),o=t,l;!r.next().done;o+=r.value.length)if(!r.lineBreak)for(;l=e.exec(r.value);)s(o+l.index,l)}function Yp(n,e){let t=n.visibleRanges;if(t.length==1&&t[0].from==n.viewport.from&&t[0].to==n.viewport.to)return t;let i=[];for(let{from:s,to:r}of t)s=Math.max(n.state.doc.lineAt(s).from,s-e),r=Math.min(n.state.doc.lineAt(r).to,r+e),i.length&&i[i.length-1].to>=s?i[i.length-1].to=r:i.push({from:s,to:r});return i}class Kp{constructor(e){const{regexp:t,decoration:i,decorate:s,boundary:r,maxLength:o=1e3}=e;if(!t.global)throw new RangeError("The regular expression given to MatchDecorator should have its 'g' flag set");if(this.regexp=t,s)this.addMatch=(l,a,h,c)=>s(c,h,h+l[0].length,l,a);else if(typeof i=="function")this.addMatch=(l,a,h,c)=>{let f=i(l,a,h);f&&c(h,h+l[0].length,f)};else if(i)this.addMatch=(l,a,h,c)=>c(h,h+l[0].length,i);else throw new RangeError("Either 'decorate' or 'decoration' should be provided to MatchDecorator");this.boundary=r,this.maxLength=o}createDeco(e){let t=new gt,i=t.add.bind(t);for(let{from:s,to:r}of Yp(e,this.maxLength))ta(e.state.doc,this.regexp,s,r,(o,l)=>this.addMatch(l,e,o,i));return t.finish()}updateDeco(e,t){let i=1e9,s=-1;return e.docChanged&&e.changes.iterChanges((r,o,l,a)=>{a>=e.view.viewport.from&&l<=e.view.viewport.to&&(i=Math.min(l,i),s=Math.max(a,s))}),e.viewportMoved||s-i>1e3?this.createDeco(e.view):s>-1?this.updateRange(e.view,t.map(e.changes),i,s):t}updateRange(e,t,i,s){for(let r of e.visibleRanges){let o=Math.max(r.from,i),l=Math.min(r.to,s);if(l>=o){let a=e.state.doc.lineAt(o),h=a.toa.from;o--)if(this.boundary.test(a.text[o-1-a.from])){c=o;break}for(;lu.push(y.range(m,g));if(a==h)for(this.regexp.lastIndex=c-a.from;(d=this.regexp.exec(a.text))&&d.indexthis.addMatch(g,e,m,p));t=t.update({filterFrom:c,filterTo:f,filter:(m,g)=>mf,add:u})}}return t}}const io=/x/.unicode!=null?"gu":"g",Jp=new RegExp(`[\0-\b +--Ÿ­؜​‎‏\u2028\u2029‭‮⁦⁧⁩\uFEFF-]`,io),em={0:"null",7:"bell",8:"backspace",10:"newline",11:"vertical tab",13:"carriage return",27:"escape",8203:"zero width space",8204:"zero width non-joiner",8205:"zero width joiner",8206:"left-to-right mark",8207:"right-to-left mark",8232:"line separator",8237:"left-to-right override",8238:"right-to-left override",8294:"left-to-right isolate",8295:"right-to-left isolate",8297:"pop directional isolate",8233:"paragraph separator",65279:"zero width no-break space",65532:"object replacement"};let js=null;function tm(){var n;if(js==null&&typeof document<"u"&&document.body){let e=document.body.style;js=((n=e.tabSize)!==null&&n!==void 0?n:e.MozTabSize)!=null}return js||!1}const Gn=A.define({combine(n){let e=rt(n,{render:null,specialChars:Jp,addSpecialChars:null});return(e.replaceTabs=!tm())&&(e.specialChars=new RegExp(" |"+e.specialChars.source,io)),e.addSpecialChars&&(e.specialChars=new RegExp(e.specialChars.source+"|"+e.addSpecialChars.source,io)),e}});function im(n={}){return[Gn.of(n),nm()]}let ia=null;function nm(){return ia||(ia=J.fromClass(class{constructor(n){this.view=n,this.decorations=R.none,this.decorationCache=Object.create(null),this.decorator=this.makeDecorator(n.state.facet(Gn)),this.decorations=this.decorator.createDeco(n)}makeDecorator(n){return new Kp({regexp:n.specialChars,decoration:(e,t,i)=>{let{doc:s}=t.state,r=Te(e[0],0);if(r==9){let o=s.lineAt(i),l=t.state.tabSize,a=gi(o.text,l,i-o.from);return R.replace({widget:new lm((l-a%l)*this.view.defaultCharacterWidth/this.view.scaleX)})}return this.decorationCache[r]||(this.decorationCache[r]=R.replace({widget:new om(n,r)}))},boundary:n.replaceTabs?void 0:/[^]/})}update(n){let e=n.state.facet(Gn);n.startState.facet(Gn)!=e?(this.decorator=this.makeDecorator(e),this.decorations=this.decorator.createDeco(n.view)):this.decorations=this.decorator.updateDeco(n,this.decorations)}},{decorations:n=>n.decorations}))}const sm="•";function rm(n){return n>=32?sm:n==10?"␤":String.fromCharCode(9216+n)}class om extends ot{constructor(e,t){super(),this.options=e,this.code=t}eq(e){return e.code==this.code}toDOM(e){let t=rm(this.code),i=e.state.phrase("Control character")+" "+(em[this.code]||"0x"+this.code.toString(16)),s=this.options.render&&this.options.render(this.code,i,t);if(s)return s;let r=document.createElement("span");return r.textContent=t,r.title=i,r.setAttribute("aria-label",i),r.className="cm-specialChar",r}ignoreEvent(){return!1}}class lm extends ot{constructor(e){super(),this.width=e}eq(e){return e.width==this.width}toDOM(){let e=document.createElement("span");return e.textContent=" ",e.className="cm-tab",e.style.width=this.width+"px",e}ignoreEvent(){return!1}}function am(){return cm}const hm=R.line({class:"cm-activeLine"}),cm=J.fromClass(class{constructor(n){this.decorations=this.getDeco(n)}update(n){(n.docChanged||n.selectionSet)&&(this.decorations=this.getDeco(n.view))}getDeco(n){let e=-1,t=[];for(let i of n.state.selection.ranges){let s=n.lineBlockAt(i.head);s.from>e&&(t.push(hm.range(s.from)),e=s.from)}return R.set(t)}},{decorations:n=>n.decorations});class fm extends ot{constructor(e){super(),this.content=e}toDOM(e){let t=document.createElement("span");return t.className="cm-placeholder",t.style.pointerEvents="none",t.appendChild(typeof this.content=="string"?document.createTextNode(this.content):typeof this.content=="function"?this.content(e):this.content.cloneNode(!0)),t.setAttribute("aria-hidden","true"),t}coordsAt(e){let t=e.firstChild?ai(e.firstChild):[];if(!t.length)return null;let i=window.getComputedStyle(e.parentNode),s=sn(t[0],i.direction!="rtl"),r=parseInt(i.lineHeight);return s.bottom-s.top>r*1.5?{left:s.left,right:s.right,top:s.top,bottom:s.top+r}:s}ignoreEvent(){return!1}}function um(n){let e=J.fromClass(class{constructor(t){this.view=t,this.placeholder=n?R.set([R.widget({widget:new fm(n),side:1}).range(0)]):R.none}get decorations(){return this.view.state.doc.length?R.none:this.placeholder}},{decorations:t=>t.decorations});return typeof n=="string"?[e,P.contentAttributes.of({"aria-placeholder":n})]:e}const no=2e3;function dm(n,e,t){let i=Math.min(e.line,t.line),s=Math.max(e.line,t.line),r=[];if(e.off>no||t.off>no||e.col<0||t.col<0){let o=Math.min(e.off,t.off),l=Math.max(e.off,t.off);for(let a=i;a<=s;a++){let h=n.doc.line(a);h.length<=l&&r.push(b.range(h.from+o,h.to+l))}}else{let o=Math.min(e.col,t.col),l=Math.max(e.col,t.col);for(let a=i;a<=s;a++){let h=n.doc.line(a),c=qr(h.text,o,n.tabSize,!0);if(c<0)r.push(b.cursor(h.to));else{let f=qr(h.text,l,n.tabSize);r.push(b.range(h.from+c,h.from+f))}}}return r}function pm(n,e){let t=n.coordsAtPos(n.viewport.from);return t?Math.round(Math.abs((t.left-e)/n.defaultCharacterWidth)):-1}function na(n,e){let t=n.posAtCoords({x:e.clientX,y:e.clientY},!1),i=n.state.doc.lineAt(t),s=t-i.from,r=s>no?-1:s==i.length?pm(n,e.clientX):gi(i.text,n.state.tabSize,t-i.from);return{line:i.number,col:r,off:s}}function mm(n,e){let t=na(n,e),i=n.state.selection;return t?{update(s){if(s.docChanged){let r=s.changes.mapPos(s.startState.doc.line(t.line).from),o=s.state.doc.lineAt(r);t={line:o.number,col:t.col,off:Math.min(t.off,o.length)},i=i.map(s.changes)}},get(s,r,o){let l=na(n,s);if(!l)return i;let a=dm(n.state,t,l);return a.length?o?b.create(a.concat(i.ranges)):b.create(a):i}}:null}function gm(n){let e=(t=>t.altKey&&t.button==0);return P.mouseSelectionStyle.of((t,i)=>e(i)?mm(t,i):null)}const Om={Alt:[18,n=>!!n.altKey],Control:[17,n=>!!n.ctrlKey],Shift:[16,n=>!!n.shiftKey],Meta:[91,n=>!!n.metaKey]},ym={style:"cursor: crosshair"};function bm(n={}){let[e,t]=Om[n.key||"Alt"],i=J.fromClass(class{constructor(s){this.view=s,this.isDown=!1}set(s){this.isDown!=s&&(this.isDown=s,this.view.update([]))}},{eventObservers:{keydown(s){this.set(s.keyCode==e||t(s))},keyup(s){(s.keyCode==e||!t(s))&&this.set(!1)},mousemove(s){this.set(t(s))}}});return[i,P.contentAttributes.of(s=>{var r;return!((r=s.plugin(i))===null||r===void 0)&&r.isDown?ym:null})]}const An="-10000px";class Nc{constructor(e,t,i,s){this.facet=t,this.createTooltipView=i,this.removeTooltipView=s,this.input=e.state.facet(t),this.tooltips=this.input.filter(o=>o);let r=null;this.tooltipViews=this.tooltips.map(o=>r=i(o,r))}update(e,t){var i;let s=e.state.facet(this.facet),r=s.filter(a=>a);if(s===this.input){for(let a of this.tooltipViews)a.update&&a.update(e);return!1}let o=[],l=t?[]:null;for(let a=0;at[h]=a),t.length=l.length),this.input=s,this.tooltips=r,this.tooltipViews=o,!0}}function Sm(n){let e=n.dom.ownerDocument.documentElement;return{top:0,left:0,bottom:e.clientHeight,right:e.clientWidth}}const Gs=A.define({combine:n=>{var e,t,i;return{position:Q.ios?"absolute":((e=n.find(s=>s.position))===null||e===void 0?void 0:e.position)||"fixed",parent:((t=n.find(s=>s.parent))===null||t===void 0?void 0:t.parent)||null,tooltipSpace:((i=n.find(s=>s.tooltipSpace))===null||i===void 0?void 0:i.tooltipSpace)||Sm}}}),sa=new WeakMap,Eo=J.fromClass(class{constructor(n){this.view=n,this.above=[],this.inView=!0,this.madeAbsolute=!1,this.lastTransaction=0,this.measureTimeout=-1;let e=n.state.facet(Gs);this.position=e.position,this.parent=e.parent,this.classes=n.themeClasses,this.createContainer(),this.measureReq={read:this.readMeasure.bind(this),write:this.writeMeasure.bind(this),key:this},this.resizeObserver=typeof ResizeObserver=="function"?new ResizeObserver(()=>this.measureSoon()):null,this.manager=new Nc(n,qo,(t,i)=>this.createTooltip(t,i),t=>{this.resizeObserver&&this.resizeObserver.unobserve(t.dom),t.dom.remove()}),this.above=this.manager.tooltips.map(t=>!!t.above),this.intersectionObserver=typeof IntersectionObserver=="function"?new IntersectionObserver(t=>{Date.now()>this.lastTransaction-50&&t.length>0&&t[t.length-1].intersectionRatio<1&&this.measureSoon()},{threshold:[1]}):null,this.observeIntersection(),n.win.addEventListener("resize",this.measureSoon=this.measureSoon.bind(this)),this.maybeMeasure()}createContainer(){this.parent?(this.container=document.createElement("div"),this.container.style.position="relative",this.container.className=this.view.themeClasses,this.parent.appendChild(this.container)):this.container=this.view.dom}observeIntersection(){if(this.intersectionObserver){this.intersectionObserver.disconnect();for(let n of this.manager.tooltipViews)this.intersectionObserver.observe(n.dom)}}measureSoon(){this.measureTimeout<0&&(this.measureTimeout=setTimeout(()=>{this.measureTimeout=-1,this.maybeMeasure()},50))}update(n){n.transactions.length&&(this.lastTransaction=Date.now());let e=this.manager.update(n,this.above);e&&this.observeIntersection();let t=e||n.geometryChanged,i=n.state.facet(Gs);if(i.position!=this.position&&!this.madeAbsolute){this.position=i.position;for(let s of this.manager.tooltipViews)s.dom.style.position=this.position;t=!0}if(i.parent!=this.parent){this.parent&&this.container.remove(),this.parent=i.parent,this.createContainer();for(let s of this.manager.tooltipViews)this.container.appendChild(s.dom);t=!0}else this.parent&&this.view.themeClasses!=this.classes&&(this.classes=this.container.className=this.view.themeClasses);t&&this.maybeMeasure()}createTooltip(n,e){let t=n.create(this.view),i=e?e.dom:null;if(t.dom.classList.add("cm-tooltip"),n.arrow&&!t.dom.querySelector(".cm-tooltip > .cm-tooltip-arrow")){let s=document.createElement("div");s.className="cm-tooltip-arrow",t.dom.appendChild(s)}return t.dom.style.position=this.position,t.dom.style.top=An,t.dom.style.left="0px",this.container.insertBefore(t.dom,i),t.mount&&t.mount(this.view),this.resizeObserver&&this.resizeObserver.observe(t.dom),t}destroy(){var n,e,t;this.view.win.removeEventListener("resize",this.measureSoon);for(let i of this.manager.tooltipViews)i.dom.remove(),(n=i.destroy)===null||n===void 0||n.call(i);this.parent&&this.container.remove(),(e=this.resizeObserver)===null||e===void 0||e.disconnect(),(t=this.intersectionObserver)===null||t===void 0||t.disconnect(),clearTimeout(this.measureTimeout)}readMeasure(){let n=1,e=1,t=!1;if(this.position=="fixed"&&this.manager.tooltipViews.length){let{dom:r}=this.manager.tooltipViews[0];if(Q.safari){let o=r.getBoundingClientRect();t=Math.abs(o.top+1e4)>1||Math.abs(o.left)>1}else t=!!r.offsetParent&&r.offsetParent!=this.container.ownerDocument.body}if(t||this.position=="absolute")if(this.parent){let r=this.parent.getBoundingClientRect();r.width&&r.height&&(n=r.width/this.parent.offsetWidth,e=r.height/this.parent.offsetHeight)}else({scaleX:n,scaleY:e}=this.view.viewState);let i=this.view.scrollDOM.getBoundingClientRect(),s=Ao(this.view);return{visible:{left:i.left+s.left,top:i.top+s.top,right:i.right-s.right,bottom:i.bottom-s.bottom},parent:this.parent?this.container.getBoundingClientRect():this.view.dom.getBoundingClientRect(),pos:this.manager.tooltips.map((r,o)=>{let l=this.manager.tooltipViews[o];return l.getCoords?l.getCoords(r.pos):this.view.coordsAtPos(r.pos)}),size:this.manager.tooltipViews.map(({dom:r})=>r.getBoundingClientRect()),space:this.view.state.facet(Gs).tooltipSpace(this.view),scaleX:n,scaleY:e,makeAbsolute:t}}writeMeasure(n){var e;if(n.makeAbsolute){this.madeAbsolute=!0,this.position="absolute";for(let l of this.manager.tooltipViews)l.dom.style.position="absolute"}let{visible:t,space:i,scaleX:s,scaleY:r}=n,o=[];for(let l=0;l=Math.min(t.bottom,i.bottom)||f.rightMath.min(t.right,i.right)+.1)){c.style.top=An;continue}let d=a.arrow?h.dom.querySelector(".cm-tooltip-arrow"):null,p=d?7:0,m=u.right-u.left,g=(e=sa.get(h))!==null&&e!==void 0?e:u.bottom-u.top,y=h.offset||km,S=this.view.textDirection==Z.LTR,x=u.width>i.right-i.left?S?i.left:i.right-u.width:S?Math.max(i.left,Math.min(f.left-(d?14:0)+y.x,i.right-m)):Math.min(Math.max(i.left,f.left-m+(d?14:0)-y.x),i.right-m),w=this.above[l];!a.strictSide&&(w?f.top-g-p-y.yi.bottom)&&w==i.bottom-f.bottom>f.top-i.top&&(w=this.above[l]=!w);let k=(w?f.top-i.top:i.bottom-f.bottom)-p;if(kx&&E.topv&&(v=w?E.top-g-2-p:E.bottom+p+2);if(this.position=="absolute"?(c.style.top=(v-n.parent.top)/r+"px",ra(c,(x-n.parent.left)/s)):(c.style.top=v/r+"px",ra(c,x/s)),d){let E=f.left+(S?y.x:-y.x)-(x+14-7);d.style.left=E/s+"px"}h.overlap!==!0&&o.push({left:x,top:v,right:T,bottom:v+g}),c.classList.toggle("cm-tooltip-above",w),c.classList.toggle("cm-tooltip-below",!w),h.positioned&&h.positioned(n.space)}}maybeMeasure(){if(this.manager.tooltips.length&&(this.view.inView&&this.view.requestMeasure(this.measureReq),this.inView!=this.view.inView&&(this.inView=this.view.inView,!this.inView)))for(let n of this.manager.tooltipViews)n.dom.style.top=An}},{eventObservers:{scroll(){this.maybeMeasure()}}});function ra(n,e){let t=parseInt(n.style.left,10);(isNaN(t)||Math.abs(e-t)>1)&&(n.style.left=e+"px")}const xm=P.baseTheme({".cm-tooltip":{zIndex:500,boxSizing:"border-box"},"&light .cm-tooltip":{border:"1px solid #bbb",backgroundColor:"#f5f5f5"},"&light .cm-tooltip-section:not(:first-child)":{borderTop:"1px solid #bbb"},"&dark .cm-tooltip":{backgroundColor:"#333338",color:"white"},".cm-tooltip-arrow":{height:"7px",width:"14px",position:"absolute",zIndex:-1,overflow:"hidden","&:before, &:after":{content:"''",position:"absolute",width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent"},".cm-tooltip-above &":{bottom:"-7px","&:before":{borderTop:"7px solid #bbb"},"&:after":{borderTop:"7px solid #f5f5f5",bottom:"1px"}},".cm-tooltip-below &":{top:"-7px","&:before":{borderBottom:"7px solid #bbb"},"&:after":{borderBottom:"7px solid #f5f5f5",top:"1px"}}},"&dark .cm-tooltip .cm-tooltip-arrow":{"&:before":{borderTopColor:"#333338",borderBottomColor:"#333338"},"&:after":{borderTopColor:"transparent",borderBottomColor:"transparent"}}}),km={x:0,y:0},qo=A.define({enables:[Eo,xm]}),hs=A.define({combine:n=>n.reduce((e,t)=>e.concat(t),[])});class Ps{static create(e){return new Ps(e)}constructor(e){this.view=e,this.mounted=!1,this.dom=document.createElement("div"),this.dom.classList.add("cm-tooltip-hover"),this.manager=new Nc(e,hs,(t,i)=>this.createHostedView(t,i),t=>t.dom.remove())}createHostedView(e,t){let i=e.create(this.view);return i.dom.classList.add("cm-tooltip-section"),this.dom.insertBefore(i.dom,t?t.dom.nextSibling:this.dom.firstChild),this.mounted&&i.mount&&i.mount(this.view),i}mount(e){for(let t of this.manager.tooltipViews)t.mount&&t.mount(e);this.mounted=!0}positioned(e){for(let t of this.manager.tooltipViews)t.positioned&&t.positioned(e)}update(e){this.manager.update(e)}destroy(){var e;for(let t of this.manager.tooltipViews)(e=t.destroy)===null||e===void 0||e.call(t)}passProp(e){let t;for(let i of this.manager.tooltipViews){let s=i[e];if(s!==void 0){if(t===void 0)t=s;else if(t!==s)return}}return t}get offset(){return this.passProp("offset")}get getCoords(){return this.passProp("getCoords")}get overlap(){return this.passProp("overlap")}get resize(){return this.passProp("resize")}}const wm=qo.compute([hs],n=>{let e=n.facet(hs);return e.length===0?null:{pos:Math.min(...e.map(t=>t.pos)),end:Math.max(...e.map(t=>{var i;return(i=t.end)!==null&&i!==void 0?i:t.pos})),create:Ps.create,above:e[0].above,arrow:e.some(t=>t.arrow)}});class vm{constructor(e,t,i,s,r){this.view=e,this.source=t,this.field=i,this.setHover=s,this.hoverTime=r,this.hoverTimeout=-1,this.restartTimeout=-1,this.pending=null,this.lastMove={x:0,y:0,target:e.dom,time:0},this.checkHover=this.checkHover.bind(this),e.dom.addEventListener("mouseleave",this.mouseleave=this.mouseleave.bind(this)),e.dom.addEventListener("mousemove",this.mousemove=this.mousemove.bind(this))}update(){this.pending&&(this.pending=null,clearTimeout(this.restartTimeout),this.restartTimeout=setTimeout(()=>this.startHover(),20))}get active(){return this.view.state.field(this.field)}checkHover(){if(this.hoverTimeout=-1,this.active.length)return;let e=Date.now()-this.lastMove.time;el.bottom||t.xl.right+e.defaultCharacterWidth)return;let a=e.bidiSpans(e.state.doc.lineAt(s)).find(c=>c.from<=s&&c.to>=s),h=a&&a.dir==Z.RTL?-1:1;r=t.x{this.pending==l&&(this.pending=null,a&&!(Array.isArray(a)&&!a.length)&&e.dispatch({effects:this.setHover.of(Array.isArray(a)?a:[a])}))},a=>Pe(e.state,a,"hover tooltip"))}else o&&!(Array.isArray(o)&&!o.length)&&e.dispatch({effects:this.setHover.of(Array.isArray(o)?o:[o])})}get tooltip(){let e=this.view.plugin(Eo),t=e?e.manager.tooltips.findIndex(i=>i.create==Ps.create):-1;return t>-1?e.manager.tooltipViews[t]:null}mousemove(e){var t,i;this.lastMove={x:e.clientX,y:e.clientY,target:e.target,time:Date.now()},this.hoverTimeout<0&&(this.hoverTimeout=setTimeout(this.checkHover,this.hoverTime));let{active:s,tooltip:r}=this;if(s.length&&r&&!Tm(r.dom,e)||this.pending){let{pos:o}=s[0]||this.pending,l=(i=(t=s[0])===null||t===void 0?void 0:t.end)!==null&&i!==void 0?i:o;(o==l?this.view.posAtCoords(this.lastMove)!=o:!Cm(this.view,o,l,e.clientX,e.clientY))&&(this.view.dispatch({effects:this.setHover.of([])}),this.pending=null)}}mouseleave(e){clearTimeout(this.hoverTimeout),this.hoverTimeout=-1;let{active:t}=this;if(t.length){let{tooltip:i}=this;i&&i.dom.contains(e.relatedTarget)?this.watchTooltipLeave(i.dom):this.view.dispatch({effects:this.setHover.of([])})}}watchTooltipLeave(e){let t=i=>{e.removeEventListener("mouseleave",t),this.active.length&&!this.view.dom.contains(i.relatedTarget)&&this.view.dispatch({effects:this.setHover.of([])})};e.addEventListener("mouseleave",t)}destroy(){clearTimeout(this.hoverTimeout),this.view.dom.removeEventListener("mouseleave",this.mouseleave),this.view.dom.removeEventListener("mousemove",this.mousemove)}}const Mn=4;function Tm(n,e){let{left:t,right:i,top:s,bottom:r}=n.getBoundingClientRect(),o;if(o=n.querySelector(".cm-tooltip-arrow")){let l=o.getBoundingClientRect();s=Math.min(l.top,s),r=Math.max(l.bottom,r)}return e.clientX>=t-Mn&&e.clientX<=i+Mn&&e.clientY>=s-Mn&&e.clientY<=r+Mn}function Cm(n,e,t,i,s,r){let o=n.scrollDOM.getBoundingClientRect(),l=n.documentTop+n.documentPadding.top+n.contentHeight;if(o.left>i||o.rights||Math.min(o.bottom,l)=e&&a<=t}function Pm(n,e={}){let t=q.define(),i=he.define({create(){return[]},update(s,r){if(s.length&&(e.hideOnChange&&(r.docChanged||r.selection)?s=[]:e.hideOn&&(s=s.filter(o=>!e.hideOn(r,o))),r.docChanged)){let o=[];for(let l of s){let a=r.changes.mapPos(l.pos,-1,de.TrackDel);if(a!=null){let h=Object.assign(Object.create(null),l);h.pos=a,h.end!=null&&(h.end=r.changes.mapPos(h.end)),o.push(h)}}s=o}for(let o of r.effects)o.is(t)&&(s=o.value),o.is(Qm)&&(s=[]);return s},provide:s=>hs.from(s)});return{active:i,extension:[i,J.define(s=>new vm(s,n,i,t,e.hoverTime||300)),wm]}}function Xc(n,e){let t=n.plugin(Eo);if(!t)return null;let i=t.manager.tooltips.indexOf(e);return i<0?null:t.manager.tooltipViews[i]}const Qm=q.define(),oa=A.define({combine(n){let e,t;for(let i of n)e=e||i.topContainer,t=t||i.bottomContainer;return{topContainer:e,bottomContainer:t}}});function Ni(n,e){let t=n.plugin(Fc),i=t?t.specs.indexOf(e):-1;return i>-1?t.panels[i]:null}const Fc=J.fromClass(class{constructor(n){this.input=n.state.facet(Xi),this.specs=this.input.filter(t=>t),this.panels=this.specs.map(t=>t(n));let e=n.state.facet(oa);this.top=new Rn(n,!0,e.topContainer),this.bottom=new Rn(n,!1,e.bottomContainer),this.top.sync(this.panels.filter(t=>t.top)),this.bottom.sync(this.panels.filter(t=>!t.top));for(let t of this.panels)t.dom.classList.add("cm-panel"),t.mount&&t.mount()}update(n){let e=n.state.facet(oa);this.top.container!=e.topContainer&&(this.top.sync([]),this.top=new Rn(n.view,!0,e.topContainer)),this.bottom.container!=e.bottomContainer&&(this.bottom.sync([]),this.bottom=new Rn(n.view,!1,e.bottomContainer)),this.top.syncClasses(),this.bottom.syncClasses();let t=n.state.facet(Xi);if(t!=this.input){let i=t.filter(a=>a),s=[],r=[],o=[],l=[];for(let a of i){let h=this.specs.indexOf(a),c;h<0?(c=a(n.view),l.push(c)):(c=this.panels[h],c.update&&c.update(n)),s.push(c),(c.top?r:o).push(c)}this.specs=i,this.panels=s,this.top.sync(r),this.bottom.sync(o);for(let a of l)a.dom.classList.add("cm-panel"),a.mount&&a.mount()}else for(let i of this.panels)i.update&&i.update(n)}destroy(){this.top.sync([]),this.bottom.sync([])}},{provide:n=>P.scrollMargins.of(e=>{let t=e.plugin(n);return t&&{top:t.top.scrollMargin(),bottom:t.bottom.scrollMargin()}})});class Rn{constructor(e,t,i){this.view=e,this.top=t,this.container=i,this.dom=void 0,this.classes="",this.panels=[],this.syncClasses()}sync(e){for(let t of this.panels)t.destroy&&e.indexOf(t)<0&&t.destroy();this.panels=e,this.syncDOM()}syncDOM(){if(this.panels.length==0){this.dom&&(this.dom.remove(),this.dom=void 0);return}if(!this.dom){this.dom=document.createElement("div"),this.dom.className=this.top?"cm-panels cm-panels-top":"cm-panels cm-panels-bottom",this.dom.style[this.top?"top":"bottom"]="0";let t=this.container||this.view.dom;t.insertBefore(this.dom,this.top?t.firstChild:null)}let e=this.dom.firstChild;for(let t of this.panels)if(t.dom.parentNode==this.dom){for(;e!=t.dom;)e=la(e);e=e.nextSibling}else this.dom.insertBefore(t.dom,e);for(;e;)e=la(e)}scrollMargin(){return!this.dom||this.container?0:Math.max(0,this.top?this.dom.getBoundingClientRect().bottom-Math.max(0,this.view.scrollDOM.getBoundingClientRect().top):Math.min(innerHeight,this.view.scrollDOM.getBoundingClientRect().bottom)-this.dom.getBoundingClientRect().top)}syncClasses(){if(!(!this.container||this.classes==this.view.themeClasses)){for(let e of this.classes.split(" "))e&&this.container.classList.remove(e);for(let e of(this.classes=this.view.themeClasses).split(" "))e&&this.container.classList.add(e)}}}function la(n){let e=n.nextSibling;return n.remove(),e}const Xi=A.define({enables:Fc});class yt extends Nt{compare(e){return this==e||this.constructor==e.constructor&&this.eq(e)}eq(e){return!1}destroy(e){}}yt.prototype.elementClass="";yt.prototype.toDOM=void 0;yt.prototype.mapMode=de.TrackBefore;yt.prototype.startSide=yt.prototype.endSide=-1;yt.prototype.point=!0;const Zn=A.define(),Am=A.define(),Mm={class:"",renderEmptyElements:!1,elementStyle:"",markers:()=>N.empty,lineMarker:()=>null,widgetMarker:()=>null,lineMarkerChange:null,initialSpacer:null,updateSpacer:null,domEventHandlers:{},side:"before"},qi=A.define();function Rm(n){return[_c(),qi.of({...Mm,...n})]}const aa=A.define({combine:n=>n.some(e=>e)});function _c(n){return[Dm]}const Dm=J.fromClass(class{constructor(n){this.view=n,this.domAfter=null,this.prevViewport=n.viewport,this.dom=document.createElement("div"),this.dom.className="cm-gutters cm-gutters-before",this.dom.setAttribute("aria-hidden","true"),this.dom.style.minHeight=this.view.contentHeight/this.view.scaleY+"px",this.gutters=n.state.facet(qi).map(e=>new ca(n,e)),this.fixed=!n.state.facet(aa);for(let e of this.gutters)e.config.side=="after"?this.getDOMAfter().appendChild(e.dom):this.dom.appendChild(e.dom);this.fixed&&(this.dom.style.position="sticky"),this.syncGutters(!1),n.scrollDOM.insertBefore(this.dom,n.contentDOM)}getDOMAfter(){return this.domAfter||(this.domAfter=document.createElement("div"),this.domAfter.className="cm-gutters cm-gutters-after",this.domAfter.setAttribute("aria-hidden","true"),this.domAfter.style.minHeight=this.view.contentHeight/this.view.scaleY+"px",this.domAfter.style.position=this.fixed?"sticky":"",this.view.scrollDOM.appendChild(this.domAfter)),this.domAfter}update(n){if(this.updateGutters(n)){let e=this.prevViewport,t=n.view.viewport,i=Math.min(e.to,t.to)-Math.max(e.from,t.from);this.syncGutters(i<(t.to-t.from)*.8)}if(n.geometryChanged){let e=this.view.contentHeight/this.view.scaleY+"px";this.dom.style.minHeight=e,this.domAfter&&(this.domAfter.style.minHeight=e)}this.view.state.facet(aa)!=!this.fixed&&(this.fixed=!this.fixed,this.dom.style.position=this.fixed?"sticky":"",this.domAfter&&(this.domAfter.style.position=this.fixed?"sticky":"")),this.prevViewport=n.view.viewport}syncGutters(n){let e=this.dom.nextSibling;n&&(this.dom.remove(),this.domAfter&&this.domAfter.remove());let t=N.iter(this.view.state.facet(Zn),this.view.viewport.from),i=[],s=this.gutters.map(r=>new Em(r,this.view.viewport,-this.view.documentPadding.top));for(let r of this.view.viewportLineBlocks)if(i.length&&(i=[]),Array.isArray(r.type)){let o=!0;for(let l of r.type)if(l.type==ke.Text&&o){so(t,i,l.from);for(let a of s)a.line(this.view,l,i);o=!1}else if(l.widget)for(let a of s)a.widget(this.view,l)}else if(r.type==ke.Text){so(t,i,r.from);for(let o of s)o.line(this.view,r,i)}else if(r.widget)for(let o of s)o.widget(this.view,r);for(let r of s)r.finish();n&&(this.view.scrollDOM.insertBefore(this.dom,e),this.domAfter&&this.view.scrollDOM.appendChild(this.domAfter))}updateGutters(n){let e=n.startState.facet(qi),t=n.state.facet(qi),i=n.docChanged||n.heightChanged||n.viewportChanged||!N.eq(n.startState.facet(Zn),n.state.facet(Zn),n.view.viewport.from,n.view.viewport.to);if(e==t)for(let s of this.gutters)s.update(n)&&(i=!0);else{i=!0;let s=[];for(let r of t){let o=e.indexOf(r);o<0?s.push(new ca(this.view,r)):(this.gutters[o].update(n),s.push(this.gutters[o]))}for(let r of this.gutters)r.dom.remove(),s.indexOf(r)<0&&r.destroy();for(let r of s)r.config.side=="after"?this.getDOMAfter().appendChild(r.dom):this.dom.appendChild(r.dom);this.gutters=s}return i}destroy(){for(let n of this.gutters)n.destroy();this.dom.remove(),this.domAfter&&this.domAfter.remove()}},{provide:n=>P.scrollMargins.of(e=>{let t=e.plugin(n);if(!t||t.gutters.length==0||!t.fixed)return null;let i=t.dom.offsetWidth*e.scaleX,s=t.domAfter?t.domAfter.offsetWidth*e.scaleX:0;return e.textDirection==Z.LTR?{left:i,right:s}:{right:i,left:s}})});function ha(n){return Array.isArray(n)?n:[n]}function so(n,e,t){for(;n.value&&n.from<=t;)n.from==t&&e.push(n.value),n.next()}class Em{constructor(e,t,i){this.gutter=e,this.height=i,this.i=0,this.cursor=N.iter(e.markers,t.from)}addElement(e,t,i){let{gutter:s}=this,r=(t.top-this.height)/e.scaleY,o=t.height/e.scaleY;if(this.i==s.elements.length){let l=new Uc(e,o,r,i);s.elements.push(l),s.dom.appendChild(l.dom)}else s.elements[this.i].update(e,o,r,i);this.height=t.bottom,this.i++}line(e,t,i){let s=[];so(this.cursor,s,t.from),i.length&&(s=s.concat(i));let r=this.gutter.config.lineMarker(e,t,s);r&&s.unshift(r);let o=this.gutter;s.length==0&&!o.config.renderEmptyElements||this.addElement(e,t,s)}widget(e,t){let i=this.gutter.config.widgetMarker(e,t.widget,t),s=i?[i]:null;for(let r of e.state.facet(Am)){let o=r(e,t.widget,t);o&&(s||(s=[])).push(o)}s&&this.addElement(e,t,s)}finish(){let e=this.gutter;for(;e.elements.length>this.i;){let t=e.elements.pop();e.dom.removeChild(t.dom),t.destroy()}}}class ca{constructor(e,t){this.view=e,this.config=t,this.elements=[],this.spacer=null,this.dom=document.createElement("div"),this.dom.className="cm-gutter"+(this.config.class?" "+this.config.class:"");for(let i in t.domEventHandlers)this.dom.addEventListener(i,s=>{let r=s.target,o;if(r!=this.dom&&this.dom.contains(r)){for(;r.parentNode!=this.dom;)r=r.parentNode;let a=r.getBoundingClientRect();o=(a.top+a.bottom)/2}else o=s.clientY;let l=e.lineBlockAtHeight(o-e.documentTop);t.domEventHandlers[i](e,l,s)&&s.preventDefault()});this.markers=ha(t.markers(e)),t.initialSpacer&&(this.spacer=new Uc(e,0,0,[t.initialSpacer(e)]),this.dom.appendChild(this.spacer.dom),this.spacer.dom.style.cssText+="visibility: hidden; pointer-events: none")}update(e){let t=this.markers;if(this.markers=ha(this.config.markers(e.view)),this.spacer&&this.config.updateSpacer){let s=this.config.updateSpacer(this.spacer.markers[0],e);s!=this.spacer.markers[0]&&this.spacer.update(e.view,0,0,[s])}let i=e.view.viewport;return!N.eq(this.markers,t,i.from,i.to)||(this.config.lineMarkerChange?this.config.lineMarkerChange(e):!1)}destroy(){for(let e of this.elements)e.destroy()}}class Uc{constructor(e,t,i,s){this.height=-1,this.above=0,this.markers=[],this.dom=document.createElement("div"),this.dom.className="cm-gutterElement",this.update(e,t,i,s)}update(e,t,i,s){this.height!=t&&(this.height=t,this.dom.style.height=t+"px"),this.above!=i&&(this.dom.style.marginTop=(this.above=i)?i+"px":""),qm(this.markers,s)||this.setMarkers(e,s)}setMarkers(e,t){let i="cm-gutterElement",s=this.dom.firstChild;for(let r=0,o=0;;){let l=o,a=rr(l,a,h)||o(l,a,h):o}return i}})}});class Zs extends yt{constructor(e){super(),this.number=e}eq(e){return this.number==e.number}toDOM(){return document.createTextNode(this.number)}}function Ys(n,e){return n.state.facet(Jt).formatNumber(e,n.state)}const Wm=qi.compute([Jt],n=>({class:"cm-lineNumbers",renderEmptyElements:!1,markers(e){return e.state.facet($m)},lineMarker(e,t,i){return i.some(s=>s.toDOM)?null:new Zs(Ys(e,e.state.doc.lineAt(t.from).number))},widgetMarker:(e,t,i)=>{for(let s of e.state.facet(Bm)){let r=s(e,t,i);if(r)return r}return null},lineMarkerChange:e=>e.startState.facet(Jt)!=e.state.facet(Jt),initialSpacer(e){return new Zs(Ys(e,fa(e.state.doc.lines)))},updateSpacer(e,t){let i=Ys(t.view,fa(t.view.state.doc.lines));return i==e.number?e:new Zs(i)},domEventHandlers:n.facet(Jt).domEventHandlers,side:"before"}));function Lm(n={}){return[Jt.of(n),_c(),Wm]}function fa(n){let e=9;for(;e{let e=[],t=-1;for(let i of n.selection.ranges){let s=n.doc.lineAt(i.head).from;s>t&&(t=s,e.push(zm.range(s)))}return N.of(e)});function Vm(){return Im}const Hc=1024;let Nm=0;class Ks{constructor(e,t){this.from=e,this.to=t}}class L{constructor(e={}){this.id=Nm++,this.perNode=!!e.perNode,this.deserialize=e.deserialize||(()=>{throw new Error("This node type doesn't define a deserialize function")}),this.combine=e.combine||null}add(e){if(this.perNode)throw new RangeError("Can't add per-node props to node types");return typeof e!="function"&&(e=ve.match(e)),t=>{let i=e(t);return i===void 0?null:[this,i]}}}L.closedBy=new L({deserialize:n=>n.split(" ")});L.openedBy=new L({deserialize:n=>n.split(" ")});L.group=new L({deserialize:n=>n.split(" ")});L.isolate=new L({deserialize:n=>{if(n&&n!="rtl"&&n!="ltr"&&n!="auto")throw new RangeError("Invalid value for isolate: "+n);return n||"auto"}});L.contextHash=new L({perNode:!0});L.lookAhead=new L({perNode:!0});L.mounted=new L({perNode:!0});class cs{constructor(e,t,i){this.tree=e,this.overlay=t,this.parser=i}static get(e){return e&&e.props&&e.props[L.mounted.id]}}const Xm=Object.create(null);class ve{constructor(e,t,i,s=0){this.name=e,this.props=t,this.id=i,this.flags=s}static define(e){let t=e.props&&e.props.length?Object.create(null):Xm,i=(e.top?1:0)|(e.skipped?2:0)|(e.error?4:0)|(e.name==null?8:0),s=new ve(e.name||"",t,e.id,i);if(e.props){for(let r of e.props)if(Array.isArray(r)||(r=r(s)),r){if(r[0].perNode)throw new RangeError("Can't store a per-node prop on a node type");t[r[0].id]=r[1]}}return s}prop(e){return this.props[e.id]}get isTop(){return(this.flags&1)>0}get isSkipped(){return(this.flags&2)>0}get isError(){return(this.flags&4)>0}get isAnonymous(){return(this.flags&8)>0}is(e){if(typeof e=="string"){if(this.name==e)return!0;let t=this.prop(L.group);return t?t.indexOf(e)>-1:!1}return this.id==e}static match(e){let t=Object.create(null);for(let i in e)for(let s of i.split(" "))t[s]=e[i];return i=>{for(let s=i.prop(L.group),r=-1;r<(s?s.length:0);r++){let o=t[r<0?i.name:s[r]];if(o)return o}}}}ve.none=new ve("",Object.create(null),0,8);class Qs{constructor(e){this.types=e;for(let t=0;t0;for(let a=this.cursor(o|re.IncludeAnonymous);;){let h=!1;if(a.from<=r&&a.to>=s&&(!l&&a.type.isAnonymous||t(a)!==!1)){if(a.firstChild())continue;h=!0}for(;h&&i&&(l||!a.type.isAnonymous)&&i(a),!a.nextSibling();){if(!a.parent())return;h=!0}}}prop(e){return e.perNode?this.props?this.props[e.id]:void 0:this.type.prop(e)}get propValues(){let e=[];if(this.props)for(let t in this.props)e.push([+t,this.props[t]]);return e}balance(e={}){return this.children.length<=8?this:Wo(ve.none,this.children,this.positions,0,this.children.length,0,this.length,(t,i,s)=>new j(this.type,t,i,s,this.propValues),e.makeTree||((t,i,s)=>new j(ve.none,t,i,s)))}static build(e){return Hm(e)}}j.empty=new j(ve.none,[],[],0);class $o{constructor(e,t){this.buffer=e,this.index=t}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}get pos(){return this.index}next(){this.index-=4}fork(){return new $o(this.buffer,this.index)}}class Qt{constructor(e,t,i){this.buffer=e,this.length=t,this.set=i}get type(){return ve.none}toString(){let e=[];for(let t=0;t0));a=o[a+3]);return l}slice(e,t,i){let s=this.buffer,r=new Uint16Array(t-e),o=0;for(let l=e,a=0;l=e&&te;case 1:return t<=e&&i>e;case 2:return i>e;case 4:return!0}}function Fi(n,e,t,i){for(var s;n.from==n.to||(t<1?n.from>=e:n.from>e)||(t>-1?n.to<=e:n.to0?l.length:-1;e!=h;e+=t){let c=l[e],f=a[e]+o.from;if(jc(s,i,f,f+c.length)){if(c instanceof Qt){if(r&re.ExcludeBuffers)continue;let u=c.findChild(0,c.buffer.length,t,i-f,s);if(u>-1)return new Je(new Fm(o,c,e,f),null,u)}else if(r&re.IncludeAnonymous||!c.type.isAnonymous||Bo(c)){let u;if(!(r&re.IgnoreMounts)&&(u=cs.get(c))&&!u.overlay)return new Ae(u.tree,f,e,o);let d=new Ae(c,f,e,o);return r&re.IncludeAnonymous||!d.type.isAnonymous?d:d.nextChild(t<0?c.children.length-1:0,t,i,s)}}}if(r&re.IncludeAnonymous||!o.type.isAnonymous||(o.index>=0?e=o.index+t:e=t<0?-1:o._parent._tree.children.length,o=o._parent,!o))return null}}get firstChild(){return this.nextChild(0,1,0,4)}get lastChild(){return this.nextChild(this._tree.children.length-1,-1,0,4)}childAfter(e){return this.nextChild(0,1,e,2)}childBefore(e){return this.nextChild(this._tree.children.length-1,-1,e,-2)}enter(e,t,i=0){let s;if(!(i&re.IgnoreOverlays)&&(s=cs.get(this._tree))&&s.overlay){let r=e-this.from;for(let{from:o,to:l}of s.overlay)if((t>0?o<=r:o=r:l>r))return new Ae(s.tree,s.overlay[0].from+this.from,-1,this)}return this.nextChild(0,1,e,t,i)}nextSignificantParent(){let e=this;for(;e.type.isAnonymous&&e._parent;)e=e._parent;return e}get parent(){return this._parent?this._parent.nextSignificantParent():null}get nextSibling(){return this._parent&&this.index>=0?this._parent.nextChild(this.index+1,1,0,4):null}get prevSibling(){return this._parent&&this.index>=0?this._parent.nextChild(this.index-1,-1,0,4):null}get tree(){return this._tree}toTree(){return this._tree}toString(){return this._tree.toString()}}function da(n,e,t,i){let s=n.cursor(),r=[];if(!s.firstChild())return r;if(t!=null){for(let o=!1;!o;)if(o=s.type.is(t),!s.nextSibling())return r}for(;;){if(i!=null&&s.type.is(i))return r;if(s.type.is(e)&&r.push(s.node),!s.nextSibling())return i==null?r:[]}}function ro(n,e,t=e.length-1){for(let i=n;t>=0;i=i.parent){if(!i)return!1;if(!i.type.isAnonymous){if(e[t]&&e[t]!=i.name)return!1;t--}}return!0}class Fm{constructor(e,t,i,s){this.parent=e,this.buffer=t,this.index=i,this.start=s}}class Je extends Gc{get name(){return this.type.name}get from(){return this.context.start+this.context.buffer.buffer[this.index+1]}get to(){return this.context.start+this.context.buffer.buffer[this.index+2]}constructor(e,t,i){super(),this.context=e,this._parent=t,this.index=i,this.type=e.buffer.set.types[e.buffer.buffer[i]]}child(e,t,i){let{buffer:s}=this.context,r=s.findChild(this.index+4,s.buffer[this.index+3],e,t-this.context.start,i);return r<0?null:new Je(this.context,this,r)}get firstChild(){return this.child(1,0,4)}get lastChild(){return this.child(-1,0,4)}childAfter(e){return this.child(1,e,2)}childBefore(e){return this.child(-1,e,-2)}enter(e,t,i=0){if(i&re.ExcludeBuffers)return null;let{buffer:s}=this.context,r=s.findChild(this.index+4,s.buffer[this.index+3],t>0?1:-1,e-this.context.start,t);return r<0?null:new Je(this.context,this,r)}get parent(){return this._parent||this.context.parent.nextSignificantParent()}externalSibling(e){return this._parent?null:this.context.parent.nextChild(this.context.index+e,e,0,4)}get nextSibling(){let{buffer:e}=this.context,t=e.buffer[this.index+3];return t<(this._parent?e.buffer[this._parent.index+3]:e.buffer.length)?new Je(this.context,this._parent,t):this.externalSibling(1)}get prevSibling(){let{buffer:e}=this.context,t=this._parent?this._parent.index+4:0;return this.index==t?this.externalSibling(-1):new Je(this.context,this._parent,e.findChild(t,this.index,-1,0,4))}get tree(){return null}toTree(){let e=[],t=[],{buffer:i}=this.context,s=this.index+4,r=i.buffer[this.index+3];if(r>s){let o=i.buffer[this.index+1];e.push(i.slice(s,r,o)),t.push(0)}return new j(this.type,e,t,this.to-this.from)}toString(){return this.context.buffer.childString(this.index)}}function Zc(n){if(!n.length)return null;let e=0,t=n[0];for(let r=1;rt.from||o.to=e){let l=new Ae(o.tree,o.overlay[0].from+r.from,-1,r);(s||(s=[i])).push(Fi(l,e,t,!1))}}return s?Zc(s):i}class oo{get name(){return this.type.name}constructor(e,t=0){if(this.mode=t,this.buffer=null,this.stack=[],this.index=0,this.bufferNode=null,e instanceof Ae)this.yieldNode(e);else{this._tree=e.context.parent,this.buffer=e.context;for(let i=e._parent;i;i=i._parent)this.stack.unshift(i.index);this.bufferNode=e,this.yieldBuf(e.index)}}yieldNode(e){return e?(this._tree=e,this.type=e.type,this.from=e.from,this.to=e.to,!0):!1}yieldBuf(e,t){this.index=e;let{start:i,buffer:s}=this.buffer;return this.type=t||s.set.types[s.buffer[e]],this.from=i+s.buffer[e+1],this.to=i+s.buffer[e+2],!0}yield(e){return e?e instanceof Ae?(this.buffer=null,this.yieldNode(e)):(this.buffer=e.context,this.yieldBuf(e.index,e.type)):!1}toString(){return this.buffer?this.buffer.buffer.childString(this.index):this._tree.toString()}enterChild(e,t,i){if(!this.buffer)return this.yield(this._tree.nextChild(e<0?this._tree._tree.children.length-1:0,e,t,i,this.mode));let{buffer:s}=this.buffer,r=s.findChild(this.index+4,s.buffer[this.index+3],e,t-this.buffer.start,i);return r<0?!1:(this.stack.push(this.index),this.yieldBuf(r))}firstChild(){return this.enterChild(1,0,4)}lastChild(){return this.enterChild(-1,0,4)}childAfter(e){return this.enterChild(1,e,2)}childBefore(e){return this.enterChild(-1,e,-2)}enter(e,t,i=this.mode){return this.buffer?i&re.ExcludeBuffers?!1:this.enterChild(1,e,t):this.yield(this._tree.enter(e,t,i))}parent(){if(!this.buffer)return this.yieldNode(this.mode&re.IncludeAnonymous?this._tree._parent:this._tree.parent);if(this.stack.length)return this.yieldBuf(this.stack.pop());let e=this.mode&re.IncludeAnonymous?this.buffer.parent:this.buffer.parent.nextSignificantParent();return this.buffer=null,this.yieldNode(e)}sibling(e){if(!this.buffer)return this._tree._parent?this.yield(this._tree.index<0?null:this._tree._parent.nextChild(this._tree.index+e,e,0,4,this.mode)):!1;let{buffer:t}=this.buffer,i=this.stack.length-1;if(e<0){let s=i<0?0:this.stack[i]+4;if(this.index!=s)return this.yieldBuf(t.findChild(s,this.index,-1,0,4))}else{let s=t.buffer[this.index+3];if(s<(i<0?t.buffer.length:t.buffer[this.stack[i]+3]))return this.yieldBuf(s)}return i<0?this.yield(this.buffer.parent.nextChild(this.buffer.index+e,e,0,4,this.mode)):!1}nextSibling(){return this.sibling(1)}prevSibling(){return this.sibling(-1)}atLastNode(e){let t,i,{buffer:s}=this;if(s){if(e>0){if(this.index-1)for(let r=t+e,o=e<0?-1:i._tree.children.length;r!=o;r+=e){let l=i._tree.children[r];if(this.mode&re.IncludeAnonymous||l instanceof Qt||!l.type.isAnonymous||Bo(l))return!1}return!0}move(e,t){if(t&&this.enterChild(e,0,4))return!0;for(;;){if(this.sibling(e))return!0;if(this.atLastNode(e)||!this.parent())return!1}}next(e=!0){return this.move(1,e)}prev(e=!0){return this.move(-1,e)}moveTo(e,t=0){for(;(this.from==this.to||(t<1?this.from>=e:this.from>e)||(t>-1?this.to<=e:this.to=0;){for(let o=e;o;o=o._parent)if(o.index==s){if(s==this.index)return o;t=o,i=r+1;break e}s=this.stack[--r]}for(let s=i;s=0;r--){if(r<0)return ro(this._tree,e,s);let o=i[t.buffer[this.stack[r]]];if(!o.isAnonymous){if(e[s]&&e[s]!=o.name)return!1;s--}}return!0}}function Bo(n){return n.children.some(e=>e instanceof Qt||!e.type.isAnonymous||Bo(e))}function Hm(n){var e;let{buffer:t,nodeSet:i,maxBufferLength:s=Hc,reused:r=[],minRepeatType:o=i.types.length}=n,l=Array.isArray(t)?new $o(t,t.length):t,a=i.types,h=0,c=0;function f(k,v,T,E,M,z){let{id:$,start:D,end:B,size:W}=l,X=c,ne=h;if(W<0)if(l.next(),W==-1){let ce=r[$];T.push(ce),E.push(D-k);return}else if(W==-3){h=$;return}else if(W==-4){c=$;return}else throw new RangeError(`Unrecognized record size: ${W}`);let oe=a[$],me,F,ee=D-k;if(B-D<=s&&(F=g(l.pos-v,M))){let ce=new Uint16Array(F.size-F.skip),ge=l.pos-F.size,_e=ce.length;for(;l.pos>ge;)_e=y(F.start,ce,_e);me=new Qt(ce,B-F.start,i),ee=F.start-k}else{let ce=l.pos-W;l.next();let ge=[],_e=[],Dt=$>=o?$:-1,Gt=0,gn=B;for(;l.pos>ce;)Dt>=0&&l.id==Dt&&l.size>=0?(l.end<=gn-s&&(p(ge,_e,D,Gt,l.end,gn,Dt,X,ne),Gt=ge.length,gn=l.end),l.next()):z>2500?u(D,ce,ge,_e):f(D,ce,ge,_e,Dt,z+1);if(Dt>=0&&Gt>0&&Gt-1&&Gt>0){let al=d(oe,ne);me=Wo(oe,ge,_e,0,ge.length,0,B-D,al,al)}else me=m(oe,ge,_e,B-D,X-B,ne)}T.push(me),E.push(ee)}function u(k,v,T,E){let M=[],z=0,$=-1;for(;l.pos>v;){let{id:D,start:B,end:W,size:X}=l;if(X>4)l.next();else{if($>-1&&B<$)break;$<0&&($=W-s),M.push(D,B,W),z++,l.next()}}if(z){let D=new Uint16Array(z*4),B=M[M.length-2];for(let W=M.length-3,X=0;W>=0;W-=3)D[X++]=M[W],D[X++]=M[W+1]-B,D[X++]=M[W+2]-B,D[X++]=X;T.push(new Qt(D,M[2]-B,i)),E.push(B-k)}}function d(k,v){return(T,E,M)=>{let z=0,$=T.length-1,D,B;if($>=0&&(D=T[$])instanceof j){if(!$&&D.type==k&&D.length==M)return D;(B=D.prop(L.lookAhead))&&(z=E[$]+D.length+B)}return m(k,T,E,M,z,v)}}function p(k,v,T,E,M,z,$,D,B){let W=[],X=[];for(;k.length>E;)W.push(k.pop()),X.push(v.pop()+T-M);k.push(m(i.types[$],W,X,z-M,D-z,B)),v.push(M-T)}function m(k,v,T,E,M,z,$){if(z){let D=[L.contextHash,z];$=$?[D].concat($):[D]}if(M>25){let D=[L.lookAhead,M];$=$?[D].concat($):[D]}return new j(k,v,T,E,$)}function g(k,v){let T=l.fork(),E=0,M=0,z=0,$=T.end-s,D={size:0,start:0,skip:0};e:for(let B=T.pos-k;T.pos>B;){let W=T.size;if(T.id==v&&W>=0){D.size=E,D.start=M,D.skip=z,z+=4,E+=4,T.next();continue}let X=T.pos-W;if(W<0||X=o?4:0,oe=T.start;for(T.next();T.pos>X;){if(T.size<0)if(T.size==-3)ne+=4;else break e;else T.id>=o&&(ne+=4);T.next()}M=oe,E+=W,z+=ne}return(v<0||E==k)&&(D.size=E,D.start=M,D.skip=z),D.size>4?D:void 0}function y(k,v,T){let{id:E,start:M,end:z,size:$}=l;if(l.next(),$>=0&&E4){let B=l.pos-($-4);for(;l.pos>B;)T=y(k,v,T)}v[--T]=D,v[--T]=z-k,v[--T]=M-k,v[--T]=E}else $==-3?h=E:$==-4&&(c=E);return T}let S=[],x=[];for(;l.pos>0;)f(n.start||0,n.bufferStart||0,S,x,-1,0);let w=(e=n.length)!==null&&e!==void 0?e:S.length?x[0]+S[0].length:0;return new j(a[n.topID],S.reverse(),x.reverse(),w)}const pa=new WeakMap;function Yn(n,e){if(!n.isAnonymous||e instanceof Qt||e.type!=n)return 1;let t=pa.get(e);if(t==null){t=1;for(let i of e.children){if(i.type!=n||!(i instanceof j)){t=1;break}t+=Yn(n,i)}pa.set(e,t)}return t}function Wo(n,e,t,i,s,r,o,l,a){let h=0;for(let p=i;p=c)break;v+=T}if(x==w+1){if(v>c){let T=p[w];d(T.children,T.positions,0,T.children.length,m[w]+S);continue}f.push(p[w])}else{let T=m[x-1]+p[x-1].length-k;f.push(Wo(n,p,m,w,x,k,T,null,a))}u.push(k+S-r)}}return d(e,t,i,s,0),(l||a)(f,u,o)}class jm{constructor(){this.map=new WeakMap}setBuffer(e,t,i){let s=this.map.get(e);s||this.map.set(e,s=new Map),s.set(t,i)}getBuffer(e,t){let i=this.map.get(e);return i&&i.get(t)}set(e,t){e instanceof Je?this.setBuffer(e.context.buffer,e.index,t):e instanceof Ae&&this.map.set(e.tree,t)}get(e){return e instanceof Je?this.getBuffer(e.context.buffer,e.index):e instanceof Ae?this.map.get(e.tree):void 0}cursorSet(e,t){e.buffer?this.setBuffer(e.buffer.buffer,e.index,t):this.map.set(e.tree,t)}cursorGet(e){return e.buffer?this.getBuffer(e.buffer.buffer,e.index):this.map.get(e.tree)}}class It{constructor(e,t,i,s,r=!1,o=!1){this.from=e,this.to=t,this.tree=i,this.offset=s,this.open=(r?1:0)|(o?2:0)}get openStart(){return(this.open&1)>0}get openEnd(){return(this.open&2)>0}static addTree(e,t=[],i=!1){let s=[new It(0,e.length,e,0,!1,i)];for(let r of t)r.to>e.length&&s.push(r);return s}static applyChanges(e,t,i=128){if(!t.length)return e;let s=[],r=1,o=e.length?e[0]:null;for(let l=0,a=0,h=0;;l++){let c=l=i)for(;o&&o.from=u.from||f<=u.to||h){let d=Math.max(u.from,a)-h,p=Math.min(u.to,f)-h;u=d>=p?null:new It(d,p,u.tree,u.offset+h,l>0,!!c)}if(u&&s.push(u),o.to>f)break;o=rnew Ks(s.from,s.to)):[new Ks(0,0)]:[new Ks(0,e.length)],this.createParse(e,t||[],i)}parse(e,t,i){let s=this.startParse(e,t,i);for(;;){let r=s.advance();if(r)return r}}}class Gm{constructor(e){this.string=e}get length(){return this.string.length}chunk(e){return this.string.slice(e)}get lineChunks(){return!1}read(e,t){return this.string.slice(e,t)}}new L({perNode:!0});let Zm=0;class qe{constructor(e,t,i,s){this.name=e,this.set=t,this.base=i,this.modified=s,this.id=Zm++}toString(){let{name:e}=this;for(let t of this.modified)t.name&&(e=`${t.name}(${e})`);return e}static define(e,t){let i=typeof e=="string"?e:"?";if(e instanceof qe&&(t=e),t?.base)throw new Error("Can not derive from a modified tag");let s=new qe(i,[],null,[]);if(s.set.push(s),t)for(let r of t.set)s.set.push(r);return s}static defineModifier(e){let t=new fs(e);return i=>i.modified.indexOf(t)>-1?i:fs.get(i.base||i,i.modified.concat(t).sort((s,r)=>s.id-r.id))}}let Ym=0;class fs{constructor(e){this.name=e,this.instances=[],this.id=Ym++}static get(e,t){if(!t.length)return e;let i=t[0].instances.find(l=>l.base==e&&Km(t,l.modified));if(i)return i;let s=[],r=new qe(e.name,s,e,t);for(let l of t)l.instances.push(r);let o=Jm(t);for(let l of e.set)if(!l.modified.length)for(let a of o)s.push(fs.get(l,a));return r}}function Km(n,e){return n.length==e.length&&n.every((t,i)=>t==e[i])}function Jm(n){let e=[[]];for(let t=0;ti.length-t.length)}function zo(n){let e=Object.create(null);for(let t in n){let i=n[t];Array.isArray(i)||(i=[i]);for(let s of t.split(" "))if(s){let r=[],o=2,l=s;for(let f=0;;){if(l=="..."&&f>0&&f+3==s.length){o=1;break}let u=/^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(l);if(!u)throw new RangeError("Invalid path: "+s);if(r.push(u[0]=="*"?"":u[0][0]=='"'?JSON.parse(u[0]):u[0]),f+=u[0].length,f==s.length)break;let d=s[f++];if(f==s.length&&d=="!"){o=0;break}if(d!="/")throw new RangeError("Invalid path: "+s);l=s.slice(f)}let a=r.length-1,h=r[a];if(!h)throw new RangeError("Invalid path: "+s);let c=new _i(i,o,a>0?r.slice(0,a):null);e[h]=c.sort(e[h])}}return Yc.add(e)}const Yc=new L({combine(n,e){let t,i,s;for(;n||e;){if(!n||e&&n.depth>=e.depth?(s=e,e=e.next):(s=n,n=n.next),t&&t.mode==s.mode&&!s.context&&!t.context)continue;let r=new _i(s.tags,s.mode,s.context);t?t.next=r:i=r,t=r}return i}});class _i{constructor(e,t,i,s){this.tags=e,this.mode=t,this.context=i,this.next=s}get opaque(){return this.mode==0}get inherit(){return this.mode==1}sort(e){return!e||e.depth{let o=s;for(let l of r)for(let a of l.set){let h=t[a.id];if(h){o=o?o+" "+h:h;break}}return o},scope:i}}function eg(n,e){let t=null;for(let i of n){let s=i.style(e);s&&(t=t?t+" "+s:s)}return t}function tg(n,e,t,i=0,s=n.length){let r=new ig(i,Array.isArray(e)?e:[e],t);r.highlightRange(n.cursor(),i,s,"",r.highlighters),r.flush(s)}class ig{constructor(e,t,i){this.at=e,this.highlighters=t,this.span=i,this.class=""}startSpan(e,t){t!=this.class&&(this.flush(e),e>this.at&&(this.at=e),this.class=t)}flush(e){e>this.at&&this.class&&this.span(this.at,e,this.class)}highlightRange(e,t,i,s,r){let{type:o,from:l,to:a}=e;if(l>=i||a<=t)return;o.isTop&&(r=this.highlighters.filter(d=>!d.scope||d.scope(o)));let h=s,c=ng(e)||_i.empty,f=eg(r,c.tags);if(f&&(h&&(h+=" "),h+=f,c.mode==1&&(s+=(s?" ":"")+f)),this.startSpan(Math.max(t,l),h),c.opaque)return;let u=e.tree&&e.tree.prop(L.mounted);if(u&&u.overlay){let d=e.node.enter(u.overlay[0].from+l,1),p=this.highlighters.filter(g=>!g.scope||g.scope(u.tree.type)),m=e.firstChild();for(let g=0,y=l;;g++){let S=g=x||!e.nextSibling())););if(!S||x>i)break;y=S.to+l,y>t&&(this.highlightRange(d.cursor(),Math.max(t,S.from+l),Math.min(i,y),"",p),this.startSpan(Math.min(i,y),h))}m&&e.parent()}else if(e.firstChild()){u&&(s="");do if(!(e.to<=t)){if(e.from>=i)break;this.highlightRange(e,t,i,s,r),this.startSpan(Math.min(i,e.to),h)}while(e.nextSibling());e.parent()}}}function ng(n){let e=n.type.prop(Yc);for(;e&&e.context&&!n.matchContext(e.context);)e=e.next;return e||null}const C=qe.define,En=C(),bt=C(),ma=C(bt),ga=C(bt),St=C(),qn=C(St),Js=C(St),Ge=C(),Et=C(Ge),He=C(),je=C(),lo=C(),ki=C(lo),$n=C(),O={comment:En,lineComment:C(En),blockComment:C(En),docComment:C(En),name:bt,variableName:C(bt),typeName:ma,tagName:C(ma),propertyName:ga,attributeName:C(ga),className:C(bt),labelName:C(bt),namespace:C(bt),macroName:C(bt),literal:St,string:qn,docString:C(qn),character:C(qn),attributeValue:C(qn),number:Js,integer:C(Js),float:C(Js),bool:C(St),regexp:C(St),escape:C(St),color:C(St),url:C(St),keyword:He,self:C(He),null:C(He),atom:C(He),unit:C(He),modifier:C(He),operatorKeyword:C(He),controlKeyword:C(He),definitionKeyword:C(He),moduleKeyword:C(He),operator:je,derefOperator:C(je),arithmeticOperator:C(je),logicOperator:C(je),bitwiseOperator:C(je),compareOperator:C(je),updateOperator:C(je),definitionOperator:C(je),typeOperator:C(je),controlOperator:C(je),punctuation:lo,separator:C(lo),bracket:ki,angleBracket:C(ki),squareBracket:C(ki),paren:C(ki),brace:C(ki),content:Ge,heading:Et,heading1:C(Et),heading2:C(Et),heading3:C(Et),heading4:C(Et),heading5:C(Et),heading6:C(Et),contentSeparator:C(Ge),list:C(Ge),quote:C(Ge),emphasis:C(Ge),strong:C(Ge),link:C(Ge),monospace:C(Ge),strikethrough:C(Ge),inserted:C(),deleted:C(),changed:C(),invalid:C(),meta:$n,documentMeta:C($n),annotation:C($n),processingInstruction:C($n),definition:qe.defineModifier("definition"),constant:qe.defineModifier("constant"),function:qe.defineModifier("function"),standard:qe.defineModifier("standard"),local:qe.defineModifier("local"),special:qe.defineModifier("special")};for(let n in O){let e=O[n];e instanceof qe&&(e.name=n)}Kc([{tag:O.link,class:"tok-link"},{tag:O.heading,class:"tok-heading"},{tag:O.emphasis,class:"tok-emphasis"},{tag:O.strong,class:"tok-strong"},{tag:O.keyword,class:"tok-keyword"},{tag:O.atom,class:"tok-atom"},{tag:O.bool,class:"tok-bool"},{tag:O.url,class:"tok-url"},{tag:O.labelName,class:"tok-labelName"},{tag:O.inserted,class:"tok-inserted"},{tag:O.deleted,class:"tok-deleted"},{tag:O.literal,class:"tok-literal"},{tag:O.string,class:"tok-string"},{tag:O.number,class:"tok-number"},{tag:[O.regexp,O.escape,O.special(O.string)],class:"tok-string2"},{tag:O.variableName,class:"tok-variableName"},{tag:O.local(O.variableName),class:"tok-variableName tok-local"},{tag:O.definition(O.variableName),class:"tok-variableName tok-definition"},{tag:O.special(O.variableName),class:"tok-variableName2"},{tag:O.definition(O.propertyName),class:"tok-propertyName tok-definition"},{tag:O.typeName,class:"tok-typeName"},{tag:O.namespace,class:"tok-namespace"},{tag:O.className,class:"tok-className"},{tag:O.macroName,class:"tok-macroName"},{tag:O.propertyName,class:"tok-propertyName"},{tag:O.operator,class:"tok-operator"},{tag:O.comment,class:"tok-comment"},{tag:O.meta,class:"tok-meta"},{tag:O.invalid,class:"tok-invalid"},{tag:O.punctuation,class:"tok-punctuation"}]);var er;const Lt=new L;function Jc(n){return A.define({combine:n?e=>e.concat(n):void 0})}const sg=new L;class $e{constructor(e,t,i=[],s=""){this.data=e,this.name=s,I.prototype.hasOwnProperty("tree")||Object.defineProperty(I.prototype,"tree",{get(){return ae(this)}}),this.parser=t,this.extension=[At.of(this),I.languageData.of((r,o,l)=>{let a=Oa(r,o,l),h=a.type.prop(Lt);if(!h)return[];let c=r.facet(h),f=a.type.prop(sg);if(f){let u=a.resolve(o-a.from,l);for(let d of f)if(d.test(u,r)){let p=r.facet(d.facet);return d.type=="replace"?p:p.concat(c)}}return c})].concat(i)}isActiveAt(e,t,i=-1){return Oa(e,t,i).type.prop(Lt)==this.data}findRegions(e){let t=e.facet(At);if(t?.data==this.data)return[{from:0,to:e.doc.length}];if(!t||!t.allowsNesting)return[];let i=[],s=(r,o)=>{if(r.prop(Lt)==this.data){i.push({from:o,to:o+r.length});return}let l=r.prop(L.mounted);if(l){if(l.tree.prop(Lt)==this.data){if(l.overlay)for(let a of l.overlay)i.push({from:a.from+o,to:a.to+o});else i.push({from:o,to:o+r.length});return}else if(l.overlay){let a=i.length;if(s(l.tree,l.overlay[0].from+o),i.length>a)return}}for(let a=0;ai.isTop?t:void 0)]}),e.name)}configure(e,t){return new Ui(this.data,this.parser.configure(e),t||this.name)}get allowsNesting(){return this.parser.hasWrappers()}}function ae(n){let e=n.field($e.state,!1);return e?e.tree:j.empty}class rg{constructor(e){this.doc=e,this.cursorPos=0,this.string="",this.cursor=e.iter()}get length(){return this.doc.length}syncTo(e){return this.string=this.cursor.next(e-this.cursorPos).value,this.cursorPos=e+this.string.length,this.cursorPos-this.string.length}chunk(e){return this.syncTo(e),this.string}get lineChunks(){return!0}read(e,t){let i=this.cursorPos-this.string.length;return e=this.cursorPos?this.doc.sliceString(e,t):this.string.slice(e-i,t-i)}}let wi=null;class ui{constructor(e,t,i=[],s,r,o,l,a){this.parser=e,this.state=t,this.fragments=i,this.tree=s,this.treeLen=r,this.viewport=o,this.skipped=l,this.scheduleOn=a,this.parse=null,this.tempSkipped=[]}static create(e,t,i){return new ui(e,t,[],j.empty,0,i,[],null)}startParse(){return this.parser.startParse(new rg(this.state.doc),this.fragments)}work(e,t){return t!=null&&t>=this.state.doc.length&&(t=void 0),this.tree!=j.empty&&this.isDone(t??this.state.doc.length)?(this.takeTree(),!0):this.withContext(()=>{var i;if(typeof e=="number"){let s=Date.now()+e;e=()=>Date.now()>s}for(this.parse||(this.parse=this.startParse()),t!=null&&(this.parse.stoppedAt==null||this.parse.stoppedAt>t)&&t=this.treeLen&&((this.parse.stoppedAt==null||this.parse.stoppedAt>e)&&this.parse.stopAt(e),this.withContext(()=>{for(;!(t=this.parse.advance()););}),this.treeLen=e,this.tree=t,this.fragments=this.withoutTempSkipped(It.addTree(this.tree,this.fragments,!0)),this.parse=null)}withContext(e){let t=wi;wi=this;try{return e()}finally{wi=t}}withoutTempSkipped(e){for(let t;t=this.tempSkipped.pop();)e=ya(e,t.from,t.to);return e}changes(e,t){let{fragments:i,tree:s,treeLen:r,viewport:o,skipped:l}=this;if(this.takeTree(),!e.empty){let a=[];if(e.iterChangedRanges((h,c,f,u)=>a.push({fromA:h,toA:c,fromB:f,toB:u})),i=It.applyChanges(i,a),s=j.empty,r=0,o={from:e.mapPos(o.from,-1),to:e.mapPos(o.to,1)},this.skipped.length){l=[];for(let h of this.skipped){let c=e.mapPos(h.from,1),f=e.mapPos(h.to,-1);ce.from&&(this.fragments=ya(this.fragments,s,r),this.skipped.splice(i--,1))}return this.skipped.length>=t?!1:(this.reset(),!0)}reset(){this.parse&&(this.takeTree(),this.parse=null)}skipUntilInView(e,t){this.skipped.push({from:e,to:t})}static getSkippingParser(e){return new class extends Lo{createParse(t,i,s){let r=s[0].from,o=s[s.length-1].to;return{parsedPos:r,advance(){let a=wi;if(a){for(let h of s)a.tempSkipped.push(h);e&&(a.scheduleOn=a.scheduleOn?Promise.all([a.scheduleOn,e]):e)}return this.parsedPos=o,new j(ve.none,[],[],o-r)},stoppedAt:null,stopAt(){}}}}}isDone(e){e=Math.min(e,this.state.doc.length);let t=this.fragments;return this.treeLen>=e&&t.length&&t[0].from==0&&t[0].to>=e}static get(){return wi}}function ya(n,e,t){return It.applyChanges(n,[{fromA:e,toA:t,fromB:e,toB:t}])}class di{constructor(e){this.context=e,this.tree=e.tree}apply(e){if(!e.docChanged&&this.tree==this.context.tree)return this;let t=this.context.changes(e.changes,e.state),i=this.context.treeLen==e.startState.doc.length?void 0:Math.max(e.changes.mapPos(this.context.treeLen),t.viewport.to);return t.work(20,i)||t.takeTree(),new di(t)}static init(e){let t=Math.min(3e3,e.doc.length),i=ui.create(e.facet(At).parser,e,{from:0,to:t});return i.work(20,t)||i.takeTree(),new di(i)}}$e.state=he.define({create:di.init,update(n,e){for(let t of e.effects)if(t.is($e.setState))return t.value;return e.startState.facet(At)!=e.state.facet(At)?di.init(e.state):n.apply(e)}});let ef=n=>{let e=setTimeout(()=>n(),500);return()=>clearTimeout(e)};typeof requestIdleCallback<"u"&&(ef=n=>{let e=-1,t=setTimeout(()=>{e=requestIdleCallback(n,{timeout:400})},100);return()=>e<0?clearTimeout(t):cancelIdleCallback(e)});const tr=typeof navigator<"u"&&(!((er=navigator.scheduling)===null||er===void 0)&&er.isInputPending)?()=>navigator.scheduling.isInputPending():null,og=J.fromClass(class{constructor(e){this.view=e,this.working=null,this.workScheduled=0,this.chunkEnd=-1,this.chunkBudget=-1,this.work=this.work.bind(this),this.scheduleWork()}update(e){let t=this.view.state.field($e.state).context;(t.updateViewport(e.view.viewport)||this.view.viewport.to>t.treeLen)&&this.scheduleWork(),(e.docChanged||e.selectionSet)&&(this.view.hasFocus&&(this.chunkBudget+=50),this.scheduleWork()),this.checkAsyncSchedule(t)}scheduleWork(){if(this.working)return;let{state:e}=this.view,t=e.field($e.state);(t.tree!=t.context.tree||!t.context.isDone(e.doc.length))&&(this.working=ef(this.work))}work(e){this.working=null;let t=Date.now();if(this.chunkEnds+1e3,a=r.context.work(()=>tr&&tr()||Date.now()>o,s+(l?0:1e5));this.chunkBudget-=Date.now()-t,(a||this.chunkBudget<=0)&&(r.context.takeTree(),this.view.dispatch({effects:$e.setState.of(new di(r.context))})),this.chunkBudget>0&&!(a&&!l)&&this.scheduleWork(),this.checkAsyncSchedule(r.context)}checkAsyncSchedule(e){e.scheduleOn&&(this.workScheduled++,e.scheduleOn.then(()=>this.scheduleWork()).catch(t=>Pe(this.view.state,t)).then(()=>this.workScheduled--),e.scheduleOn=null)}destroy(){this.working&&this.working()}isWorking(){return!!(this.working||this.workScheduled>0)}},{eventHandlers:{focus(){this.scheduleWork()}}}),At=A.define({combine(n){return n.length?n[0]:null},enables:n=>[$e.state,og,P.contentAttributes.compute([n],e=>{let t=e.facet(n);return t&&t.name?{"data-language":t.name}:{}})]});class tf{constructor(e,t=[]){this.language=e,this.support=t,this.extension=[e,t]}}const lg=A.define(),cn=A.define({combine:n=>{if(!n.length)return" ";let e=n[0];if(!e||/\S/.test(e)||Array.from(e).some(t=>t!=e[0]))throw new Error("Invalid indent unit: "+JSON.stringify(n[0]));return e}});function Ut(n){let e=n.facet(cn);return e.charCodeAt(0)==9?n.tabSize*e.length:e.length}function Hi(n,e){let t="",i=n.tabSize,s=n.facet(cn)[0];if(s==" "){for(;e>=i;)t+=" ",e-=i;s=" "}for(let r=0;r=e?ag(n,t,e):null}class As{constructor(e,t={}){this.state=e,this.options=t,this.unit=Ut(e)}lineAt(e,t=1){let i=this.state.doc.lineAt(e),{simulateBreak:s,simulateDoubleBreak:r}=this.options;return s!=null&&s>=i.from&&s<=i.to?r&&s==e?{text:"",from:e}:(t<0?s-1&&(r+=o-this.countColumn(i,i.search(/\S|$/))),r}countColumn(e,t=e.length){return gi(e,this.state.tabSize,t)}lineIndent(e,t=1){let{text:i,from:s}=this.lineAt(e,t),r=this.options.overrideIndentation;if(r){let o=r(s);if(o>-1)return o}return this.countColumn(i,i.search(/\S|$/))}get simulatedBreak(){return this.options.simulateBreak||null}}const Ms=new L;function ag(n,e,t){let i=e.resolveStack(t),s=e.resolveInner(t,-1).resolve(t,0).enterUnfinishedNodesBefore(t);if(s!=i.node){let r=[];for(let o=s;o&&!(o.fromi.node.to||o.from==i.node.from&&o.type==i.node.type);o=o.parent)r.push(o);for(let o=r.length-1;o>=0;o--)i={node:r[o],next:i}}return nf(i,n,t)}function nf(n,e,t){for(let i=n;i;i=i.next){let s=cg(i.node);if(s)return s(Vo.create(e,t,i))}return 0}function hg(n){return n.pos==n.options.simulateBreak&&n.options.simulateDoubleBreak}function cg(n){let e=n.type.prop(Ms);if(e)return e;let t=n.firstChild,i;if(t&&(i=t.type.prop(L.closedBy))){let s=n.lastChild,r=s&&i.indexOf(s.name)>-1;return o=>sf(o,!0,1,void 0,r&&!hg(o)?s.from:void 0)}return n.parent==null?fg:null}function fg(){return 0}class Vo extends As{constructor(e,t,i){super(e.state,e.options),this.base=e,this.pos=t,this.context=i}get node(){return this.context.node}static create(e,t,i){return new Vo(e,t,i)}get textAfter(){return this.textAfterPos(this.pos)}get baseIndent(){return this.baseIndentFor(this.node)}baseIndentFor(e){let t=this.state.doc.lineAt(e.from);for(;;){let i=e.resolve(t.from);for(;i.parent&&i.parent.from==i.from;)i=i.parent;if(ug(i,e))break;t=this.state.doc.lineAt(i.from)}return this.lineIndent(t.from)}continue(){return nf(this.context.next,this.base,this.pos)}}function ug(n,e){for(let t=e;t;t=t.parent)if(n==t)return!0;return!1}function dg(n){let e=n.node,t=e.childAfter(e.from),i=e.lastChild;if(!t)return null;let s=n.options.simulateBreak,r=n.state.doc.lineAt(t.from),o=s==null||s<=r.from?r.to:Math.min(r.to,s);for(let l=t.to;;){let a=e.childAfter(l);if(!a||a==i)return null;if(!a.type.isSkipped){if(a.from>=o)return null;let h=/^ */.exec(r.text.slice(t.to-r.from))[0].length;return{from:t.from,to:t.to+h}}l=a.to}}function ir({closing:n,align:e=!0,units:t=1}){return i=>sf(i,e,t,n)}function sf(n,e,t,i,s){let r=n.textAfter,o=r.match(/^\s*/)[0].length,l=i&&r.slice(o,o+i.length)==i||s==n.pos+o,a=e?dg(n):null;return a?l?n.column(a.from):n.column(a.to):n.baseIndent+(l?0:n.unit*t)}function ba({except:n,units:e=1}={}){return t=>{let i=n&&n.test(t.textAfter);return t.baseIndent+(i?0:e*t.unit)}}const pg=200;function mg(){return I.transactionFilter.of(n=>{if(!n.docChanged||!n.isUserEvent("input.type")&&!n.isUserEvent("input.complete"))return n;let e=n.startState.languageDataAt("indentOnInput",n.startState.selection.main.head);if(!e.length)return n;let t=n.newDoc,{head:i}=n.newSelection.main,s=t.lineAt(i);if(i>s.from+pg)return n;let r=t.sliceString(s.from,i);if(!e.some(h=>h.test(r)))return n;let{state:o}=n,l=-1,a=[];for(let{head:h}of o.selection.ranges){let c=o.doc.lineAt(h);if(c.from==l)continue;l=c.from;let f=Io(o,c.from);if(f==null)continue;let u=/^\s*/.exec(c.text)[0],d=Hi(o,f);u!=d&&a.push({from:c.from,to:c.from+u.length,insert:d})}return a.length?[n,{changes:a,sequential:!0}]:n})}const gg=A.define(),No=new L;function rf(n){let e=n.firstChild,t=n.lastChild;return e&&e.tot)continue;if(r&&l.from=e&&h.to>t&&(r=h)}}return r}function yg(n){let e=n.lastChild;return e&&e.to==n.to&&e.type.isError}function us(n,e,t){for(let i of n.facet(gg)){let s=i(n,e,t);if(s)return s}return Og(n,e,t)}function of(n,e){let t=e.mapPos(n.from,1),i=e.mapPos(n.to,-1);return t>=i?void 0:{from:t,to:i}}const Rs=q.define({map:of}),fn=q.define({map:of});function lf(n){let e=[];for(let{head:t}of n.state.selection.ranges)e.some(i=>i.from<=t&&i.to>=t)||e.push(n.lineBlockAt(t));return e}const Ht=he.define({create(){return R.none},update(n,e){e.isUserEvent("delete")&&e.changes.iterChangedRanges((t,i)=>n=Sa(n,t,i)),n=n.map(e.changes);for(let t of e.effects)if(t.is(Rs)&&!bg(n,t.value.from,t.value.to)){let{preparePlaceholder:i}=e.state.facet(cf),s=i?R.replace({widget:new Cg(i(e.state,t.value))}):xa;n=n.update({add:[s.range(t.value.from,t.value.to)]})}else t.is(fn)&&(n=n.update({filter:(i,s)=>t.value.from!=i||t.value.to!=s,filterFrom:t.value.from,filterTo:t.value.to}));return e.selection&&(n=Sa(n,e.selection.main.head)),n},provide:n=>P.decorations.from(n),toJSON(n,e){let t=[];return n.between(0,e.doc.length,(i,s)=>{t.push(i,s)}),t},fromJSON(n){if(!Array.isArray(n)||n.length%2)throw new RangeError("Invalid JSON for fold state");let e=[];for(let t=0;t{se&&(i=!0)}),i?n.update({filterFrom:e,filterTo:t,filter:(s,r)=>s>=t||r<=e}):n}function ds(n,e,t){var i;let s=null;return(i=n.field(Ht,!1))===null||i===void 0||i.between(e,t,(r,o)=>{(!s||s.from>r)&&(s={from:r,to:o})}),s}function bg(n,e,t){let i=!1;return n.between(e,e,(s,r)=>{s==e&&r==t&&(i=!0)}),i}function af(n,e){return n.field(Ht,!1)?e:e.concat(q.appendConfig.of(ff()))}const Sg=n=>{for(let e of lf(n)){let t=us(n.state,e.from,e.to);if(t)return n.dispatch({effects:af(n.state,[Rs.of(t),hf(n,t)])}),!0}return!1},xg=n=>{if(!n.state.field(Ht,!1))return!1;let e=[];for(let t of lf(n)){let i=ds(n.state,t.from,t.to);i&&e.push(fn.of(i),hf(n,i,!1))}return e.length&&n.dispatch({effects:e}),e.length>0};function hf(n,e,t=!0){let i=n.state.doc.lineAt(e.from).number,s=n.state.doc.lineAt(e.to).number;return P.announce.of(`${n.state.phrase(t?"Folded lines":"Unfolded lines")} ${i} ${n.state.phrase("to")} ${s}.`)}const kg=n=>{let{state:e}=n,t=[];for(let i=0;i{let e=n.state.field(Ht,!1);if(!e||!e.size)return!1;let t=[];return e.between(0,n.state.doc.length,(i,s)=>{t.push(fn.of({from:i,to:s}))}),n.dispatch({effects:t}),!0},vg=[{key:"Ctrl-Shift-[",mac:"Cmd-Alt-[",run:Sg},{key:"Ctrl-Shift-]",mac:"Cmd-Alt-]",run:xg},{key:"Ctrl-Alt-[",run:kg},{key:"Ctrl-Alt-]",run:wg}],Tg={placeholderDOM:null,preparePlaceholder:null,placeholderText:"…"},cf=A.define({combine(n){return rt(n,Tg)}});function ff(n){return[Ht,Ag]}function uf(n,e){let{state:t}=n,i=t.facet(cf),s=o=>{let l=n.lineBlockAt(n.posAtDOM(o.target)),a=ds(n.state,l.from,l.to);a&&n.dispatch({effects:fn.of(a)}),o.preventDefault()};if(i.placeholderDOM)return i.placeholderDOM(n,s,e);let r=document.createElement("span");return r.textContent=i.placeholderText,r.setAttribute("aria-label",t.phrase("folded code")),r.title=t.phrase("unfold"),r.className="cm-foldPlaceholder",r.onclick=s,r}const xa=R.replace({widget:new class extends ot{toDOM(n){return uf(n,null)}}});class Cg extends ot{constructor(e){super(),this.value=e}eq(e){return this.value==e.value}toDOM(e){return uf(e,this.value)}}const Pg={openText:"⌄",closedText:"›",markerDOM:null,domEventHandlers:{},foldingChanged:()=>!1};class nr extends yt{constructor(e,t){super(),this.config=e,this.open=t}eq(e){return this.config==e.config&&this.open==e.open}toDOM(e){if(this.config.markerDOM)return this.config.markerDOM(this.open);let t=document.createElement("span");return t.textContent=this.open?this.config.openText:this.config.closedText,t.title=e.state.phrase(this.open?"Fold line":"Unfold line"),t}}function Qg(n={}){let e={...Pg,...n},t=new nr(e,!0),i=new nr(e,!1),s=J.fromClass(class{constructor(o){this.from=o.viewport.from,this.markers=this.buildMarkers(o)}update(o){(o.docChanged||o.viewportChanged||o.startState.facet(At)!=o.state.facet(At)||o.startState.field(Ht,!1)!=o.state.field(Ht,!1)||ae(o.startState)!=ae(o.state)||e.foldingChanged(o))&&(this.markers=this.buildMarkers(o.view))}buildMarkers(o){let l=new gt;for(let a of o.viewportLineBlocks){let h=ds(o.state,a.from,a.to)?i:us(o.state,a.from,a.to)?t:null;h&&l.add(a.from,a.from,h)}return l.finish()}}),{domEventHandlers:r}=e;return[s,Rm({class:"cm-foldGutter",markers(o){var l;return((l=o.plugin(s))===null||l===void 0?void 0:l.markers)||N.empty},initialSpacer(){return new nr(e,!1)},domEventHandlers:{...r,click:(o,l,a)=>{if(r.click&&r.click(o,l,a))return!0;let h=ds(o.state,l.from,l.to);if(h)return o.dispatch({effects:fn.of(h)}),!0;let c=us(o.state,l.from,l.to);return c?(o.dispatch({effects:Rs.of(c)}),!0):!1}}}),ff()]}const Ag=P.baseTheme({".cm-foldPlaceholder":{backgroundColor:"#eee",border:"1px solid #ddd",color:"#888",borderRadius:".2em",margin:"0 1px",padding:"0 1px",cursor:"pointer"},".cm-foldGutter span":{padding:"0 1px",cursor:"pointer"}});class un{constructor(e,t){this.specs=e;let i;function s(l){let a=Tt.newName();return(i||(i=Object.create(null)))["."+a]=l,a}const r=typeof t.all=="string"?t.all:t.all?s(t.all):void 0,o=t.scope;this.scope=o instanceof $e?l=>l.prop(Lt)==o.data:o?l=>l==o:void 0,this.style=Kc(e.map(l=>({tag:l.tag,class:l.class||s(Object.assign({},l,{tag:null}))})),{all:r}).style,this.module=i?new Tt(i):null,this.themeType=t.themeType}static define(e,t){return new un(e,t||{})}}const ao=A.define(),df=A.define({combine(n){return n.length?[n[0]]:null}});function sr(n){let e=n.facet(ao);return e.length?e:n.facet(df)}function pf(n,e){let t=[Rg],i;return n instanceof un&&(n.module&&t.push(P.styleModule.of(n.module)),i=n.themeType),e?.fallback?t.push(df.of(n)):i?t.push(ao.computeN([P.darkTheme],s=>s.facet(P.darkTheme)==(i=="dark")?[n]:[])):t.push(ao.of(n)),t}class Mg{constructor(e){this.markCache=Object.create(null),this.tree=ae(e.state),this.decorations=this.buildDeco(e,sr(e.state)),this.decoratedTo=e.viewport.to}update(e){let t=ae(e.state),i=sr(e.state),s=i!=sr(e.startState),{viewport:r}=e.view,o=e.changes.mapPos(this.decoratedTo,1);t.length=r.to?(this.decorations=this.decorations.map(e.changes),this.decoratedTo=o):(t!=this.tree||e.viewportChanged||s)&&(this.tree=t,this.decorations=this.buildDeco(e.view,i),this.decoratedTo=r.to)}buildDeco(e,t){if(!t||!this.tree.length)return R.none;let i=new gt;for(let{from:s,to:r}of e.visibleRanges)tg(this.tree,t,(o,l,a)=>{i.add(o,l,this.markCache[a]||(this.markCache[a]=R.mark({class:a})))},s,r);return i.finish()}}const Rg=Mt.high(J.fromClass(Mg,{decorations:n=>n.decorations})),Dg=un.define([{tag:O.meta,color:"#404740"},{tag:O.link,textDecoration:"underline"},{tag:O.heading,textDecoration:"underline",fontWeight:"bold"},{tag:O.emphasis,fontStyle:"italic"},{tag:O.strong,fontWeight:"bold"},{tag:O.strikethrough,textDecoration:"line-through"},{tag:O.keyword,color:"#708"},{tag:[O.atom,O.bool,O.url,O.contentSeparator,O.labelName],color:"#219"},{tag:[O.literal,O.inserted],color:"#164"},{tag:[O.string,O.deleted],color:"#a11"},{tag:[O.regexp,O.escape,O.special(O.string)],color:"#e40"},{tag:O.definition(O.variableName),color:"#00f"},{tag:O.local(O.variableName),color:"#30a"},{tag:[O.typeName,O.namespace],color:"#085"},{tag:O.className,color:"#167"},{tag:[O.special(O.variableName),O.macroName],color:"#256"},{tag:O.definition(O.propertyName),color:"#00c"},{tag:O.comment,color:"#940"},{tag:O.invalid,color:"#f00"}]),Eg=P.baseTheme({"&.cm-focused .cm-matchingBracket":{backgroundColor:"#328c8252"},"&.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bb555544"}}),mf=1e4,gf="()[]{}",Of=A.define({combine(n){return rt(n,{afterCursor:!0,brackets:gf,maxScanDistance:mf,renderMatch:Bg})}}),qg=R.mark({class:"cm-matchingBracket"}),$g=R.mark({class:"cm-nonmatchingBracket"});function Bg(n){let e=[],t=n.matched?qg:$g;return e.push(t.range(n.start.from,n.start.to)),n.end&&e.push(t.range(n.end.from,n.end.to)),e}const Wg=he.define({create(){return R.none},update(n,e){if(!e.docChanged&&!e.selection)return n;let t=[],i=e.state.facet(Of);for(let s of e.state.selection.ranges){if(!s.empty)continue;let r=et(e.state,s.head,-1,i)||s.head>0&&et(e.state,s.head-1,1,i)||i.afterCursor&&(et(e.state,s.head,1,i)||s.headP.decorations.from(n)}),Lg=[Wg,Eg];function zg(n={}){return[Of.of(n),Lg]}const Ig=new L;function ho(n,e,t){let i=n.prop(e<0?L.openedBy:L.closedBy);if(i)return i;if(n.name.length==1){let s=t.indexOf(n.name);if(s>-1&&s%2==(e<0?1:0))return[t[s+e]]}return null}function co(n){let e=n.type.prop(Ig);return e?e(n.node):n}function et(n,e,t,i={}){let s=i.maxScanDistance||mf,r=i.brackets||gf,o=ae(n),l=o.resolveInner(e,t);for(let a=l;a;a=a.parent){let h=ho(a.type,t,r);if(h&&a.from0?e>=c.from&&ec.from&&e<=c.to))return Vg(n,e,t,a,c,h,r)}}return Ng(n,e,t,o,l.type,s,r)}function Vg(n,e,t,i,s,r,o){let l=i.parent,a={from:s.from,to:s.to},h=0,c=l?.cursor();if(c&&(t<0?c.childBefore(i.from):c.childAfter(i.to)))do if(t<0?c.to<=i.from:c.from>=i.to){if(h==0&&r.indexOf(c.type.name)>-1&&c.from0)return null;let h={from:t<0?e-1:e,to:t>0?e+1:e},c=n.doc.iterRange(e,t>0?n.doc.length:0),f=0;for(let u=0;!c.next().done&&u<=r;){let d=c.value;t<0&&(u+=d.length);let p=e+u*t;for(let m=t>0?0:d.length-1,g=t>0?d.length:-1;m!=g;m+=t){let y=o.indexOf(d[m]);if(!(y<0||i.resolveInner(p+m,1).type!=s))if(y%2==0==t>0)f++;else{if(f==1)return{start:h,end:{from:p+m,to:p+m+1},matched:y>>1==a>>1};f--}}t>0&&(u+=d.length)}return c.done?{start:h,matched:!1}:null}function ka(n,e,t,i=0,s=0){e==null&&(e=n.search(/[^\s\u00a0]/),e==-1&&(e=n.length));let r=s;for(let o=i;o=this.string.length}sol(){return this.pos==0}peek(){return this.string.charAt(this.pos)||void 0}next(){if(this.post}eatSpace(){let e=this.pos;for(;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e}skipToEnd(){this.pos=this.string.length}skipTo(e){let t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0}backUp(e){this.pos-=e}column(){return this.lastColumnPosi?o.toLowerCase():o,r=this.string.substr(this.pos,e.length);return s(r)==s(e)?(t!==!1&&(this.pos+=e.length),!0):null}else{let s=this.string.slice(this.pos).match(e);return s&&s.index>0?null:(s&&t!==!1&&(this.pos+=s[0].length),s)}}current(){return this.string.slice(this.start,this.pos)}}function Xg(n){return{name:n.name||"",token:n.token,blankLine:n.blankLine||(()=>{}),startState:n.startState||(()=>!0),copyState:n.copyState||Fg,indent:n.indent||(()=>null),languageData:n.languageData||{},tokenTable:n.tokenTable||Fo,mergeTokens:n.mergeTokens!==!1}}function Fg(n){if(typeof n!="object")return n;let e={};for(let t in n){let i=n[t];e[t]=i instanceof Array?i.slice():i}return e}const wa=new WeakMap;class bf extends $e{constructor(e){let t=Jc(e.languageData),i=Xg(e),s,r=new class extends Lo{createParse(o,l,a){return new Ug(s,o,l,a)}};super(t,r,[],e.name),this.topNode=Gg(t,this),s=this,this.streamParser=i,this.stateAfter=new L({perNode:!0}),this.tokenTable=e.tokenTable?new wf(i.tokenTable):jg}static define(e){return new bf(e)}getIndent(e){let t,{overrideIndentation:i}=e.options;i&&(t=wa.get(e.state),t!=null&&t1e4)return null;for(;r=i&&t+e.length<=s&&e.prop(n.stateAfter);if(r)return{state:n.streamParser.copyState(r),pos:t+e.length};for(let o=e.children.length-1;o>=0;o--){let l=e.children[o],a=t+e.positions[o],h=l instanceof j&&a=e.length)return e;!s&&t==0&&e.type==n.topNode&&(s=!0);for(let r=e.children.length-1;r>=0;r--){let o=e.positions[r],l=e.children[r],a;if(ot&&Xo(n,r.tree,0-r.offset,t,l),h;if(a&&a.pos<=i&&(h=Sf(n,r.tree,t+r.offset,a.pos+r.offset,!1)))return{state:a.state,tree:h}}return{state:n.streamParser.startState(s?Ut(s):4),tree:j.empty}}let Ug=class{constructor(e,t,i,s){this.lang=e,this.input=t,this.fragments=i,this.ranges=s,this.stoppedAt=null,this.chunks=[],this.chunkPos=[],this.chunk=[],this.chunkReused=void 0,this.rangeIndex=0,this.to=s[s.length-1].to;let r=ui.get(),o=s[0].from,{state:l,tree:a}=_g(e,i,o,this.to,r?.state);this.state=l,this.parsedPos=this.chunkStart=o+a.length;for(let h=0;hh.from<=r.viewport.from&&h.to>=r.viewport.from)&&(this.state=this.lang.streamParser.startState(Ut(r.state)),r.skipUntilInView(this.parsedPos,r.viewport.from),this.parsedPos=r.viewport.from),this.moveRangeIndex()}advance(){let e=ui.get(),t=this.stoppedAt==null?this.to:Math.min(this.to,this.stoppedAt),i=Math.min(t,this.chunkStart+512);for(e&&(i=Math.min(i,e.viewport.to));this.parsedPos=t?this.finish():e&&this.parsedPos>=e.viewport.to?(e.skipUntilInView(this.parsedPos,t),this.finish()):null}stopAt(e){this.stoppedAt=e}lineAfter(e){let t=this.input.chunk(e);if(this.input.lineChunks)t==` +`&&(t="");else{let i=t.indexOf(` +`);i>-1&&(t=t.slice(0,i))}return e+t.length<=this.to?t:t.slice(0,this.to-e)}nextLine(){let e=this.parsedPos,t=this.lineAfter(e),i=e+t.length;for(let s=this.rangeIndex;;){let r=this.ranges[s].to;if(r>=i||(t=t.slice(0,r-(i-t.length)),s++,s==this.ranges.length))break;let o=this.ranges[s].from,l=this.lineAfter(o);t+=l,i=o+l.length}return{line:t,end:i}}skipGapsTo(e,t,i){for(;;){let s=this.ranges[this.rangeIndex].to,r=e+t;if(i>0?s>r:s>=r)break;let o=this.ranges[++this.rangeIndex].from;t+=o-s}return t}moveRangeIndex(){for(;this.ranges[this.rangeIndex].to1){s=this.skipGapsTo(t,s,1),t+=s;let l=this.chunk.length;s=this.skipGapsTo(i,s,-1),i+=s,r+=this.chunk.length-l}let o=this.chunk.length-4;return this.lang.streamParser.mergeTokens&&r==4&&o>=0&&this.chunk[o]==e&&this.chunk[o+2]==t?this.chunk[o+2]=i:this.chunk.push(e,t,i,r),s}parseLine(e){let{line:t,end:i}=this.nextLine(),s=0,{streamParser:r}=this.lang,o=new yf(t,e?e.state.tabSize:4,e?Ut(e.state):2);if(o.eol())r.blankLine(this.state,o.indentUnit);else for(;!o.eol();){let l=xf(r.token,o,this.state);if(l&&(s=this.emitToken(this.lang.tokenTable.resolve(l),this.parsedPos+o.start,this.parsedPos+o.pos,s)),o.start>1e4)break}this.parsedPos=i,this.moveRangeIndex(),this.parsedPose.start)return s}throw new Error("Stream parser failed to advance stream.")}const Fo=Object.create(null),ji=[ve.none],Hg=new Qs(ji),va=[],Ta=Object.create(null),kf=Object.create(null);for(let[n,e]of[["variable","variableName"],["variable-2","variableName.special"],["string-2","string.special"],["def","variableName.definition"],["tag","tagName"],["attribute","attributeName"],["type","typeName"],["builtin","variableName.standard"],["qualifier","modifier"],["error","invalid"],["header","heading"],["property","propertyName"]])kf[n]=vf(Fo,e);class wf{constructor(e){this.extra=e,this.table=Object.assign(Object.create(null),kf)}resolve(e){return e?this.table[e]||(this.table[e]=vf(this.extra,e)):0}}const jg=new wf(Fo);function rr(n,e){va.indexOf(n)>-1||(va.push(n),console.warn(e))}function vf(n,e){let t=[];for(let l of e.split(" ")){let a=[];for(let h of l.split(".")){let c=n[h]||O[h];c?typeof c=="function"?a.length?a=a.map(c):rr(h,`Modifier ${h} used at start of tag`):a.length?rr(h,`Tag ${h} used as modifier`):a=Array.isArray(c)?c:[c]:rr(h,`Unknown highlighting tag ${h}`)}for(let h of a)t.push(h)}if(!t.length)return 0;let i=e.replace(/ /g,"_"),s=i+" "+t.map(l=>l.id),r=Ta[s];if(r)return r.id;let o=Ta[s]=ve.define({id:ji.length,name:i,props:[zo({[i]:t})]});return ji.push(o),o.id}function Gg(n,e){let t=ve.define({id:ji.length,name:"Document",props:[Lt.add(()=>n),Ms.add(()=>i=>e.getIndent(i))],top:!0});return ji.push(t),t}Z.RTL,Z.LTR;const Zg=n=>{let{state:e}=n,t=e.doc.lineAt(e.selection.main.from),i=Uo(n.state,t.from);return i.line?Yg(n):i.block?Jg(n):!1};function _o(n,e){return({state:t,dispatch:i})=>{if(t.readOnly)return!1;let s=n(e,t);return s?(i(t.update(s)),!0):!1}}const Yg=_o(iO,0),Kg=_o(Tf,0),Jg=_o((n,e)=>Tf(n,e,tO(e)),0);function Uo(n,e){let t=n.languageDataAt("commentTokens",e,1);return t.length?t[0]:{}}const vi=50;function eO(n,{open:e,close:t},i,s){let r=n.sliceDoc(i-vi,i),o=n.sliceDoc(s,s+vi),l=/\s*$/.exec(r)[0].length,a=/^\s*/.exec(o)[0].length,h=r.length-l;if(r.slice(h-e.length,h)==e&&o.slice(a,a+t.length)==t)return{open:{pos:i-l,margin:l&&1},close:{pos:s+a,margin:a&&1}};let c,f;s-i<=2*vi?c=f=n.sliceDoc(i,s):(c=n.sliceDoc(i,i+vi),f=n.sliceDoc(s-vi,s));let u=/^\s*/.exec(c)[0].length,d=/\s*$/.exec(f)[0].length,p=f.length-d-t.length;return c.slice(u,u+e.length)==e&&f.slice(p,p+t.length)==t?{open:{pos:i+u+e.length,margin:/\s/.test(c.charAt(u+e.length))?1:0},close:{pos:s-d-t.length,margin:/\s/.test(f.charAt(p-1))?1:0}}:null}function tO(n){let e=[];for(let t of n.selection.ranges){let i=n.doc.lineAt(t.from),s=t.to<=i.to?i:n.doc.lineAt(t.to);s.from>i.from&&s.from==t.to&&(s=t.to==i.to+1?i:n.doc.lineAt(t.to-1));let r=e.length-1;r>=0&&e[r].to>i.from?e[r].to=s.to:e.push({from:i.from+/^\s*/.exec(i.text)[0].length,to:s.to})}return e}function Tf(n,e,t=e.selection.ranges){let i=t.map(r=>Uo(e,r.from).block);if(!i.every(r=>r))return null;let s=t.map((r,o)=>eO(e,i[o],r.from,r.to));if(n!=2&&!s.every(r=>r))return{changes:e.changes(t.map((r,o)=>s[o]?[]:[{from:r.from,insert:i[o].open+" "},{from:r.to,insert:" "+i[o].close}]))};if(n!=1&&s.some(r=>r)){let r=[];for(let o=0,l;os&&(r==o||o>f.from)){s=f.from;let u=/^\s*/.exec(f.text)[0].length,d=u==f.length,p=f.text.slice(u,u+h.length)==h?u:-1;ur.comment<0&&(!r.empty||r.single))){let r=[];for(let{line:l,token:a,indent:h,empty:c,single:f}of i)(f||!c)&&r.push({from:l.from+h,insert:a+" "});let o=e.changes(r);return{changes:o,selection:e.selection.map(o,1)}}else if(n!=1&&i.some(r=>r.comment>=0)){let r=[];for(let{line:o,comment:l,token:a}of i)if(l>=0){let h=o.from+l,c=h+a.length;o.text[c-o.from]==" "&&c++,r.push({from:h,to:c})}return{changes:r}}return null}const fo=st.define(),nO=st.define(),sO=A.define(),Cf=A.define({combine(n){return rt(n,{minDepth:100,newGroupDelay:500,joinToEvent:(e,t)=>t},{minDepth:Math.max,newGroupDelay:Math.min,joinToEvent:(e,t)=>(i,s)=>e(i,s)||t(i,s)})}}),Pf=he.define({create(){return tt.empty},update(n,e){let t=e.state.facet(Cf),i=e.annotation(fo);if(i){let a=Qe.fromTransaction(e,i.selection),h=i.side,c=h==0?n.undone:n.done;return a?c=ps(c,c.length,t.minDepth,a):c=Mf(c,e.startState.selection),new tt(h==0?i.rest:c,h==0?c:i.rest)}let s=e.annotation(nO);if((s=="full"||s=="before")&&(n=n.isolate()),e.annotation(ie.addToHistory)===!1)return e.changes.empty?n:n.addMapping(e.changes.desc);let r=Qe.fromTransaction(e),o=e.annotation(ie.time),l=e.annotation(ie.userEvent);return r?n=n.addChanges(r,o,l,t,e):e.selection&&(n=n.addSelection(e.startState.selection,o,l,t.newGroupDelay)),(s=="full"||s=="after")&&(n=n.isolate()),n},toJSON(n){return{done:n.done.map(e=>e.toJSON()),undone:n.undone.map(e=>e.toJSON())}},fromJSON(n){return new tt(n.done.map(Qe.fromJSON),n.undone.map(Qe.fromJSON))}});function rO(n={}){return[Pf,Cf.of(n),P.domEventHandlers({beforeinput(e,t){let i=e.inputType=="historyUndo"?Qf:e.inputType=="historyRedo"?uo:null;return i?(e.preventDefault(),i(t)):!1}})]}function Ds(n,e){return function({state:t,dispatch:i}){if(!e&&t.readOnly)return!1;let s=t.field(Pf,!1);if(!s)return!1;let r=s.pop(n,t,e);return r?(i(r),!0):!1}}const Qf=Ds(0,!1),uo=Ds(1,!1),oO=Ds(0,!0),lO=Ds(1,!0);class Qe{constructor(e,t,i,s,r){this.changes=e,this.effects=t,this.mapped=i,this.startSelection=s,this.selectionsAfter=r}setSelAfter(e){return new Qe(this.changes,this.effects,this.mapped,this.startSelection,e)}toJSON(){var e,t,i;return{changes:(e=this.changes)===null||e===void 0?void 0:e.toJSON(),mapped:(t=this.mapped)===null||t===void 0?void 0:t.toJSON(),startSelection:(i=this.startSelection)===null||i===void 0?void 0:i.toJSON(),selectionsAfter:this.selectionsAfter.map(s=>s.toJSON())}}static fromJSON(e){return new Qe(e.changes&&se.fromJSON(e.changes),[],e.mapped&&it.fromJSON(e.mapped),e.startSelection&&b.fromJSON(e.startSelection),e.selectionsAfter.map(b.fromJSON))}static fromTransaction(e,t){let i=Be;for(let s of e.startState.facet(sO)){let r=s(e);r.length&&(i=i.concat(r))}return!i.length&&e.changes.empty?null:new Qe(e.changes.invert(e.startState.doc),i,void 0,t||e.startState.selection,Be)}static selection(e){return new Qe(void 0,Be,void 0,void 0,e)}}function ps(n,e,t,i){let s=e+1>t+20?e-t-1:0,r=n.slice(s,e);return r.push(i),r}function aO(n,e){let t=[],i=!1;return n.iterChangedRanges((s,r)=>t.push(s,r)),e.iterChangedRanges((s,r,o,l)=>{for(let a=0;a=h&&o<=c&&(i=!0)}}),i}function hO(n,e){return n.ranges.length==e.ranges.length&&n.ranges.filter((t,i)=>t.empty!=e.ranges[i].empty).length===0}function Af(n,e){return n.length?e.length?n.concat(e):n:e}const Be=[],cO=200;function Mf(n,e){if(n.length){let t=n[n.length-1],i=t.selectionsAfter.slice(Math.max(0,t.selectionsAfter.length-cO));return i.length&&i[i.length-1].eq(e)?n:(i.push(e),ps(n,n.length-1,1e9,t.setSelAfter(i)))}else return[Qe.selection([e])]}function fO(n){let e=n[n.length-1],t=n.slice();return t[n.length-1]=e.setSelAfter(e.selectionsAfter.slice(0,e.selectionsAfter.length-1)),t}function or(n,e){if(!n.length)return n;let t=n.length,i=Be;for(;t;){let s=uO(n[t-1],e,i);if(s.changes&&!s.changes.empty||s.effects.length){let r=n.slice(0,t);return r[t-1]=s,r}else e=s.mapped,t--,i=s.selectionsAfter}return i.length?[Qe.selection(i)]:Be}function uO(n,e,t){let i=Af(n.selectionsAfter.length?n.selectionsAfter.map(l=>l.map(e)):Be,t);if(!n.changes)return Qe.selection(i);let s=n.changes.map(e),r=e.mapDesc(n.changes,!0),o=n.mapped?n.mapped.composeDesc(r):r;return new Qe(s,q.mapEffects(n.effects,e),o,n.startSelection.map(r),i)}const dO=/^(input\.type|delete)($|\.)/;class tt{constructor(e,t,i=0,s=void 0){this.done=e,this.undone=t,this.prevTime=i,this.prevUserEvent=s}isolate(){return this.prevTime?new tt(this.done,this.undone):this}addChanges(e,t,i,s,r){let o=this.done,l=o[o.length-1];return l&&l.changes&&!l.changes.empty&&e.changes&&(!i||dO.test(i))&&(!l.selectionsAfter.length&&t-this.prevTime0&&t-this.prevTimet.empty?n.moveByChar(t,e):Es(t,e))}function be(n){return n.textDirectionAt(n.state.selection.main.head)==Z.LTR}const Df=n=>Rf(n,!be(n)),Ef=n=>Rf(n,be(n));function qf(n,e){return Fe(n,t=>t.empty?n.moveByGroup(t,e):Es(t,e))}const mO=n=>qf(n,!be(n)),gO=n=>qf(n,be(n));function OO(n,e,t){if(e.type.prop(t))return!0;let i=e.to-e.from;return i&&(i>2||/[^\s,.;:]/.test(n.sliceDoc(e.from,e.to)))||e.firstChild}function qs(n,e,t){let i=ae(n).resolveInner(e.head),s=t?L.closedBy:L.openedBy;for(let a=e.head;;){let h=t?i.childAfter(a):i.childBefore(a);if(!h)break;OO(n,h,s)?i=h:a=t?h.to:h.from}let r=i.type.prop(s),o,l;return r&&(o=t?et(n,i.from,1):et(n,i.to,-1))&&o.matched?l=t?o.end.to:o.end.from:l=t?i.to:i.from,b.cursor(l,t?-1:1)}const yO=n=>Fe(n,e=>qs(n.state,e,!be(n))),bO=n=>Fe(n,e=>qs(n.state,e,be(n)));function $f(n,e){return Fe(n,t=>{if(!t.empty)return Es(t,e);let i=n.moveVertically(t,e);return i.head!=t.head?i:n.moveToLineBoundary(t,e)})}const Bf=n=>$f(n,!1),Wf=n=>$f(n,!0);function Lf(n){let e=n.scrollDOM.clientHeighto.empty?n.moveVertically(o,e,t.height):Es(o,e));if(s.eq(i.selection))return!1;let r;if(t.selfScroll){let o=n.coordsAtPos(i.selection.main.head),l=n.scrollDOM.getBoundingClientRect(),a=l.top+t.marginTop,h=l.bottom-t.marginBottom;o&&o.top>a&&o.bottomzf(n,!1),po=n=>zf(n,!0);function Rt(n,e,t){let i=n.lineBlockAt(e.head),s=n.moveToLineBoundary(e,t);if(s.head==e.head&&s.head!=(t?i.to:i.from)&&(s=n.moveToLineBoundary(e,t,!1)),!t&&s.head==i.from&&i.length){let r=/^\s*/.exec(n.state.sliceDoc(i.from,Math.min(i.from+100,i.to)))[0].length;r&&e.head!=i.from+r&&(s=b.cursor(i.from+r))}return s}const SO=n=>Fe(n,e=>Rt(n,e,!0)),xO=n=>Fe(n,e=>Rt(n,e,!1)),kO=n=>Fe(n,e=>Rt(n,e,!be(n))),wO=n=>Fe(n,e=>Rt(n,e,be(n))),vO=n=>Fe(n,e=>b.cursor(n.lineBlockAt(e.head).from,1)),TO=n=>Fe(n,e=>b.cursor(n.lineBlockAt(e.head).to,-1));function CO(n,e,t){let i=!1,s=Oi(n.selection,r=>{let o=et(n,r.head,-1)||et(n,r.head,1)||r.head>0&&et(n,r.head-1,1)||r.headCO(n,e);function Ie(n,e){let t=Oi(n.state.selection,i=>{let s=e(i);return b.range(i.anchor,s.head,s.goalColumn,s.bidiLevel||void 0)});return t.eq(n.state.selection)?!1:(n.dispatch(Xe(n.state,t)),!0)}function If(n,e){return Ie(n,t=>n.moveByChar(t,e))}const Vf=n=>If(n,!be(n)),Nf=n=>If(n,be(n));function Xf(n,e){return Ie(n,t=>n.moveByGroup(t,e))}const QO=n=>Xf(n,!be(n)),AO=n=>Xf(n,be(n)),MO=n=>Ie(n,e=>qs(n.state,e,!be(n))),RO=n=>Ie(n,e=>qs(n.state,e,be(n)));function Ff(n,e){return Ie(n,t=>n.moveVertically(t,e))}const _f=n=>Ff(n,!1),Uf=n=>Ff(n,!0);function Hf(n,e){return Ie(n,t=>n.moveVertically(t,e,Lf(n).height))}const Pa=n=>Hf(n,!1),Qa=n=>Hf(n,!0),DO=n=>Ie(n,e=>Rt(n,e,!0)),EO=n=>Ie(n,e=>Rt(n,e,!1)),qO=n=>Ie(n,e=>Rt(n,e,!be(n))),$O=n=>Ie(n,e=>Rt(n,e,be(n))),BO=n=>Ie(n,e=>b.cursor(n.lineBlockAt(e.head).from)),WO=n=>Ie(n,e=>b.cursor(n.lineBlockAt(e.head).to)),Aa=({state:n,dispatch:e})=>(e(Xe(n,{anchor:0})),!0),Ma=({state:n,dispatch:e})=>(e(Xe(n,{anchor:n.doc.length})),!0),Ra=({state:n,dispatch:e})=>(e(Xe(n,{anchor:n.selection.main.anchor,head:0})),!0),Da=({state:n,dispatch:e})=>(e(Xe(n,{anchor:n.selection.main.anchor,head:n.doc.length})),!0),LO=({state:n,dispatch:e})=>(e(n.update({selection:{anchor:0,head:n.doc.length},userEvent:"select"})),!0),zO=({state:n,dispatch:e})=>{let t=$s(n).map(({from:i,to:s})=>b.range(i,Math.min(s+1,n.doc.length)));return e(n.update({selection:b.create(t),userEvent:"select"})),!0},IO=({state:n,dispatch:e})=>{let t=Oi(n.selection,i=>{let s=ae(n),r=s.resolveStack(i.from,1);if(i.empty){let o=s.resolveStack(i.from,-1);o.node.from>=r.node.from&&o.node.to<=r.node.to&&(r=o)}for(let o=r;o;o=o.next){let{node:l}=o;if((l.from=i.to||l.to>i.to&&l.from<=i.from)&&o.next)return b.range(l.to,l.from)}return i});return t.eq(n.selection)?!1:(e(Xe(n,t)),!0)};function jf(n,e){let{state:t}=n,i=t.selection,s=t.selection.ranges.slice();for(let r of t.selection.ranges){let o=t.doc.lineAt(r.head);if(e?o.to0)for(let l=r;;){let a=n.moveVertically(l,e);if(a.heado.to){s.some(h=>h.head==a.head)||s.push(a);break}else{if(a.head==l.head)break;l=a}}}return s.length==i.ranges.length?!1:(n.dispatch(Xe(t,b.create(s,s.length-1))),!0)}const VO=n=>jf(n,!1),NO=n=>jf(n,!0),XO=({state:n,dispatch:e})=>{let t=n.selection,i=null;return t.ranges.length>1?i=b.create([t.main]):t.main.empty||(i=b.create([b.cursor(t.main.head)])),i?(e(Xe(n,i)),!0):!1};function dn(n,e){if(n.state.readOnly)return!1;let t="delete.selection",{state:i}=n,s=i.changeByRange(r=>{let{from:o,to:l}=r;if(o==l){let a=e(r);ao&&(t="delete.forward",a=Bn(n,a,!0)),o=Math.min(o,a),l=Math.max(l,a)}else o=Bn(n,o,!1),l=Bn(n,l,!0);return o==l?{range:r}:{changes:{from:o,to:l},range:b.cursor(o,os(n)))i.between(e,e,(s,r)=>{se&&(e=t?r:s)});return e}const Gf=(n,e,t)=>dn(n,i=>{let s=i.from,{state:r}=n,o=r.doc.lineAt(s),l,a;if(t&&!e&&s>o.from&&sGf(n,!1,!0),Zf=n=>Gf(n,!0,!1),Yf=(n,e)=>dn(n,t=>{let i=t.head,{state:s}=n,r=s.doc.lineAt(i),o=s.charCategorizer(i);for(let l=null;;){if(i==(e?r.to:r.from)){i==t.head&&r.number!=(e?s.doc.lines:1)&&(i+=e?1:-1);break}let a=pe(r.text,i-r.from,e)+r.from,h=r.text.slice(Math.min(i,a)-r.from,Math.max(i,a)-r.from),c=o(h);if(l!=null&&c!=l)break;(h!=" "||i!=t.head)&&(l=c),i=a}return i}),Kf=n=>Yf(n,!1),FO=n=>Yf(n,!0),_O=n=>dn(n,e=>{let t=n.lineBlockAt(e.head).to;return e.headdn(n,e=>{let t=n.moveToLineBoundary(e,!1).head;return e.head>t?t:Math.max(0,e.head-1)}),HO=n=>dn(n,e=>{let t=n.moveToLineBoundary(e,!0).head;return e.head{if(n.readOnly)return!1;let t=n.changeByRange(i=>({changes:{from:i.from,to:i.to,insert:V.of(["",""])},range:b.cursor(i.from)}));return e(n.update(t,{scrollIntoView:!0,userEvent:"input"})),!0},GO=({state:n,dispatch:e})=>{if(n.readOnly)return!1;let t=n.changeByRange(i=>{if(!i.empty||i.from==0||i.from==n.doc.length)return{range:i};let s=i.from,r=n.doc.lineAt(s),o=s==r.from?s-1:pe(r.text,s-r.from,!1)+r.from,l=s==r.to?s+1:pe(r.text,s-r.from,!0)+r.from;return{changes:{from:o,to:l,insert:n.doc.slice(s,l).append(n.doc.slice(o,s))},range:b.cursor(l)}});return t.changes.empty?!1:(e(n.update(t,{scrollIntoView:!0,userEvent:"move.character"})),!0)};function $s(n){let e=[],t=-1;for(let i of n.selection.ranges){let s=n.doc.lineAt(i.from),r=n.doc.lineAt(i.to);if(!i.empty&&i.to==r.from&&(r=n.doc.lineAt(i.to-1)),t>=s.number){let o=e[e.length-1];o.to=r.to,o.ranges.push(i)}else e.push({from:s.from,to:r.to,ranges:[i]});t=r.number+1}return e}function Jf(n,e,t){if(n.readOnly)return!1;let i=[],s=[];for(let r of $s(n)){if(t?r.to==n.doc.length:r.from==0)continue;let o=n.doc.lineAt(t?r.to+1:r.from-1),l=o.length+1;if(t){i.push({from:r.to,to:o.to},{from:r.from,insert:o.text+n.lineBreak});for(let a of r.ranges)s.push(b.range(Math.min(n.doc.length,a.anchor+l),Math.min(n.doc.length,a.head+l)))}else{i.push({from:o.from,to:r.from},{from:r.to,insert:n.lineBreak+o.text});for(let a of r.ranges)s.push(b.range(a.anchor-l,a.head-l))}}return i.length?(e(n.update({changes:i,scrollIntoView:!0,selection:b.create(s,n.selection.mainIndex),userEvent:"move.line"})),!0):!1}const ZO=({state:n,dispatch:e})=>Jf(n,e,!1),YO=({state:n,dispatch:e})=>Jf(n,e,!0);function eu(n,e,t){if(n.readOnly)return!1;let i=[];for(let s of $s(n))t?i.push({from:s.from,insert:n.doc.slice(s.from,s.to)+n.lineBreak}):i.push({from:s.to,insert:n.lineBreak+n.doc.slice(s.from,s.to)});return e(n.update({changes:i,scrollIntoView:!0,userEvent:"input.copyline"})),!0}const KO=({state:n,dispatch:e})=>eu(n,e,!1),JO=({state:n,dispatch:e})=>eu(n,e,!0),e0=n=>{if(n.state.readOnly)return!1;let{state:e}=n,t=e.changes($s(e).map(({from:s,to:r})=>(s>0?s--:r{let r;if(n.lineWrapping){let o=n.lineBlockAt(s.head),l=n.coordsAtPos(s.head,s.assoc||1);l&&(r=o.bottom+n.documentTop-l.bottom+n.defaultLineHeight/2)}return n.moveVertically(s,!0,r)}).map(t);return n.dispatch({changes:t,selection:i,scrollIntoView:!0,userEvent:"delete.line"}),!0};function t0(n,e){if(/\(\)|\[\]|\{\}/.test(n.sliceDoc(e-1,e+1)))return{from:e,to:e};let t=ae(n).resolveInner(e),i=t.childBefore(e),s=t.childAfter(e),r;return i&&s&&i.to<=e&&s.from>=e&&(r=i.type.prop(L.closedBy))&&r.indexOf(s.name)>-1&&n.doc.lineAt(i.to).from==n.doc.lineAt(s.from).from&&!/\S/.test(n.sliceDoc(i.to,s.from))?{from:i.to,to:s.from}:null}const Ea=tu(!1),i0=tu(!0);function tu(n){return({state:e,dispatch:t})=>{if(e.readOnly)return!1;let i=e.changeByRange(s=>{let{from:r,to:o}=s,l=e.doc.lineAt(r),a=!n&&r==o&&t0(e,r);n&&(r=o=(o<=l.to?l:e.doc.lineAt(o)).to);let h=new As(e,{simulateBreak:r,simulateDoubleBreak:!!a}),c=Io(h,r);for(c==null&&(c=gi(/^\s*/.exec(e.doc.lineAt(r).text)[0],e.tabSize));ol.from&&r{let s=[];for(let o=i.from;o<=i.to;){let l=n.doc.lineAt(o);l.number>t&&(i.empty||i.to>l.from)&&(e(l,s,i),t=l.number),o=l.to+1}let r=n.changes(s);return{changes:s,range:b.range(r.mapPos(i.anchor,1),r.mapPos(i.head,1))}})}const n0=({state:n,dispatch:e})=>{if(n.readOnly)return!1;let t=Object.create(null),i=new As(n,{overrideIndentation:r=>{let o=t[r];return o??-1}}),s=Ho(n,(r,o,l)=>{let a=Io(i,r.from);if(a==null)return;/\S/.test(r.text)||(a=0);let h=/^\s*/.exec(r.text)[0],c=Hi(n,a);(h!=c||l.fromn.readOnly?!1:(e(n.update(Ho(n,(t,i)=>{i.push({from:t.from,insert:n.facet(cn)})}),{userEvent:"input.indent"})),!0),nu=({state:n,dispatch:e})=>n.readOnly?!1:(e(n.update(Ho(n,(t,i)=>{let s=/^\s*/.exec(t.text)[0];if(!s)return;let r=gi(s,n.tabSize),o=0,l=Hi(n,Math.max(0,r-Ut(n)));for(;o(n.setTabFocusMode(),!0),r0=[{key:"Ctrl-b",run:Df,shift:Vf,preventDefault:!0},{key:"Ctrl-f",run:Ef,shift:Nf},{key:"Ctrl-p",run:Bf,shift:_f},{key:"Ctrl-n",run:Wf,shift:Uf},{key:"Ctrl-a",run:vO,shift:BO},{key:"Ctrl-e",run:TO,shift:WO},{key:"Ctrl-d",run:Zf},{key:"Ctrl-h",run:mo},{key:"Ctrl-k",run:_O},{key:"Ctrl-Alt-h",run:Kf},{key:"Ctrl-o",run:jO},{key:"Ctrl-t",run:GO},{key:"Ctrl-v",run:po}],o0=[{key:"ArrowLeft",run:Df,shift:Vf,preventDefault:!0},{key:"Mod-ArrowLeft",mac:"Alt-ArrowLeft",run:mO,shift:QO,preventDefault:!0},{mac:"Cmd-ArrowLeft",run:kO,shift:qO,preventDefault:!0},{key:"ArrowRight",run:Ef,shift:Nf,preventDefault:!0},{key:"Mod-ArrowRight",mac:"Alt-ArrowRight",run:gO,shift:AO,preventDefault:!0},{mac:"Cmd-ArrowRight",run:wO,shift:$O,preventDefault:!0},{key:"ArrowUp",run:Bf,shift:_f,preventDefault:!0},{mac:"Cmd-ArrowUp",run:Aa,shift:Ra},{mac:"Ctrl-ArrowUp",run:Ca,shift:Pa},{key:"ArrowDown",run:Wf,shift:Uf,preventDefault:!0},{mac:"Cmd-ArrowDown",run:Ma,shift:Da},{mac:"Ctrl-ArrowDown",run:po,shift:Qa},{key:"PageUp",run:Ca,shift:Pa},{key:"PageDown",run:po,shift:Qa},{key:"Home",run:xO,shift:EO,preventDefault:!0},{key:"Mod-Home",run:Aa,shift:Ra},{key:"End",run:SO,shift:DO,preventDefault:!0},{key:"Mod-End",run:Ma,shift:Da},{key:"Enter",run:Ea,shift:Ea},{key:"Mod-a",run:LO},{key:"Backspace",run:mo,shift:mo,preventDefault:!0},{key:"Delete",run:Zf,preventDefault:!0},{key:"Mod-Backspace",mac:"Alt-Backspace",run:Kf,preventDefault:!0},{key:"Mod-Delete",mac:"Alt-Delete",run:FO,preventDefault:!0},{mac:"Mod-Backspace",run:UO,preventDefault:!0},{mac:"Mod-Delete",run:HO,preventDefault:!0}].concat(r0.map(n=>({mac:n.key,run:n.run,shift:n.shift}))),l0=[{key:"Alt-ArrowLeft",mac:"Ctrl-ArrowLeft",run:yO,shift:MO},{key:"Alt-ArrowRight",mac:"Ctrl-ArrowRight",run:bO,shift:RO},{key:"Alt-ArrowUp",run:ZO},{key:"Shift-Alt-ArrowUp",run:KO},{key:"Alt-ArrowDown",run:YO},{key:"Shift-Alt-ArrowDown",run:JO},{key:"Mod-Alt-ArrowUp",run:VO},{key:"Mod-Alt-ArrowDown",run:NO},{key:"Escape",run:XO},{key:"Mod-Enter",run:i0},{key:"Alt-l",mac:"Ctrl-l",run:zO},{key:"Mod-i",run:IO,preventDefault:!0},{key:"Mod-[",run:nu},{key:"Mod-]",run:iu},{key:"Mod-Alt-\\",run:n0},{key:"Shift-Mod-k",run:e0},{key:"Shift-Mod-\\",run:PO},{key:"Mod-/",run:Zg},{key:"Alt-A",run:Kg},{key:"Ctrl-m",mac:"Shift-Alt-m",run:s0}].concat(o0),a0={key:"Tab",run:iu,shift:nu},qa=typeof String.prototype.normalize=="function"?n=>n.normalize("NFKD"):n=>n;class pi{constructor(e,t,i=0,s=e.length,r,o){this.test=o,this.value={from:0,to:0},this.done=!1,this.matches=[],this.buffer="",this.bufferPos=0,this.iter=e.iterRange(i,s),this.bufferStart=i,this.normalize=r?l=>r(qa(l)):qa,this.query=this.normalize(t)}peek(){if(this.bufferPos==this.buffer.length){if(this.bufferStart+=this.buffer.length,this.iter.next(),this.iter.done)return-1;this.bufferPos=0,this.buffer=this.iter.value}return Te(this.buffer,this.bufferPos)}next(){for(;this.matches.length;)this.matches.pop();return this.nextOverlapping()}nextOverlapping(){for(;;){let e=this.peek();if(e<0)return this.done=!0,this;let t=So(e),i=this.bufferStart+this.bufferPos;this.bufferPos+=Ye(e);let s=this.normalize(t);if(s.length)for(let r=0,o=i;;r++){let l=s.charCodeAt(r),a=this.match(l,o,this.bufferPos+this.bufferStart);if(r==s.length-1){if(a)return this.value=a,this;break}o==i&&rthis.to&&(this.curLine=this.curLine.slice(0,this.to-this.curLineStart)),this.iter.next())}nextLine(){this.curLineStart=this.curLineStart+this.curLine.length+1,this.curLineStart>this.to?this.curLine="":this.getLine(0)}next(){for(let e=this.matchPos-this.curLineStart;;){this.re.lastIndex=e;let t=this.matchPos<=this.to&&this.re.exec(this.curLine);if(t){let i=this.curLineStart+t.index,s=i+t[0].length;if(this.matchPos=ms(this.text,s+(i==s?1:0)),i==this.curLineStart+this.curLine.length&&this.nextLine(),(ithis.value.to)&&(!this.test||this.test(i,s,t)))return this.value={from:i,to:s,match:t},this;e=this.matchPos-this.curLineStart}else if(this.curLineStart+this.curLine.length=i||s.to<=t){let l=new si(t,e.sliceString(t,i));return lr.set(e,l),l}if(s.from==t&&s.to==i)return s;let{text:r,from:o}=s;return o>t&&(r=e.sliceString(t,o)+r,o=t),s.to=this.to?this.to:this.text.lineAt(e).to}next(){for(;;){let e=this.re.lastIndex=this.matchPos-this.flat.from,t=this.re.exec(this.flat.text);if(t&&!t[0]&&t.index==e&&(this.re.lastIndex=e+1,t=this.re.exec(this.flat.text)),t){let i=this.flat.from+t.index,s=i+t[0].length;if((this.flat.to>=this.to||t.index+t[0].length<=this.flat.text.length-10)&&(!this.test||this.test(i,s,t)))return this.value={from:i,to:s,match:t},this.matchPos=ms(this.text,s+(i==s?1:0)),this}if(this.flat.to==this.to)return this.done=!0,this;this.flat=si.get(this.text,this.flat.from,this.chunkEnd(this.flat.from+this.flat.text.length*2))}}}typeof Symbol<"u"&&(ru.prototype[Symbol.iterator]=ou.prototype[Symbol.iterator]=function(){return this});function h0(n){try{return new RegExp(n,jo),!0}catch{return!1}}function ms(n,e){if(e>=n.length)return e;let t=n.lineAt(e),i;for(;e=56320&&i<57344;)e++;return e}function go(n){let e=String(n.state.doc.lineAt(n.state.selection.main.head).number),t=U("input",{class:"cm-textfield",name:"line",value:e}),i=U("form",{class:"cm-gotoLine",onkeydown:r=>{r.keyCode==27?(r.preventDefault(),n.dispatch({effects:$i.of(!1)}),n.focus()):r.keyCode==13&&(r.preventDefault(),s())},onsubmit:r=>{r.preventDefault(),s()}},U("label",n.state.phrase("Go to line"),": ",t)," ",U("button",{class:"cm-button",type:"submit"},n.state.phrase("go")),U("button",{name:"close",onclick:()=>{n.dispatch({effects:$i.of(!1)}),n.focus()},"aria-label":n.state.phrase("close"),type:"button"},["×"]));function s(){let r=/^([+-])?(\d+)?(:\d+)?(%)?$/.exec(t.value);if(!r)return;let{state:o}=n,l=o.doc.lineAt(o.selection.main.head),[,a,h,c,f]=r,u=c?+c.slice(1):0,d=h?+h:l.number;if(h&&f){let g=d/100;a&&(g=g*(a=="-"?-1:1)+l.number/o.doc.lines),d=Math.round(o.doc.lines*g)}else h&&a&&(d=d*(a=="-"?-1:1)+l.number);let p=o.doc.line(Math.max(1,Math.min(o.doc.lines,d))),m=b.cursor(p.from+Math.max(0,Math.min(u,p.length)));n.dispatch({effects:[$i.of(!1),P.scrollIntoView(m.from,{y:"center"})],selection:m}),n.focus()}return{dom:i}}const $i=q.define(),$a=he.define({create(){return!0},update(n,e){for(let t of e.effects)t.is($i)&&(n=t.value);return n},provide:n=>Xi.from(n,e=>e?go:null)}),c0=n=>{let e=Ni(n,go);if(!e){let t=[$i.of(!0)];n.state.field($a,!1)==null&&t.push(q.appendConfig.of([$a,f0])),n.dispatch({effects:t}),e=Ni(n,go)}return e&&e.dom.querySelector("input").select(),!0},f0=P.baseTheme({".cm-panel.cm-gotoLine":{padding:"2px 6px 4px",position:"relative","& label":{fontSize:"80%"},"& [name=close]":{position:"absolute",top:"0",bottom:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:"0"}}}),u0={highlightWordAroundCursor:!1,minSelectionLength:1,maxMatches:100,wholeWords:!1},d0=A.define({combine(n){return rt(n,u0,{highlightWordAroundCursor:(e,t)=>e||t,minSelectionLength:Math.min,maxMatches:Math.min})}});function p0(n){return[b0,y0]}const m0=R.mark({class:"cm-selectionMatch"}),g0=R.mark({class:"cm-selectionMatch cm-selectionMatch-main"});function Ba(n,e,t,i){return(t==0||n(e.sliceDoc(t-1,t))!=Y.Word)&&(i==e.doc.length||n(e.sliceDoc(i,i+1))!=Y.Word)}function O0(n,e,t,i){return n(e.sliceDoc(t,t+1))==Y.Word&&n(e.sliceDoc(i-1,i))==Y.Word}const y0=J.fromClass(class{constructor(n){this.decorations=this.getDeco(n)}update(n){(n.selectionSet||n.docChanged||n.viewportChanged)&&(this.decorations=this.getDeco(n.view))}getDeco(n){let e=n.state.facet(d0),{state:t}=n,i=t.selection;if(i.ranges.length>1)return R.none;let s=i.main,r,o=null;if(s.empty){if(!e.highlightWordAroundCursor)return R.none;let a=t.wordAt(s.head);if(!a)return R.none;o=t.charCategorizer(s.head),r=t.sliceDoc(a.from,a.to)}else{let a=s.to-s.from;if(a200)return R.none;if(e.wholeWords){if(r=t.sliceDoc(s.from,s.to),o=t.charCategorizer(s.head),!(Ba(o,t,s.from,s.to)&&O0(o,t,s.from,s.to)))return R.none}else if(r=t.sliceDoc(s.from,s.to),!r)return R.none}let l=[];for(let a of n.visibleRanges){let h=new pi(t.doc,r,a.from,a.to);for(;!h.next().done;){let{from:c,to:f}=h.value;if((!o||Ba(o,t,c,f))&&(s.empty&&c<=s.from&&f>=s.to?l.push(g0.range(c,f)):(c>=s.to||f<=s.from)&&l.push(m0.range(c,f)),l.length>e.maxMatches))return R.none}}return R.set(l)}},{decorations:n=>n.decorations}),b0=P.baseTheme({".cm-selectionMatch":{backgroundColor:"#99ff7780"},".cm-searchMatch .cm-selectionMatch":{backgroundColor:"transparent"}}),S0=({state:n,dispatch:e})=>{let{selection:t}=n,i=b.create(t.ranges.map(s=>n.wordAt(s.head)||b.cursor(s.head)),t.mainIndex);return i.eq(t)?!1:(e(n.update({selection:i})),!0)};function x0(n,e){let{main:t,ranges:i}=n.selection,s=n.wordAt(t.head),r=s&&s.from==t.from&&s.to==t.to;for(let o=!1,l=new pi(n.doc,e,i[i.length-1].to);;)if(l.next(),l.done){if(o)return null;l=new pi(n.doc,e,0,Math.max(0,i[i.length-1].from-1)),o=!0}else{if(o&&i.some(a=>a.from==l.value.from))continue;if(r){let a=n.wordAt(l.value.from);if(!a||a.from!=l.value.from||a.to!=l.value.to)continue}return l.value}}const k0=({state:n,dispatch:e})=>{let{ranges:t}=n.selection;if(t.some(r=>r.from===r.to))return S0({state:n,dispatch:e});let i=n.sliceDoc(t[0].from,t[0].to);if(n.selection.ranges.some(r=>n.sliceDoc(r.from,r.to)!=i))return!1;let s=x0(n,i);return s?(e(n.update({selection:n.selection.addRange(b.range(s.from,s.to),!1),effects:P.scrollIntoView(s.to)})),!0):!1},yi=A.define({combine(n){return rt(n,{top:!1,caseSensitive:!1,literal:!1,regexp:!1,wholeWord:!1,createPanel:e=>new q0(e),scrollToMatch:e=>P.scrollIntoView(e)})}});class lu{constructor(e){this.search=e.search,this.caseSensitive=!!e.caseSensitive,this.literal=!!e.literal,this.regexp=!!e.regexp,this.replace=e.replace||"",this.valid=!!this.search&&(!this.regexp||h0(this.search)),this.unquoted=this.unquote(this.search),this.wholeWord=!!e.wholeWord}unquote(e){return this.literal?e:e.replace(/\\([nrt\\])/g,(t,i)=>i=="n"?` +`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord}create(){return this.regexp?new C0(this):new v0(this)}getCursor(e,t=0,i){let s=e.doc?e:I.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?Yt(this,s,t,i):Zt(this,s,t,i)}}class au{constructor(e){this.spec=e}}function Zt(n,e,t,i){return new pi(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:s=>s.toLowerCase(),n.wholeWord?w0(e.doc,e.charCategorizer(e.selection.main.head)):void 0)}function w0(n,e){return(t,i,s,r)=>((r>t||r+s.length=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=Zt(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function Yt(n,e,t,i){return new ru(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:n.wholeWord?T0(e.charCategorizer(e.selection.main.head)):void 0},t,i)}function gs(n,e){return n.slice(pe(n,e,!1),e)}function Os(n,e){return n.slice(e,pe(n,e))}function T0(n){return(e,t,i)=>!i[0].length||(n(gs(i.input,i.index))!=Y.Word||n(Os(i.input,i.index))!=Y.Word)&&(n(Os(i.input,i.index+i[0].length))!=Y.Word||n(gs(i.input,i.index+i[0].length))!=Y.Word)}class C0 extends au{nextMatch(e,t,i){let s=Yt(this.spec,e,i,e.doc.length).next();return s.done&&(s=Yt(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=Yt(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=Yt(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const Gi=q.define(),Go=q.define(),vt=he.define({create(n){return new ar(Oo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(Gi)?n=new ar(t.value.create(),n.panel):t.is(Go)&&(n=new ar(n.query,t.value?Zo:null));return n},provide:n=>Xi.from(n,e=>e.panel)});class ar{constructor(e,t){this.query=e,this.panel=t}}const P0=R.mark({class:"cm-searchMatch"}),Q0=R.mark({class:"cm-searchMatch cm-searchMatch-selected"}),A0=J.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(vt))}update(n){let e=n.state.field(vt);(e!=n.startState.field(vt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return R.none;let{view:t}=this,i=new gt;for(let s=0,r=t.visibleRanges,o=r.length;sr[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?Q0:P0)})}return i.finish()}},{decorations:n=>n.decorations});function pn(n){return e=>{let t=e.state.field(vt,!1);return t&&t.query.spec.valid?n(e,t):fu(e)}}const ys=pn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(yi);return n.dispatch({selection:s,effects:[Yo(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),cu(n),!0}),bs=pn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r=b.single(s.from,s.to),o=n.state.facet(yi);return n.dispatch({selection:r,effects:[Yo(n,s),o.scrollToMatch(r.main,n)],userEvent:"select.search"}),cu(n),!0}),M0=pn((n,{query:e})=>{let t=e.matchAll(n.state,1e3);return!t||!t.length?!1:(n.dispatch({selection:b.create(t.map(i=>b.range(i.from,i.to))),userEvent:"select.search.matches"}),!0)}),R0=({state:n,dispatch:e})=>{let t=n.selection;if(t.ranges.length>1||t.main.empty)return!1;let{from:i,to:s}=t.main,r=[],o=0;for(let l=new pi(n.doc,n.sliceDoc(i,s));!l.next().done;){if(r.length>1e3)return!1;l.value.from==i&&(o=r.length),r.push(b.range(l.value.from,l.value.to))}return e(n.update({selection:b.create(r,o),userEvent:"select.search.matches"})),!0},Wa=pn((n,{query:e})=>{let{state:t}=n,{from:i,to:s}=t.selection.main;if(t.readOnly)return!1;let r=e.nextMatch(t,i,i);if(!r)return!1;let o=r,l=[],a,h,c=[];o.from==i&&o.to==s&&(h=t.toText(e.getReplacement(o)),l.push({from:o.from,to:o.to,insert:h}),o=e.nextMatch(t,o.from,o.to),c.push(P.announce.of(t.phrase("replaced match on line $",t.doc.lineAt(i).number)+".")));let f=n.state.changes(l);return o&&(a=b.single(o.from,o.to).map(f),c.push(Yo(n,o)),c.push(t.facet(yi).scrollToMatch(a.main,n))),n.dispatch({changes:f,selection:a,effects:c,userEvent:"input.replace"}),!0}),D0=pn((n,{query:e})=>{if(n.state.readOnly)return!1;let t=e.matchAll(n.state,1e9).map(s=>{let{from:r,to:o}=s;return{from:r,to:o,insert:e.getReplacement(s)}});if(!t.length)return!1;let i=n.state.phrase("replaced $ matches",t.length)+".";return n.dispatch({changes:t,effects:P.announce.of(i),userEvent:"input.replace.all"}),!0});function Zo(n){return n.state.facet(yi).createPanel(n)}function Oo(n,e){var t,i,s,r,o;let l=n.selection.main,a=l.empty||l.to>l.from+100?"":n.sliceDoc(l.from,l.to);if(e&&!a)return e;let h=n.facet(yi);return new lu({search:((t=e?.literal)!==null&&t!==void 0?t:h.literal)?a:a.replace(/\n/g,"\\n"),caseSensitive:(i=e?.caseSensitive)!==null&&i!==void 0?i:h.caseSensitive,literal:(s=e?.literal)!==null&&s!==void 0?s:h.literal,regexp:(r=e?.regexp)!==null&&r!==void 0?r:h.regexp,wholeWord:(o=e?.wholeWord)!==null&&o!==void 0?o:h.wholeWord})}function hu(n){let e=Ni(n,Zo);return e&&e.dom.querySelector("[main-field]")}function cu(n){let e=hu(n);e&&e==n.root.activeElement&&e.select()}const fu=n=>{let e=n.state.field(vt,!1);if(e&&e.panel){let t=hu(n);if(t&&t!=n.root.activeElement){let i=Oo(n.state,e.query.spec);i.valid&&n.dispatch({effects:Gi.of(i)}),t.focus(),t.select()}}else n.dispatch({effects:[Go.of(!0),e?Gi.of(Oo(n.state,e.query.spec)):q.appendConfig.of(B0)]});return!0},uu=n=>{let e=n.state.field(vt,!1);if(!e||!e.panel)return!1;let t=Ni(n,Zo);return t&&t.dom.contains(n.root.activeElement)&&n.focus(),n.dispatch({effects:Go.of(!1)}),!0},E0=[{key:"Mod-f",run:fu,scope:"editor search-panel"},{key:"F3",run:ys,shift:bs,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:ys,shift:bs,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:uu,scope:"editor search-panel"},{key:"Mod-Shift-l",run:R0},{key:"Mod-Alt-g",run:c0},{key:"Mod-d",run:k0,preventDefault:!0}];class q0{constructor(e){this.view=e;let t=this.query=e.state.field(vt).query.spec;this.commit=this.commit.bind(this),this.searchField=U("input",{value:t.search,placeholder:Me(e,"Find"),"aria-label":Me(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=U("input",{value:t.replace,placeholder:Me(e,"Replace"),"aria-label":Me(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=U("input",{type:"checkbox",name:"case",form:"",checked:t.caseSensitive,onchange:this.commit}),this.reField=U("input",{type:"checkbox",name:"re",form:"",checked:t.regexp,onchange:this.commit}),this.wordField=U("input",{type:"checkbox",name:"word",form:"",checked:t.wholeWord,onchange:this.commit});function i(s,r,o){return U("button",{class:"cm-button",name:s,onclick:r,type:"button"},o)}this.dom=U("div",{onkeydown:s=>this.keydown(s),class:"cm-search"},[this.searchField,i("next",()=>ys(e),[Me(e,"next")]),i("prev",()=>bs(e),[Me(e,"previous")]),i("select",()=>M0(e),[Me(e,"all")]),U("label",null,[this.caseField,Me(e,"match case")]),U("label",null,[this.reField,Me(e,"regexp")]),U("label",null,[this.wordField,Me(e,"by word")]),...e.state.readOnly?[]:[U("br"),this.replaceField,i("replace",()=>Wa(e),[Me(e,"replace")]),i("replaceAll",()=>D0(e),[Me(e,"replace all")])],U("button",{name:"close",onclick:()=>uu(e),"aria-label":Me(e,"close"),type:"button"},["×"])])}commit(){let e=new lu({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:Gi.of(e)}))}keydown(e){zp(this.view,e,"search-panel")?e.preventDefault():e.keyCode==13&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?bs:ys)(this.view)):e.keyCode==13&&e.target==this.replaceField&&(e.preventDefault(),Wa(this.view))}update(e){for(let t of e.transactions)for(let i of t.effects)i.is(Gi)&&!i.value.eq(this.query)&&this.setQuery(i.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(yi).top}}function Me(n,e){return n.state.phrase(e)}const Wn=30,Ln=/[\s\.,:;?!]/;function Yo(n,{from:e,to:t}){let i=n.state.doc.lineAt(e),s=n.state.doc.lineAt(t).to,r=Math.max(i.from,e-Wn),o=Math.min(s,t+Wn),l=n.state.sliceDoc(r,o);if(r!=i.from){for(let a=0;al.length-Wn;a--)if(!Ln.test(l[a-1])&&Ln.test(l[a])){l=l.slice(0,a);break}}return P.announce.of(`${n.state.phrase("current match")}. ${l} ${n.state.phrase("on line")} ${i.number}.`)}const $0=P.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),B0=[vt,Mt.low(A0),$0];class du{constructor(e,t,i,s){this.state=e,this.pos=t,this.explicit=i,this.view=s,this.abortListeners=[],this.abortOnDocChange=!1}tokenBefore(e){let t=ae(this.state).resolveInner(this.pos,-1);for(;t&&e.indexOf(t.name)<0;)t=t.parent;return t?{from:t.from,to:this.pos,text:this.state.sliceDoc(t.from,this.pos),type:t.type}:null}matchBefore(e){let t=this.state.doc.lineAt(this.pos),i=Math.max(t.from,this.pos-250),s=t.text.slice(i-t.from,this.pos-t.from),r=s.search(mu(e,!1));return r<0?null:{from:i+r,to:this.pos,text:s.slice(r)}}get aborted(){return this.abortListeners==null}addEventListener(e,t,i){e=="abort"&&this.abortListeners&&(this.abortListeners.push(t),i&&i.onDocChange&&(this.abortOnDocChange=!0))}}function La(n){let e=Object.keys(n).join(""),t=/\w/.test(e);return t&&(e=e.replace(/\w/g,"")),`[${t?"\\w":""}${e.replace(/[^\w\s]/g,"\\$&")}]`}function W0(n){let e=Object.create(null),t=Object.create(null);for(let{label:s}of n){e[s[0]]=!0;for(let r=1;rtypeof s=="string"?{label:s}:s),[t,i]=e.every(s=>/^\w+$/.test(s.label))?[/\w*$/,/\w+$/]:W0(e);return s=>{let r=s.matchBefore(i);return r||s.explicit?{from:r?r.from:s.pos,options:e,validFor:t}:null}}function L0(n,e){return t=>{for(let i=ae(t.state).resolveInner(t.pos,-1);i;i=i.parent){if(n.indexOf(i.name)>-1)return null;if(i.type.isTop)break}return e(t)}}class za{constructor(e,t,i,s){this.completion=e,this.source=t,this.match=i,this.score=s}}function Vt(n){return n.selection.main.from}function mu(n,e){var t;let{source:i}=n,s=e&&i[0]!="^",r=i[i.length-1]!="$";return!s&&!r?n:new RegExp(`${s?"^":""}(?:${i})${r?"$":""}`,(t=n.flags)!==null&&t!==void 0?t:n.ignoreCase?"i":"")}const Ko=st.define();function z0(n,e,t,i){let{main:s}=n.selection,r=t-s.from,o=i-s.from;return{...n.changeByRange(l=>{if(l!=s&&t!=i&&n.sliceDoc(l.from+r,l.from+o)!=n.sliceDoc(t,i))return{range:l};let a=n.toText(e);return{changes:{from:l.from+r,to:i==s.from?l.to:l.from+o,insert:a},range:b.cursor(l.from+r+a.length)}}),scrollIntoView:!0,userEvent:"input.complete"}}const Ia=new WeakMap;function I0(n){if(!Array.isArray(n))return n;let e=Ia.get(n);return e||Ia.set(n,e=pu(n)),e}const Ss=q.define(),Zi=q.define();class V0{constructor(e){this.pattern=e,this.chars=[],this.folded=[],this.any=[],this.precise=[],this.byWord=[],this.score=0,this.matched=[];for(let t=0;t=48&&k<=57||k>=97&&k<=122?2:k>=65&&k<=90?1:0:(v=So(k))!=v.toLowerCase()?1:v!=v.toUpperCase()?2:0;(!S||T==1&&g||w==0&&T!=0)&&(t[f]==k||i[f]==k&&(u=!0)?o[f++]=S:o.length&&(y=!1)),w=T,S+=Ye(k)}return f==a&&o[0]==0&&y?this.result(-100+(u?-200:0),o,e):d==a&&p==0?this.ret(-200-e.length+(m==e.length?0:-100),[0,m]):l>-1?this.ret(-700-e.length,[l,l+this.pattern.length]):d==a?this.ret(-900-e.length,[p,m]):f==a?this.result(-100+(u?-200:0)+-700+(y?0:-1100),o,e):t.length==2?null:this.result((s[0]?-700:0)+-200+-1100,s,e)}result(e,t,i){let s=[],r=0;for(let o of t){let l=o+(this.astral?Ye(Te(i,o)):1);r&&s[r-1]==o?s[r-1]=l:(s[r++]=o,s[r++]=l)}return this.ret(e-i.length,s)}}class N0{constructor(e){this.pattern=e,this.matched=[],this.score=0,this.folded=e.toLowerCase()}match(e){if(e.length!1,activateOnTypingDelay:100,selectOnOpen:!0,override:null,closeOnBlur:!0,maxRenderedOptions:100,defaultKeymap:!0,tooltipClass:()=>"",optionClass:()=>"",aboveCursor:!1,icons:!0,addToOptions:[],positionInfo:X0,filterStrict:!1,compareCompletions:(e,t)=>e.label.localeCompare(t.label),interactionDelay:75,updateSyncTime:100},{defaultKeymap:(e,t)=>e&&t,closeOnBlur:(e,t)=>e&&t,icons:(e,t)=>e&&t,tooltipClass:(e,t)=>i=>Va(e(i),t(i)),optionClass:(e,t)=>i=>Va(e(i),t(i)),addToOptions:(e,t)=>e.concat(t),filterStrict:(e,t)=>e||t})}});function Va(n,e){return n?e?n+" "+e:n:e}function X0(n,e,t,i,s,r){let o=n.textDirection==Z.RTL,l=o,a=!1,h="top",c,f,u=e.left-s.left,d=s.right-e.right,p=i.right-i.left,m=i.bottom-i.top;if(l&&u=m||S>e.top?c=t.bottom-e.top:(h="bottom",c=e.bottom-t.top)}let g=(e.bottom-e.top)/r.offsetHeight,y=(e.right-e.left)/r.offsetWidth;return{style:`${h}: ${c/g}px; max-width: ${f/y}px`,class:"cm-completionInfo-"+(a?o?"left-narrow":"right-narrow":l?"left":"right")}}function F0(n){let e=n.addToOptions.slice();return n.icons&&e.push({render(t){let i=document.createElement("div");return i.classList.add("cm-completionIcon"),t.type&&i.classList.add(...t.type.split(/\s+/g).map(s=>"cm-completionIcon-"+s)),i.setAttribute("aria-hidden","true"),i},position:20}),e.push({render(t,i,s,r){let o=document.createElement("span");o.className="cm-completionLabel";let l=t.displayLabel||t.label,a=0;for(let h=0;ha&&o.appendChild(document.createTextNode(l.slice(a,c)));let u=o.appendChild(document.createElement("span"));u.appendChild(document.createTextNode(l.slice(c,f))),u.className="cm-completionMatchedText",a=f}return at.position-i.position).map(t=>t.render)}function hr(n,e,t){if(n<=t)return{from:0,to:n};if(e<0&&(e=0),e<=n>>1){let s=Math.floor(e/t);return{from:s*t,to:(s+1)*t}}let i=Math.floor((n-e)/t);return{from:n-(i+1)*t,to:n-i*t}}class _0{constructor(e,t,i){this.view=e,this.stateField=t,this.applyCompletion=i,this.info=null,this.infoDestroy=null,this.placeInfoReq={read:()=>this.measureInfo(),write:a=>this.placeInfo(a),key:this},this.space=null,this.currentClass="";let s=e.state.field(t),{options:r,selected:o}=s.open,l=e.state.facet(le);this.optionContent=F0(l),this.optionClass=l.optionClass,this.tooltipClass=l.tooltipClass,this.range=hr(r.length,o,l.maxRenderedOptions),this.dom=document.createElement("div"),this.dom.className="cm-tooltip-autocomplete",this.updateTooltipClass(e.state),this.dom.addEventListener("mousedown",a=>{let{options:h}=e.state.field(t).open;for(let c=a.target,f;c&&c!=this.dom;c=c.parentNode)if(c.nodeName=="LI"&&(f=/-(\d+)$/.exec(c.id))&&+f[1]{let h=e.state.field(this.stateField,!1);h&&h.tooltip&&e.state.facet(le).closeOnBlur&&a.relatedTarget!=e.contentDOM&&e.dispatch({effects:Zi.of(null)})}),this.showOptions(r,s.id)}mount(){this.updateSel()}showOptions(e,t){this.list&&this.list.remove(),this.list=this.dom.appendChild(this.createListBox(e,t,this.range)),this.list.addEventListener("scroll",()=>{this.info&&this.view.requestMeasure(this.placeInfoReq)})}update(e){var t;let i=e.state.field(this.stateField),s=e.startState.field(this.stateField);if(this.updateTooltipClass(e.state),i!=s){let{options:r,selected:o,disabled:l}=i.open;(!s.open||s.open.options!=r)&&(this.range=hr(r.length,o,e.state.facet(le).maxRenderedOptions),this.showOptions(r,i.id)),this.updateSel(),l!=((t=s.open)===null||t===void 0?void 0:t.disabled)&&this.dom.classList.toggle("cm-tooltip-autocomplete-disabled",!!l)}}updateTooltipClass(e){let t=this.tooltipClass(e);if(t!=this.currentClass){for(let i of this.currentClass.split(" "))i&&this.dom.classList.remove(i);for(let i of t.split(" "))i&&this.dom.classList.add(i);this.currentClass=t}}positioned(e){this.space=e,this.info&&this.view.requestMeasure(this.placeInfoReq)}updateSel(){let e=this.view.state.field(this.stateField),t=e.open;(t.selected>-1&&t.selected=this.range.to)&&(this.range=hr(t.options.length,t.selected,this.view.state.facet(le).maxRenderedOptions),this.showOptions(t.options,e.id));let i=this.updateSelectedOption(t.selected);if(i){this.destroyInfo();let{completion:s}=t.options[t.selected],{info:r}=s;if(!r)return;let o=typeof r=="string"?document.createTextNode(r):r(s);if(!o)return;"then"in o?o.then(l=>{l&&this.view.state.field(this.stateField,!1)==e&&this.addInfoPane(l,s)}).catch(l=>Pe(this.view.state,l,"completion info")):(this.addInfoPane(o,s),i.setAttribute("aria-describedby",this.info.id))}}addInfoPane(e,t){this.destroyInfo();let i=this.info=document.createElement("div");if(i.className="cm-tooltip cm-completionInfo",i.id="cm-completionInfo-"+Math.floor(Math.random()*65535).toString(16),e.nodeType!=null)i.appendChild(e),this.infoDestroy=null;else{let{dom:s,destroy:r}=e;i.appendChild(s),this.infoDestroy=r||null}this.dom.appendChild(i),this.view.requestMeasure(this.placeInfoReq)}updateSelectedOption(e){let t=null;for(let i=this.list.firstChild,s=this.range.from;i;i=i.nextSibling,s++)i.nodeName!="LI"||!i.id?s--:s==e?i.hasAttribute("aria-selected")||(i.setAttribute("aria-selected","true"),t=i):i.hasAttribute("aria-selected")&&(i.removeAttribute("aria-selected"),i.removeAttribute("aria-describedby"));return t&&H0(this.list,t),t}measureInfo(){let e=this.dom.querySelector("[aria-selected]");if(!e||!this.info)return null;let t=this.dom.getBoundingClientRect(),i=this.info.getBoundingClientRect(),s=e.getBoundingClientRect(),r=this.space;if(!r){let o=this.dom.ownerDocument.documentElement;r={left:0,top:0,right:o.clientWidth,bottom:o.clientHeight}}return s.top>Math.min(r.bottom,t.bottom)-10||s.bottom{o.target==s&&o.preventDefault()});let r=null;for(let o=i.from;oi.from||i.from==0))if(r=u,typeof h!="string"&&h.header)s.appendChild(h.header(h));else{let d=s.appendChild(document.createElement("completion-section"));d.textContent=u}}const c=s.appendChild(document.createElement("li"));c.id=t+"-"+o,c.setAttribute("role","option");let f=this.optionClass(l);f&&(c.className=f);for(let u of this.optionContent){let d=u(l,this.view.state,this.view,a);d&&c.appendChild(d)}}return i.from&&s.classList.add("cm-completionListIncompleteTop"),i.tonew _0(t,n,e)}function H0(n,e){let t=n.getBoundingClientRect(),i=e.getBoundingClientRect(),s=t.height/n.offsetHeight;i.topt.bottom&&(n.scrollTop+=(i.bottom-t.bottom)/s)}function Na(n){return(n.boost||0)*100+(n.apply?10:0)+(n.info?5:0)+(n.type?1:0)}function j0(n,e){let t=[],i=null,s=null,r=c=>{t.push(c);let{section:f}=c.completion;if(f){i||(i=[]);let u=typeof f=="string"?f:f.name;i.some(d=>d.name==u)||i.push(typeof f=="string"?{name:u}:f)}},o=e.facet(le);for(let c of n)if(c.hasResult()){let f=c.result.getMatch;if(c.result.filter===!1)for(let u of c.result.options)r(new za(u,c.source,f?f(u):[],1e9-t.length));else{let u=e.sliceDoc(c.from,c.to),d,p=o.filterStrict?new N0(u):new V0(u);for(let m of c.result.options)if(d=p.match(m.label)){let g=m.displayLabel?f?f(m,d.matched):[]:d.matched,y=d.score+(m.boost||0);if(r(new za(m,c.source,g,y)),typeof m.section=="object"&&m.section.rank==="dynamic"){let{name:S}=m.section;s||(s=Object.create(null)),s[S]=Math.max(y,s[S]||-1e9)}}}}if(i){let c=Object.create(null),f=0,u=(d,p)=>(d.rank==="dynamic"&&p.rank==="dynamic"?s[p.name]-s[d.name]:0)||(typeof d.rank=="number"?d.rank:1e9)-(typeof p.rank=="number"?p.rank:1e9)||(d.nameu.score-f.score||h(f.completion,u.completion))){let f=c.completion;!a||a.label!=f.label||a.detail!=f.detail||a.type!=null&&f.type!=null&&a.type!=f.type||a.apply!=f.apply||a.boost!=f.boost?l.push(c):Na(c.completion)>Na(a)&&(l[l.length-1]=c),a=c.completion}return l}class ei{constructor(e,t,i,s,r,o){this.options=e,this.attrs=t,this.tooltip=i,this.timestamp=s,this.selected=r,this.disabled=o}setSelected(e,t){return e==this.selected||e>=this.options.length?this:new ei(this.options,Xa(t,e),this.tooltip,this.timestamp,e,this.disabled)}static build(e,t,i,s,r,o){if(s&&!o&&e.some(h=>h.isPending))return s.setDisabled();let l=j0(e,t);if(!l.length)return s&&e.some(h=>h.isPending)?s.setDisabled():null;let a=t.facet(le).selectOnOpen?0:-1;if(s&&s.selected!=a&&s.selected!=-1){let h=s.options[s.selected].completion;for(let c=0;cc.hasResult()?Math.min(h,c.from):h,1e8),create:ey,above:r.aboveCursor},s?s.timestamp:Date.now(),a,!1)}map(e){return new ei(this.options,this.attrs,{...this.tooltip,pos:e.mapPos(this.tooltip.pos)},this.timestamp,this.selected,this.disabled)}setDisabled(){return new ei(this.options,this.attrs,this.tooltip,this.timestamp,this.selected,!0)}}class xs{constructor(e,t,i){this.active=e,this.id=t,this.open=i}static start(){return new xs(K0,"cm-ac-"+Math.floor(Math.random()*2e6).toString(36),null)}update(e){let{state:t}=e,i=t.facet(le),r=(i.override||t.languageDataAt("autocomplete",Vt(t)).map(I0)).map(a=>(this.active.find(c=>c.source==a)||new We(a,this.active.some(c=>c.state!=0)?1:0)).update(e,i));r.length==this.active.length&&r.every((a,h)=>a==this.active[h])&&(r=this.active);let o=this.open,l=e.effects.some(a=>a.is(Jo));o&&e.docChanged&&(o=o.map(e.changes)),e.selection||r.some(a=>a.hasResult()&&e.changes.touchesRange(a.from,a.to))||!G0(r,this.active)||l?o=ei.build(r,t,this.id,o,i,l):o&&o.disabled&&!r.some(a=>a.isPending)&&(o=null),!o&&r.every(a=>!a.isPending)&&r.some(a=>a.hasResult())&&(r=r.map(a=>a.hasResult()?new We(a.source,0):a));for(let a of e.effects)a.is(Ou)&&(o=o&&o.setSelected(a.value,this.id));return r==this.active&&o==this.open?this:new xs(r,this.id,o)}get tooltip(){return this.open?this.open.tooltip:null}get attrs(){return this.open?this.open.attrs:this.active.length?Z0:Y0}}function G0(n,e){if(n==e)return!0;for(let t=0,i=0;;){for(;t-1&&(t["aria-activedescendant"]=n+"-"+e),t}const K0=[];function gu(n,e){if(n.isUserEvent("input.complete")){let i=n.annotation(Ko);if(i&&e.activateOnCompletion(i))return 12}let t=n.isUserEvent("input.type");return t&&e.activateOnTyping?5:t?1:n.isUserEvent("delete.backward")?2:n.selection?8:n.docChanged?16:0}class We{constructor(e,t,i=!1){this.source=e,this.state=t,this.explicit=i}hasResult(){return!1}get isPending(){return this.state==1}update(e,t){let i=gu(e,t),s=this;(i&8||i&16&&this.touches(e))&&(s=new We(s.source,0)),i&4&&s.state==0&&(s=new We(this.source,1)),s=s.updateFor(e,i);for(let r of e.effects)if(r.is(Ss))s=new We(s.source,1,r.value);else if(r.is(Zi))s=new We(s.source,0);else if(r.is(Jo))for(let o of r.value)o.source==s.source&&(s=o);return s}updateFor(e,t){return this.map(e.changes)}map(e){return this}touches(e){return e.changes.touchesRange(Vt(e.state))}}class ri extends We{constructor(e,t,i,s,r,o){super(e,3,t),this.limit=i,this.result=s,this.from=r,this.to=o}hasResult(){return!0}updateFor(e,t){var i;if(!(t&3))return this.map(e.changes);let s=this.result;s.map&&!e.changes.empty&&(s=s.map(s,e.changes));let r=e.changes.mapPos(this.from),o=e.changes.mapPos(this.to,1),l=Vt(e.state);if(l>o||!s||t&2&&(Vt(e.startState)==this.from||lt.map(e))}}),Ou=q.define(),Ce=he.define({create(){return xs.start()},update(n,e){return n.update(e)},provide:n=>[qo.from(n,e=>e.tooltip),P.contentAttributes.from(n,e=>e.attrs)]});function el(n,e){const t=e.completion.apply||e.completion.label;let i=n.state.field(Ce).active.find(s=>s.source==e.source);return i instanceof ri?(typeof t=="string"?n.dispatch({...z0(n.state,t,i.from,i.to),annotations:Ko.of(e.completion)}):t(n,e.completion,i.from,i.to),!0):!1}const ey=U0(Ce,el);function zn(n,e="option"){return t=>{let i=t.state.field(Ce,!1);if(!i||!i.open||i.open.disabled||Date.now()-i.open.timestamp-1?i.open.selected+s*(n?1:-1):n?0:o-1;return l<0?l=e=="page"?0:o-1:l>=o&&(l=e=="page"?o-1:0),t.dispatch({effects:Ou.of(l)}),!0}}const ty=n=>{let e=n.state.field(Ce,!1);return n.state.readOnly||!e||!e.open||e.open.selected<0||e.open.disabled||Date.now()-e.open.timestampn.state.field(Ce,!1)?(n.dispatch({effects:Ss.of(!0)}),!0):!1,iy=n=>{let e=n.state.field(Ce,!1);return!e||!e.active.some(t=>t.state!=0)?!1:(n.dispatch({effects:Zi.of(null)}),!0)};class ny{constructor(e,t){this.active=e,this.context=t,this.time=Date.now(),this.updates=[],this.done=void 0}}const sy=50,ry=1e3,oy=J.fromClass(class{constructor(n){this.view=n,this.debounceUpdate=-1,this.running=[],this.debounceAccept=-1,this.pendingStart=!1,this.composing=0;for(let e of n.state.field(Ce).active)e.isPending&&this.startQuery(e)}update(n){let e=n.state.field(Ce),t=n.state.facet(le);if(!n.selectionSet&&!n.docChanged&&n.startState.field(Ce)==e)return;let i=n.transactions.some(r=>{let o=gu(r,t);return o&8||(r.selection||r.docChanged)&&!(o&3)});for(let r=0;rsy&&Date.now()-o.time>ry){for(let l of o.context.abortListeners)try{l()}catch(a){Pe(this.view.state,a)}o.context.abortListeners=null,this.running.splice(r--,1)}else o.updates.push(...n.transactions)}this.debounceUpdate>-1&&clearTimeout(this.debounceUpdate),n.transactions.some(r=>r.effects.some(o=>o.is(Ss)))&&(this.pendingStart=!0);let s=this.pendingStart?50:t.activateOnTypingDelay;if(this.debounceUpdate=e.active.some(r=>r.isPending&&!this.running.some(o=>o.active.source==r.source))?setTimeout(()=>this.startUpdate(),s):-1,this.composing!=0)for(let r of n.transactions)r.isUserEvent("input.type")?this.composing=2:this.composing==2&&r.selection&&(this.composing=3)}startUpdate(){this.debounceUpdate=-1,this.pendingStart=!1;let{state:n}=this.view,e=n.field(Ce);for(let t of e.active)t.isPending&&!this.running.some(i=>i.active.source==t.source)&&this.startQuery(t);this.running.length&&e.open&&e.open.disabled&&(this.debounceAccept=setTimeout(()=>this.accept(),this.view.state.facet(le).updateSyncTime))}startQuery(n){let{state:e}=this.view,t=Vt(e),i=new du(e,t,n.explicit,this.view),s=new ny(n,i);this.running.push(s),Promise.resolve(n.source(i)).then(r=>{s.context.aborted||(s.done=r||null,this.scheduleAccept())},r=>{this.view.dispatch({effects:Zi.of(null)}),Pe(this.view.state,r)})}scheduleAccept(){this.running.every(n=>n.done!==void 0)?this.accept():this.debounceAccept<0&&(this.debounceAccept=setTimeout(()=>this.accept(),this.view.state.facet(le).updateSyncTime))}accept(){var n;this.debounceAccept>-1&&clearTimeout(this.debounceAccept),this.debounceAccept=-1;let e=[],t=this.view.state.facet(le),i=this.view.state.field(Ce);for(let s=0;sl.source==r.active.source);if(o&&o.isPending)if(r.done==null){let l=new We(r.active.source,0);for(let a of r.updates)l=l.update(a,t);l.isPending||e.push(l)}else this.startQuery(o)}(e.length||i.open&&i.open.disabled)&&this.view.dispatch({effects:Jo.of(e)})}},{eventHandlers:{blur(n){let e=this.view.state.field(Ce,!1);if(e&&e.tooltip&&this.view.state.facet(le).closeOnBlur){let t=e.open&&Xc(this.view,e.open.tooltip);(!t||!t.dom.contains(n.relatedTarget))&&setTimeout(()=>this.view.dispatch({effects:Zi.of(null)}),10)}},compositionstart(){this.composing=1},compositionend(){this.composing==3&&setTimeout(()=>this.view.dispatch({effects:Ss.of(!1)}),20),this.composing=0}}}),ly=typeof navigator=="object"&&/Win/.test(navigator.platform),ay=Mt.highest(P.domEventHandlers({keydown(n,e){let t=e.state.field(Ce,!1);if(!t||!t.open||t.open.disabled||t.open.selected<0||n.key.length>1||n.ctrlKey&&!(ly&&n.altKey)||n.metaKey)return!1;let i=t.open.options[t.open.selected],s=t.active.find(o=>o.source==i.source),r=i.completion.commitCharacters||s.result.commitCharacters;return r&&r.indexOf(n.key)>-1&&el(e,i),!1}})),yu=P.baseTheme({".cm-tooltip.cm-tooltip-autocomplete":{"& > ul":{fontFamily:"monospace",whiteSpace:"nowrap",overflow:"hidden auto",maxWidth_fallback:"700px",maxWidth:"min(700px, 95vw)",minWidth:"250px",maxHeight:"10em",height:"100%",listStyle:"none",margin:0,padding:0,"& > li, & > completion-section":{padding:"1px 3px",lineHeight:1.2},"& > li":{overflowX:"hidden",textOverflow:"ellipsis",cursor:"pointer"},"& > completion-section":{display:"list-item",borderBottom:"1px solid silver",paddingLeft:"0.5em",opacity:.7}}},"&light .cm-tooltip-autocomplete ul li[aria-selected]":{background:"#17c",color:"white"},"&light .cm-tooltip-autocomplete-disabled ul li[aria-selected]":{background:"#777"},"&dark .cm-tooltip-autocomplete ul li[aria-selected]":{background:"#347",color:"white"},"&dark .cm-tooltip-autocomplete-disabled ul li[aria-selected]":{background:"#444"},".cm-completionListIncompleteTop:before, .cm-completionListIncompleteBottom:after":{content:'"···"',opacity:.5,display:"block",textAlign:"center"},".cm-tooltip.cm-completionInfo":{position:"absolute",padding:"3px 9px",width:"max-content",maxWidth:"400px",boxSizing:"border-box",whiteSpace:"pre-line"},".cm-completionInfo.cm-completionInfo-left":{right:"100%"},".cm-completionInfo.cm-completionInfo-right":{left:"100%"},".cm-completionInfo.cm-completionInfo-left-narrow":{right:"30px"},".cm-completionInfo.cm-completionInfo-right-narrow":{left:"30px"},"&light .cm-snippetField":{backgroundColor:"#00000022"},"&dark .cm-snippetField":{backgroundColor:"#ffffff22"},".cm-snippetFieldPosition":{verticalAlign:"text-top",width:0,height:"1.15em",display:"inline-block",margin:"0 -0.7px -.7em",borderLeft:"1.4px dotted #888"},".cm-completionMatchedText":{textDecoration:"underline"},".cm-completionDetail":{marginLeft:"0.5em",fontStyle:"italic"},".cm-completionIcon":{fontSize:"90%",width:".8em",display:"inline-block",textAlign:"center",paddingRight:".6em",opacity:"0.6",boxSizing:"content-box"},".cm-completionIcon-function, .cm-completionIcon-method":{"&:after":{content:"'ƒ'"}},".cm-completionIcon-class":{"&:after":{content:"'○'"}},".cm-completionIcon-interface":{"&:after":{content:"'◌'"}},".cm-completionIcon-variable":{"&:after":{content:"'𝑥'"}},".cm-completionIcon-constant":{"&:after":{content:"'𝐶'"}},".cm-completionIcon-type":{"&:after":{content:"'𝑡'"}},".cm-completionIcon-enum":{"&:after":{content:"'∪'"}},".cm-completionIcon-property":{"&:after":{content:"'□'"}},".cm-completionIcon-keyword":{"&:after":{content:"'🔑︎'"}},".cm-completionIcon-namespace":{"&:after":{content:"'▢'"}},".cm-completionIcon-text":{"&:after":{content:"'abc'",fontSize:"50%",verticalAlign:"middle"}}});class hy{constructor(e,t,i,s){this.field=e,this.line=t,this.from=i,this.to=s}}class tl{constructor(e,t,i){this.field=e,this.from=t,this.to=i}map(e){let t=e.mapPos(this.from,-1,de.TrackDel),i=e.mapPos(this.to,1,de.TrackDel);return t==null||i==null?null:new tl(this.field,t,i)}}class il{constructor(e,t){this.lines=e,this.fieldPositions=t}instantiate(e,t){let i=[],s=[t],r=e.doc.lineAt(t),o=/^\s*/.exec(r.text)[0];for(let a of this.lines){if(i.length){let h=o,c=/^\t*/.exec(a)[0].length;for(let f=0;fnew tl(a.field,s[a.line]+a.from,s[a.line]+a.to));return{text:i,ranges:l}}static parse(e){let t=[],i=[],s=[],r;for(let o of e.split(/\r\n?|\n/)){for(;r=/[#$]\{(?:(\d+)(?::([^{}]*))?|((?:\\[{}]|[^{}])*))\}/.exec(o);){let l=r[1]?+r[1]:null,a=r[2]||r[3]||"",h=-1,c=a.replace(/\\[{}]/g,f=>f[1]);for(let f=0;f=h&&u.field++}for(let f of s)if(f.line==i.length&&f.from>r.index){let u=r[2]?3+(r[1]||"").length:2;f.from-=u,f.to-=u}s.push(new hy(h,i.length,r.index,r.index+c.length)),o=o.slice(0,r.index)+a+o.slice(r.index+r[0].length)}o=o.replace(/\\([{}])/g,(l,a,h)=>{for(let c of s)c.line==i.length&&c.from>h&&(c.from--,c.to--);return a}),i.push(o)}return new il(i,s)}}let cy=R.widget({widget:new class extends ot{toDOM(){let n=document.createElement("span");return n.className="cm-snippetFieldPosition",n}ignoreEvent(){return!1}}}),fy=R.mark({class:"cm-snippetField"});class bi{constructor(e,t){this.ranges=e,this.active=t,this.deco=R.set(e.map(i=>(i.from==i.to?cy:fy).range(i.from,i.to)),!0)}map(e){let t=[];for(let i of this.ranges){let s=i.map(e);if(!s)return null;t.push(s)}return new bi(t,this.active)}selectionInsideField(e){return e.ranges.every(t=>this.ranges.some(i=>i.field==this.active&&i.from<=t.from&&i.to>=t.to))}}const mn=q.define({map(n,e){return n&&n.map(e)}}),uy=q.define(),Yi=he.define({create(){return null},update(n,e){for(let t of e.effects){if(t.is(mn))return t.value;if(t.is(uy)&&n)return new bi(n.ranges,t.value)}return n&&e.docChanged&&(n=n.map(e.changes)),n&&e.selection&&!n.selectionInsideField(e.selection)&&(n=null),n},provide:n=>P.decorations.from(n,e=>e?e.deco:R.none)});function nl(n,e){return b.create(n.filter(t=>t.field==e).map(t=>b.range(t.from,t.to)))}function dy(n){let e=il.parse(n);return(t,i,s,r)=>{let{text:o,ranges:l}=e.instantiate(t.state,s),{main:a}=t.state.selection,h={changes:{from:s,to:r==a.from?a.to:r,insert:V.of(o)},scrollIntoView:!0,annotations:i?[Ko.of(i),ie.userEvent.of("input.complete")]:void 0};if(l.length&&(h.selection=nl(l,0)),l.some(c=>c.field>0)){let c=new bi(l,0),f=h.effects=[mn.of(c)];t.state.field(Yi,!1)===void 0&&f.push(q.appendConfig.of([Yi,yy,by,yu]))}t.dispatch(t.state.update(h))}}function bu(n){return({state:e,dispatch:t})=>{let i=e.field(Yi,!1);if(!i||n<0&&i.active==0)return!1;let s=i.active+n,r=n>0&&!i.ranges.some(o=>o.field==s+n);return t(e.update({selection:nl(i.ranges,s),effects:mn.of(r?null:new bi(i.ranges,s)),scrollIntoView:!0})),!0}}const py=({state:n,dispatch:e})=>n.field(Yi,!1)?(e(n.update({effects:mn.of(null)})),!0):!1,my=bu(1),gy=bu(-1),Oy=[{key:"Tab",run:my,shift:gy},{key:"Escape",run:py}],Fa=A.define({combine(n){return n.length?n[0]:Oy}}),yy=Mt.highest(an.compute([Fa],n=>n.facet(Fa)));function lt(n,e){return{...e,apply:dy(n)}}const by=P.domEventHandlers({mousedown(n,e){let t=e.state.field(Yi,!1),i;if(!t||(i=e.posAtCoords({x:n.clientX,y:n.clientY}))==null)return!1;let s=t.ranges.find(r=>r.from<=i&&r.to>=i);return!s||s.field==t.active?!1:(e.dispatch({selection:nl(t.ranges,s.field),effects:mn.of(t.ranges.some(r=>r.field>s.field)?new bi(t.ranges,s.field):null),scrollIntoView:!0}),!0)}}),Ki={brackets:["(","[","{","'",'"'],before:")]}:;>",stringPrefixes:[]},zt=q.define({map(n,e){let t=e.mapPos(n,-1,de.TrackAfter);return t??void 0}}),sl=new class extends Nt{};sl.startSide=1;sl.endSide=-1;const Su=he.define({create(){return N.empty},update(n,e){if(n=n.map(e.changes),e.selection){let t=e.state.doc.lineAt(e.selection.main.head);n=n.update({filter:i=>i>=t.from&&i<=t.to})}for(let t of e.effects)t.is(zt)&&(n=n.update({add:[sl.range(t.value,t.value+1)]}));return n}});function Sy(){return[ky,Su]}const fr="()[]{}<>«»»«[]{}";function xu(n){for(let e=0;e{if((xy?n.composing:n.compositionStarted)||n.state.readOnly)return!1;let s=n.state.selection.main;if(i.length>2||i.length==2&&Ye(Te(i,0))==1||e!=s.from||t!=s.to)return!1;let r=Ty(n.state,i);return r?(n.dispatch(r),!0):!1}),wy=({state:n,dispatch:e})=>{if(n.readOnly)return!1;let i=ku(n,n.selection.main.head).brackets||Ki.brackets,s=null,r=n.changeByRange(o=>{if(o.empty){let l=Cy(n.doc,o.head);for(let a of i)if(a==l&&Bs(n.doc,o.head)==xu(Te(a,0)))return{changes:{from:o.head-a.length,to:o.head+a.length},range:b.cursor(o.head-a.length)}}return{range:s=o}});return s||e(n.update(r,{scrollIntoView:!0,userEvent:"delete.backward"})),!s},vy=[{key:"Backspace",run:wy}];function Ty(n,e){let t=ku(n,n.selection.main.head),i=t.brackets||Ki.brackets;for(let s of i){let r=xu(Te(s,0));if(e==s)return r==s?Ay(n,s,i.indexOf(s+s+s)>-1,t):Py(n,s,r,t.before||Ki.before);if(e==r&&wu(n,n.selection.main.from))return Qy(n,s,r)}return null}function wu(n,e){let t=!1;return n.field(Su).between(0,n.doc.length,i=>{i==e&&(t=!0)}),t}function Bs(n,e){let t=n.sliceString(e,e+2);return t.slice(0,Ye(Te(t,0)))}function Cy(n,e){let t=n.sliceString(e-2,e);return Ye(Te(t,0))==t.length?t:t.slice(1)}function Py(n,e,t,i){let s=null,r=n.changeByRange(o=>{if(!o.empty)return{changes:[{insert:e,from:o.from},{insert:t,from:o.to}],effects:zt.of(o.to+e.length),range:b.range(o.anchor+e.length,o.head+e.length)};let l=Bs(n.doc,o.head);return!l||/\s/.test(l)||i.indexOf(l)>-1?{changes:{insert:e+t,from:o.head},effects:zt.of(o.head+e.length),range:b.cursor(o.head+e.length)}:{range:s=o}});return s?null:n.update(r,{scrollIntoView:!0,userEvent:"input.type"})}function Qy(n,e,t){let i=null,s=n.changeByRange(r=>r.empty&&Bs(n.doc,r.head)==t?{changes:{from:r.head,to:r.head+t.length,insert:t},range:b.cursor(r.head+t.length)}:i={range:r});return i?null:n.update(s,{scrollIntoView:!0,userEvent:"input.type"})}function Ay(n,e,t,i){let s=i.stringPrefixes||Ki.stringPrefixes,r=null,o=n.changeByRange(l=>{if(!l.empty)return{changes:[{insert:e,from:l.from},{insert:e,from:l.to}],effects:zt.of(l.to+e.length),range:b.range(l.anchor+e.length,l.head+e.length)};let a=l.head,h=Bs(n.doc,a),c;if(h==e){if(_a(n,a))return{changes:{insert:e+e,from:a},effects:zt.of(a+e.length),range:b.cursor(a+e.length)};if(wu(n,a)){let u=t&&n.sliceDoc(a,a+e.length*3)==e+e+e?e+e+e:e;return{changes:{from:a,to:a+u.length,insert:u},range:b.cursor(a+u.length)}}}else{if(t&&n.sliceDoc(a-2*e.length,a)==e+e&&(c=Ua(n,a-2*e.length,s))>-1&&_a(n,c))return{changes:{insert:e+e+e+e,from:a},effects:zt.of(a+e.length),range:b.cursor(a+e.length)};if(n.charCategorizer(a)(h)!=Y.Word&&Ua(n,a,s)>-1&&!My(n,a,e,s))return{changes:{insert:e+e,from:a},effects:zt.of(a+e.length),range:b.cursor(a+e.length)}}return{range:r=l}});return r?null:n.update(o,{scrollIntoView:!0,userEvent:"input.type"})}function _a(n,e){let t=ae(n).resolveInner(e+1);return t.parent&&t.from==e}function My(n,e,t,i){let s=ae(n).resolveInner(e,-1),r=i.reduce((o,l)=>Math.max(o,l.length),0);for(let o=0;o<5;o++){let l=n.sliceDoc(s.from,Math.min(s.to,s.from+t.length+r)),a=l.indexOf(t);if(!a||a>-1&&i.indexOf(l.slice(0,a))>-1){let c=s.firstChild;for(;c&&c.from==s.from&&c.to-c.from>t.length+a;){if(n.sliceDoc(c.to-t.length,c.to)==t)return!1;c=c.firstChild}return!0}let h=s.to==e&&s.parent;if(!h)break;s=h}return!1}function Ua(n,e,t){let i=n.charCategorizer(e);if(i(n.sliceDoc(e-1,e))!=Y.Word)return e;for(let s of t){let r=e-s.length;if(n.sliceDoc(r,e)==s&&i(n.sliceDoc(r-1,r))!=Y.Word)return r}return-1}function Ry(n={}){return[ay,Ce,le.of(n),oy,Dy,yu]}const vu=[{key:"Ctrl-Space",run:cr},{mac:"Alt-`",run:cr},{mac:"Alt-i",run:cr},{key:"Escape",run:iy},{key:"ArrowDown",run:zn(!0)},{key:"ArrowUp",run:zn(!1)},{key:"PageDown",run:zn(!0,"page")},{key:"PageUp",run:zn(!1,"page")},{key:"Enter",run:ty}],Dy=Mt.highest(an.computeN([le],n=>n.facet(le).defaultKeymap?[vu]:[]));class Ha{constructor(e,t,i){this.from=e,this.to=t,this.diagnostic=i}}class Bt{constructor(e,t,i){this.diagnostics=e,this.panel=t,this.selected=i}static init(e,t,i){let s=i.facet(Ji).markerFilter;s&&(e=s(e,i));let r=e.slice().sort((d,p)=>d.from-p.from||d.to-p.to),o=new gt,l=[],a=0,h=i.doc.iter(),c=0,f=i.doc.length;for(let d=0;;){let p=d==r.length?null:r[d];if(!p&&!l.length)break;let m,g;if(l.length)m=a,g=l.reduce((x,w)=>Math.min(x,w.to),p&&p.from>m?p.from:1e8);else{if(m=p.from,m>f)break;g=p.to,l.push(p),d++}for(;dx.from||x.to==m))l.push(x),d++,g=Math.min(x.to,g);else{g=Math.min(x.from,g);break}}g=Math.min(g,f);let y=!1;if(l.some(x=>x.from==m&&(x.to==g||g==f))&&(y=m==g,!y&&g-m<10)){let x=m-(c+h.value.length);x>0&&(h.next(x),c=m);for(let w=m;;){if(w>=g){y=!0;break}if(!h.lineBreak&&c+h.value.length>w)break;w=c+h.value.length,c+=h.value.length,h.next()}}let S=_y(l);if(y)o.add(m,m,R.widget({widget:new Vy(S),diagnostics:l.slice()}));else{let x=l.reduce((w,k)=>k.markClass?w+" "+k.markClass:w,"");o.add(m,g,R.mark({class:"cm-lintRange cm-lintRange-"+S+x,diagnostics:l.slice(),inclusiveEnd:l.some(w=>w.to>g)}))}if(a=g,a==f)break;for(let x=0;x{if(!(e&&o.diagnostics.indexOf(e)<0))if(!i)i=new Ha(s,r,e||o.diagnostics[0]);else{if(o.diagnostics.indexOf(i.diagnostic)<0)return!1;i=new Ha(i.from,r,i.diagnostic)}}),i}function Ey(n,e){let t=e.pos,i=e.end||t,s=n.state.facet(Ji).hideOn(n,t,i);if(s!=null)return s;let r=n.startState.doc.lineAt(e.pos);return!!(n.effects.some(o=>o.is(Tu))||n.changes.touchesRange(r.from,Math.max(r.to,i)))}function qy(n,e){return n.field(Ee,!1)?e:e.concat(q.appendConfig.of(Uy))}const Tu=q.define(),rl=q.define(),Cu=q.define(),Ee=he.define({create(){return new Bt(R.none,null,null)},update(n,e){if(e.docChanged&&n.diagnostics.size){let t=n.diagnostics.map(e.changes),i=null,s=n.panel;if(n.selected){let r=e.changes.mapPos(n.selected.from,1);i=mi(t,n.selected.diagnostic,r)||mi(t,null,r)}!t.size&&s&&e.state.facet(Ji).autoPanel&&(s=null),n=new Bt(t,s,i)}for(let t of e.effects)if(t.is(Tu)){let i=e.state.facet(Ji).autoPanel?t.value.length?en.open:null:n.panel;n=Bt.init(t.value,i,e.state)}else t.is(rl)?n=new Bt(n.diagnostics,t.value?en.open:null,n.selected):t.is(Cu)&&(n=new Bt(n.diagnostics,n.panel,t.value));return n},provide:n=>[Xi.from(n,e=>e.panel),P.decorations.from(n,e=>e.diagnostics)]}),$y=R.mark({class:"cm-lintRange cm-lintRange-active"});function By(n,e,t){let{diagnostics:i}=n.state.field(Ee),s,r=-1,o=-1;i.between(e-(t<0?1:0),e+(t>0?1:0),(a,h,{spec:c})=>{if(e>=a&&e<=h&&(a==h||(e>a||t>0)&&(eQu(n,t,!1)))}const Ly=n=>{let e=n.state.field(Ee,!1);(!e||!e.panel)&&n.dispatch({effects:qy(n.state,[rl.of(!0)])});let t=Ni(n,en.open);return t&&t.dom.querySelector(".cm-panel-lint ul").focus(),!0},ja=n=>{let e=n.state.field(Ee,!1);return!e||!e.panel?!1:(n.dispatch({effects:rl.of(!1)}),!0)},zy=n=>{let e=n.state.field(Ee,!1);if(!e)return!1;let t=n.state.selection.main,i=e.diagnostics.iter(t.to+1);return!i.value&&(i=e.diagnostics.iter(0),!i.value||i.from==t.from&&i.to==t.to)?!1:(n.dispatch({selection:{anchor:i.from,head:i.to},scrollIntoView:!0}),!0)},Iy=[{key:"Mod-Shift-m",run:Ly,preventDefault:!0},{key:"F8",run:zy}],Ji=A.define({combine(n){return{sources:n.map(e=>e.source).filter(e=>e!=null),...rt(n.map(e=>e.config),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null,hideOn:()=>null},{delay:Math.max,markerFilter:Ga,tooltipFilter:Ga,needsRefresh:(e,t)=>e?t?i=>e(i)||t(i):e:t,hideOn:(e,t)=>e?t?(i,s,r)=>e(i,s,r)||t(i,s,r):e:t,autoPanel:(e,t)=>e||t})}}});function Ga(n,e){return n?e?(t,i)=>e(n(t,i),i):n:e}function Pu(n){let e=[];if(n)e:for(let{name:t}of n){for(let i=0;ir.toLowerCase()==s.toLowerCase())){e.push(s);continue e}}e.push("")}return e}function Qu(n,e,t){var i;let s=t?Pu(e.actions):[];return U("li",{class:"cm-diagnostic cm-diagnostic-"+e.severity},U("span",{class:"cm-diagnosticText"},e.renderMessage?e.renderMessage(n):e.message),(i=e.actions)===null||i===void 0?void 0:i.map((r,o)=>{let l=!1,a=d=>{if(d.preventDefault(),l)return;l=!0;let p=mi(n.state.field(Ee).diagnostics,e);p&&r.apply(n,p.from,p.to)},{name:h}=r,c=s[o]?h.indexOf(s[o]):-1,f=c<0?h:[h.slice(0,c),U("u",h.slice(c,c+1)),h.slice(c+1)],u=r.markClass?" "+r.markClass:"";return U("button",{type:"button",class:"cm-diagnosticAction"+u,onclick:a,onmousedown:a,"aria-label":` Action: ${h}${c<0?"":` (access key "${s[o]})"`}.`},f)}),e.source&&U("div",{class:"cm-diagnosticSource"},e.source))}class Vy extends ot{constructor(e){super(),this.sev=e}eq(e){return e.sev==this.sev}toDOM(){return U("span",{class:"cm-lintPoint cm-lintPoint-"+this.sev})}}class Za{constructor(e,t){this.diagnostic=t,this.id="item_"+Math.floor(Math.random()*4294967295).toString(16),this.dom=Qu(e,t,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class en{constructor(e){this.view=e,this.items=[];let t=s=>{if(s.keyCode==27)ja(this.view),this.view.focus();else if(s.keyCode==38||s.keyCode==33)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(s.keyCode==40||s.keyCode==34)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(s.keyCode==36)this.moveSelection(0);else if(s.keyCode==35)this.moveSelection(this.items.length-1);else if(s.keyCode==13)this.view.focus();else if(s.keyCode>=65&&s.keyCode<=90&&this.selectedIndex>=0){let{diagnostic:r}=this.items[this.selectedIndex],o=Pu(r.actions);for(let l=0;l{for(let r=0;rja(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(Ee).selected;if(!e)return-1;for(let t=0;t{for(let c of h.diagnostics){if(o.has(c))continue;o.add(c);let f=-1,u;for(let d=i;di&&(this.items.splice(i,f-i),s=!0)),t&&u.diagnostic==t.diagnostic?u.dom.hasAttribute("aria-selected")||(u.dom.setAttribute("aria-selected","true"),r=u):u.dom.hasAttribute("aria-selected")&&u.dom.removeAttribute("aria-selected"),i++}});i({sel:r.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:l,panel:a})=>{let h=a.height/this.list.offsetHeight;l.topa.bottom&&(this.list.scrollTop+=(l.bottom-a.bottom)/h)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),s&&this.sync()}sync(){let e=this.list.firstChild;function t(){let i=e;e=i.nextSibling,i.remove()}for(let i of this.items)if(i.dom.parentNode==this.list){for(;e!=i.dom;)t();e=i.dom.nextSibling}else this.list.insertBefore(i.dom,e);for(;e;)t()}moveSelection(e){if(this.selectedIndex<0)return;let t=this.view.state.field(Ee),i=mi(t.diagnostics,this.items[e].diagnostic);i&&this.view.dispatch({selection:{anchor:i.from,head:i.to},scrollIntoView:!0,effects:Cu.of(i)})}static open(e){return new en(e)}}function Ny(n,e='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(n)}')`}function In(n){return Ny(``,'width="6" height="3"')}const Xy=P.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:In("#d11")},".cm-lintRange-warning":{backgroundImage:In("orange")},".cm-lintRange-info":{backgroundImage:In("#999")},".cm-lintRange-hint":{backgroundImage:In("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}}});function Fy(n){return n=="error"?4:n=="warning"?3:n=="info"?2:1}function _y(n){let e="hint",t=1;for(let i of n){let s=Fy(i.severity);s>t&&(t=s,e=i.severity)}return e}const Uy=[Ee,P.decorations.compute([Ee],n=>{let{selected:e,panel:t}=n.field(Ee);return!e||!t||e.from==e.to?R.none:R.set([$y.range(e.from,e.to)])}),Pm(By,{hideOn:Ey}),Xy];var Ya=function(e){e===void 0&&(e={});var{crosshairCursor:t=!1}=e,i=[];e.closeBracketsKeymap!==!1&&(i=i.concat(vy)),e.defaultKeymap!==!1&&(i=i.concat(l0)),e.searchKeymap!==!1&&(i=i.concat(E0)),e.historyKeymap!==!1&&(i=i.concat(pO)),e.foldKeymap!==!1&&(i=i.concat(vg)),e.completionKeymap!==!1&&(i=i.concat(vu)),e.lintKeymap!==!1&&(i=i.concat(Iy));var s=[];return e.lineNumbers!==!1&&s.push(Lm()),e.highlightActiveLineGutter!==!1&&s.push(Vm()),e.highlightSpecialChars!==!1&&s.push(im()),e.history!==!1&&s.push(rO()),e.foldGutter!==!1&&s.push(Qg()),e.drawSelection!==!1&&s.push(_p()),e.dropCursor!==!1&&s.push(Zp()),e.allowMultipleSelections!==!1&&s.push(I.allowMultipleSelections.of(!0)),e.indentOnInput!==!1&&s.push(mg()),e.syntaxHighlighting!==!1&&s.push(pf(Dg,{fallback:!0})),e.bracketMatching!==!1&&s.push(zg()),e.closeBrackets!==!1&&s.push(Sy()),e.autocompletion!==!1&&s.push(Ry()),e.rectangularSelection!==!1&&s.push(gm()),t!==!1&&s.push(bm()),e.highlightActiveLine!==!1&&s.push(am()),e.highlightSelectionMatches!==!1&&s.push(p0()),e.tabSize&&typeof e.tabSize=="number"&&s.push(cn.of(" ".repeat(e.tabSize))),s.concat([an.of(i.flat())]).filter(Boolean)};const Hy="#e5c07b",Ka="#e06c75",jy="#56b6c2",Gy="#ffffff",Kn="#abb2bf",yo="#7d8799",Zy="#61afef",Yy="#98c379",Ja="#d19a66",Ky="#c678dd",Jy="#21252b",eh="#2c313a",th="#282c34",ur="#353a42",e1="#3E4451",ih="#528bff",t1=P.theme({"&":{color:Kn,backgroundColor:th},".cm-content":{caretColor:ih},".cm-cursor, .cm-dropCursor":{borderLeftColor:ih},"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:e1},".cm-panels":{backgroundColor:Jy,color:Kn},".cm-panels.cm-panels-top":{borderBottom:"2px solid black"},".cm-panels.cm-panels-bottom":{borderTop:"2px solid black"},".cm-searchMatch":{backgroundColor:"#72a1ff59",outline:"1px solid #457dff"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:"#6199ff2f"},".cm-activeLine":{backgroundColor:"#6699ff0b"},".cm-selectionMatch":{backgroundColor:"#aafe661a"},"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bad0f847"},".cm-gutters":{backgroundColor:th,color:yo,border:"none"},".cm-activeLineGutter":{backgroundColor:eh},".cm-foldPlaceholder":{backgroundColor:"transparent",border:"none",color:"#ddd"},".cm-tooltip":{border:"none",backgroundColor:ur},".cm-tooltip .cm-tooltip-arrow:before":{borderTopColor:"transparent",borderBottomColor:"transparent"},".cm-tooltip .cm-tooltip-arrow:after":{borderTopColor:ur,borderBottomColor:ur},".cm-tooltip-autocomplete":{"& > ul > li[aria-selected]":{backgroundColor:eh,color:Kn}}},{dark:!0}),i1=un.define([{tag:O.keyword,color:Ky},{tag:[O.name,O.deleted,O.character,O.propertyName,O.macroName],color:Ka},{tag:[O.function(O.variableName),O.labelName],color:Zy},{tag:[O.color,O.constant(O.name),O.standard(O.name)],color:Ja},{tag:[O.definition(O.name),O.separator],color:Kn},{tag:[O.typeName,O.className,O.number,O.changed,O.annotation,O.modifier,O.self,O.namespace],color:Hy},{tag:[O.operator,O.operatorKeyword,O.url,O.escape,O.regexp,O.link,O.special(O.string)],color:jy},{tag:[O.meta,O.comment],color:yo},{tag:O.strong,fontWeight:"bold"},{tag:O.emphasis,fontStyle:"italic"},{tag:O.strikethrough,textDecoration:"line-through"},{tag:O.link,color:yo,textDecoration:"underline"},{tag:O.heading,fontWeight:"bold",color:Ka},{tag:[O.atom,O.bool,O.special(O.variableName)],color:Ja},{tag:[O.processingInstruction,O.string,O.inserted],color:Yy},{tag:O.invalid,color:Gy}]),n1=[t1,pf(i1)];var s1=P.theme({"&":{backgroundColor:"#fff"}},{dark:!1}),r1=function(e){e===void 0&&(e={});var{indentWithTab:t=!0,editable:i=!0,readOnly:s=!1,theme:r="light",placeholder:o="",basicSetup:l=!0}=e,a=[];switch(t&&a.unshift(an.of([a0])),l&&(typeof l=="boolean"?a.unshift(Ya()):a.unshift(Ya(l))),o&&a.unshift(um(o)),r){case"light":a.push(s1);break;case"dark":a.push(n1);break;case"none":break;default:a.push(r);break}return i===!1&&a.push(P.editable.of(!1)),s&&a.push(I.readOnly.of(!0)),[...a]},o1=n=>({line:n.state.doc.lineAt(n.state.selection.main.from),lineCount:n.state.doc.lines,lineBreak:n.state.lineBreak,length:n.state.doc.length,readOnly:n.state.readOnly,tabSize:n.state.tabSize,selection:n.state.selection,selectionAsSingle:n.state.selection.asSingle().main,ranges:n.state.selection.ranges,selectionCode:n.state.sliceDoc(n.state.selection.main.from,n.state.selection.main.to),selections:n.state.selection.ranges.map(e=>n.state.sliceDoc(e.from,e.to)),selectedText:n.state.selection.ranges.some(e=>!e.empty)});class l1{constructor(e,t){this.timeLeftMS=void 0,this.timeoutMS=void 0,this.isCancelled=!1,this.isTimeExhausted=!1,this.callbacks=[],this.timeLeftMS=t,this.timeoutMS=t,this.callbacks.push(e)}tick(){if(!this.isCancelled&&!this.isTimeExhausted&&(this.timeLeftMS--,this.timeLeftMS<=0)){this.isTimeExhausted=!0;var e=this.callbacks.slice();this.callbacks.length=0,e.forEach(t=>{try{t()}catch(i){console.error("TimeoutLatch callback error:",i)}})}}cancel(){this.isCancelled=!0,this.callbacks.length=0}reset(){this.timeLeftMS=this.timeoutMS,this.isCancelled=!1,this.isTimeExhausted=!1}get isDone(){return this.isCancelled||this.isTimeExhausted}}class nh{constructor(){this.interval=null,this.latches=new Set}add(e){this.latches.add(e),this.start()}remove(e){this.latches.delete(e),this.latches.size===0&&this.stop()}start(){this.interval===null&&(this.interval=setInterval(()=>{this.latches.forEach(e=>{e.tick(),e.isDone&&this.remove(e)})},1))}stop(){this.interval!==null&&(clearInterval(this.interval),this.interval=null)}}var dr=null,a1=()=>typeof window>"u"?new nh:(dr||(dr=new nh),dr),sh=st.define(),h1=200,c1=[];function f1(n){var{value:e,selection:t,onChange:i,onStatistics:s,onCreateEditor:r,onUpdate:o,extensions:l=c1,autoFocus:a,theme:h="light",height:c=null,minHeight:f=null,maxHeight:u=null,width:d=null,minWidth:p=null,maxWidth:m=null,placeholder:g="",editable:y=!0,readOnly:S=!1,indentWithTab:x=!0,basicSetup:w=!0,root:k,initialState:v}=n,[T,E]=Se.useState(),[M,z]=Se.useState(),[$,D]=Se.useState(),B=Se.useState(()=>({current:null}))[0],W=Se.useState(()=>({current:null}))[0],X=P.theme({"&":{height:c,minHeight:f,maxHeight:u,width:d,minWidth:p,maxWidth:m},"& .cm-scroller":{height:"100% !important"}}),ne=P.updateListener.of(F=>{if(F.docChanged&&typeof i=="function"&&!F.transactions.some(ge=>ge.annotation(sh))){B.current?B.current.reset():(B.current=new l1(()=>{if(W.current){var ge=W.current;W.current=null,ge()}B.current=null},h1),a1().add(B.current));var ee=F.state.doc,ce=ee.toString();i(ce,F)}s&&s(o1(F))}),oe=r1({theme:h,editable:y,readOnly:S,placeholder:g,indentWithTab:x,basicSetup:w}),me=[ne,X,...oe];return o&&typeof o=="function"&&me.push(P.updateListener.of(o)),me=me.concat(l),Se.useLayoutEffect(()=>{if(T&&!$){var F={doc:e,selection:t,extensions:me},ee=v?I.fromJSON(v.json,F,v.fields):I.create(F);if(D(ee),!M){var ce=new P({state:ee,parent:T,root:k});z(ce),r&&r(ce,ee)}}return()=>{M&&(D(void 0),z(void 0))}},[T,$]),Se.useEffect(()=>{n.container&&E(n.container)},[n.container]),Se.useEffect(()=>()=>{M&&(M.destroy(),z(void 0)),B.current&&(B.current.cancel(),B.current=null)},[M]),Se.useEffect(()=>{a&&M&&M.focus()},[a,M]),Se.useEffect(()=>{M&&M.dispatch({effects:q.reconfigure.of(me)})},[h,l,c,f,u,d,p,m,g,y,S,x,w,i,o]),Se.useEffect(()=>{if(e!==void 0){var F=M?M.state.doc.toString():"";if(M&&e!==F){var ee=B.current&&!B.current.isDone,ce=()=>{M&&e!==M.state.doc.toString()&&M.dispatch({changes:{from:0,to:M.state.doc.toString().length,insert:e||""},annotations:[sh.of(!0)]})};ee?W.current=ce:ce()}}},[e,M]),{state:$,setState:D,view:M,setView:z,container:T,setContainer:E}}var u1=["className","value","selection","extensions","onChange","onStatistics","onCreateEditor","onUpdate","autoFocus","theme","height","minHeight","maxHeight","width","minWidth","maxWidth","basicSetup","placeholder","indentWithTab","editable","readOnly","root","initialState"],d1=Se.forwardRef((n,e)=>{var{className:t,value:i="",selection:s,extensions:r=[],onChange:o,onStatistics:l,onCreateEditor:a,onUpdate:h,autoFocus:c,theme:f="light",height:u,minHeight:d,maxHeight:p,width:m,minWidth:g,maxWidth:y,basicSetup:S,placeholder:x,indentWithTab:w,editable:k,readOnly:v,root:T,initialState:E}=n,M=Iu(n,u1),z=Se.useRef(null),{state:$,view:D,container:B,setContainer:W}=f1({root:T,value:i,autoFocus:c,theme:f,height:u,minHeight:d,maxHeight:p,width:m,minWidth:g,maxWidth:y,basicSetup:S,placeholder:x,indentWithTab:w,editable:k,readOnly:v,selection:s,onChange:o,onStatistics:l,onCreateEditor:a,onUpdate:h,extensions:r,initialState:E});Se.useImperativeHandle(e,()=>({editor:z.current,state:$,view:D}),[z,B,$,D]);var X=Se.useCallback(oe=>{z.current=oe,W(oe)},[W]);if(typeof i!="string")throw new Error("value must be typeof string but got "+typeof i);var ne=typeof f=="string"?"cm-theme-"+f:"cm-theme";return zu.jsx("div",xr({ref:X,className:""+ne+(t?" "+t:"")},M))});d1.displayName="CodeMirror";var rh={};class ks{constructor(e,t,i,s,r,o,l,a,h,c=0,f){this.p=e,this.stack=t,this.state=i,this.reducePos=s,this.pos=r,this.score=o,this.buffer=l,this.bufferBase=a,this.curContext=h,this.lookAhead=c,this.parent=f}toString(){return`[${this.stack.filter((e,t)=>t%3==0).concat(this.state)}]@${this.pos}${this.score?"!"+this.score:""}`}static start(e,t,i=0){let s=e.parser.context;return new ks(e,[],t,i,i,0,[],0,s?new oh(s,s.start):null,0,null)}get context(){return this.curContext?this.curContext.context:null}pushState(e,t){this.stack.push(this.state,t,this.bufferBase+this.buffer.length),this.state=e}reduce(e){var t;let i=e>>19,s=e&65535,{parser:r}=this.p,o=this.reducePos=2e3&&!(!((t=this.p.parser.nodeSet.types[s])===null||t===void 0)&&t.isAnonymous)&&(h==this.p.lastBigReductionStart?(this.p.bigReductionCount++,this.p.lastBigReductionSize=c):this.p.lastBigReductionSizea;)this.stack.pop();this.reduceContext(s,h)}storeNode(e,t,i,s=4,r=!1){if(e==0&&(!this.stack.length||this.stack[this.stack.length-1]0&&o.buffer[l-4]==0&&o.buffer[l-1]>-1){if(t==i)return;if(o.buffer[l-2]>=t){o.buffer[l-2]=i;return}}}if(!r||this.pos==i)this.buffer.push(e,t,i,s);else{let o=this.buffer.length;if(o>0&&(this.buffer[o-4]!=0||this.buffer[o-1]<0)){let l=!1;for(let a=o;a>0&&this.buffer[a-2]>i;a-=4)if(this.buffer[a-1]>=0){l=!0;break}if(l)for(;o>0&&this.buffer[o-2]>i;)this.buffer[o]=this.buffer[o-4],this.buffer[o+1]=this.buffer[o-3],this.buffer[o+2]=this.buffer[o-2],this.buffer[o+3]=this.buffer[o-1],o-=4,s>4&&(s-=4)}this.buffer[o]=e,this.buffer[o+1]=t,this.buffer[o+2]=i,this.buffer[o+3]=s}}shift(e,t,i,s){if(e&131072)this.pushState(e&65535,this.pos);else if((e&262144)==0){let r=e,{parser:o}=this.p;(s>this.pos||t<=o.maxNode)&&(this.pos=s,o.stateFlag(r,1)||(this.reducePos=s)),this.pushState(r,i),this.shiftContext(t,i),t<=o.maxNode&&this.buffer.push(t,i,s,4)}else this.pos=s,this.shiftContext(t,i),t<=this.p.parser.maxNode&&this.buffer.push(t,i,s,4)}apply(e,t,i,s){e&65536?this.reduce(e):this.shift(e,t,i,s)}useNode(e,t){let i=this.p.reused.length-1;(i<0||this.p.reused[i]!=e)&&(this.p.reused.push(e),i++);let s=this.pos;this.reducePos=this.pos=s+e.length,this.pushState(t,s),this.buffer.push(i,s,this.reducePos,-1),this.curContext&&this.updateContext(this.curContext.tracker.reuse(this.curContext.context,e,this,this.p.stream.reset(this.pos-e.length)))}split(){let e=this,t=e.buffer.length;for(;t>0&&e.buffer[t-2]>e.reducePos;)t-=4;let i=e.buffer.slice(t),s=e.bufferBase+t;for(;e&&s==e.bufferBase;)e=e.parent;return new ks(this.p,this.stack.slice(),this.state,this.reducePos,this.pos,this.score,i,s,this.curContext,this.lookAhead,e)}recoverByDelete(e,t){let i=e<=this.p.parser.maxNode;i&&this.storeNode(e,this.pos,t,4),this.storeNode(0,this.pos,t,i?8:4),this.pos=this.reducePos=t,this.score-=190}canShift(e){for(let t=new p1(this);;){let i=this.p.parser.stateSlot(t.state,4)||this.p.parser.hasAction(t.state,e);if(i==0)return!1;if((i&65536)==0)return!0;t.reduce(i)}}recoverByInsert(e){if(this.stack.length>=300)return[];let t=this.p.parser.nextStates(this.state);if(t.length>8||this.stack.length>=120){let s=[];for(let r=0,o;ra&1&&l==o)||s.push(t[r],o)}t=s}let i=[];for(let s=0;s>19,s=t&65535,r=this.stack.length-i*3;if(r<0||e.getGoto(this.stack[r],s,!1)<0){let o=this.findForcedReduction();if(o==null)return!1;t=o}this.storeNode(0,this.pos,this.pos,4,!0),this.score-=100}return this.reducePos=this.pos,this.reduce(t),!0}findForcedReduction(){let{parser:e}=this.p,t=[],i=(s,r)=>{if(!t.includes(s))return t.push(s),e.allActions(s,o=>{if(!(o&393216))if(o&65536){let l=(o>>19)-r;if(l>1){let a=o&65535,h=this.stack.length-l*3;if(h>=0&&e.getGoto(this.stack[h],a,!1)>=0)return l<<19|65536|a}}else{let l=i(o,r+1);if(l!=null)return l}})};return i(this.state,0)}forceAll(){for(;!this.p.parser.stateFlag(this.state,2);)if(!this.forceReduce()){this.storeNode(0,this.pos,this.pos,4,!0);break}return this}get deadEnd(){if(this.stack.length!=3)return!1;let{parser:e}=this.p;return e.data[e.stateSlot(this.state,1)]==65535&&!e.stateSlot(this.state,4)}restart(){this.storeNode(0,this.pos,this.pos,4,!0),this.state=this.stack[0],this.stack.length=0}sameState(e){if(this.state!=e.state||this.stack.length!=e.stack.length)return!1;for(let t=0;tthis.lookAhead&&(this.emitLookAhead(),this.lookAhead=e)}close(){this.curContext&&this.curContext.tracker.strict&&this.emitContext(),this.lookAhead>0&&this.emitLookAhead()}}class oh{constructor(e,t){this.tracker=e,this.context=t,this.hash=e.strict?e.hash(t):0}}class p1{constructor(e){this.start=e,this.state=e.state,this.stack=e.stack,this.base=this.stack.length}reduce(e){let t=e&65535,i=e>>19;i==0?(this.stack==this.start.stack&&(this.stack=this.stack.slice()),this.stack.push(this.state,0,0),this.base+=3):this.base-=(i-1)*3;let s=this.start.p.parser.getGoto(this.stack[this.base-3],t,!0);this.state=s}}class ws{constructor(e,t,i){this.stack=e,this.pos=t,this.index=i,this.buffer=e.buffer,this.index==0&&this.maybeNext()}static create(e,t=e.bufferBase+e.buffer.length){return new ws(e,t,t-e.bufferBase)}maybeNext(){let e=this.stack.parent;e!=null&&(this.index=this.stack.bufferBase-e.bufferBase,this.stack=e,this.buffer=e.buffer)}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}next(){this.index-=4,this.pos-=4,this.index==0&&this.maybeNext()}fork(){return new ws(this.stack,this.pos,this.index)}}function Vn(n,e=Uint16Array){if(typeof n!="string")return n;let t=null;for(let i=0,s=0;i=92&&o--,o>=34&&o--;let a=o-32;if(a>=46&&(a-=46,l=!0),r+=a,l)break;r*=46}t?t[s++]=r:t=new e(r)}return t}class Jn{constructor(){this.start=-1,this.value=-1,this.end=-1,this.extended=-1,this.lookAhead=0,this.mask=0,this.context=0}}const lh=new Jn;class m1{constructor(e,t){this.input=e,this.ranges=t,this.chunk="",this.chunkOff=0,this.chunk2="",this.chunk2Pos=0,this.next=-1,this.token=lh,this.rangeIndex=0,this.pos=this.chunkPos=t[0].from,this.range=t[0],this.end=t[t.length-1].to,this.readNext()}resolveOffset(e,t){let i=this.range,s=this.rangeIndex,r=this.pos+e;for(;ri.to:r>=i.to;){if(s==this.ranges.length-1)return null;let o=this.ranges[++s];r+=o.from-i.to,i=o}return r}clipPos(e){if(e>=this.range.from&&ee)return Math.max(e,t.from);return this.end}peek(e){let t=this.chunkOff+e,i,s;if(t>=0&&t=this.chunk2Pos&&il.to&&(this.chunk2=this.chunk2.slice(0,l.to-i)),s=this.chunk2.charCodeAt(0)}}return i>=this.token.lookAhead&&(this.token.lookAhead=i+1),s}acceptToken(e,t=0){let i=t?this.resolveOffset(t,-1):this.pos;if(i==null||i=this.chunk2Pos&&this.posthis.range.to?e.slice(0,this.range.to-this.pos):e,this.chunkPos=this.pos,this.chunkOff=0}}readNext(){return this.chunkOff>=this.chunk.length&&(this.getChunk(),this.chunkOff==this.chunk.length)?this.next=-1:this.next=this.chunk.charCodeAt(this.chunkOff)}advance(e=1){for(this.chunkOff+=e;this.pos+e>=this.range.to;){if(this.rangeIndex==this.ranges.length-1)return this.setDone();e-=this.range.to-this.pos,this.range=this.ranges[++this.rangeIndex],this.pos=this.range.from}return this.pos+=e,this.pos>=this.token.lookAhead&&(this.token.lookAhead=this.pos+1),this.readNext()}setDone(){return this.pos=this.chunkPos=this.end,this.range=this.ranges[this.rangeIndex=this.ranges.length-1],this.chunk="",this.next=-1}reset(e,t){if(t?(this.token=t,t.start=e,t.lookAhead=e+1,t.value=t.extended=-1):this.token=lh,this.pos!=e){if(this.pos=e,e==this.end)return this.setDone(),this;for(;e=this.range.to;)this.range=this.ranges[++this.rangeIndex];e>=this.chunkPos&&e=this.chunkPos&&t<=this.chunkPos+this.chunk.length)return this.chunk.slice(e-this.chunkPos,t-this.chunkPos);if(e>=this.chunk2Pos&&t<=this.chunk2Pos+this.chunk2.length)return this.chunk2.slice(e-this.chunk2Pos,t-this.chunk2Pos);if(e>=this.range.from&&t<=this.range.to)return this.input.read(e,t);let i="";for(let s of this.ranges){if(s.from>=t)break;s.to>e&&(i+=this.input.read(Math.max(s.from,e),Math.min(s.to,t)))}return i}}class oi{constructor(e,t){this.data=e,this.id=t}token(e,t){let{parser:i}=t.p;g1(this.data,e,t,this.id,i.data,i.tokenPrecTable)}}oi.prototype.contextual=oi.prototype.fallback=oi.prototype.extend=!1;oi.prototype.fallback=oi.prototype.extend=!1;class Ws{constructor(e,t={}){this.token=e,this.contextual=!!t.contextual,this.fallback=!!t.fallback,this.extend=!!t.extend}}function g1(n,e,t,i,s,r){let o=0,l=1<0){let p=n[d];if(a.allows(p)&&(e.token.value==-1||e.token.value==p||O1(p,e.token.value,s,r))){e.acceptToken(p);break}}let c=e.next,f=0,u=n[o+2];if(e.next<0&&u>f&&n[h+u*3-3]==65535){o=n[h+u*3-1];continue e}for(;f>1,p=h+d+(d<<1),m=n[p],g=n[p+1]||65536;if(c=g)f=d+1;else{o=n[p+2],e.advance();continue e}}break}}function ah(n,e,t){for(let i=e,s;(s=n[i])!=65535;i++)if(s==t)return i-e;return-1}function O1(n,e,t,i){let s=ah(t,i,e);return s<0||ah(t,i,n)e)&&!i.type.isError)return t<0?Math.max(0,Math.min(i.to-1,e-25)):Math.min(n.length,Math.max(i.from+1,e+25));if(t<0?i.prevSibling():i.nextSibling())break;if(!i.parent())return t<0?0:n.length}}class y1{constructor(e,t){this.fragments=e,this.nodeSet=t,this.i=0,this.fragment=null,this.safeFrom=-1,this.safeTo=-1,this.trees=[],this.start=[],this.index=[],this.nextFragment()}nextFragment(){let e=this.fragment=this.i==this.fragments.length?null:this.fragments[this.i++];if(e){for(this.safeFrom=e.openStart?hh(e.tree,e.from+e.offset,1)-e.offset:e.from,this.safeTo=e.openEnd?hh(e.tree,e.to+e.offset,-1)-e.offset:e.to;this.trees.length;)this.trees.pop(),this.start.pop(),this.index.pop();this.trees.push(e.tree),this.start.push(-e.offset),this.index.push(0),this.nextStart=this.safeFrom}else this.nextStart=1e9}nodeAt(e){if(ee)return this.nextStart=o,null;if(r instanceof j){if(o==e){if(o=Math.max(this.safeFrom,e)&&(this.trees.push(r),this.start.push(o),this.index.push(0))}else this.index[t]++,this.nextStart=o+r.length}}}class b1{constructor(e,t){this.stream=t,this.tokens=[],this.mainToken=null,this.actions=[],this.tokens=e.tokenizers.map(i=>new Jn)}getActions(e){let t=0,i=null,{parser:s}=e.p,{tokenizers:r}=s,o=s.stateSlot(e.state,3),l=e.curContext?e.curContext.hash:0,a=0;for(let h=0;hf.end+25&&(a=Math.max(f.lookAhead,a)),f.value!=0)){let u=t;if(f.extended>-1&&(t=this.addActions(e,f.extended,f.end,t)),t=this.addActions(e,f.value,f.end,t),!c.extend&&(i=f,t>u))break}}for(;this.actions.length>t;)this.actions.pop();return a&&e.setLookAhead(a),!i&&e.pos==this.stream.end&&(i=new Jn,i.value=e.p.parser.eofTerm,i.start=i.end=e.pos,t=this.addActions(e,i.value,i.end,t)),this.mainToken=i,this.actions}getMainToken(e){if(this.mainToken)return this.mainToken;let t=new Jn,{pos:i,p:s}=e;return t.start=i,t.end=Math.min(i+1,s.stream.end),t.value=i==s.stream.end?s.parser.eofTerm:0,t}updateCachedToken(e,t,i){let s=this.stream.clipPos(i.pos);if(t.token(this.stream.reset(s,e),i),e.value>-1){let{parser:r}=i.p;for(let o=0;o=0&&i.p.parser.dialect.allows(l>>1)){(l&1)==0?e.value=l>>1:e.extended=l>>1;break}}}else e.value=0,e.end=this.stream.clipPos(s+1)}putAction(e,t,i,s){for(let r=0;re.bufferLength*4?new y1(i,e.nodeSet):null}get parsedPos(){return this.minStackPos}advance(){let e=this.stacks,t=this.minStackPos,i=this.stacks=[],s,r;if(this.bigReductionCount>300&&e.length==1){let[o]=e;for(;o.forceReduce()&&o.stack.length&&o.stack[o.stack.length-2]>=this.lastBigReductionStart;);this.bigReductionCount=this.lastBigReductionSize=0}for(let o=0;ot)i.push(l);else{if(this.advanceStack(l,i,e))continue;{s||(s=[],r=[]),s.push(l);let a=this.tokens.getMainToken(l);r.push(a.value,a.end)}}break}}if(!i.length){let o=s&&w1(s);if(o)return Re&&console.log("Finish with "+this.stackID(o)),this.stackToTree(o);if(this.parser.strict)throw Re&&s&&console.log("Stuck with token "+(this.tokens.mainToken?this.parser.getName(this.tokens.mainToken.value):"none")),new SyntaxError("No parse at "+t);this.recovering||(this.recovering=5)}if(this.recovering&&s){let o=this.stoppedAt!=null&&s[0].pos>this.stoppedAt?s[0]:this.runRecovery(s,r,i);if(o)return Re&&console.log("Force-finish "+this.stackID(o)),this.stackToTree(o.forceAll())}if(this.recovering){let o=this.recovering==1?1:this.recovering*3;if(i.length>o)for(i.sort((l,a)=>a.score-l.score);i.length>o;)i.pop();i.some(l=>l.reducePos>t)&&this.recovering--}else if(i.length>1){e:for(let o=0;o500&&h.buffer.length>500)if((l.score-h.score||l.buffer.length-h.buffer.length)>0)i.splice(a--,1);else{i.splice(o--,1);continue e}}}i.length>12&&i.splice(12,i.length-12)}this.minStackPos=i[0].pos;for(let o=1;o ":"";if(this.stoppedAt!=null&&s>this.stoppedAt)return e.forceReduce()?e:null;if(this.fragments){let h=e.curContext&&e.curContext.tracker.strict,c=h?e.curContext.hash:0;for(let f=this.fragments.nodeAt(s);f;){let u=this.parser.nodeSet.types[f.type.id]==f.type?r.getGoto(e.state,f.type.id):-1;if(u>-1&&f.length&&(!h||(f.prop(L.contextHash)||0)==c))return e.useNode(f,u),Re&&console.log(o+this.stackID(e)+` (via reuse of ${r.getName(f.type.id)})`),!0;if(!(f instanceof j)||f.children.length==0||f.positions[0]>0)break;let d=f.children[0];if(d instanceof j&&f.positions[0]==0)f=d;else break}}let l=r.stateSlot(e.state,4);if(l>0)return e.reduce(l),Re&&console.log(o+this.stackID(e)+` (via always-reduce ${r.getName(l&65535)})`),!0;if(e.stack.length>=8400)for(;e.stack.length>6e3&&e.forceReduce(););let a=this.tokens.getActions(e);for(let h=0;hs?t.push(p):i.push(p)}return!1}advanceFully(e,t){let i=e.pos;for(;;){if(!this.advanceStack(e,null,null))return!1;if(e.pos>i)return ch(e,t),!0}}runRecovery(e,t,i){let s=null,r=!1;for(let o=0;o ":"";if(l.deadEnd&&(r||(r=!0,l.restart(),Re&&console.log(c+this.stackID(l)+" (restarted)"),this.advanceFully(l,i))))continue;let f=l.split(),u=c;for(let d=0;d<10&&f.forceReduce()&&(Re&&console.log(u+this.stackID(f)+" (via force-reduce)"),!this.advanceFully(f,i));d++)Re&&(u=this.stackID(f)+" -> ");for(let d of l.recoverByInsert(a))Re&&console.log(c+this.stackID(d)+" (via recover-insert)"),this.advanceFully(d,i);this.stream.end>l.pos?(h==l.pos&&(h++,a=0),l.recoverByDelete(a,h),Re&&console.log(c+this.stackID(l)+` (via recover-delete ${this.parser.getName(a)})`),ch(l,i)):(!s||s.scoren;class k1{constructor(e){this.start=e.start,this.shift=e.shift||mr,this.reduce=e.reduce||mr,this.reuse=e.reuse||mr,this.hash=e.hash||(()=>0),this.strict=e.strict!==!1}}class tn extends Lo{constructor(e){if(super(),this.wrappers=[],e.version!=14)throw new RangeError(`Parser version (${e.version}) doesn't match runtime version (14)`);let t=e.nodeNames.split(" ");this.minRepeatTerm=t.length;for(let l=0;le.topRules[l][1]),s=[];for(let l=0;l=0)r(c,a,l[h++]);else{let f=l[h+-c];for(let u=-c;u>0;u--)r(l[h++],a,f);h++}}}this.nodeSet=new Qs(t.map((l,a)=>ve.define({name:a>=this.minRepeatTerm?void 0:l,id:a,props:s[a],top:i.indexOf(a)>-1,error:a==0,skipped:e.skippedNodes&&e.skippedNodes.indexOf(a)>-1}))),e.propSources&&(this.nodeSet=this.nodeSet.extend(...e.propSources)),this.strict=!1,this.bufferLength=Hc;let o=Vn(e.tokenData);this.context=e.context,this.specializerSpecs=e.specialized||[],this.specialized=new Uint16Array(this.specializerSpecs.length);for(let l=0;ltypeof l=="number"?new oi(o,l):l),this.topRules=e.topRules,this.dialects=e.dialects||{},this.dynamicPrecedences=e.dynamicPrecedences||null,this.tokenPrecTable=e.tokenPrec,this.termNames=e.termNames||null,this.maxNode=this.nodeSet.types.length-1,this.dialect=this.parseDialect(),this.top=this.topRules[Object.keys(this.topRules)[0]]}createParse(e,t,i){let s=new S1(this,e,t,i);for(let r of this.wrappers)s=r(s,e,t,i);return s}getGoto(e,t,i=!1){let s=this.goto;if(t>=s[0])return-1;for(let r=s[t+1];;){let o=s[r++],l=o&1,a=s[r++];if(l&&i)return a;for(let h=r+(o>>1);r0}validAction(e,t){return!!this.allActions(e,i=>i==t?!0:null)}allActions(e,t){let i=this.stateSlot(e,4),s=i?t(i):void 0;for(let r=this.stateSlot(e,1);s==null;r+=3){if(this.data[r]==65535)if(this.data[r+1]==1)r=ut(this.data,r+2);else break;s=t(ut(this.data,r+1))}return s}nextStates(e){let t=[];for(let i=this.stateSlot(e,1);;i+=3){if(this.data[i]==65535)if(this.data[i+1]==1)i=ut(this.data,i+2);else break;if((this.data[i+2]&1)==0){let s=this.data[i+1];t.some((r,o)=>o&1&&r==s)||t.push(this.data[i],s)}}return t}configure(e){let t=Object.assign(Object.create(tn.prototype),this);if(e.props&&(t.nodeSet=this.nodeSet.extend(...e.props)),e.top){let i=this.topRules[e.top];if(!i)throw new RangeError(`Invalid top rule name ${e.top}`);t.top=i}return e.tokenizers&&(t.tokenizers=this.tokenizers.map(i=>{let s=e.tokenizers.find(r=>r.from==i);return s?s.to:i})),e.specializers&&(t.specializers=this.specializers.slice(),t.specializerSpecs=this.specializerSpecs.map((i,s)=>{let r=e.specializers.find(l=>l.from==i.external);if(!r)return i;let o=Object.assign(Object.assign({},i),{external:r.to});return t.specializers[s]=fh(o),o})),e.contextTracker&&(t.context=e.contextTracker),e.dialect&&(t.dialect=this.parseDialect(e.dialect)),e.strict!=null&&(t.strict=e.strict),e.wrap&&(t.wrappers=t.wrappers.concat(e.wrap)),e.bufferLength!=null&&(t.bufferLength=e.bufferLength),t}hasWrappers(){return this.wrappers.length>0}getName(e){return this.termNames?this.termNames[e]:String(e<=this.maxNode&&this.nodeSet.types[e].name||e)}get eofTerm(){return this.maxNode+1}get topNode(){return this.nodeSet.types[this.top[1]]}dynamicPrecedence(e){let t=this.dynamicPrecedences;return t==null?0:t[e]||0}parseDialect(e){let t=Object.keys(this.dialects),i=t.map(()=>!1);if(e)for(let r of e.split(" ")){let o=t.indexOf(r);o>=0&&(i[o]=!0)}let s=null;for(let r=0;ri)&&t.p.parser.stateFlag(t.state,2)&&(!e||e.scoren.external(t,i)<<1|e}return n.get}const v1=1,Au=194,Mu=195,T1=196,uh=197,C1=198,P1=199,Q1=200,A1=2,Ru=3,dh=201,M1=24,R1=25,D1=49,E1=50,q1=55,$1=56,B1=57,W1=59,L1=60,z1=61,I1=62,V1=63,N1=65,X1=238,F1=71,_1=241,U1=242,H1=243,j1=244,G1=245,Z1=246,Y1=247,K1=248,Du=72,J1=249,eb=250,tb=251,ib=252,nb=253,sb=254,rb=255,ob=256,lb=73,ab=77,hb=263,cb=112,fb=130,ub=151,db=152,pb=155,jt=10,nn=13,ol=32,Ls=9,ll=35,mb=40,gb=46,bo=123,ph=125,Eu=39,qu=34,mh=92,Ob=111,yb=120,bb=78,Sb=117,xb=85,kb=new Set([R1,D1,E1,hb,N1,fb,$1,B1,X1,I1,V1,Du,lb,ab,L1,z1,ub,db,pb,cb]);function gr(n){return n==jt||n==nn}function Or(n){return n>=48&&n<=57||n>=65&&n<=70||n>=97&&n<=102}const wb=new Ws((n,e)=>{let t;if(n.next<0)n.acceptToken(P1);else if(e.context.flags&es)gr(n.next)&&n.acceptToken(C1,1);else if(((t=n.peek(-1))<0||gr(t))&&e.canShift(uh)){let i=0;for(;n.next==ol||n.next==Ls;)n.advance(),i++;(n.next==jt||n.next==nn||n.next==ll)&&n.acceptToken(uh,-i)}else gr(n.next)&&n.acceptToken(T1,1)},{contextual:!0}),vb=new Ws((n,e)=>{let t=e.context;if(t.flags)return;let i=n.peek(-1);if(i==jt||i==nn){let s=0,r=0;for(;;){if(n.next==ol)s++;else if(n.next==Ls)s+=8-s%8;else break;n.advance(),r++}s!=t.indent&&n.next!=jt&&n.next!=nn&&n.next!=ll&&(s[n,e|$u])),Pb=new k1({start:Tb,reduce(n,e,t,i){return n.flags&es&&kb.has(e)||(e==F1||e==Du)&&n.flags&$u?n.parent:n},shift(n,e,t,i){return e==Au?new ts(n,Cb(i.read(i.pos,t.pos)),0):e==Mu?n.parent:e==M1||e==q1||e==W1||e==Ru?new ts(n,0,es):gh.has(e)?new ts(n,0,gh.get(e)|n.flags&es):n},hash(n){return n.hash}}),Qb=new Ws(n=>{for(let e=0;e<5;e++){if(n.next!="print".charCodeAt(e))return;n.advance()}if(!/\w/.test(String.fromCharCode(n.next)))for(let e=0;;e++){let t=n.peek(e);if(!(t==ol||t==Ls)){t!=mb&&t!=gb&&t!=jt&&t!=nn&&t!=ll&&n.acceptToken(v1);return}}}),Ab=new Ws((n,e)=>{let{flags:t}=e.context,i=t&at?qu:Eu,s=(t&ht)>0,r=!(t&ct),o=(t&ft)>0,l=n.pos;for(;!(n.next<0);)if(o&&n.next==bo)if(n.peek(1)==bo)n.advance(2);else{if(n.pos==l){n.acceptToken(Ru,1);return}break}else if(r&&n.next==mh){if(n.pos==l){n.advance();let a=n.next;a>=0&&(n.advance(),Mb(n,a)),n.acceptToken(A1);return}break}else if(n.next==mh&&!r&&n.peek(1)>-1)n.advance(2);else if(n.next==i&&(!s||n.peek(1)==i&&n.peek(2)==i)){if(n.pos==l){n.acceptToken(dh,s?3:1);return}break}else if(n.next==jt){if(s)n.advance();else if(n.pos==l){n.acceptToken(dh);return}break}else n.advance();n.pos>l&&n.acceptToken(Q1)});function Mb(n,e){if(e==Ob)for(let t=0;t<2&&n.next>=48&&n.next<=55;t++)n.advance();else if(e==yb)for(let t=0;t<2&&Or(n.next);t++)n.advance();else if(e==Sb)for(let t=0;t<4&&Or(n.next);t++)n.advance();else if(e==xb)for(let t=0;t<8&&Or(n.next);t++)n.advance();else if(e==bb&&n.next==bo){for(n.advance();n.next>=0&&n.next!=ph&&n.next!=Eu&&n.next!=qu&&n.next!=jt;)n.advance();n.next==ph&&n.advance()}}const Rb=zo({'async "*" "**" FormatConversion FormatSpec':O.modifier,"for while if elif else try except finally return raise break continue with pass assert await yield match case":O.controlKeyword,"in not and or is del":O.operatorKeyword,"from def class global nonlocal lambda":O.definitionKeyword,import:O.moduleKeyword,"with as print":O.keyword,Boolean:O.bool,None:O.null,VariableName:O.variableName,"CallExpression/VariableName":O.function(O.variableName),"FunctionDefinition/VariableName":O.function(O.definition(O.variableName)),"ClassDefinition/VariableName":O.definition(O.className),PropertyName:O.propertyName,"CallExpression/MemberExpression/PropertyName":O.function(O.propertyName),Comment:O.lineComment,Number:O.number,String:O.string,FormatString:O.special(O.string),Escape:O.escape,UpdateOp:O.updateOperator,"ArithOp!":O.arithmeticOperator,BitOp:O.bitwiseOperator,CompareOp:O.compareOperator,AssignOp:O.definitionOperator,Ellipsis:O.punctuation,At:O.meta,"( )":O.paren,"[ ]":O.squareBracket,"{ }":O.brace,".":O.derefOperator,", ;":O.separator}),Db={__proto__:null,await:44,or:54,and:56,in:60,not:62,is:64,if:70,else:72,lambda:76,yield:94,from:96,async:102,for:104,None:162,True:164,False:164,del:178,pass:182,break:186,continue:190,return:194,raise:202,import:206,as:208,global:212,nonlocal:214,assert:218,type:223,elif:236,while:240,try:246,except:248,finally:250,with:254,def:258,class:268,match:279,case:285},Eb=tn.deserialize({version:14,states:"##jO`QeOOP$}OSOOO&WQtO'#HUOOQS'#Co'#CoOOQS'#Cp'#CpO'vQdO'#CnO*UQtO'#HTOOQS'#HU'#HUOOQS'#DU'#DUOOQS'#HT'#HTO*rQdO'#D_O+VQdO'#DfO+gQdO'#DjO+zOWO'#DuO,VOWO'#DvO.[QtO'#GuOOQS'#Gu'#GuO'vQdO'#GtO0ZQtO'#GtOOQS'#Eb'#EbO0rQdO'#EcOOQS'#Gs'#GsO0|QdO'#GrOOQV'#Gr'#GrO1XQdO'#FYOOQS'#G^'#G^O1^QdO'#FXOOQV'#IS'#ISOOQV'#Gq'#GqOOQV'#Fq'#FqQ`QeOOO'vQdO'#CqO1lQdO'#C}O1sQdO'#DRO2RQdO'#HYO2cQtO'#EVO'vQdO'#EWOOQS'#EY'#EYOOQS'#E['#E[OOQS'#E^'#E^O2wQdO'#E`O3_QdO'#EdO3rQdO'#EfO3zQtO'#EfO1XQdO'#EiO0rQdO'#ElO1XQdO'#EnO0rQdO'#EtO0rQdO'#EwO4VQdO'#EyO4^QdO'#FOO4iQdO'#EzO0rQdO'#FOO1XQdO'#FQO1XQdO'#FVO4nQdO'#F[P4uOdO'#GpPOOO)CBd)CBdOOQS'#Ce'#CeOOQS'#Cf'#CfOOQS'#Cg'#CgOOQS'#Ch'#ChOOQS'#Ci'#CiOOQS'#Cj'#CjOOQS'#Cl'#ClO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO5TQdO'#DoOOQS,5:Y,5:YO5hQdO'#HdOOQS,5:],5:]O5uQ!fO,5:]O5zQtO,59YO1lQdO,59bO1lQdO,59bO1lQdO,59bO8jQdO,59bO8oQdO,59bO8vQdO,59jO8}QdO'#HTO:TQdO'#HSOOQS'#HS'#HSOOQS'#D['#D[O:lQdO,59aO'vQdO,59aO:zQdO,59aOOQS,59y,59yO;PQdO,5:RO'vQdO,5:ROOQS,5:Q,5:QO;_QdO,5:QO;dQdO,5:XO'vQdO,5:XO'vQdO,5:VOOQS,5:U,5:UO;uQdO,5:UO;zQdO,5:WOOOW'#Fy'#FyOOOOQS'#Ds'#DsOOQS1G/w1G/wOOQS1G.|1G.|O!/[QtO1G.|O!/cQtO1G.|O1lQdO1G.|O!0OQdO1G/UOOQS'#DZ'#DZO0rQdO,59tOOQS1G.{1G.{O!0VQdO1G/eO!0gQdO1G/eO!0oQdO1G/fO'vQdO'#H[O!0tQdO'#H[O!0yQtO1G.{O!1ZQdO,59iO!2aQdO,5=zO!2qQdO,5=zO!2yQdO1G/mO!3OQtO1G/mOOQS1G/l1G/lO!3`QdO,5=uO!4VQdO,5=uO0rQdO1G/qO!4tQdO1G/sO!4yQtO1G/sO!5ZQtO1G/qOOQS1G/p1G/pOOQS1G/r1G/rOOOW-E9w-E9wOOQS1G/{1G/{O!5kQdO'#HxO0rQdO'#HxO!5|QdO,5>cOOOW-E9x-E9xOOQS1G/|1G/|OOQS-E9{-E9{O!6[Q#xO1G2zO!6{QtO1G2zO'vQdO,5kOOQS1G1`1G1`O!8RQdO1G1`OOQS'#DV'#DVO0rQdO,5=qOOQS,5=q,5=qO!8WQdO'#FrO!8cQdO,59oO!8kQdO1G/XO!8uQtO,5=uOOQS1G3`1G3`OOQS,5:m,5:mO!9fQdO'#GtOOQS,5jO!;ZQdO,5>jO1XQdO,5>jO!;lQdO,5>iOOQS-E:R-E:RO!;qQdO1G0lO!;|QdO1G0lO!lO!lO!hO!=VQdO,5>hO!=hQdO'#EpO0rQdO1G0tO!=sQdO1G0tO!=xQgO1G0zO!AvQgO1G0}O!EqQdO,5>oO!E{QdO,5>oO!FTQtO,5>oO0rQdO1G1PO!F_QdO1G1PO4iQdO1G1UO!!vQdO1G1WOOQV,5;a,5;aO!FdQfO,5;aO!FiQgO1G1QO!JjQdO'#GZO4iQdO1G1QO4iQdO1G1QO!JzQdO,5>pO!KXQdO,5>pO1XQdO,5>pOOQV1G1U1G1UO!KaQdO'#FSO!KrQ!fO1G1WO!KzQdO1G1WOOQV1G1]1G1]O4iQdO1G1]O!LPQdO1G1]O!LXQdO'#F^OOQV1G1b1G1bO!#ZQtO1G1bPOOO1G2v1G2vP!L^OSO1G2vOOQS,5=},5=}OOQS'#Dp'#DpO0rQdO,5=}O!LfQdO,5=|O!LyQdO,5=|OOQS1G/u1G/uO!MRQdO,5>PO!McQdO,5>PO!MkQdO,5>PO!NOQdO,5>PO!N`QdO,5>POOQS1G3j1G3jOOQS7+$h7+$hO!8kQdO7+$pO#!RQdO1G.|O#!YQdO1G.|OOQS1G/`1G/`OOQS,5<`,5<`O'vQdO,5<`OOQS7+%P7+%PO#!aQdO7+%POOQS-E9r-E9rOOQS7+%Q7+%QO#!qQdO,5=vO'vQdO,5=vOOQS7+$g7+$gO#!vQdO7+%PO##OQdO7+%QO##TQdO1G3fOOQS7+%X7+%XO##eQdO1G3fO##mQdO7+%XOOQS,5<_,5<_O'vQdO,5<_O##rQdO1G3aOOQS-E9q-E9qO#$iQdO7+%]OOQS7+%_7+%_O#$wQdO1G3aO#%fQdO7+%_O#%kQdO1G3gO#%{QdO1G3gO#&TQdO7+%]O#&YQdO,5>dO#&sQdO,5>dO#&sQdO,5>dOOQS'#Dx'#DxO#'UO&jO'#DzO#'aO`O'#HyOOOW1G3}1G3}O#'fQdO1G3}O#'nQdO1G3}O#'yQ#xO7+(fO#(jQtO1G2UP#)TQdO'#GOOOQS,5nQdO,5sQdO1G4OOOQS-E9y-E9yO#?^QdO1G4OO<[QdO'#H{OOOO'#D{'#D{OOOO'#F|'#F|O#?oO&jO,5:fOOOW,5>e,5>eOOOW7+)i7+)iO#?zQdO7+)iO#@SQdO1G2zO#@mQdO1G2zP'vQdO'#FuO0rQdO<mO#BQQdO,5>mOOQS1G0v1G0vOOQS<rO#KgQdO,5>rO#KrQdO,5>rO#K}QdO,5>qO#L`QdO,5>qOOQS1G1Y1G1YOOQS,5;p,5;pOOQV<VAN>VO$ oQdO<cAN>cO0rQdO1G1|O$!PQtO1G1|P$!ZQdO'#FvOOQS1G2R1G2RP$!hQdO'#F{O$!uQdO7+)jO$#`QdO,5>gOOOO-E9z-E9zOOOW<tO$4{QdO,5>tO1XQdO,5vO$)nQdO,5>vOOQS1G1p1G1pOOQS,5<[,5<[OOQU7+'P7+'PO$+zQdO1G/iO$)nQdO,5wO$8zQdO,5>wOOQS1G1s1G1sOOQS7+'S7+'SP$)nQdO'#GdO$9SQdO1G4bO$9^QdO1G4bO$9fQdO1G4bOOQS7+%T7+%TO$9tQdO1G1tO$:SQtO'#FaO$:ZQdO,5<}OOQS,5<},5<}O$:iQdO1G4cOOQS-E:a-E:aO$)nQdO,5<|O$:pQdO,5<|O$:uQdO7+)|OOQS-E:`-E:`O$;PQdO7+)|O$)nQdO,5S~O%cOS%^OSSOS%]PQ~OPdOVaOfoOhYOopOs!POvqO!PrO!Q{O!T!SO!U!RO!XZO!][O!h`O!r`O!s`O!t`O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO#l!QO#o!TO#s!UO#u!VO#z!WO#}hO$P!XO%oRO%pRO%tSO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O~O%]!YO~OV!aO_!aOa!bOh!iO!X!kO!f!mO%j![O%k!]O%l!^O%m!_O%n!_O%o!`O%p!`O%q!aO%r!aO%s!aO~Ok%xXl%xXm%xXn%xXo%xXp%xXs%xXz%xX{%xX!x%xX#g%xX%[%xX%_%xX%z%xXg%xX!T%xX!U%xX%{%xX!W%xX![%xX!Q%xX#[%xXt%xX!m%xX~P%SOfoOhYO!XZO!][O!h`O!r`O!s`O!t`O%oRO%pRO%tSO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O~Oz%wX{%wX#g%wX%[%wX%_%wX%z%wX~Ok!pOl!qOm!oOn!oOo!rOp!sOs!tO!x%wX~P)pOV!zOg!|Oo0cOv0qO!PrO~P'vOV#OOo0cOv0qO!W#PO~P'vOV#SOa#TOo0cOv0qO![#UO~P'vOQ#XO%`#XO%a#ZO~OQ#^OR#[O%`#^O%a#`O~OV%iX_%iXa%iXh%iXk%iXl%iXm%iXn%iXo%iXp%iXs%iXz%iX!X%iX!f%iX%j%iX%k%iX%l%iX%m%iX%n%iX%o%iX%p%iX%q%iX%r%iX%s%iXg%iX!T%iX!U%iX~O&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O{%iX!x%iX#g%iX%[%iX%_%iX%z%iX%{%iX!W%iX![%iX!Q%iX#[%iXt%iX!m%iX~P,eOz#dO{%hX!x%hX#g%hX%[%hX%_%hX%z%hX~Oo0cOv0qO~P'vO#g#gO%[#iO%_#iO~O%uWO~O!T#nO#u!VO#z!WO#}hO~OopO~P'vOV#sOa#tO%uWO{wP~OV#xOo0cOv0qO!Q#yO~P'vO{#{O!x$QO%z#|O#g!yX%[!yX%_!yX~OV#xOo0cOv0qO#g#SX%[#SX%_#SX~P'vOo0cOv0qO#g#WX%[#WX%_#WX~P'vOh$WO%uWO~O!f$YO!r$YO%uWO~OV$eO~P'vO!U$gO#s$hO#u$iO~O{$jO~OV$qO~P'vOS$sO%[$rO%_$rO%c$tO~OV$}Oa$}Og%POo0cOv0qO~P'vOo0cOv0qO{%SO~P'vO&Y%UO~Oa!bOh!iO!X!kO!f!mOVba_bakbalbambanbaobapbasbazba{ba!xba#gba%[ba%_ba%jba%kba%lba%mba%nba%oba%pba%qba%rba%sba%zbagba!Tba!Uba%{ba!Wba![ba!Qba#[batba!mba~On%ZO~Oo%ZO~P'vOo0cO~P'vOk0eOl0fOm0dOn0dOo0mOp0nOs0rOg%wX!T%wX!U%wX%{%wX!W%wX![%wX!Q%wX#[%wX!m%wX~P)pO%{%]Og%vXz%vX!T%vX!U%vX!W%vX{%vX~Og%_Oz%`O!T%dO!U%cO~Og%_O~Oz%gO!T%dO!U%cO!W&SX~O!W%kO~Oz%lO{%nO!T%dO!U%cO![%}X~O![%rO~O![%sO~OQ#XO%`#XO%a%uO~OV%wOo0cOv0qO!PrO~P'vOQ#^OR#[O%`#^O%a%zO~OV!qa_!qaa!qah!qak!qal!qam!qan!qao!qap!qas!qaz!qa{!qa!X!qa!f!qa!x!qa#g!qa%[!qa%_!qa%j!qa%k!qa%l!qa%m!qa%n!qa%o!qa%p!qa%q!qa%r!qa%s!qa%z!qag!qa!T!qa!U!qa%{!qa!W!qa![!qa!Q!qa#[!qat!qa!m!qa~P#yOz%|O{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~P%SOV&OOopOvqO{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~P'vOz%|O{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~OPdOVaOopOvqO!PrO!Q{O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO#g$zX%[$zX%_$zX~P'vO#g#gO%[&TO%_&TO~O!f&UOh&sX%[&sXz&sX#[&sX#g&sX%_&sX#Z&sXg&sX~Oh!iO%[&WO~Okealeameaneaoeapeaseazea{ea!xea#gea%[ea%_ea%zeagea!Tea!Uea%{ea!Wea![ea!Qea#[eatea!mea~P%SOsqazqa{qa#gqa%[qa%_qa%zqa~Ok!pOl!qOm!oOn!oOo!rOp!sO!xqa~PEcO%z&YOz%yX{%yX~O%uWOz%yX{%yX~Oz&]O{wX~O{&_O~Oz%lO#g%}X%[%}X%_%}Xg%}X{%}X![%}X!m%}X%z%}X~OV0lOo0cOv0qO!PrO~P'vO%z#|O#gUa%[Ua%_Ua~Oz&hO#g&PX%[&PX%_&PXn&PX~P%SOz&kO!Q&jO#g#Wa%[#Wa%_#Wa~Oz&lO#[&nO#g&rX%[&rX%_&rXg&rX~O!f$YO!r$YO#Z&qO%uWO~O#Z&qO~Oz&sO#g&tX%[&tX%_&tX~Oz&uO#g&pX%[&pX%_&pX{&pX~O!X&wO%z&xO~Oz&|On&wX~P%SOn'PO~OPdOVaOopOvqO!PrO!Q{O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO%['UO~P'vOt'YO#p'WO#q'XOP#naV#naf#nah#nao#nas#nav#na!P#na!Q#na!T#na!U#na!X#na!]#na!h#na!r#na!s#na!t#na!{#na!}#na#P#na#R#na#T#na#X#na#Z#na#^#na#_#na#a#na#c#na#l#na#o#na#s#na#u#na#z#na#}#na$P#na%X#na%o#na%p#na%t#na%u#na&Z#na&[#na&]#na&^#na&_#na&`#na&a#na&b#na&c#na&d#na&e#na&f#na&g#na&h#na&i#na&j#na%Z#na%_#na~Oz'ZO#[']O{&xX~Oh'_O!X&wO~Oh!iO{$jO!X&wO~O{'eO~P%SO%['hO%_'hO~OS'iO%['hO%_'hO~OV!aO_!aOa!bOh!iO!X!kO!f!mO%l!^O%m!_O%n!_O%o!`O%p!`O%q!aO%r!aO%s!aOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~O%k!]O~P!#uO%kWi~P!#uOV!aO_!aOa!bOh!iO!X!kO!f!mO%o!`O%p!`O%q!aO%r!aO%s!aOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%kWi%lWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~O%m!_O%n!_O~P!&pO%mWi%nWi~P!&pOa!bOh!iO!X!kO!f!mOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%kWi%lWi%mWi%nWi%oWi%pWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~OV!aO_!aO%q!aO%r!aO%s!aO~P!)nOVWi_Wi%qWi%rWi%sWi~P!)nO!T%dO!U%cOg&VXz&VX~O%z'kO%{'kO~P,eOz'mOg&UX~Og'oO~Oz'pO{'rO!W&XX~Oo0cOv0qOz'pO{'sO!W&XX~P'vO!W'uO~Om!oOn!oOo!rOp!sOkjisjizji{ji!xji#gji%[ji%_ji%zji~Ol!qO~P!.aOlji~P!.aOk0eOl0fOm0dOn0dOo0mOp0nO~Ot'wO~P!/jOV'|Og'}Oo0cOv0qO~P'vOg'}Oz(OO~Og(QO~O!U(SO~Og(TOz(OO!T%dO!U%cO~P%SOk0eOl0fOm0dOn0dOo0mOp0nOgqa!Tqa!Uqa%{qa!Wqa![qa!Qqa#[qatqa!mqa~PEcOV'|Oo0cOv0qO!W&Sa~P'vOz(WO!W&Sa~O!W(XO~Oz(WO!T%dO!U%cO!W&Sa~P%SOV(]Oo0cOv0qO![%}a#g%}a%[%}a%_%}ag%}a{%}a!m%}a%z%}a~P'vOz(^O![%}a#g%}a%[%}a%_%}ag%}a{%}a!m%}a%z%}a~O![(aO~Oz(^O!T%dO!U%cO![%}a~P%SOz(dO!T%dO!U%cO![&Ta~P%SOz(gO{&lX![&lX!m&lX%z&lX~O{(kO![(mO!m(nO%z(jO~OV&OOopOvqO{%hi!x%hi#g%hi%[%hi%_%hi%z%hi~P'vOz(pO{%hi!x%hi#g%hi%[%hi%_%hi%z%hi~O!f&UOh&sa%[&saz&sa#[&sa#g&sa%_&sa#Z&sag&sa~O%[(uO~OV#sOa#tO%uWO~Oz&]O{wa~OopOvqO~P'vOz(^O#g%}a%[%}a%_%}ag%}a{%}a![%}a!m%}a%z%}a~P%SOz(zO#g%hX%[%hX%_%hX%z%hX~O%z#|O#gUi%[Ui%_Ui~O#g&Pa%[&Pa%_&Pan&Pa~P'vOz(}O#g&Pa%[&Pa%_&Pan&Pa~O%uWO#g&ra%[&ra%_&rag&ra~Oz)SO#g&ra%[&ra%_&rag&ra~Og)VO~OV)WOh$WO%uWO~O#Z)XO~O%uWO#g&ta%[&ta%_&ta~Oz)ZO#g&ta%[&ta%_&ta~Oo0cOv0qO#g&pa%[&pa%_&pa{&pa~P'vOz)^O#g&pa%[&pa%_&pa{&pa~OV)`Oa)`O%uWO~O%z)eO~Ot)hO#j)gOP#hiV#hif#hih#hio#his#hiv#hi!P#hi!Q#hi!T#hi!U#hi!X#hi!]#hi!h#hi!r#hi!s#hi!t#hi!{#hi!}#hi#P#hi#R#hi#T#hi#X#hi#Z#hi#^#hi#_#hi#a#hi#c#hi#l#hi#o#hi#s#hi#u#hi#z#hi#}#hi$P#hi%X#hi%o#hi%p#hi%t#hi%u#hi&Z#hi&[#hi&]#hi&^#hi&_#hi&`#hi&a#hi&b#hi&c#hi&d#hi&e#hi&f#hi&g#hi&h#hi&i#hi&j#hi%Z#hi%_#hi~Ot)iOP#kiV#kif#kih#kio#kis#kiv#ki!P#ki!Q#ki!T#ki!U#ki!X#ki!]#ki!h#ki!r#ki!s#ki!t#ki!{#ki!}#ki#P#ki#R#ki#T#ki#X#ki#Z#ki#^#ki#_#ki#a#ki#c#ki#l#ki#o#ki#s#ki#u#ki#z#ki#}#ki$P#ki%X#ki%o#ki%p#ki%t#ki%u#ki&Z#ki&[#ki&]#ki&^#ki&_#ki&`#ki&a#ki&b#ki&c#ki&d#ki&e#ki&f#ki&g#ki&h#ki&i#ki&j#ki%Z#ki%_#ki~OV)kOn&wa~P'vOz)lOn&wa~Oz)lOn&wa~P%SOn)pO~O%Y)tO~Ot)wO#p'WO#q)vOP#niV#nif#nih#nio#nis#niv#ni!P#ni!Q#ni!T#ni!U#ni!X#ni!]#ni!h#ni!r#ni!s#ni!t#ni!{#ni!}#ni#P#ni#R#ni#T#ni#X#ni#Z#ni#^#ni#_#ni#a#ni#c#ni#l#ni#o#ni#s#ni#u#ni#z#ni#}#ni$P#ni%X#ni%o#ni%p#ni%t#ni%u#ni&Z#ni&[#ni&]#ni&^#ni&_#ni&`#ni&a#ni&b#ni&c#ni&d#ni&e#ni&f#ni&g#ni&h#ni&i#ni&j#ni%Z#ni%_#ni~OV)zOo0cOv0qO{$jO~P'vOo0cOv0qO{&xa~P'vOz*OO{&xa~OV*SOa*TOg*WO%q*UO%uWO~O{$jO&{*YO~Oh'_O~Oh!iO{$jO~O%[*_O~O%[*aO%_*aO~OV$}Oa$}Oo0cOv0qOg&Ua~P'vOz*dOg&Ua~Oo0cOv0qO{*gO!W&Xa~P'vOz*hO!W&Xa~Oo0cOv0qOz*hO{*kO!W&Xa~P'vOo0cOv0qOz*hO!W&Xa~P'vOz*hO{*kO!W&Xa~Om0dOn0dOo0mOp0nOgjikjisjizji!Tji!Uji%{ji!Wji{ji![ji#gji%[ji%_ji!Qji#[jitji!mji%zji~Ol0fO~P!NkOlji~P!NkOV'|Og*pOo0cOv0qO~P'vOn*rO~Og*pOz*tO~Og*uO~OV'|Oo0cOv0qO!W&Si~P'vOz*vO!W&Si~O!W*wO~OV(]Oo0cOv0qO![%}i#g%}i%[%}i%_%}ig%}i{%}i!m%}i%z%}i~P'vOz*zO!T%dO!U%cO![&Ti~Oz*}O![%}i#g%}i%[%}i%_%}ig%}i{%}i!m%}i%z%}i~O![+OO~Oa+QOo0cOv0qO![&Ti~P'vOz*zO![&Ti~O![+SO~OV+UOo0cOv0qO{&la![&la!m&la%z&la~P'vOz+VO{&la![&la!m&la%z&la~O!]+YO&n+[O![!nX~O![+^O~O{(kO![+_O~O{(kO![+_O!m+`O~OV&OOopOvqO{%hq!x%hq#g%hq%[%hq%_%hq%z%hq~P'vOz$ri{$ri!x$ri#g$ri%[$ri%_$ri%z$ri~P%SOV&OOopOvqO~P'vOV&OOo0cOv0qO#g%ha%[%ha%_%ha%z%ha~P'vOz+aO#g%ha%[%ha%_%ha%z%ha~Oz$ia#g$ia%[$ia%_$ian$ia~P%SO#g&Pi%[&Pi%_&Pin&Pi~P'vOz+dO#g#Wq%[#Wq%_#Wq~O#[+eOz$va#g$va%[$va%_$vag$va~O%uWO#g&ri%[&ri%_&rig&ri~Oz+gO#g&ri%[&ri%_&rig&ri~OV+iOh$WO%uWO~O%uWO#g&ti%[&ti%_&ti~Oo0cOv0qO#g&pi%[&pi%_&pi{&pi~P'vO{#{Oz#eX!W#eX~Oz+mO!W&uX~O!W+oO~Ot+rO#j)gOP#hqV#hqf#hqh#hqo#hqs#hqv#hq!P#hq!Q#hq!T#hq!U#hq!X#hq!]#hq!h#hq!r#hq!s#hq!t#hq!{#hq!}#hq#P#hq#R#hq#T#hq#X#hq#Z#hq#^#hq#_#hq#a#hq#c#hq#l#hq#o#hq#s#hq#u#hq#z#hq#}#hq$P#hq%X#hq%o#hq%p#hq%t#hq%u#hq&Z#hq&[#hq&]#hq&^#hq&_#hq&`#hq&a#hq&b#hq&c#hq&d#hq&e#hq&f#hq&g#hq&h#hq&i#hq&j#hq%Z#hq%_#hq~On$|az$|a~P%SOV)kOn&wi~P'vOz+yOn&wi~Oz,TO{$jO#[,TO~O#q,VOP#nqV#nqf#nqh#nqo#nqs#nqv#nq!P#nq!Q#nq!T#nq!U#nq!X#nq!]#nq!h#nq!r#nq!s#nq!t#nq!{#nq!}#nq#P#nq#R#nq#T#nq#X#nq#Z#nq#^#nq#_#nq#a#nq#c#nq#l#nq#o#nq#s#nq#u#nq#z#nq#}#nq$P#nq%X#nq%o#nq%p#nq%t#nq%u#nq&Z#nq&[#nq&]#nq&^#nq&_#nq&`#nq&a#nq&b#nq&c#nq&d#nq&e#nq&f#nq&g#nq&h#nq&i#nq&j#nq%Z#nq%_#nq~O#[,WOz%Oa{%Oa~Oo0cOv0qO{&xi~P'vOz,YO{&xi~O{#{O%z,[Og&zXz&zX~O%uWOg&zXz&zX~Oz,`Og&yX~Og,bO~O%Y,eO~O!T%dO!U%cOg&Viz&Vi~OV$}Oa$}Oo0cOv0qOg&Ui~P'vO{,hOz$la!W$la~Oo0cOv0qO{,iOz$la!W$la~P'vOo0cOv0qO{*gO!W&Xi~P'vOz,lO!W&Xi~Oo0cOv0qOz,lO!W&Xi~P'vOz,lO{,oO!W&Xi~Og$hiz$hi!W$hi~P%SOV'|Oo0cOv0qO~P'vOn,qO~OV'|Og,rOo0cOv0qO~P'vOV'|Oo0cOv0qO!W&Sq~P'vOz$gi![$gi#g$gi%[$gi%_$gig$gi{$gi!m$gi%z$gi~P%SOV(]Oo0cOv0qO~P'vOa+QOo0cOv0qO![&Tq~P'vOz,sO![&Tq~O![,tO~OV(]Oo0cOv0qO![%}q#g%}q%[%}q%_%}qg%}q{%}q!m%}q%z%}q~P'vO{,uO~OV+UOo0cOv0qO{&li![&li!m&li%z&li~P'vOz,zO{&li![&li!m&li%z&li~O!]+YO&n+[O![!na~O{(kO![,}O~OV&OOo0cOv0qO#g%hi%[%hi%_%hi%z%hi~P'vOz-OO#g%hi%[%hi%_%hi%z%hi~O%uWO#g&rq%[&rq%_&rqg&rq~Oz-RO#g&rq%[&rq%_&rqg&rq~OV)`Oa)`O%uWO!W&ua~Oz-TO!W&ua~On$|iz$|i~P%SOV)kO~P'vOV)kOn&wq~P'vOt-XOP#myV#myf#myh#myo#mys#myv#my!P#my!Q#my!T#my!U#my!X#my!]#my!h#my!r#my!s#my!t#my!{#my!}#my#P#my#R#my#T#my#X#my#Z#my#^#my#_#my#a#my#c#my#l#my#o#my#s#my#u#my#z#my#}#my$P#my%X#my%o#my%p#my%t#my%u#my&Z#my&[#my&]#my&^#my&_#my&`#my&a#my&b#my&c#my&d#my&e#my&f#my&g#my&h#my&i#my&j#my%Z#my%_#my~O%Z-]O%_-]O~P`O#q-^OP#nyV#nyf#nyh#nyo#nys#nyv#ny!P#ny!Q#ny!T#ny!U#ny!X#ny!]#ny!h#ny!r#ny!s#ny!t#ny!{#ny!}#ny#P#ny#R#ny#T#ny#X#ny#Z#ny#^#ny#_#ny#a#ny#c#ny#l#ny#o#ny#s#ny#u#ny#z#ny#}#ny$P#ny%X#ny%o#ny%p#ny%t#ny%u#ny&Z#ny&[#ny&]#ny&^#ny&_#ny&`#ny&a#ny&b#ny&c#ny&d#ny&e#ny&f#ny&g#ny&h#ny&i#ny&j#ny%Z#ny%_#ny~Oz-aO{$jO#[-aO~Oo0cOv0qO{&xq~P'vOz-dO{&xq~O%z,[Og&zaz&za~O{#{Og&zaz&za~OV*SOa*TO%q*UO%uWOg&ya~Oz-hOg&ya~O$S-lO~OV$}Oa$}Oo0cOv0qO~P'vOo0cOv0qO{-mOz$li!W$li~P'vOo0cOv0qOz$li!W$li~P'vO{-mOz$li!W$li~Oo0cOv0qO{*gO~P'vOo0cOv0qO{*gO!W&Xq~P'vOz-pO!W&Xq~Oo0cOv0qOz-pO!W&Xq~P'vOs-sO!T%dO!U%cOg&Oq!W&Oq![&Oqz&Oq~P!/jOa+QOo0cOv0qO![&Ty~P'vOz$ji![$ji~P%SOa+QOo0cOv0qO~P'vOV+UOo0cOv0qO~P'vOV+UOo0cOv0qO{&lq![&lq!m&lq%z&lq~P'vO{(kO![-xO!m-yO%z-wO~OV&OOo0cOv0qO#g%hq%[%hq%_%hq%z%hq~P'vO%uWO#g&ry%[&ry%_&ryg&ry~OV)`Oa)`O%uWO!W&ui~Ot-}OP#m!RV#m!Rf#m!Rh#m!Ro#m!Rs#m!Rv#m!R!P#m!R!Q#m!R!T#m!R!U#m!R!X#m!R!]#m!R!h#m!R!r#m!R!s#m!R!t#m!R!{#m!R!}#m!R#P#m!R#R#m!R#T#m!R#X#m!R#Z#m!R#^#m!R#_#m!R#a#m!R#c#m!R#l#m!R#o#m!R#s#m!R#u#m!R#z#m!R#}#m!R$P#m!R%X#m!R%o#m!R%p#m!R%t#m!R%u#m!R&Z#m!R&[#m!R&]#m!R&^#m!R&_#m!R&`#m!R&a#m!R&b#m!R&c#m!R&d#m!R&e#m!R&f#m!R&g#m!R&h#m!R&i#m!R&j#m!R%Z#m!R%_#m!R~Oo0cOv0qO{&xy~P'vOV*SOa*TO%q*UO%uWOg&yi~O$S-lO%Z.VO%_.VO~OV.aOh._O!X.^O!].`O!h.YO!s.[O!t.[O%p.XO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O~Oo0cOv0qOz$lq!W$lq~P'vO{.fOz$lq!W$lq~Oo0cOv0qO{*gO!W&Xy~P'vOz.gO!W&Xy~Oo0cOv.kO~P'vOs-sO!T%dO!U%cOg&Oy!W&Oy![&Oyz&Oy~P!/jO{(kO![.nO~O{(kO![.nO!m.oO~OV*SOa*TO%q*UO%uWO~Oh.tO!f.rOz$TX#[$TX%j$TXg$TX~Os$TX{$TX!W$TX![$TX~P$-bO%o.vO%p.vOs$UXz$UX{$UX#[$UX%j$UX!W$UXg$UX![$UX~O!h.xO~Oz.|O#[/OO%j.yOs&|X{&|X!W&|Xg&|X~Oa/RO~P$)zOh.tOs&}Xz&}X{&}X#[&}X%j&}X!W&}Xg&}X![&}X~Os/VO{$jO~Oo0cOv0qOz$ly!W$ly~P'vOo0cOv0qO{*gO!W&X!R~P'vOz/ZO!W&X!R~Og&RXs&RX!T&RX!U&RX!W&RX![&RXz&RX~P!/jOs-sO!T%dO!U%cOg&Qa!W&Qa![&Qaz&Qa~O{(kO![/^O~O!f.rOh$[as$[az$[a{$[a#[$[a%j$[a!W$[ag$[a![$[a~O!h/eO~O%o.vO%p.vOs$Uaz$Ua{$Ua#[$Ua%j$Ua!W$Uag$Ua![$Ua~O%j.yOs$Yaz$Ya{$Ya#[$Ya!W$Yag$Ya![$Ya~Os&|a{&|a!W&|ag&|a~P$)nOz/jOs&|a{&|a!W&|ag&|a~O!W/mO~Og/mO~O{/oO~O![/pO~Oo0cOv0qO{*gO!W&X!Z~P'vO{/sO~O%z/tO~P$-bOz/uO#[/OO%j.yOg'PX~Oz/uOg'PX~Og/wO~O!h/xO~O#[/OOs%Saz%Sa{%Sa%j%Sa!W%Sag%Sa![%Sa~O#[/OO%j.yOs%Waz%Wa{%Wa!W%Wag%Wa~Os&|i{&|i!W&|ig&|i~P$)nOz/zO#[/OO%j.yO!['Oa~Og'Pa~P$)nOz0SOg'Pa~Oa0UO!['Oi~P$)zOz0WO!['Oi~Oz0WO#[/OO%j.yO!['Oi~O#[/OO%j.yOg$biz$bi~O%z0ZO~P$-bO#[/OO%j.yOg%Vaz%Va~Og'Pi~P$)nO{0^O~Oa0UO!['Oq~P$)zOz0`O!['Oq~O#[/OO%j.yOz%Ui![%Ui~Oa0UO~P$)zOa0UO!['Oy~P$)zO#[/OO%j.yOg$ciz$ci~O#[/OO%j.yOz%Uq![%Uq~Oz+aO#g%ha%[%ha%_%ha%z%ha~P%SOV&OOo0cOv0qO~P'vOn0hO~Oo0hO~P'vO{0iO~Ot0jO~P!/jO&]&Z&j&h&i&g&f&d&e&c&b&`&a&_&^&[%u~",goto:"!=j'QPPPPPP'RP'Z*s+[+t,_,y-fP.SP'Z.r.r'ZPPP'Z2[PPPPPP2[5PPP5PP7b7k=sPP=v>h>kPP'Z'ZPP>zPP'Z'ZPP'Z'Z'Z'Z'Z?O?w'ZP?zP@QDXGuGyPG|HWH['ZPPPH_Hk'RP'R'RP'RP'RP'RP'RP'R'R'RP'RPP'RPP'RP'RPHqH}IVPI^IdPI^PI^I^PPPI^PKrPK{LVL]KrPI^LfPI^PLmLsPLwM]MzNeLwLwNkNxLwLwLwLw! ^! d! g! l! o! y!!P!!]!!o!!u!#P!#V!#s!#y!$P!$Z!$a!$g!$y!%T!%Z!%a!%k!%q!%w!%}!&T!&Z!&e!&k!&u!&{!'U!'[!'k!'s!'}!(UPPPPPPPPPPP!([!(_!(e!(n!(x!)TPPPPPPPPPPPP!-u!/Z!3^!6oPP!6w!7W!7a!8Y!8P!8c!8i!8l!8o!8r!8z!9jPPPPPPPPPPPPPPPPP!9m!9q!9wP!:]!:a!:m!:v!;S!;j!;m!;p!;v!;|!_![!]Do!]!^Es!^!_FZ!_!`Gk!`!aHX!a!b%T!b!cIf!c!dJU!d!eK^!e!hJU!h!i!#f!i!tJU!t!u!,|!u!wJU!w!x!.t!x!}JU!}#O!0S#O#P&o#P#Q!0j#Q#R!1Q#R#SJU#S#T%T#T#UJU#U#VK^#V#YJU#Y#Z!#f#Z#fJU#f#g!,|#g#iJU#i#j!.t#j#oJU#o#p!1n#p#q!1s#q#r!2a#r#s!2f#s$g%T$g;'SJU;'S;=`KW<%lOJU`%YT&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T`%lP;=`<%l%To%v]&n`%c_OX%TXY%oY[%T[]%o]p%Tpq%oq#O%T#O#P&o#P#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To&tX&n`OY%TYZ%oZ]%T]^%o^#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc'f[&n`O!_%T!_!`([!`#T%T#T#U(r#U#f%T#f#g(r#g#h(r#h#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc(cTmR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc(yT!mR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk)aV&n`&[ZOr%Trs)vs#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk){V&n`Or%Trs*bs#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk*iT&n`&^ZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To+PZS_&n`OY*xYZ%TZ]*x]^%T^#o*x#o#p+r#p#q*x#q#r+r#r;'S*x;'S;=`,^<%lO*x_+wTS_OY+rZ]+r^;'S+r;'S;=`,W<%lO+r_,ZP;=`<%l+ro,aP;=`<%l*xj,kV%rQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj-XT!xY&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj-oV%lQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk.]V&n`&ZZOw%Twx.rx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk.wV&n`Ow%Twx/^x#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk/eT&n`&]ZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk/{ThZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc0cTgR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk0yXVZ&n`Oz%Tz{1f{!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk1mVaR&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk2ZV%oZ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc2wTzR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To3_W%pZ&n`O!_%T!_!`-Q!`!a3w!a#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Td4OT&{S&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk4fX!fQ&n`O!O%T!O!P5R!P!Q%T!Q![6T![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk5WV&n`O!O%T!O!P5m!P#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk5tT!rZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti6[a!hX&n`O!Q%T!Q![6T![!g%T!g!h7a!h!l%T!l!m9s!m#R%T#R#S6T#S#X%T#X#Y7a#Y#^%T#^#_9s#_#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti7fZ&n`O{%T{|8X|}%T}!O8X!O!Q%T!Q![8s![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti8^V&n`O!Q%T!Q![8s![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti8z]!hX&n`O!Q%T!Q![8s![!l%T!l!m9s!m#R%T#R#S8s#S#^%T#^#_9s#_#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti9zT!hX&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk:bX%qR&n`O!P%T!P!Q:}!Q!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj;UV%sQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti;ro!hX&n`O!O%T!O!P=s!P!Q%T!Q![>_![!d%T!d!e?q!e!g%T!g!h7a!h!l%T!l!m9s!m!q%T!q!rA]!r!z%T!z!{Bq!{#R%T#R#S>_#S#U%T#U#V?q#V#X%T#X#Y7a#Y#^%T#^#_9s#_#c%T#c#dA]#d#l%T#l#mBq#m#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti=xV&n`O!Q%T!Q![6T![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti>fc!hX&n`O!O%T!O!P=s!P!Q%T!Q![>_![!g%T!g!h7a!h!l%T!l!m9s!m#R%T#R#S>_#S#X%T#X#Y7a#Y#^%T#^#_9s#_#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti?vY&n`O!Q%T!Q!R@f!R!S@f!S#R%T#R#S@f#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti@mY!hX&n`O!Q%T!Q!R@f!R!S@f!S#R%T#R#S@f#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiAbX&n`O!Q%T!Q!YA}!Y#R%T#R#SA}#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiBUX!hX&n`O!Q%T!Q!YA}!Y#R%T#R#SA}#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiBv]&n`O!Q%T!Q![Co![!c%T!c!iCo!i#R%T#R#SCo#S#T%T#T#ZCo#Z#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiCv]!hX&n`O!Q%T!Q![Co![!c%T!c!iCo!i#R%T#R#SCo#S#T%T#T#ZCo#Z#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%ToDvV{_&n`O!_%T!_!`E]!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TcEdT%{R&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkEzT#gZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkFbXmR&n`O!^%T!^!_F}!_!`([!`!a([!a#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TjGUV%mQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkGrV%zZ&n`O!_%T!_!`([!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkH`WmR&n`O!_%T!_!`([!`!aHx!a#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TjIPV%nQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkIoV_Q#}P&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%ToJ_]&n`&YS%uZO!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUoKZP;=`<%lJUoKge&n`&YS%uZOr%Trs)Ysw%Twx.Ux!Q%T!Q![JU![!c%T!c!tJU!t!uLx!u!}JU!}#R%T#R#SJU#S#T%T#T#fJU#f#gLx#g#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUoMRa&n`&YS%uZOr%TrsNWsw%Twx! vx!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUkN_V&n`&`ZOr%TrsNts#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkNyV&n`Or%Trs! `s#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk! gT&n`&bZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk! }V&n`&_ZOw%Twx!!dx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!!iV&n`Ow%Twx!#Ox#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!#VT&n`&aZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To!#oe&n`&YS%uZOr%Trs!%Qsw%Twx!&px!Q%T!Q![JU![!c%T!c!tJU!t!u!(`!u!}JU!}#R%T#R#SJU#S#T%T#T#fJU#f#g!(`#g#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUk!%XV&n`&dZOr%Trs!%ns#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!%sV&n`Or%Trs!&Ys#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!&aT&n`&fZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!&wV&n`&cZOw%Twx!'^x#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!'cV&n`Ow%Twx!'xx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!(PT&n`&eZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To!(ia&n`&YS%uZOr%Trs!)nsw%Twx!+^x!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUk!)uV&n`&hZOr%Trs!*[s#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!*aV&n`Or%Trs!*vs#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!*}T&n`&jZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!+eV&n`&gZOw%Twx!+zx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!,PV&n`Ow%Twx!,fx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!,mT&n`&iZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To!-Vi&n`&YS%uZOr%TrsNWsw%Twx! vx!Q%T!Q![JU![!c%T!c!dJU!d!eLx!e!hJU!h!i!(`!i!}JU!}#R%T#R#SJU#S#T%T#T#UJU#U#VLx#V#YJU#Y#Z!(`#Z#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUo!.}a&n`&YS%uZOr%Trs)Ysw%Twx.Ux!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUk!0ZT!XZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc!0qT!WR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj!1XV%kQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T~!1sO!]~k!1zV%jR&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T~!2fO![~i!2mT%tX&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T",tokenizers:[Qb,vb,wb,Ab,0,1,2,3,4],topRules:{Script:[0,5]},specialized:[{term:221,get:n=>Db[n]||-1}],tokenPrec:7668}),Oh=new jm,Bu=new Set(["Script","Body","FunctionDefinition","ClassDefinition","LambdaExpression","ForStatement","MatchClause"]);function Nn(n){return(e,t,i)=>{if(i)return!1;let s=e.node.getChild("VariableName");return s&&t(s,n),!0}}const qb={FunctionDefinition:Nn("function"),ClassDefinition:Nn("class"),ForStatement(n,e,t){if(t){for(let i=n.node.firstChild;i;i=i.nextSibling)if(i.name=="VariableName")e(i,"variable");else if(i.name=="in")break}},ImportStatement(n,e){var t,i;let{node:s}=n,r=((t=s.firstChild)===null||t===void 0?void 0:t.name)=="from";for(let o=s.getChild("import");o;o=o.nextSibling)o.name=="VariableName"&&((i=o.nextSibling)===null||i===void 0?void 0:i.name)!="as"&&e(o,r?"variable":"namespace")},AssignStatement(n,e){for(let t=n.node.firstChild;t;t=t.nextSibling)if(t.name=="VariableName")e(t,"variable");else if(t.name==":"||t.name=="AssignOp")break},ParamList(n,e){for(let t=null,i=n.node.firstChild;i;i=i.nextSibling)i.name=="VariableName"&&(!t||!/\*|AssignOp/.test(t.name))&&e(i,"variable"),t=i},CapturePattern:Nn("variable"),AsPattern:Nn("variable"),__proto__:null};function Wu(n,e){let t=Oh.get(e);if(t)return t;let i=[],s=!0;function r(o,l){let a=n.sliceString(o.from,o.to);i.push({label:a,type:l})}return e.cursor(re.IncludeAnonymous).iterate(o=>{if(o.name){let l=qb[o.name];if(l&&l(o,r,s)||!s&&Bu.has(o.name))return!1;s=!1}else if(o.to-o.from>8192){for(let l of Wu(n,o.node))i.push(l);return!1}}),Oh.set(e,i),i}const yh=/^[\w\xa1-\uffff][\w\d\xa1-\uffff]*$/,Lu=["String","FormatString","Comment","PropertyName"];function $b(n){let e=ae(n.state).resolveInner(n.pos,-1);if(Lu.indexOf(e.name)>-1)return null;let t=e.name=="VariableName"||e.to-e.from<20&&yh.test(n.state.sliceDoc(e.from,e.to));if(!t&&!n.explicit)return null;let i=[];for(let s=e;s;s=s.parent)Bu.has(s.name)&&(i=i.concat(Wu(n.state.doc,s)));return{options:i,from:t?e.from:n.pos,validFor:yh}}const Bb=["__annotations__","__builtins__","__debug__","__doc__","__import__","__name__","__loader__","__package__","__spec__","False","None","True"].map(n=>({label:n,type:"constant"})).concat(["ArithmeticError","AssertionError","AttributeError","BaseException","BlockingIOError","BrokenPipeError","BufferError","BytesWarning","ChildProcessError","ConnectionAbortedError","ConnectionError","ConnectionRefusedError","ConnectionResetError","DeprecationWarning","EOFError","Ellipsis","EncodingWarning","EnvironmentError","Exception","FileExistsError","FileNotFoundError","FloatingPointError","FutureWarning","GeneratorExit","IOError","ImportError","ImportWarning","IndentationError","IndexError","InterruptedError","IsADirectoryError","KeyError","KeyboardInterrupt","LookupError","MemoryError","ModuleNotFoundError","NameError","NotADirectoryError","NotImplemented","NotImplementedError","OSError","OverflowError","PendingDeprecationWarning","PermissionError","ProcessLookupError","RecursionError","ReferenceError","ResourceWarning","RuntimeError","RuntimeWarning","StopAsyncIteration","StopIteration","SyntaxError","SyntaxWarning","SystemError","SystemExit","TabError","TimeoutError","TypeError","UnboundLocalError","UnicodeDecodeError","UnicodeEncodeError","UnicodeError","UnicodeTranslateError","UnicodeWarning","UserWarning","ValueError","Warning","ZeroDivisionError"].map(n=>({label:n,type:"type"}))).concat(["bool","bytearray","bytes","classmethod","complex","float","frozenset","int","list","map","memoryview","object","range","set","staticmethod","str","super","tuple","type"].map(n=>({label:n,type:"class"}))).concat(["abs","aiter","all","anext","any","ascii","bin","breakpoint","callable","chr","compile","delattr","dict","dir","divmod","enumerate","eval","exec","exit","filter","format","getattr","globals","hasattr","hash","help","hex","id","input","isinstance","issubclass","iter","len","license","locals","max","min","next","oct","open","ord","pow","print","property","quit","repr","reversed","round","setattr","slice","sorted","sum","vars","zip"].map(n=>({label:n,type:"function"}))),Wb=[lt("def ${name}(${params}):\n ${}",{label:"def",detail:"function",type:"keyword"}),lt("for ${name} in ${collection}:\n ${}",{label:"for",detail:"loop",type:"keyword"}),lt("while ${}:\n ${}",{label:"while",detail:"loop",type:"keyword"}),lt("try:\n ${}\nexcept ${error}:\n ${}",{label:"try",detail:"/ except block",type:"keyword"}),lt(`if \${}: + +`,{label:"if",detail:"block",type:"keyword"}),lt("if ${}:\n ${}\nelse:\n ${}",{label:"if",detail:"/ else block",type:"keyword"}),lt("class ${name}:\n def __init__(self, ${params}):\n ${}",{label:"class",detail:"definition",type:"keyword"}),lt("import ${module}",{label:"import",detail:"statement",type:"keyword"}),lt("from ${module} import ${names}",{label:"from",detail:"import",type:"keyword"})],Lb=L0(Lu,pu(Bb.concat(Wb)));function yr(n){let{node:e,pos:t}=n,i=n.lineIndent(t,-1),s=null;for(;;){let r=e.childBefore(t);if(r)if(r.name=="Comment")t=r.from;else if(r.name=="Body"||r.name=="MatchBody")n.baseIndentFor(r)+n.unit<=i&&(s=r),e=r;else if(r.name=="MatchClause")e=r;else if(r.type.is("Statement"))e=r;else break;else break}return s}function br(n,e){let t=n.baseIndentFor(e),i=n.lineAt(n.pos,-1),s=i.from+i.text.length;return/^\s*($|#)/.test(i.text)&&n.node.tot?null:t+n.unit}const Sr=Ui.define({name:"python",parser:Eb.configure({props:[Ms.add({Body:n=>{var e;let t=/^\s*(#|$)/.test(n.textAfter)&&yr(n)||n.node;return(e=br(n,t))!==null&&e!==void 0?e:n.continue()},MatchBody:n=>{var e;let t=yr(n);return(e=br(n,t||n.node))!==null&&e!==void 0?e:n.continue()},IfStatement:n=>/^\s*(else:|elif )/.test(n.textAfter)?n.baseIndent:n.continue(),"ForStatement WhileStatement":n=>/^\s*else:/.test(n.textAfter)?n.baseIndent:n.continue(),TryStatement:n=>/^\s*(except[ :]|finally:|else:)/.test(n.textAfter)?n.baseIndent:n.continue(),MatchStatement:n=>/^\s*case /.test(n.textAfter)?n.baseIndent+n.unit:n.continue(),"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression":ir({closing:")"}),"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression":ir({closing:"}"}),"ArrayExpression ArrayComprehensionExpression":ir({closing:"]"}),MemberExpression:n=>n.baseIndent+n.unit,"String FormatString":()=>null,Script:n=>{var e;let t=yr(n);return(e=t&&br(n,t))!==null&&e!==void 0?e:n.continue()}}),No.add({"ArrayExpression DictionaryExpression SetExpression TupleExpression":rf,Body:(n,e)=>({from:n.from+1,to:n.to-(n.to==e.doc.length?0:1)}),"String FormatString":(n,e)=>({from:e.doc.lineAt(n.from).to,to:n.to})})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"'''",'"""'],stringPrefixes:["f","fr","rf","r","u","b","br","rb","F","FR","RF","R","U","B","BR","RB"]},commentTokens:{line:"#"},indentOnInput:/^\s*([\}\]\)]|else:|elif |except |finally:|case\s+[^:]*:?)$/}});function Hb(){return new tf(Sr,[Sr.data.of({autocomplete:$b}),Sr.data.of({autocomplete:Lb})])}const zb=zo({String:O.string,Number:O.number,"True False":O.bool,PropertyName:O.propertyName,Null:O.null,", :":O.separator,"[ ]":O.squareBracket,"{ }":O.brace}),Ib=tn.deserialize({version:14,states:"$bOVQPOOOOQO'#Cb'#CbOnQPO'#CeOvQPO'#ClOOQO'#Cr'#CrQOQPOOOOQO'#Cg'#CgO}QPO'#CfO!SQPO'#CtOOQO,59P,59PO![QPO,59PO!aQPO'#CuOOQO,59W,59WO!iQPO,59WOVQPO,59QOqQPO'#CmO!nQPO,59`OOQO1G.k1G.kOVQPO'#CnO!vQPO,59aOOQO1G.r1G.rOOQO1G.l1G.lOOQO,59X,59XOOQO-E6k-E6kOOQO,59Y,59YOOQO-E6l-E6l",stateData:"#O~OeOS~OQSORSOSSOTSOWQO_ROgPO~OVXOgUO~O^[O~PVO[^O~O]_OVhX~OVaO~O]bO^iX~O^dO~O]_OVha~O]bO^ia~O",goto:"!kjPPPPPPkPPkqwPPPPk{!RPPP!XP!e!hXSOR^bQWQRf_TVQ_Q`WRg`QcZRicQTOQZRQe^RhbRYQR]R",nodeNames:"⚠ JsonText True False Null Number String } { Object Property PropertyName : , ] [ Array",maxTerm:25,nodeProps:[["isolate",-2,6,11,""],["openedBy",7,"{",14,"["],["closedBy",8,"}",15,"]"]],propSources:[zb],skippedNodes:[0],repeatNodeCount:2,tokenData:"(|~RaXY!WYZ!W]^!Wpq!Wrs!]|}$u}!O$z!Q!R%T!R![&c![!]&t!}#O&y#P#Q'O#Y#Z'T#b#c'r#h#i(Z#o#p(r#q#r(w~!]Oe~~!`Wpq!]qr!]rs!xs#O!]#O#P!}#P;'S!];'S;=`$o<%lO!]~!}Og~~#QXrs!]!P!Q!]#O#P!]#U#V!]#Y#Z!]#b#c!]#f#g!]#h#i!]#i#j#m~#pR!Q![#y!c!i#y#T#Z#y~#|R!Q![$V!c!i$V#T#Z$V~$YR!Q![$c!c!i$c#T#Z$c~$fR!Q![!]!c!i!]#T#Z!]~$rP;=`<%l!]~$zO]~~$}Q!Q!R%T!R![&c~%YRT~!O!P%c!g!h%w#X#Y%w~%fP!Q![%i~%nRT~!Q![%i!g!h%w#X#Y%w~%zR{|&T}!O&T!Q![&Z~&WP!Q![&Z~&`PT~!Q![&Z~&hST~!O!P%c!Q![&c!g!h%w#X#Y%w~&yO[~~'OO_~~'TO^~~'WP#T#U'Z~'^P#`#a'a~'dP#g#h'g~'jP#X#Y'm~'rOR~~'uP#i#j'x~'{P#`#a(O~(RP#`#a(U~(ZOS~~(^P#f#g(a~(dP#i#j(g~(jP#X#Y(m~(rOQ~~(wOW~~(|OV~",tokenizers:[0],topRules:{JsonText:[0,1]},tokenPrec:0}),jb=()=>n=>{try{JSON.parse(n.state.doc.toString())}catch(e){if(!(e instanceof SyntaxError))throw e;const t=Vb(e,n.state.doc);return[{from:t,message:e.message,severity:"error",to:t}]}return[]};function Vb(n,e){let t;return(t=n.message.match(/at position (\d+)/))?Math.min(+t[1],e.length):(t=n.message.match(/at line (\d+) column (\d+)/))?Math.min(e.line(+t[1]).from+ +t[2]-1,e.length):0}const Nb=Ui.define({name:"json",parser:Ib.configure({props:[Ms.add({Object:ba({except:/^\s*\}/}),Array:ba({except:/^\s*\]/})}),No.add({"Object Array":rf})]}),languageData:{closeBrackets:{brackets:["[","{",'"']},indentOnInput:/^\s*[\}\]]$/}});function Gb(){return new tf(Nb)}export{P as E,d1 as R,bf as S,jb as a,Gb as j,n1 as o,Hb as p}; diff --git a/webui/dist/assets/dnd-BiPfFtVp.js b/webui/dist/assets/dnd-BiPfFtVp.js new file mode 100644 index 00000000..2cb9ef46 --- /dev/null +++ b/webui/dist/assets/dnd-BiPfFtVp.js @@ -0,0 +1,5 @@ +import{r as c,R as P,b as Oe}from"./router-9vIXuQkh.js";function Sn(){for(var e=arguments.length,t=new Array(e),n=0;nr=>{t.forEach(o=>o(r))},t)}const tt=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function me(e){const t=Object.prototype.toString.call(e);return t==="[object Window]"||t==="[object global]"}function bt(e){return"nodeType"in e}function B(e){var t,n;return e?me(e)?e:bt(e)&&(t=(n=e.ownerDocument)==null?void 0:n.defaultView)!=null?t:window:window}function wt(e){const{Document:t}=B(e);return e instanceof t}function Be(e){return me(e)?!1:e instanceof B(e).HTMLElement}function Wt(e){return e instanceof B(e).SVGElement}function ye(e){return e?me(e)?e.document:bt(e)?wt(e)?e:Be(e)||Wt(e)?e.ownerDocument:document:document:document}const Q=tt?c.useLayoutEffect:c.useEffect;function mt(e){const t=c.useRef(e);return Q(()=>{t.current=e}),c.useCallback(function(){for(var n=arguments.length,r=new Array(n),o=0;o{e.current=setInterval(r,o)},[]),n=c.useCallback(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[]);return[t,n]}function ke(e,t){t===void 0&&(t=[e]);const n=c.useRef(e);return Q(()=>{n.current!==e&&(n.current=e)},t),n}function Fe(e,t){const n=c.useRef();return c.useMemo(()=>{const r=e(n.current);return n.current=r,r},[...t])}function Je(e){const t=mt(e),n=c.useRef(null),r=c.useCallback(o=>{o!==n.current&&t?.(o,n.current),n.current=o},[]);return[n,r]}function ft(e){const t=c.useRef();return c.useEffect(()=>{t.current=e},[e]),t.current}let ct={};function $e(e,t){return c.useMemo(()=>{if(t)return t;const n=ct[e]==null?0:ct[e]+1;return ct[e]=n,e+"-"+n},[e,t])}function Ht(e){return function(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o{const a=Object.entries(s);for(const[l,u]of a){const f=i[l];f!=null&&(i[l]=f+e*u)}return i},{...t})}}const we=Ht(1),ze=Ht(-1);function In(e){return"clientX"in e&&"clientY"in e}function yt(e){if(!e)return!1;const{KeyboardEvent:t}=B(e.target);return t&&e instanceof t}function Mn(e){if(!e)return!1;const{TouchEvent:t}=B(e.target);return t&&e instanceof t}function ht(e){if(Mn(e)){if(e.touches&&e.touches.length){const{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){const{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return In(e)?{x:e.clientX,y:e.clientY}:null}const _e=Object.freeze({Translate:{toString(e){if(!e)return;const{x:t,y:n}=e;return"translate3d("+(t?Math.round(t):0)+"px, "+(n?Math.round(n):0)+"px, 0)"}},Scale:{toString(e){if(!e)return;const{scaleX:t,scaleY:n}=e;return"scaleX("+t+") scaleY("+n+")"}},Transform:{toString(e){if(e)return[_e.Translate.toString(e),_e.Scale.toString(e)].join(" ")}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+" "+n+"ms "+r}}}),Tt="a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";function An(e){return e.matches(Tt)?e:e.querySelector(Tt)}const On={display:"none"};function Tn(e){let{id:t,value:n}=e;return P.createElement("div",{id:t,style:On},n)}function Nn(e){let{id:t,announcement:n,ariaLiveType:r="assertive"}=e;const o={position:"fixed",top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0 0 0 0)",clipPath:"inset(100%)",whiteSpace:"nowrap"};return P.createElement("div",{id:t,style:o,role:"status","aria-live":r,"aria-atomic":!0},n)}function Ln(){const[e,t]=c.useState("");return{announce:c.useCallback(r=>{r!=null&&t(r)},[]),announcement:e}}const Kt=c.createContext(null);function kn(e){const t=c.useContext(Kt);c.useEffect(()=>{if(!t)throw new Error("useDndMonitor must be used within a children of ");return t(e)},[e,t])}function zn(){const[e]=c.useState(()=>new Set),t=c.useCallback(r=>(e.add(r),()=>e.delete(r)),[e]);return[c.useCallback(r=>{let{type:o,event:i}=r;e.forEach(s=>{var a;return(a=s[o])==null?void 0:a.call(s,i)})},[e]),t]}const Pn={draggable:` + To pick up a draggable item, press the space bar. + While dragging, use the arrow keys to move the item. + Press space again to drop the item in its new position, or press escape to cancel. + `},Bn={onDragStart(e){let{active:t}=e;return"Picked up draggable item "+t.id+"."},onDragOver(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was moved over droppable area "+n.id+".":"Draggable item "+t.id+" is no longer over a droppable area."},onDragEnd(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was dropped over droppable area "+n.id:"Draggable item "+t.id+" was dropped."},onDragCancel(e){let{active:t}=e;return"Dragging was cancelled. Draggable item "+t.id+" was dropped."}};function Fn(e){let{announcements:t=Bn,container:n,hiddenTextDescribedById:r,screenReaderInstructions:o=Pn}=e;const{announce:i,announcement:s}=Ln(),a=$e("DndLiveRegion"),[l,u]=c.useState(!1);if(c.useEffect(()=>{u(!0)},[]),kn(c.useMemo(()=>({onDragStart(d){let{active:g}=d;i(t.onDragStart({active:g}))},onDragMove(d){let{active:g,over:h}=d;t.onDragMove&&i(t.onDragMove({active:g,over:h}))},onDragOver(d){let{active:g,over:h}=d;i(t.onDragOver({active:g,over:h}))},onDragEnd(d){let{active:g,over:h}=d;i(t.onDragEnd({active:g,over:h}))},onDragCancel(d){let{active:g,over:h}=d;i(t.onDragCancel({active:g,over:h}))}}),[i,t])),!l)return null;const f=P.createElement(P.Fragment,null,P.createElement(Tn,{id:r,value:o.draggable}),P.createElement(Nn,{id:a,announcement:s}));return n?Oe.createPortal(f,n):f}var O;(function(e){e.DragStart="dragStart",e.DragMove="dragMove",e.DragEnd="dragEnd",e.DragCancel="dragCancel",e.DragOver="dragOver",e.RegisterDroppable="registerDroppable",e.SetDroppableDisabled="setDroppableDisabled",e.UnregisterDroppable="unregisterDroppable"})(O||(O={}));function Qe(){}function ao(e,t){return c.useMemo(()=>({sensor:e,options:t??{}}),[e,t])}function co(){for(var e=arguments.length,t=new Array(e),n=0;n[...t].filter(r=>r!=null),[...t])}const V=Object.freeze({x:0,y:0});function Vt(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function qt(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return n-r}function $n(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return r-n}function Nt(e){let{left:t,top:n,height:r,width:o}=e;return[{x:t,y:n},{x:t+o,y:n},{x:t,y:n+r},{x:t+o,y:n+r}]}function Gt(e,t){if(!e||e.length===0)return null;const[n]=e;return n[t]}function Lt(e,t,n){return t===void 0&&(t=e.left),n===void 0&&(n=e.top),{x:t+e.width*.5,y:n+e.height*.5}}const lo=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const o=Lt(t,t.left,t.top),i=[];for(const s of r){const{id:a}=s,l=n.get(a);if(l){const u=Vt(Lt(l),o);i.push({id:a,data:{droppableContainer:s,value:u}})}}return i.sort(qt)},Xn=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const o=Nt(t),i=[];for(const s of r){const{id:a}=s,l=n.get(a);if(l){const u=Nt(l),f=o.reduce((g,h,C)=>g+Vt(u[C],h),0),d=Number((f/4).toFixed(4));i.push({id:a,data:{droppableContainer:s,value:d}})}}return i.sort(qt)};function Yn(e,t){const n=Math.max(t.top,e.top),r=Math.max(t.left,e.left),o=Math.min(t.left+t.width,e.left+e.width),i=Math.min(t.top+t.height,e.top+e.height),s=o-r,a=i-n;if(r{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const o=[];for(const i of r){const{id:s}=i,a=n.get(s);if(a){const l=Yn(a,t);l>0&&o.push({id:s,data:{droppableContainer:i,value:l}})}}return o.sort($n)};function Un(e,t,n){return{...e,scaleX:t&&n?t.width/n.width:1,scaleY:t&&n?t.height/n.height:1}}function Jt(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:V}function Wn(e){return function(n){for(var r=arguments.length,o=new Array(r>1?r-1:0),i=1;i({...s,top:s.top+e*a.y,bottom:s.bottom+e*a.y,left:s.left+e*a.x,right:s.right+e*a.x}),{...n})}}const Hn=Wn(1);function Kn(e){if(e.startsWith("matrix3d(")){const t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith("matrix(")){const t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function Vn(e,t,n){const r=Kn(t);if(!r)return e;const{scaleX:o,scaleY:i,x:s,y:a}=r,l=e.left-s-(1-o)*parseFloat(n),u=e.top-a-(1-i)*parseFloat(n.slice(n.indexOf(" ")+1)),f=o?e.width/o:e.width,d=i?e.height/i:e.height;return{width:f,height:d,top:u,right:l+f,bottom:u+d,left:l}}const qn={ignoreTransform:!1};function xe(e,t){t===void 0&&(t=qn);let n=e.getBoundingClientRect();if(t.ignoreTransform){const{transform:u,transformOrigin:f}=B(e).getComputedStyle(e);u&&(n=Vn(n,u,f))}const{top:r,left:o,width:i,height:s,bottom:a,right:l}=n;return{top:r,left:o,width:i,height:s,bottom:a,right:l}}function kt(e){return xe(e,{ignoreTransform:!0})}function Gn(e){const t=e.innerWidth,n=e.innerHeight;return{top:0,left:0,right:t,bottom:n,width:t,height:n}}function Jn(e,t){return t===void 0&&(t=B(e).getComputedStyle(e)),t.position==="fixed"}function _n(e,t){t===void 0&&(t=B(e).getComputedStyle(e));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(o=>{const i=t[o];return typeof i=="string"?n.test(i):!1})}function nt(e,t){const n=[];function r(o){if(t!=null&&n.length>=t||!o)return n;if(wt(o)&&o.scrollingElement!=null&&!n.includes(o.scrollingElement))return n.push(o.scrollingElement),n;if(!Be(o)||Wt(o)||n.includes(o))return n;const i=B(e).getComputedStyle(o);return o!==e&&_n(o,i)&&n.push(o),Jn(o,i)?n:r(o.parentNode)}return e?r(e):n}function _t(e){const[t]=nt(e,1);return t??null}function lt(e){return!tt||!e?null:me(e)?e:bt(e)?wt(e)||e===ye(e).scrollingElement?window:Be(e)?e:null:null}function Qt(e){return me(e)?e.scrollX:e.scrollLeft}function Zt(e){return me(e)?e.scrollY:e.scrollTop}function gt(e){return{x:Qt(e),y:Zt(e)}}var N;(function(e){e[e.Forward=1]="Forward",e[e.Backward=-1]="Backward"})(N||(N={}));function en(e){return!tt||!e?!1:e===document.scrollingElement}function tn(e){const t={x:0,y:0},n=en(e)?{height:window.innerHeight,width:window.innerWidth}:{height:e.clientHeight,width:e.clientWidth},r={x:e.scrollWidth-n.width,y:e.scrollHeight-n.height},o=e.scrollTop<=t.y,i=e.scrollLeft<=t.x,s=e.scrollTop>=r.y,a=e.scrollLeft>=r.x;return{isTop:o,isLeft:i,isBottom:s,isRight:a,maxScroll:r,minScroll:t}}const Qn={x:.2,y:.2};function Zn(e,t,n,r,o){let{top:i,left:s,right:a,bottom:l}=n;r===void 0&&(r=10),o===void 0&&(o=Qn);const{isTop:u,isBottom:f,isLeft:d,isRight:g}=tn(e),h={x:0,y:0},C={x:0,y:0},v={height:t.height*o.y,width:t.width*o.x};return!u&&i<=t.top+v.height?(h.y=N.Backward,C.y=r*Math.abs((t.top+v.height-i)/v.height)):!f&&l>=t.bottom-v.height&&(h.y=N.Forward,C.y=r*Math.abs((t.bottom-v.height-l)/v.height)),!g&&a>=t.right-v.width?(h.x=N.Forward,C.x=r*Math.abs((t.right-v.width-a)/v.width)):!d&&s<=t.left+v.width&&(h.x=N.Backward,C.x=r*Math.abs((t.left+v.width-s)/v.width)),{direction:h,speed:C}}function er(e){if(e===document.scrollingElement){const{innerWidth:i,innerHeight:s}=window;return{top:0,left:0,right:i,bottom:s,width:i,height:s}}const{top:t,left:n,right:r,bottom:o}=e.getBoundingClientRect();return{top:t,left:n,right:r,bottom:o,width:e.clientWidth,height:e.clientHeight}}function nn(e){return e.reduce((t,n)=>we(t,gt(n)),V)}function tr(e){return e.reduce((t,n)=>t+Qt(n),0)}function nr(e){return e.reduce((t,n)=>t+Zt(n),0)}function rr(e,t){if(t===void 0&&(t=xe),!e)return;const{top:n,left:r,bottom:o,right:i}=t(e);_t(e)&&(o<=0||i<=0||n>=window.innerHeight||r>=window.innerWidth)&&e.scrollIntoView({block:"center",inline:"center"})}const or=[["x",["left","right"],tr],["y",["top","bottom"],nr]];class xt{constructor(t,n){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const r=nt(n),o=nn(r);this.rect={...t},this.width=t.width,this.height=t.height;for(const[i,s,a]of or)for(const l of s)Object.defineProperty(this,l,{get:()=>{const u=a(r),f=o[i]-u;return this.rect[l]+f},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class Te{constructor(t){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(n=>{var r;return(r=this.target)==null?void 0:r.removeEventListener(...n)})},this.target=t}add(t,n,r){var o;(o=this.target)==null||o.addEventListener(t,n,r),this.listeners.push([t,n,r])}}function ir(e){const{EventTarget:t}=B(e);return e instanceof t?e:ye(e)}function ut(e,t){const n=Math.abs(e.x),r=Math.abs(e.y);return typeof t=="number"?Math.sqrt(n**2+r**2)>t:"x"in t&&"y"in t?n>t.x&&r>t.y:"x"in t?n>t.x:"y"in t?r>t.y:!1}var W;(function(e){e.Click="click",e.DragStart="dragstart",e.Keydown="keydown",e.ContextMenu="contextmenu",e.Resize="resize",e.SelectionChange="selectionchange",e.VisibilityChange="visibilitychange"})(W||(W={}));function zt(e){e.preventDefault()}function sr(e){e.stopPropagation()}var w;(function(e){e.Space="Space",e.Down="ArrowDown",e.Right="ArrowRight",e.Left="ArrowLeft",e.Up="ArrowUp",e.Esc="Escape",e.Enter="Enter",e.Tab="Tab"})(w||(w={}));const rn={start:[w.Space,w.Enter],cancel:[w.Esc],end:[w.Space,w.Enter,w.Tab]},ar=(e,t)=>{let{currentCoordinates:n}=t;switch(e.code){case w.Right:return{...n,x:n.x+25};case w.Left:return{...n,x:n.x-25};case w.Down:return{...n,y:n.y+25};case w.Up:return{...n,y:n.y-25}}};class on{constructor(t){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=t;const{event:{target:n}}=t;this.props=t,this.listeners=new Te(ye(n)),this.windowListeners=new Te(B(n)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(W.Resize,this.handleCancel),this.windowListeners.add(W.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(W.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:t,onStart:n}=this.props,r=t.node.current;r&&rr(r),n(V)}handleKeyDown(t){if(yt(t)){const{active:n,context:r,options:o}=this.props,{keyboardCodes:i=rn,coordinateGetter:s=ar,scrollBehavior:a="smooth"}=o,{code:l}=t;if(i.end.includes(l)){this.handleEnd(t);return}if(i.cancel.includes(l)){this.handleCancel(t);return}const{collisionRect:u}=r.current,f=u?{x:u.left,y:u.top}:V;this.referenceCoordinates||(this.referenceCoordinates=f);const d=s(t,{active:n,context:r.current,currentCoordinates:f});if(d){const g=ze(d,f),h={x:0,y:0},{scrollableAncestors:C}=r.current;for(const v of C){const p=t.code,{isTop:m,isRight:y,isLeft:b,isBottom:R,maxScroll:S,minScroll:E}=tn(v),x=er(v),D={x:Math.min(p===w.Right?x.right-x.width/2:x.right,Math.max(p===w.Right?x.left:x.left+x.width/2,d.x)),y:Math.min(p===w.Down?x.bottom-x.height/2:x.bottom,Math.max(p===w.Down?x.top:x.top+x.height/2,d.y))},A=p===w.Right&&!y||p===w.Left&&!b,T=p===w.Down&&!R||p===w.Up&&!m;if(A&&D.x!==d.x){const M=v.scrollLeft+g.x,H=p===w.Right&&M<=S.x||p===w.Left&&M>=E.x;if(H&&!g.y){v.scrollTo({left:M,behavior:a});return}H?h.x=v.scrollLeft-M:h.x=p===w.Right?v.scrollLeft-S.x:v.scrollLeft-E.x,h.x&&v.scrollBy({left:-h.x,behavior:a});break}else if(T&&D.y!==d.y){const M=v.scrollTop+g.y,H=p===w.Down&&M<=S.y||p===w.Up&&M>=E.y;if(H&&!g.x){v.scrollTo({top:M,behavior:a});return}H?h.y=v.scrollTop-M:h.y=p===w.Down?v.scrollTop-S.y:v.scrollTop-E.y,h.y&&v.scrollBy({top:-h.y,behavior:a});break}}this.handleMove(t,we(ze(d,this.referenceCoordinates),h))}}}handleMove(t,n){const{onMove:r}=this.props;t.preventDefault(),r(n)}handleEnd(t){const{onEnd:n}=this.props;t.preventDefault(),this.detach(),n()}handleCancel(t){const{onCancel:n}=this.props;t.preventDefault(),this.detach(),n()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}on.activators=[{eventName:"onKeyDown",handler:(e,t,n)=>{let{keyboardCodes:r=rn,onActivation:o}=t,{active:i}=n;const{code:s}=e.nativeEvent;if(r.start.includes(s)){const a=i.activatorNode.current;return a&&e.target!==a?!1:(e.preventDefault(),o?.({event:e.nativeEvent}),!0)}return!1}}];function Pt(e){return!!(e&&"distance"in e)}function Bt(e){return!!(e&&"delay"in e)}class Dt{constructor(t,n,r){var o;r===void 0&&(r=ir(t.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=t,this.events=n;const{event:i}=t,{target:s}=i;this.props=t,this.events=n,this.document=ye(s),this.documentListeners=new Te(this.document),this.listeners=new Te(r),this.windowListeners=new Te(B(s)),this.initialCoordinates=(o=ht(i))!=null?o:V,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:t,props:{options:{activationConstraint:n,bypassActivationConstraint:r}}}=this;if(this.listeners.add(t.move.name,this.handleMove,{passive:!1}),this.listeners.add(t.end.name,this.handleEnd),t.cancel&&this.listeners.add(t.cancel.name,this.handleCancel),this.windowListeners.add(W.Resize,this.handleCancel),this.windowListeners.add(W.DragStart,zt),this.windowListeners.add(W.VisibilityChange,this.handleCancel),this.windowListeners.add(W.ContextMenu,zt),this.documentListeners.add(W.Keydown,this.handleKeydown),n){if(r!=null&&r({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(Bt(n)){this.timeoutId=setTimeout(this.handleStart,n.delay),this.handlePending(n);return}if(Pt(n)){this.handlePending(n);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(t,n){const{active:r,onPending:o}=this.props;o(r,t,this.initialCoordinates,n)}handleStart(){const{initialCoordinates:t}=this,{onStart:n}=this.props;t&&(this.activated=!0,this.documentListeners.add(W.Click,sr,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(W.SelectionChange,this.removeTextSelection),n(t))}handleMove(t){var n;const{activated:r,initialCoordinates:o,props:i}=this,{onMove:s,options:{activationConstraint:a}}=i;if(!o)return;const l=(n=ht(t))!=null?n:V,u=ze(o,l);if(!r&&a){if(Pt(a)){if(a.tolerance!=null&&ut(u,a.tolerance))return this.handleCancel();if(ut(u,a.distance))return this.handleStart()}if(Bt(a)&&ut(u,a.tolerance))return this.handleCancel();this.handlePending(a,u);return}t.cancelable&&t.preventDefault(),s(l)}handleEnd(){const{onAbort:t,onEnd:n}=this.props;this.detach(),this.activated||t(this.props.active),n()}handleCancel(){const{onAbort:t,onCancel:n}=this.props;this.detach(),this.activated||t(this.props.active),n()}handleKeydown(t){t.code===w.Esc&&this.handleCancel()}removeTextSelection(){var t;(t=this.document.getSelection())==null||t.removeAllRanges()}}const cr={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class sn extends Dt{constructor(t){const{event:n}=t,r=ye(n.target);super(t,cr,r)}}sn.activators=[{eventName:"onPointerDown",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return!n.isPrimary||n.button!==0?!1:(r?.({event:n}),!0)}}];const lr={move:{name:"mousemove"},end:{name:"mouseup"}};var vt;(function(e){e[e.RightClick=2]="RightClick"})(vt||(vt={}));class ur extends Dt{constructor(t){super(t,lr,ye(t.event.target))}}ur.activators=[{eventName:"onMouseDown",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return n.button===vt.RightClick?!1:(r?.({event:n}),!0)}}];const dt={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class dr extends Dt{constructor(t){super(t,dt)}static setup(){return window.addEventListener(dt.move.name,t,{capture:!1,passive:!1}),function(){window.removeEventListener(dt.move.name,t)};function t(){}}}dr.activators=[{eventName:"onTouchStart",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;const{touches:o}=n;return o.length>1?!1:(r?.({event:n}),!0)}}];var Ne;(function(e){e[e.Pointer=0]="Pointer",e[e.DraggableRect=1]="DraggableRect"})(Ne||(Ne={}));var Ze;(function(e){e[e.TreeOrder=0]="TreeOrder",e[e.ReversedTreeOrder=1]="ReversedTreeOrder"})(Ze||(Ze={}));function fr(e){let{acceleration:t,activator:n=Ne.Pointer,canScroll:r,draggingRect:o,enabled:i,interval:s=5,order:a=Ze.TreeOrder,pointerCoordinates:l,scrollableAncestors:u,scrollableAncestorRects:f,delta:d,threshold:g}=e;const h=gr({delta:d,disabled:!i}),[C,v]=En(),p=c.useRef({x:0,y:0}),m=c.useRef({x:0,y:0}),y=c.useMemo(()=>{switch(n){case Ne.Pointer:return l?{top:l.y,bottom:l.y,left:l.x,right:l.x}:null;case Ne.DraggableRect:return o}},[n,o,l]),b=c.useRef(null),R=c.useCallback(()=>{const E=b.current;if(!E)return;const x=p.current.x*m.current.x,D=p.current.y*m.current.y;E.scrollBy(x,D)},[]),S=c.useMemo(()=>a===Ze.TreeOrder?[...u].reverse():u,[a,u]);c.useEffect(()=>{if(!i||!u.length||!y){v();return}for(const E of S){if(r?.(E)===!1)continue;const x=u.indexOf(E),D=f[x];if(!D)continue;const{direction:A,speed:T}=Zn(E,D,y,t,g);for(const M of["x","y"])h[M][A[M]]||(T[M]=0,A[M]=0);if(T.x>0||T.y>0){v(),b.current=E,C(R,s),p.current=T,m.current=A;return}}p.current={x:0,y:0},m.current={x:0,y:0},v()},[t,R,r,v,i,s,JSON.stringify(y),JSON.stringify(h),C,u,S,f,JSON.stringify(g)])}const hr={x:{[N.Backward]:!1,[N.Forward]:!1},y:{[N.Backward]:!1,[N.Forward]:!1}};function gr(e){let{delta:t,disabled:n}=e;const r=ft(t);return Fe(o=>{if(n||!r||!o)return hr;const i={x:Math.sign(t.x-r.x),y:Math.sign(t.y-r.y)};return{x:{[N.Backward]:o.x[N.Backward]||i.x===-1,[N.Forward]:o.x[N.Forward]||i.x===1},y:{[N.Backward]:o.y[N.Backward]||i.y===-1,[N.Forward]:o.y[N.Forward]||i.y===1}}},[n,t,r])}function vr(e,t){const n=t!=null?e.get(t):void 0,r=n?n.node.current:null;return Fe(o=>{var i;return t==null?null:(i=r??o)!=null?i:null},[r,t])}function pr(e,t){return c.useMemo(()=>e.reduce((n,r)=>{const{sensor:o}=r,i=o.activators.map(s=>({eventName:s.eventName,handler:t(s.handler,r)}));return[...n,...i]},[]),[e,t])}var Pe;(function(e){e[e.Always=0]="Always",e[e.BeforeDragging=1]="BeforeDragging",e[e.WhileDragging=2]="WhileDragging"})(Pe||(Pe={}));var pt;(function(e){e.Optimized="optimized"})(pt||(pt={}));const Ft=new Map;function br(e,t){let{dragging:n,dependencies:r,config:o}=t;const[i,s]=c.useState(null),{frequency:a,measure:l,strategy:u}=o,f=c.useRef(e),d=p(),g=ke(d),h=c.useCallback(function(m){m===void 0&&(m=[]),!g.current&&s(y=>y===null?m:y.concat(m.filter(b=>!y.includes(b))))},[g]),C=c.useRef(null),v=Fe(m=>{if(d&&!n)return Ft;if(!m||m===Ft||f.current!==e||i!=null){const y=new Map;for(let b of e){if(!b)continue;if(i&&i.length>0&&!i.includes(b.id)&&b.rect.current){y.set(b.id,b.rect.current);continue}const R=b.node.current,S=R?new xt(l(R),R):null;b.rect.current=S,S&&y.set(b.id,S)}return y}return m},[e,i,n,d,l]);return c.useEffect(()=>{f.current=e},[e]),c.useEffect(()=>{d||h()},[n,d]),c.useEffect(()=>{i&&i.length>0&&s(null)},[JSON.stringify(i)]),c.useEffect(()=>{d||typeof a!="number"||C.current!==null||(C.current=setTimeout(()=>{h(),C.current=null},a))},[a,d,h,...r]),{droppableRects:v,measureDroppableContainers:h,measuringScheduled:i!=null};function p(){switch(u){case Pe.Always:return!1;case Pe.BeforeDragging:return n;default:return!n}}}function an(e,t){return Fe(n=>e?n||(typeof t=="function"?t(e):e):null,[t,e])}function wr(e,t){return an(e,t)}function mr(e){let{callback:t,disabled:n}=e;const r=mt(t),o=c.useMemo(()=>{if(n||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:i}=window;return new i(r)},[r,n]);return c.useEffect(()=>()=>o?.disconnect(),[o]),o}function rt(e){let{callback:t,disabled:n}=e;const r=mt(t),o=c.useMemo(()=>{if(n||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:i}=window;return new i(r)},[n]);return c.useEffect(()=>()=>o?.disconnect(),[o]),o}function yr(e){return new xt(xe(e),e)}function $t(e,t,n){t===void 0&&(t=yr);const[r,o]=c.useState(null);function i(){o(l=>{if(!e)return null;if(e.isConnected===!1){var u;return(u=l??n)!=null?u:null}const f=t(e);return JSON.stringify(l)===JSON.stringify(f)?l:f})}const s=mr({callback(l){if(e)for(const u of l){const{type:f,target:d}=u;if(f==="childList"&&d instanceof HTMLElement&&d.contains(e)){i();break}}}}),a=rt({callback:i});return Q(()=>{i(),e?(a?.observe(e),s?.observe(document.body,{childList:!0,subtree:!0})):(a?.disconnect(),s?.disconnect())},[e]),r}function xr(e){const t=an(e);return Jt(e,t)}const Xt=[];function Dr(e){const t=c.useRef(e),n=Fe(r=>e?r&&r!==Xt&&e&&t.current&&e.parentNode===t.current.parentNode?r:nt(e):Xt,[e]);return c.useEffect(()=>{t.current=e},[e]),n}function Cr(e){const[t,n]=c.useState(null),r=c.useRef(e),o=c.useCallback(i=>{const s=lt(i.target);s&&n(a=>a?(a.set(s,gt(s)),new Map(a)):null)},[]);return c.useEffect(()=>{const i=r.current;if(e!==i){s(i);const a=e.map(l=>{const u=lt(l);return u?(u.addEventListener("scroll",o,{passive:!0}),[u,gt(u)]):null}).filter(l=>l!=null);n(a.length?new Map(a):null),r.current=e}return()=>{s(e),s(i)};function s(a){a.forEach(l=>{const u=lt(l);u?.removeEventListener("scroll",o)})}},[o,e]),c.useMemo(()=>e.length?t?Array.from(t.values()).reduce((i,s)=>we(i,s),V):nn(e):V,[e,t])}function Yt(e,t){t===void 0&&(t=[]);const n=c.useRef(null);return c.useEffect(()=>{n.current=null},t),c.useEffect(()=>{const r=e!==V;r&&!n.current&&(n.current=e),!r&&n.current&&(n.current=null)},[e]),n.current?ze(e,n.current):V}function Rr(e){c.useEffect(()=>{if(!tt)return;const t=e.map(n=>{let{sensor:r}=n;return r.setup==null?void 0:r.setup()});return()=>{for(const n of t)n?.()}},e.map(t=>{let{sensor:n}=t;return n}))}function Sr(e,t){return c.useMemo(()=>e.reduce((n,r)=>{let{eventName:o,handler:i}=r;return n[o]=s=>{i(s,t)},n},{}),[e,t])}function cn(e){return c.useMemo(()=>e?Gn(e):null,[e])}const jt=[];function Er(e,t){t===void 0&&(t=xe);const[n]=e,r=cn(n?B(n):null),[o,i]=c.useState(jt);function s(){i(()=>e.length?e.map(l=>en(l)?r:new xt(t(l),l)):jt)}const a=rt({callback:s});return Q(()=>{a?.disconnect(),s(),e.forEach(l=>a?.observe(l))},[e]),o}function Ir(e){if(!e)return null;if(e.children.length>1)return e;const t=e.children[0];return Be(t)?t:e}function Mr(e){let{measure:t}=e;const[n,r]=c.useState(null),o=c.useCallback(u=>{for(const{target:f}of u)if(Be(f)){r(d=>{const g=t(f);return d?{...d,width:g.width,height:g.height}:g});break}},[t]),i=rt({callback:o}),s=c.useCallback(u=>{const f=Ir(u);i?.disconnect(),f&&i?.observe(f),r(f?t(f):null)},[t,i]),[a,l]=Je(s);return c.useMemo(()=>({nodeRef:a,rect:n,setRef:l}),[n,a,l])}const Ar=[{sensor:sn,options:{}},{sensor:on,options:{}}],Or={current:{}},Ge={draggable:{measure:kt},droppable:{measure:kt,strategy:Pe.WhileDragging,frequency:pt.Optimized},dragOverlay:{measure:xe}};class Le extends Map{get(t){var n;return t!=null&&(n=super.get(t))!=null?n:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(t=>{let{disabled:n}=t;return!n})}getNodeFor(t){var n,r;return(n=(r=this.get(t))==null?void 0:r.node.current)!=null?n:void 0}}const Tr={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Le,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:Qe},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:Ge,measureDroppableContainers:Qe,windowRect:null,measuringScheduled:!1},Nr={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:Qe,draggableNodes:new Map,over:null,measureDroppableContainers:Qe},ot=c.createContext(Nr),ln=c.createContext(Tr);function Lr(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Le}}}function kr(e,t){switch(t.type){case O.DragStart:return{...e,draggable:{...e.draggable,initialCoordinates:t.initialCoordinates,active:t.active}};case O.DragMove:return e.draggable.active==null?e:{...e,draggable:{...e.draggable,translate:{x:t.coordinates.x-e.draggable.initialCoordinates.x,y:t.coordinates.y-e.draggable.initialCoordinates.y}}};case O.DragEnd:case O.DragCancel:return{...e,draggable:{...e.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case O.RegisterDroppable:{const{element:n}=t,{id:r}=n,o=new Le(e.droppable.containers);return o.set(r,n),{...e,droppable:{...e.droppable,containers:o}}}case O.SetDroppableDisabled:{const{id:n,key:r,disabled:o}=t,i=e.droppable.containers.get(n);if(!i||r!==i.key)return e;const s=new Le(e.droppable.containers);return s.set(n,{...i,disabled:o}),{...e,droppable:{...e.droppable,containers:s}}}case O.UnregisterDroppable:{const{id:n,key:r}=t,o=e.droppable.containers.get(n);if(!o||r!==o.key)return e;const i=new Le(e.droppable.containers);return i.delete(n),{...e,droppable:{...e.droppable,containers:i}}}default:return e}}function zr(e){let{disabled:t}=e;const{active:n,activatorEvent:r,draggableNodes:o}=c.useContext(ot),i=ft(r),s=ft(n?.id);return c.useEffect(()=>{if(!t&&!r&&i&&s!=null){if(!yt(i)||document.activeElement===i.target)return;const a=o.get(s);if(!a)return;const{activatorNode:l,node:u}=a;if(!l.current&&!u.current)return;requestAnimationFrame(()=>{for(const f of[l.current,u.current]){if(!f)continue;const d=An(f);if(d){d.focus();break}}})}},[r,t,o,s,i]),null}function Pr(e,t){let{transform:n,...r}=t;return e!=null&&e.length?e.reduce((o,i)=>i({transform:o,...r}),n):n}function Br(e){return c.useMemo(()=>({draggable:{...Ge.draggable,...e?.draggable},droppable:{...Ge.droppable,...e?.droppable},dragOverlay:{...Ge.dragOverlay,...e?.dragOverlay}}),[e?.draggable,e?.droppable,e?.dragOverlay])}function Fr(e){let{activeNode:t,measure:n,initialRect:r,config:o=!0}=e;const i=c.useRef(!1),{x:s,y:a}=typeof o=="boolean"?{x:o,y:o}:o;Q(()=>{if(!s&&!a||!t){i.current=!1;return}if(i.current||!r)return;const u=t?.node.current;if(!u||u.isConnected===!1)return;const f=n(u),d=Jt(f,r);if(s||(d.x=0),a||(d.y=0),i.current=!0,Math.abs(d.x)>0||Math.abs(d.y)>0){const g=_t(u);g&&g.scrollBy({top:d.y,left:d.x})}},[t,s,a,r,n])}const un=c.createContext({...V,scaleX:1,scaleY:1});var ue;(function(e){e[e.Uninitialized=0]="Uninitialized",e[e.Initializing=1]="Initializing",e[e.Initialized=2]="Initialized"})(ue||(ue={}));const uo=c.memo(function(t){var n,r,o,i;let{id:s,accessibility:a,autoScroll:l=!0,children:u,sensors:f=Ar,collisionDetection:d=jn,measuring:g,modifiers:h,...C}=t;const v=c.useReducer(kr,void 0,Lr),[p,m]=v,[y,b]=zn(),[R,S]=c.useState(ue.Uninitialized),E=R===ue.Initialized,{draggable:{active:x,nodes:D,translate:A},droppable:{containers:T}}=p,M=x!=null?D.get(x):null,H=c.useRef({initial:null,translated:null}),K=c.useMemo(()=>{var k;return x!=null?{id:x,data:(k=M?.data)!=null?k:Or,rect:H}:null},[x,M]),q=c.useRef(null),[De,Xe]=c.useState(null),[F,Ye]=c.useState(null),Z=ke(C,Object.values(C)),Ce=$e("DndDescribedBy",s),je=c.useMemo(()=>T.getEnabled(),[T]),z=Br(g),{droppableRects:ee,measureDroppableContainers:de,measuringScheduled:Re}=br(je,{dragging:E,dependencies:[A.x,A.y],config:z.droppable}),j=vr(D,x),Ue=c.useMemo(()=>F?ht(F):null,[F]),oe=Rn(),te=wr(j,z.draggable.measure);Fr({activeNode:x!=null?D.get(x):null,config:oe.layoutShiftCompensation,initialRect:te,measure:z.draggable.measure});const I=$t(j,z.draggable.measure,te),Se=$t(j?j.parentElement:null),G=c.useRef({activatorEvent:null,active:null,activeNode:j,collisionRect:null,collisions:null,droppableRects:ee,draggableNodes:D,draggingNode:null,draggingNodeRect:null,droppableContainers:T,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),fe=T.getNodeFor((n=G.current.over)==null?void 0:n.id),ne=Mr({measure:z.dragOverlay.measure}),he=(r=ne.nodeRef.current)!=null?r:j,ge=E?(o=ne.rect)!=null?o:I:null,Ct=!!(ne.nodeRef.current&&ne.rect),Rt=xr(Ct?null:I),it=cn(he?B(he):null),ie=Dr(E?fe??j:null),We=Er(ie),He=Pr(h,{transform:{x:A.x-Rt.x,y:A.y-Rt.y,scaleX:1,scaleY:1},activatorEvent:F,active:K,activeNodeRect:I,containerNodeRect:Se,draggingNodeRect:ge,over:G.current.over,overlayNodeRect:ne.rect,scrollableAncestors:ie,scrollableAncestorRects:We,windowRect:it}),St=Ue?we(Ue,A):null,Et=Cr(ie),bn=Yt(Et),wn=Yt(Et,[I]),ve=we(He,bn),pe=ge?Hn(ge,He):null,Ee=K&&pe?d({active:K,collisionRect:pe,droppableRects:ee,droppableContainers:je,pointerCoordinates:St}):null,It=Gt(Ee,"id"),[se,Mt]=c.useState(null),mn=Ct?He:we(He,wn),yn=Un(mn,(i=se?.rect)!=null?i:null,I),st=c.useRef(null),At=c.useCallback((k,$)=>{let{sensor:X,options:ae}=$;if(q.current==null)return;const U=D.get(q.current);if(!U)return;const Y=k.nativeEvent,J=new X({active:q.current,activeNode:U,event:Y,options:ae,context:G,onAbort(L){if(!D.get(L))return;const{onDragAbort:_}=Z.current,re={id:L};_?.(re),y({type:"onDragAbort",event:re})},onPending(L,ce,_,re){if(!D.get(L))return;const{onDragPending:Me}=Z.current,le={id:L,constraint:ce,initialCoordinates:_,offset:re};Me?.(le),y({type:"onDragPending",event:le})},onStart(L){const ce=q.current;if(ce==null)return;const _=D.get(ce);if(!_)return;const{onDragStart:re}=Z.current,Ie={activatorEvent:Y,active:{id:ce,data:_.data,rect:H}};Oe.unstable_batchedUpdates(()=>{re?.(Ie),S(ue.Initializing),m({type:O.DragStart,initialCoordinates:L,active:ce}),y({type:"onDragStart",event:Ie}),Xe(st.current),Ye(Y)})},onMove(L){m({type:O.DragMove,coordinates:L})},onEnd:be(O.DragEnd),onCancel:be(O.DragCancel)});st.current=J;function be(L){return async function(){const{active:_,collisions:re,over:Ie,scrollAdjustedTranslate:Me}=G.current;let le=null;if(_&&Me){const{cancelDrop:Ae}=Z.current;le={activatorEvent:Y,active:_,collisions:re,delta:Me,over:Ie},L===O.DragEnd&&typeof Ae=="function"&&await Promise.resolve(Ae(le))&&(L=O.DragCancel)}q.current=null,Oe.unstable_batchedUpdates(()=>{m({type:L}),S(ue.Uninitialized),Mt(null),Xe(null),Ye(null),st.current=null;const Ae=L===O.DragEnd?"onDragEnd":"onDragCancel";if(le){const at=Z.current[Ae];at?.(le),y({type:Ae,event:le})}})}}},[D]),xn=c.useCallback((k,$)=>(X,ae)=>{const U=X.nativeEvent,Y=D.get(ae);if(q.current!==null||!Y||U.dndKit||U.defaultPrevented)return;const J={active:Y};k(X,$.options,J)===!0&&(U.dndKit={capturedBy:$.sensor},q.current=ae,At(X,$))},[D,At]),Ot=pr(f,xn);Rr(f),Q(()=>{I&&R===ue.Initializing&&S(ue.Initialized)},[I,R]),c.useEffect(()=>{const{onDragMove:k}=Z.current,{active:$,activatorEvent:X,collisions:ae,over:U}=G.current;if(!$||!X)return;const Y={active:$,activatorEvent:X,collisions:ae,delta:{x:ve.x,y:ve.y},over:U};Oe.unstable_batchedUpdates(()=>{k?.(Y),y({type:"onDragMove",event:Y})})},[ve.x,ve.y]),c.useEffect(()=>{const{active:k,activatorEvent:$,collisions:X,droppableContainers:ae,scrollAdjustedTranslate:U}=G.current;if(!k||q.current==null||!$||!U)return;const{onDragOver:Y}=Z.current,J=ae.get(It),be=J&&J.rect.current?{id:J.id,rect:J.rect.current,data:J.data,disabled:J.disabled}:null,L={active:k,activatorEvent:$,collisions:X,delta:{x:U.x,y:U.y},over:be};Oe.unstable_batchedUpdates(()=>{Mt(be),Y?.(L),y({type:"onDragOver",event:L})})},[It]),Q(()=>{G.current={activatorEvent:F,active:K,activeNode:j,collisionRect:pe,collisions:Ee,droppableRects:ee,draggableNodes:D,draggingNode:he,draggingNodeRect:ge,droppableContainers:T,over:se,scrollableAncestors:ie,scrollAdjustedTranslate:ve},H.current={initial:ge,translated:pe}},[K,j,Ee,pe,D,he,ge,ee,T,se,ie,ve]),fr({...oe,delta:A,draggingRect:pe,pointerCoordinates:St,scrollableAncestors:ie,scrollableAncestorRects:We});const Dn=c.useMemo(()=>({active:K,activeNode:j,activeNodeRect:I,activatorEvent:F,collisions:Ee,containerNodeRect:Se,dragOverlay:ne,draggableNodes:D,droppableContainers:T,droppableRects:ee,over:se,measureDroppableContainers:de,scrollableAncestors:ie,scrollableAncestorRects:We,measuringConfiguration:z,measuringScheduled:Re,windowRect:it}),[K,j,I,F,Ee,Se,ne,D,T,ee,se,de,ie,We,z,Re,it]),Cn=c.useMemo(()=>({activatorEvent:F,activators:Ot,active:K,activeNodeRect:I,ariaDescribedById:{draggable:Ce},dispatch:m,draggableNodes:D,over:se,measureDroppableContainers:de}),[F,Ot,K,I,m,Ce,D,se,de]);return P.createElement(Kt.Provider,{value:b},P.createElement(ot.Provider,{value:Cn},P.createElement(ln.Provider,{value:Dn},P.createElement(un.Provider,{value:yn},u)),P.createElement(zr,{disabled:a?.restoreFocus===!1})),P.createElement(Fn,{...a,hiddenTextDescribedById:Ce}));function Rn(){const k=De?.autoScrollEnabled===!1,$=typeof l=="object"?l.enabled===!1:l===!1,X=E&&!k&&!$;return typeof l=="object"?{...l,enabled:X}:{enabled:X}}}),$r=c.createContext(null),Ut="button",Xr="Draggable";function Yr(e){let{id:t,data:n,disabled:r=!1,attributes:o}=e;const i=$e(Xr),{activators:s,activatorEvent:a,active:l,activeNodeRect:u,ariaDescribedById:f,draggableNodes:d,over:g}=c.useContext(ot),{role:h=Ut,roleDescription:C="draggable",tabIndex:v=0}=o??{},p=l?.id===t,m=c.useContext(p?un:$r),[y,b]=Je(),[R,S]=Je(),E=Sr(s,t),x=ke(n);Q(()=>(d.set(t,{id:t,key:i,node:y,activatorNode:R,data:x}),()=>{const A=d.get(t);A&&A.key===i&&d.delete(t)}),[d,t]);const D=c.useMemo(()=>({role:h,tabIndex:v,"aria-disabled":r,"aria-pressed":p&&h===Ut?!0:void 0,"aria-roledescription":C,"aria-describedby":f.draggable}),[r,h,v,p,C,f.draggable]);return{active:l,activatorEvent:a,activeNodeRect:u,attributes:D,isDragging:p,listeners:r?void 0:E,node:y,over:g,setNodeRef:b,setActivatorNodeRef:S,transform:m}}function jr(){return c.useContext(ln)}const Ur="Droppable",Wr={timeout:25};function Hr(e){let{data:t,disabled:n=!1,id:r,resizeObserverConfig:o}=e;const i=$e(Ur),{active:s,dispatch:a,over:l,measureDroppableContainers:u}=c.useContext(ot),f=c.useRef({disabled:n}),d=c.useRef(!1),g=c.useRef(null),h=c.useRef(null),{disabled:C,updateMeasurementsFor:v,timeout:p}={...Wr,...o},m=ke(v??r),y=c.useCallback(()=>{if(!d.current){d.current=!0;return}h.current!=null&&clearTimeout(h.current),h.current=setTimeout(()=>{u(Array.isArray(m.current)?m.current:[m.current]),h.current=null},p)},[p]),b=rt({callback:y,disabled:C||!s}),R=c.useCallback((D,A)=>{b&&(A&&(b.unobserve(A),d.current=!1),D&&b.observe(D))},[b]),[S,E]=Je(R),x=ke(t);return c.useEffect(()=>{!b||!S.current||(b.disconnect(),d.current=!1,b.observe(S.current))},[S,b]),c.useEffect(()=>(a({type:O.RegisterDroppable,element:{id:r,key:i,disabled:n,node:S,rect:g,data:x}}),()=>a({type:O.UnregisterDroppable,key:i,id:r})),[r]),c.useEffect(()=>{n!==f.current.disabled&&(a({type:O.SetDroppableDisabled,id:r,key:i,disabled:n}),f.current.disabled=n)},[r,i,n,a]),{active:s,rect:g,isOver:l?.id===r,node:S,over:l,setNodeRef:E}}function dn(e,t,n){const r=e.slice();return r.splice(n<0?r.length+n:n,0,r.splice(t,1)[0]),r}function Kr(e,t){return e.reduce((n,r,o)=>{const i=t.get(r);return i&&(n[o]=i),n},Array(e.length))}function Ke(e){return e!==null&&e>=0}function Vr(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n{var t;let{rects:n,activeNodeRect:r,activeIndex:o,overIndex:i,index:s}=e;const a=(t=n[o])!=null?t:r;if(!a)return null;const l=Gr(n,s,o);if(s===o){const u=n[i];return u?{x:oo&&s<=i?{x:-a.width-l,y:0,...Ve}:s=i?{x:a.width+l,y:0,...Ve}:{x:0,y:0,...Ve}};function Gr(e,t,n){const r=e[t],o=e[t-1],i=e[t+1];return!r||!o&&!i?0:n{let{rects:t,activeIndex:n,overIndex:r,index:o}=e;const i=dn(t,r,n),s=t[o],a=i[o];return!a||!s?null:{x:a.left-s.left,y:a.top-s.top,scaleX:a.width/s.width,scaleY:a.height/s.height}},qe={scaleX:1,scaleY:1},ho=e=>{var t;let{activeIndex:n,activeNodeRect:r,index:o,rects:i,overIndex:s}=e;const a=(t=i[n])!=null?t:r;if(!a)return null;if(o===n){const u=i[s];return u?{x:0,y:nn&&o<=s?{x:0,y:-a.height-l,...qe}:o=s?{x:0,y:a.height+l,...qe}:{x:0,y:0,...qe}};function Jr(e,t,n){const r=e[t],o=e[t-1],i=e[t+1];return r?nr.map(E=>typeof E=="object"&&"id"in E?E.id:E),[r]),C=s!=null,v=s?h.indexOf(s.id):-1,p=u?h.indexOf(u.id):-1,m=c.useRef(h),y=!Vr(h,m.current),b=p!==-1&&v===-1||y,R=qr(i);Q(()=>{y&&C&&f(h)},[y,h,C,f]),c.useEffect(()=>{m.current=h},[h]);const S=c.useMemo(()=>({activeIndex:v,containerId:d,disabled:R,disableTransforms:b,items:h,overIndex:p,useDragOverlay:g,sortedRects:Kr(h,l),strategy:o}),[v,d,R.draggable,R.droppable,b,h,p,l,g,o]);return P.createElement(gn.Provider,{value:S},t)}const _r=e=>{let{id:t,items:n,activeIndex:r,overIndex:o}=e;return dn(n,r,o).indexOf(t)},Qr=e=>{let{containerId:t,isSorting:n,wasDragging:r,index:o,items:i,newIndex:s,previousItems:a,previousContainerId:l,transition:u}=e;return!u||!r||a!==i&&o===s?!1:n?!0:s!==o&&t===l},Zr={duration:200,easing:"ease"},vn="transform",eo=_e.Transition.toString({property:vn,duration:0,easing:"linear"}),to={roleDescription:"sortable"};function no(e){let{disabled:t,index:n,node:r,rect:o}=e;const[i,s]=c.useState(null),a=c.useRef(n);return Q(()=>{if(!t&&n!==a.current&&r.current){const l=o.current;if(l){const u=xe(r.current,{ignoreTransform:!0}),f={x:l.left-u.left,y:l.top-u.top,scaleX:l.width/u.width,scaleY:l.height/u.height};(f.x||f.y)&&s(f)}}n!==a.current&&(a.current=n)},[t,n,r,o]),c.useEffect(()=>{i&&s(null)},[i]),i}function vo(e){let{animateLayoutChanges:t=Qr,attributes:n,disabled:r,data:o,getNewIndex:i=_r,id:s,strategy:a,resizeObserverConfig:l,transition:u=Zr}=e;const{items:f,containerId:d,activeIndex:g,disabled:h,disableTransforms:C,sortedRects:v,overIndex:p,useDragOverlay:m,strategy:y}=c.useContext(gn),b=ro(r,h),R=f.indexOf(s),S=c.useMemo(()=>({sortable:{containerId:d,index:R,items:f},...o}),[d,o,R,f]),E=c.useMemo(()=>f.slice(f.indexOf(s)),[f,s]),{rect:x,node:D,isOver:A,setNodeRef:T}=Hr({id:s,data:S,disabled:b.droppable,resizeObserverConfig:{updateMeasurementsFor:E,...l}}),{active:M,activatorEvent:H,activeNodeRect:K,attributes:q,setNodeRef:De,listeners:Xe,isDragging:F,over:Ye,setActivatorNodeRef:Z,transform:Ce}=Yr({id:s,data:S,attributes:{...to,...n},disabled:b.draggable}),je=Sn(T,De),z=!!M,ee=z&&!C&&Ke(g)&&Ke(p),de=!m&&F,Re=de&&ee?Ce:null,Ue=ee?Re??(a??y)({rects:v,activeNodeRect:K,activeIndex:g,overIndex:p,index:R}):null,oe=Ke(g)&&Ke(p)?i({id:s,items:f,activeIndex:g,overIndex:p}):R,te=M?.id,I=c.useRef({activeId:te,items:f,newIndex:oe,containerId:d}),Se=f!==I.current.items,G=t({active:M,containerId:d,isDragging:F,isSorting:z,id:s,index:R,items:f,newIndex:I.current.newIndex,previousItems:I.current.items,previousContainerId:I.current.containerId,transition:u,wasDragging:I.current.activeId!=null}),fe=no({disabled:!G,index:R,node:D,rect:x});return c.useEffect(()=>{z&&I.current.newIndex!==oe&&(I.current.newIndex=oe),d!==I.current.containerId&&(I.current.containerId=d),f!==I.current.items&&(I.current.items=f)},[z,oe,d,f]),c.useEffect(()=>{if(te===I.current.activeId)return;if(te!=null&&I.current.activeId==null){I.current.activeId=te;return}const he=setTimeout(()=>{I.current.activeId=te},50);return()=>clearTimeout(he)},[te]),{active:M,activeIndex:g,attributes:q,data:S,rect:x,index:R,newIndex:oe,items:f,isOver:A,isSorting:z,isDragging:F,listeners:Xe,node:D,overIndex:p,over:Ye,setNodeRef:je,setActivatorNodeRef:Z,setDroppableNodeRef:T,setDraggableNodeRef:De,transform:fe??Ue,transition:ne()};function ne(){if(fe||Se&&I.current.newIndex===R)return eo;if(!(de&&!yt(H)||!u)&&(z||G))return _e.Transition.toString({...u,property:vn})}}function ro(e,t){var n,r;return typeof e=="boolean"?{draggable:e,droppable:!1}:{draggable:(n=e?.draggable)!=null?n:t.draggable,droppable:(r=e?.droppable)!=null?r:t.droppable}}function et(e){if(!e)return!1;const t=e.data.current;return!!(t&&"sortable"in t&&typeof t.sortable=="object"&&"containerId"in t.sortable&&"items"in t.sortable&&"index"in t.sortable)}const oo=[w.Down,w.Right,w.Up,w.Left],po=(e,t)=>{let{context:{active:n,collisionRect:r,droppableRects:o,droppableContainers:i,over:s,scrollableAncestors:a}}=t;if(oo.includes(e.code)){if(e.preventDefault(),!n||!r)return;const l=[];i.getEnabled().forEach(d=>{if(!d||d!=null&&d.disabled)return;const g=o.get(d.id);if(g)switch(e.code){case w.Down:r.topg.top&&l.push(d);break;case w.Left:r.left>g.left&&l.push(d);break;case w.Right:r.left1&&(f=u[1].id),f!=null){const d=i.get(n.id),g=i.get(f),h=g?o.get(g.id):null,C=g?.node.current;if(C&&h&&d&&g){const p=nt(C).some((E,x)=>a[x]!==E),m=pn(d,g),y=io(d,g),b=p||!m?{x:0,y:0}:{x:y?r.width-h.width:0,y:y?r.height-h.height:0},R={x:h.left,y:h.top};return b.x&&b.y?R:ze(R,b)}}}};function pn(e,t){return!et(e)||!et(t)?!1:e.data.current.sortable.containerId===t.data.current.sortable.containerId}function io(e,t){return!et(e)||!et(t)||!pn(e,t)?!1:e.data.current.sortable.indext.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),M=t=>t.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,c,o)=>o?o.toUpperCase():c.toLowerCase()),d=t=>{const a=M(t);return a.charAt(0).toUpperCase()+a.slice(1)},r=(...t)=>t.filter((a,c,o)=>!!a&&a.trim()!==""&&o.indexOf(a)===c).join(" ").trim(),x=t=>{for(const a in t)if(a.startsWith("aria-")||a==="role"||a==="title")return!0};var m={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const v=y.forwardRef(({color:t="currentColor",size:a=24,strokeWidth:c=2,absoluteStrokeWidth:o,className:s="",children:n,iconNode:k,...h},i)=>y.createElement("svg",{ref:i,...m,width:a,height:a,stroke:t,strokeWidth:o?Number(c)*24/Number(a):c,className:r("lucide",s),...!n&&!x(h)&&{"aria-hidden":"true"},...h},[...k.map(([p,l])=>y.createElement(p,l)),...Array.isArray(n)?n:[n]]));const e=(t,a)=>{const c=y.forwardRef(({className:o,...s},n)=>y.createElement(v,{ref:n,iconNode:a,className:r(`lucide-${_(d(t))}`,`lucide-${t}`,o),...s}));return c.displayName=d(t),c};const g=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],u2=e("activity",g);const u=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],f2=e("arrow-left",u);const f=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],w2=e("arrow-right",f);const w=[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]],N2=e("arrow-up-down",w);const N=[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]],$2=e("arrow-up",N);const $=[["path",{d:"M4.929 4.929 19.07 19.071",key:"196cmz"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],z2=e("ban",$);const z=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",key:"ruj8y"}]],q2=e("book-open",z);const q=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],b2=e("bot",q);const b=[["path",{d:"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",key:"lc1i9w"}],["path",{d:"m7 16.5-4.74-2.85",key:"1o9zyk"}],["path",{d:"m7 16.5 5-3",key:"va8pkn"}],["path",{d:"M7 16.5v5.17",key:"jnp8gn"}],["path",{d:"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z",key:"8zsnat"}],["path",{d:"m17 16.5-5-3",key:"8arw3v"}],["path",{d:"m17 16.5 4.74-2.85",key:"8rfmw"}],["path",{d:"M17 16.5v5.17",key:"k6z78m"}],["path",{d:"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z",key:"1xygjf"}],["path",{d:"M12 8 7.26 5.15",key:"1vbdud"}],["path",{d:"m12 8 4.74-2.85",key:"3rx089"}],["path",{d:"M12 13.5V8",key:"1io7kd"}]],C2=e("boxes",b);const C=[["path",{d:"M12 20v-9",key:"1qisl0"}],["path",{d:"M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z",key:"uouzyp"}],["path",{d:"M14.12 3.88 16 2",key:"qol33r"}],["path",{d:"M21 21a4 4 0 0 0-3.81-4",key:"1b0z45"}],["path",{d:"M21 5a4 4 0 0 1-3.55 3.97",key:"5cxbf6"}],["path",{d:"M22 13h-4",key:"1jl80f"}],["path",{d:"M3 21a4 4 0 0 1 3.81-4",key:"1fjd4g"}],["path",{d:"M3 5a4 4 0 0 0 3.55 3.97",key:"1d7oge"}],["path",{d:"M6 13H2",key:"82j7cp"}],["path",{d:"m8 2 1.88 1.88",key:"fmnt4t"}],["path",{d:"M9 7.13V6a3 3 0 1 1 6 0v1.13",key:"1vgav8"}]],j2=e("bug",C);const j=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]],A2=e("calendar",j);const A=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],L2=e("chart-column",A);const L=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],V2=e("check",L);const V=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],H2=e("chevron-down",V);const H=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],S2=e("chevron-left",H);const S=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],P2=e("chevron-right",S);const P=[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]],U2=e("chevron-up",P);const U=[["path",{d:"m11 17-5-5 5-5",key:"13zhaf"}],["path",{d:"m18 17-5-5 5-5",key:"h8a8et"}]],B2=e("chevrons-left",U);const B=[["path",{d:"m6 17 5-5-5-5",key:"xnjwq"}],["path",{d:"m13 17 5-5-5-5",key:"17xmmf"}]],D2=e("chevrons-right",B);const D=[["path",{d:"m7 15 5 5 5-5",key:"1hf1tw"}],["path",{d:"m7 9 5-5 5 5",key:"sgt6xg"}]],R2=e("chevrons-up-down",D);const R=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],T2=e("circle-alert",R);const T=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],E2=e("circle-check",T);const E=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],Z2=e("circle-question-mark",E);const Z=[["path",{d:"M18 20a6 6 0 0 0-12 0",key:"1qehca"}],["circle",{cx:"12",cy:"10",r:"4",key:"1h16sb"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],F2=e("circle-user-round",Z);const F=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}],["path",{d:"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662",key:"154egf"}]],G2=e("circle-user",F);const G=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],O2=e("circle-x",G);const O=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],I2=e("circle",O);const I=[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"M12 11h4",key:"1jrz19"}],["path",{d:"M12 16h4",key:"n85exb"}],["path",{d:"M8 11h.01",key:"1dfujw"}],["path",{d:"M8 16h.01",key:"18s6g9"}]],W2=e("clipboard-list",I);const W=[["path",{d:"M12 6v6l4 2",key:"mmk7yg"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],K2=e("clock",W);const K=[["path",{d:"m18 16 4-4-4-4",key:"1inbqp"}],["path",{d:"m6 8-4 4 4 4",key:"15zrgr"}],["path",{d:"m14.5 4-5 16",key:"e7oirm"}]],Q2=e("code-xml",K);const Q=[["path",{d:"M22 7.7c0-.6-.4-1.2-.8-1.5l-6.3-3.9a1.72 1.72 0 0 0-1.7 0l-10.3 6c-.5.2-.9.8-.9 1.4v6.6c0 .5.4 1.2.8 1.5l6.3 3.9a1.72 1.72 0 0 0 1.7 0l10.3-6c.5-.3.9-1 .9-1.5Z",key:"1t2lqe"}],["path",{d:"M10 21.9V14L2.1 9.1",key:"o7czzq"}],["path",{d:"m10 14 11.9-6.9",key:"zm5e20"}],["path",{d:"M14 19.8v-8.1",key:"159ecu"}],["path",{d:"M18 17.5V9.4",key:"11uown"}]],X2=e("container",Q);const X=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],J2=e("copy",X);const J=[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]],Y2=e("database",J);const Y=[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]],e0=e("dollar-sign",Y);const e1=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],a0=e("download",e1);const a1=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],t0=e("external-link",a1);const t1=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],c0=e("eye-off",t1);const c1=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],o0=e("eye",c1);const o1=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M12 17h.01",key:"p32p05"}],["path",{d:"M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3",key:"mhlwft"}]],n0=e("file-question-mark",o1);const n1=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["circle",{cx:"11.5",cy:"14.5",r:"2.5",key:"1bq0ko"}],["path",{d:"M13.3 16.3 15 18",key:"2quom7"}]],y0=e("file-search",n1);const y1=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]],s0=e("file-text",y1);const s1=[["path",{d:"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2",key:"usdka0"}]],h0=e("folder-open",s1);const h1=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],d0=e("funnel",h1);const d1=[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]],r0=e("git-branch",d1);const r1=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]],k0=e("globe",r1);const k1=[["path",{d:"M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0z",key:"j76jl0"}],["path",{d:"M22 10v6",key:"1lu8f3"}],["path",{d:"M6 12.5V16a6 3 0 0 0 12 0v-3.5",key:"1r8lef"}]],i0=e("graduation-cap",k1);const i1=[["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}],["circle",{cx:"9",cy:"5",r:"1",key:"hp0tcf"}],["circle",{cx:"9",cy:"19",r:"1",key:"fkjjf6"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"15",cy:"5",r:"1",key:"19l28e"}],["circle",{cx:"15",cy:"19",r:"1",key:"f4zoj3"}]],p0=e("grip-vertical",i1);const p1=[["line",{x1:"22",x2:"2",y1:"12",y2:"12",key:"1y58io"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}],["line",{x1:"6",x2:"6.01",y1:"16",y2:"16",key:"sgf278"}],["line",{x1:"10",x2:"10.01",y1:"16",y2:"16",key:"1l4acy"}]],l0=e("hard-drive",p1);const l1=[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]],_0=e("hash",l1);const _1=[["path",{d:"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",key:"mvr1a0"}]],M0=e("heart",_1);const M1=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"r6nss1"}]],x0=e("house",M1);const x1=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2",key:"1m3agn"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",key:"1xmnt7"}]],m0=e("image",x1);const m1=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],v0=e("info",m1);const v1=[["path",{d:"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",key:"g0fldk"}],["path",{d:"m21 2-9.6 9.6",key:"1j0ho8"}],["circle",{cx:"7.5",cy:"15.5",r:"5.5",key:"yqb3hr"}]],g0=e("key",v1);const g1=[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]],u0=e("layers",g1);const u1=[["rect",{width:"7",height:"7",x:"3",y:"3",rx:"1",key:"1g98yp"}],["rect",{width:"7",height:"7",x:"14",y:"3",rx:"1",key:"6d4xhi"}],["rect",{width:"7",height:"7",x:"14",y:"14",rx:"1",key:"nxv5o0"}],["rect",{width:"7",height:"7",x:"3",y:"14",rx:"1",key:"1bb6yr"}]],f0=e("layout-grid",u1);const f1=[["path",{d:"M13 5h8",key:"a7qcls"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 19h8",key:"c3s6r1"}],["path",{d:"m3 17 2 2 4-4",key:"1jhpwq"}],["path",{d:"m3 7 2 2 4-4",key:"1obspn"}]],w0=e("list-checks",f1);const w1=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],N0=e("loader-circle",w1);const N1=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]],$0=e("lock",N1);const $1=[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]],z0=e("log-out",$1);const z1=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],q0=e("menu",z1);const q1=[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]],b0=e("message-circle",q1);const b1=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]],C0=e("message-square",b1);const C1=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],j0=e("moon",C1);const j1=[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]],A0=e("network",j1);const A1=[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["polyline",{points:"3.29 7 12 12 20.71 7",key:"ousv84"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]],L0=e("package",A1);const L1=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],V0=e("palette",L1);const V1=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M9 21V9",key:"1oto5p"}]],H0=e("panels-top-left",V1);const H1=[["rect",{x:"14",y:"3",width:"5",height:"18",rx:"1",key:"kaeet6"}],["rect",{x:"5",y:"3",width:"5",height:"18",rx:"1",key:"1wsw3u"}]],S0=e("pause",H1);const S1=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]],P0=e("pen",S1);const P1=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],U0=e("pencil",P1);const U1=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],B0=e("play",U1);const B1=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],D0=e("plus",B1);const D1=[["path",{d:"M12 2v10",key:"mnfbl"}],["path",{d:"M18.4 6.6a9 9 0 1 1-12.77.04",key:"obofu9"}]],R0=e("power",D1);const R1=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],T0=e("puzzle",R1);const T1=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],E0=e("refresh-cw",T1);const E1=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],Z0=e("rotate-ccw",E1);const Z1=[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]],F0=e("rotate-cw",Z1);const F1=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],G0=e("save",F1);const G1=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],O0=e("search",G1);const O1=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]],I0=e("send",O1);const I1=[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]],W0=e("server",I1);const W1=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],K0=e("settings-2",W1);const K1=[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],Q0=e("settings",K1);const Q1=[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]],X0=e("share-2",Q1);const X1=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],J0=e("shield",X1);const J1=[["path",{d:"M21 4v16",key:"7j8fe9"}],["path",{d:"M6.029 4.285A2 2 0 0 0 3 6v12a2 2 0 0 0 3.029 1.715l9.997-5.998a2 2 0 0 0 .003-3.432z",key:"zs4d6"}]],Y0=e("skip-forward",J1);const Y1=[["path",{d:"M10 8h4",key:"1sr2af"}],["path",{d:"M12 21v-9",key:"17s77i"}],["path",{d:"M12 8V3",key:"13r4qs"}],["path",{d:"M17 16h4",key:"h1uq16"}],["path",{d:"M19 12V3",key:"o1uvq1"}],["path",{d:"M19 21v-5",key:"qua636"}],["path",{d:"M3 14h4",key:"bcjad9"}],["path",{d:"M5 10V3",key:"cb8scm"}],["path",{d:"M5 21v-7",key:"1w1uti"}]],ee=e("sliders-vertical",Y1);const e2=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 14s1.5 2 4 2 4-2 4-2",key:"1y1vjs"}],["line",{x1:"9",x2:"9.01",y1:"9",y2:"9",key:"yxxnd0"}],["line",{x1:"15",x2:"15.01",y1:"9",y2:"9",key:"1p4y9e"}]],ae=e("smile",e2);const a2=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],te=e("sparkles",a2);const t2=[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]],ce=e("square-pen",t2);const c2=[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]],oe=e("star",c2);const o2=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],ne=e("sun",o2);const n2=[["path",{d:"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z",key:"vktsd0"}],["circle",{cx:"7.5",cy:"7.5",r:".5",fill:"currentColor",key:"kqv944"}]],ye=e("tag",n2);const y2=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],se=e("terminal",y2);const s2=[["path",{d:"M17 14V2",key:"8ymqnk"}],["path",{d:"M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z",key:"m61m77"}]],he=e("thumbs-down",s2);const h2=[["path",{d:"M7 10v12",key:"1qc93n"}],["path",{d:"M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z",key:"emmmcr"}]],de=e("thumbs-up",h2);const d2=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],re=e("trash-2",d2);const r2=[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]],ke=e("trending-up",r2);const k2=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],ie=e("triangle-alert",k2);const i2=[["path",{d:"M12 4v16",key:"1654pz"}],["path",{d:"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2",key:"e0r10z"}],["path",{d:"M9 20h6",key:"s66wpe"}]],pe=e("type",i2);const p2=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],le=e("upload",p2);const l2=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],_e=e("user",l2);const _2=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],Me=e("users",_2);const M2=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],xe=e("wifi-off",M2);const x2=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],me=e("wifi",x2);const m2=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],ve=e("x",m2);const v2=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],ge=e("zap",v2);export{H0 as $,u2 as A,b2 as B,T2 as C,e0 as D,c0 as E,s0 as F,O0 as G,l0 as H,v0 as I,x0 as J,g0 as K,N0 as L,C0 as M,f2 as N,D0 as O,R0 as P,H2 as Q,E0 as R,Q0 as S,ke as T,le as U,U2 as V,y0 as W,ve as X,p0 as Y,ge as Z,G0 as _,Z0 as a,Q2 as a0,U0 as a1,B2 as a2,S2 as a3,P2 as a4,D2 as a5,R2 as a6,X0 as a7,L0 as a8,W0 as a9,F2 as aA,me as aB,xe as aC,P0 as aD,I0 as aE,I2 as aF,n0 as aG,M0 as aH,N2 as aI,C2 as aJ,G2 as aK,L2 as aL,$2 as aM,ee as aN,q0 as aO,q2 as aP,z0 as aQ,j2 as aR,u0 as aa,w0 as ab,ye as ac,i0 as ad,X2 as ae,h0 as af,m0 as ag,d0 as ah,ce as ai,z2 as aj,_0 as ak,b0 as al,k0 as am,Me as an,A0 as ao,S0 as ap,B0 as aq,A2 as ar,pe as as,F0 as at,K0 as au,oe as av,f0 as aw,de as ax,he as ay,r0 as az,E2 as b,T0 as c,W2 as d,Y2 as e,K2 as f,V0 as g,J0 as h,ie as i,V2 as j,J2 as k,o0 as l,O2 as m,re as n,a0 as o,ne as p,j0 as q,$0 as r,Z2 as s,se as t,t0 as u,te as v,_e as w,ae as x,Y0 as y,w2 as z}; diff --git a/webui/dist/assets/icons-D6w7t-x9.js b/webui/dist/assets/icons-D6w7t-x9.js deleted file mode 100644 index 2cac469f..00000000 --- a/webui/dist/assets/icons-D6w7t-x9.js +++ /dev/null @@ -1 +0,0 @@ -import{r as s}from"./router-BWgTyY51.js";const _=t=>t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),M=t=>t.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,o,c)=>c?c.toUpperCase():o.toLowerCase()),d=t=>{const a=M(t);return a.charAt(0).toUpperCase()+a.slice(1)},r=(...t)=>t.filter((a,o,c)=>!!a&&a.trim()!==""&&c.indexOf(a)===o).join(" ").trim(),m=t=>{for(const a in t)if(a.startsWith("aria-")||a==="role"||a==="title")return!0};var v={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const x=s.forwardRef(({color:t="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:c,className:y="",children:n,iconNode:k,...h},i)=>s.createElement("svg",{ref:i,...v,width:a,height:a,stroke:t,strokeWidth:c?Number(o)*24/Number(a):o,className:r("lucide",y),...!n&&!m(h)&&{"aria-hidden":"true"},...h},[...k.map(([p,l])=>s.createElement(p,l)),...Array.isArray(n)?n:[n]]));const e=(t,a)=>{const o=s.forwardRef(({className:c,...y},n)=>s.createElement(x,{ref:n,iconNode:a,className:r(`lucide-${_(d(t))}`,`lucide-${t}`,c),...y}));return o.displayName=d(t),o};const u=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],W1=e("activity",u);const g=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],X1=e("arrow-left",g);const $=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],Q1=e("arrow-right",$);const N=[["path",{d:"M4.929 4.929 19.07 19.071",key:"196cmz"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],G1=e("ban",N);const f=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",key:"ruj8y"}]],J1=e("book-open",f);const w=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],Y1=e("bot",w);const z=[["path",{d:"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",key:"lc1i9w"}],["path",{d:"m7 16.5-4.74-2.85",key:"1o9zyk"}],["path",{d:"m7 16.5 5-3",key:"va8pkn"}],["path",{d:"M7 16.5v5.17",key:"jnp8gn"}],["path",{d:"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z",key:"8zsnat"}],["path",{d:"m17 16.5-5-3",key:"8arw3v"}],["path",{d:"m17 16.5 4.74-2.85",key:"8rfmw"}],["path",{d:"M17 16.5v5.17",key:"k6z78m"}],["path",{d:"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z",key:"1xygjf"}],["path",{d:"M12 8 7.26 5.15",key:"1vbdud"}],["path",{d:"m12 8 4.74-2.85",key:"3rx089"}],["path",{d:"M12 13.5V8",key:"1io7kd"}]],e2=e("boxes",z);const C=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]],a2=e("calendar",C);const b=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],t2=e("chart-column",b);const q=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],o2=e("check",q);const A=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],c2=e("chevron-down",A);const j=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],n2=e("chevron-left",j);const H=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],s2=e("chevron-right",H);const V=[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]],y2=e("chevron-up",V);const L=[["path",{d:"m11 17-5-5 5-5",key:"13zhaf"}],["path",{d:"m18 17-5-5 5-5",key:"h8a8et"}]],h2=e("chevrons-left",L);const S=[["path",{d:"m6 17 5-5-5-5",key:"xnjwq"}],["path",{d:"m13 17 5-5-5-5",key:"17xmmf"}]],d2=e("chevrons-right",S);const P=[["path",{d:"m7 15 5 5 5-5",key:"1hf1tw"}],["path",{d:"m7 9 5-5 5 5",key:"sgt6xg"}]],r2=e("chevrons-up-down",P);const U=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],k2=e("circle-alert",U);const R=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],i2=e("circle-check",R);const T=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],p2=e("circle-question-mark",T);const Z=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}],["path",{d:"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662",key:"154egf"}]],l2=e("circle-user",Z);const E=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],_2=e("circle-x",E);const B=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],M2=e("circle",B);const D=[["path",{d:"M12 6v6l4 2",key:"mmk7yg"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],m2=e("clock",D);const F=[["path",{d:"m18 16 4-4-4-4",key:"1inbqp"}],["path",{d:"m6 8-4 4 4 4",key:"15zrgr"}],["path",{d:"m14.5 4-5 16",key:"e7oirm"}]],v2=e("code-xml",F);const O=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],x2=e("copy",O);const I=[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]],u2=e("database",I);const K=[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]],g2=e("dollar-sign",K);const W=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],$2=e("download",W);const X=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],N2=e("external-link",X);const Q=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],f2=e("eye-off",Q);const G=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],w2=e("eye",G);const J=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["circle",{cx:"11.5",cy:"14.5",r:"2.5",key:"1bq0ko"}],["path",{d:"M13.3 16.3 15 18",key:"2quom7"}]],z2=e("file-search",J);const Y=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]],C2=e("file-text",Y);const e1=[["path",{d:"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2",key:"usdka0"}]],b2=e("folder-open",e1);const a1=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],q2=e("funnel",a1);const t1=[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]],A2=e("hash",t1);const o1=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"r6nss1"}]],j2=e("house",o1);const c1=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],H2=e("info",c1);const n1=[["path",{d:"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",key:"g0fldk"}],["path",{d:"m21 2-9.6 9.6",key:"1j0ho8"}],["circle",{cx:"7.5",cy:"15.5",r:"5.5",key:"yqb3hr"}]],V2=e("key",n1);const s1=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],L2=e("loader-circle",s1);const y1=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]],S2=e("lock",y1);const h1=[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]],P2=e("log-out",h1);const d1=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],U2=e("menu",d1);const r1=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]],R2=e("message-square",r1);const k1=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],T2=e("moon",k1);const i1=[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["polyline",{points:"3.29 7 12 12 20.71 7",key:"ousv84"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]],Z2=e("package",i1);const p1=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],E2=e("palette",p1);const l1=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M9 21V9",key:"1oto5p"}]],B2=e("panels-top-left",l1);const _1=[["rect",{x:"14",y:"3",width:"5",height:"18",rx:"1",key:"kaeet6"}],["rect",{x:"5",y:"3",width:"5",height:"18",rx:"1",key:"1wsw3u"}]],D2=e("pause",_1);const M1=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],F2=e("pencil",M1);const m1=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],O2=e("play",m1);const v1=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],I2=e("plus",v1);const x1=[["path",{d:"M12 2v10",key:"mnfbl"}],["path",{d:"M18.4 6.6a9 9 0 1 1-12.77.04",key:"obofu9"}]],K2=e("power",x1);const u1=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],W2=e("refresh-cw",u1);const g1=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],X2=e("rotate-ccw",g1);const $1=[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]],Q2=e("rotate-cw",$1);const N1=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],G2=e("save",N1);const f1=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],J2=e("search",f1);const w1=[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]],Y2=e("server",w1);const z1=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],e0=e("settings-2",z1);const C1=[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],a0=e("settings",C1);const b1=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],t0=e("shield",b1);const q1=[["path",{d:"M21 4v16",key:"7j8fe9"}],["path",{d:"M6.029 4.285A2 2 0 0 0 3 6v12a2 2 0 0 0 3.029 1.715l9.997-5.998a2 2 0 0 0 .003-3.432z",key:"zs4d6"}]],o0=e("skip-forward",q1);const A1=[["path",{d:"M10 8h4",key:"1sr2af"}],["path",{d:"M12 21v-9",key:"17s77i"}],["path",{d:"M12 8V3",key:"13r4qs"}],["path",{d:"M17 16h4",key:"h1uq16"}],["path",{d:"M19 12V3",key:"o1uvq1"}],["path",{d:"M19 21v-5",key:"qua636"}],["path",{d:"M3 14h4",key:"bcjad9"}],["path",{d:"M5 10V3",key:"cb8scm"}],["path",{d:"M5 21v-7",key:"1w1uti"}]],c0=e("sliders-vertical",A1);const j1=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 14s1.5 2 4 2 4-2 4-2",key:"1y1vjs"}],["line",{x1:"9",x2:"9.01",y1:"9",y2:"9",key:"yxxnd0"}],["line",{x1:"15",x2:"15.01",y1:"9",y2:"9",key:"1p4y9e"}]],n0=e("smile",j1);const H1=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],s0=e("sparkles",H1);const V1=[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]],y0=e("square-pen",V1);const L1=[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]],h0=e("star",L1);const S1=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],d0=e("sun",S1);const P1=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],r0=e("terminal",P1);const U1=[["path",{d:"M7 10v12",key:"1qc93n"}],["path",{d:"M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z",key:"emmmcr"}]],k0=e("thumbs-up",U1);const R1=[["path",{d:"M17 14V2",key:"8ymqnk"}],["path",{d:"M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z",key:"m61m77"}]],i0=e("thumbs-down",R1);const T1=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],p0=e("trash-2",T1);const Z1=[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]],l0=e("trending-up",Z1);const E1=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],_0=e("triangle-alert",E1);const B1=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],M0=e("upload",B1);const D1=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],m0=e("user",D1);const F1=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],v0=e("users",F1);const O1=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],x0=e("x",O1);const I1=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],u0=e("zap",I1);export{r2 as $,W1 as A,Y1 as B,m2 as C,g2 as D,f2 as E,C2 as F,K2 as G,j2 as H,H2 as I,I2 as J,V2 as K,S2 as L,R2 as M,p0 as N,z2 as O,E2 as P,F2 as Q,W2 as R,t0 as S,l0 as T,m0 as U,h2 as V,n2 as W,x0 as X,s2 as Y,u0 as Z,d2 as _,u2 as a,M0 as a0,b2 as a1,$2 as a2,q2 as a3,y0 as a4,G1 as a5,A2 as a6,v0 as a7,a2 as a8,D2 as a9,O2 as aa,h0 as ab,k0 as ac,i0 as ad,e0 as ae,N2 as af,Z2 as ag,Y2 as ah,e2 as ai,l2 as aj,t2 as ak,M2 as al,c0 as am,U2 as an,J1 as ao,P2 as ap,Q2 as aq,a0 as b,_0 as c,o2 as d,x2 as e,w2 as f,i2 as g,_2 as h,X2 as i,d0 as j,T2 as k,k2 as l,p2 as m,r0 as n,s0 as o,n0 as p,o0 as q,Q1 as r,J2 as s,X1 as t,c2 as u,y2 as v,L2 as w,B2 as x,v2 as y,G2 as z}; diff --git a/webui/dist/assets/index-BmybQ2BG.css b/webui/dist/assets/index-BmybQ2BG.css deleted file mode 100644 index bb6e4a9a..00000000 --- a/webui/dist/assets/index-BmybQ2BG.css +++ /dev/null @@ -1 +0,0 @@ -*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--primary: 221.2 83.2% 53.3%;--primary-foreground: 210 40% 98%;--primary-gradient: none;--secondary: 210 40% 96.1%;--secondary-foreground: 222.2 47.4% 11.2%;--muted: 210 40% 96.1%;--muted-foreground: 215.4 16.3% 46.9%;--accent: 210 40% 96.1%;--accent-foreground: 222.2 47.4% 11.2%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;--border: 214.3 31.8% 91.4%;--input: 214.3 31.8% 91.4%;--ring: 221.2 83.2% 53.3%;--radius: .5rem;--chart-1: 221.2 83.2% 53.3%;--chart-2: 160 60% 45%;--chart-3: 30 80% 55%;--chart-4: 280 65% 60%;--chart-5: 340 75% 55%}.dark{--background: 222.2 84% 4.9%;--foreground: 210 40% 98%;--card: 222.2 84% 4.9%;--card-foreground: 210 40% 98%;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--primary: 217.2 91.2% 59.8%;--primary-foreground: 222.2 47.4% 11.2%;--primary-gradient: none;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 215 20.2% 65.1%;--accent: 217.2 32.6% 17.5%;--accent-foreground: 210 40% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 210 40% 98%;--border: 217.2 32.6% 17.5%;--input: 217.2 32.6% 17.5%;--ring: 224.3 76.3% 48%;--chart-1: 217.2 91.2% 59.8%;--chart-2: 160 60% 50%;--chart-3: 30 80% 60%;--chart-4: 280 65% 65%;--chart-5: 340 75% 60%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.invisible{visibility:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.bottom-1\/4{bottom:25%}.bottom-4{bottom:1rem}.left-0{left:0}.left-1\/2{left:50%}.left-1\/4{left:25%}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-\[50\%\]{left:50%}.right-0{right:0}.right-1{right:.25rem}.right-1\.5{right:.375rem}.right-1\/4{right:25%}.right-2{right:.5rem}.right-4{right:1rem}.top-0{top:0}.top-1{top:.25rem}.top-1\.5{top:.375rem}.top-1\/2{top:50%}.top-1\/4{top:25%}.top-2{top:.5rem}.top-2\.5{top:.625rem}.top-3{top:.75rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.order-1{order:1}.order-2{order:2}.col-span-2{grid-column:span 2 / span 2}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.-mt-2{margin-top:-.5rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-auto{aspect-ratio:auto}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.size-4{width:1rem;height:1rem}.size-\[--cell-size\]{width:var(--cell-size);height:var(--cell-size)}.h-0\.5{height:.125rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-60{height:15rem}.h-64{height:16rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[--cell-size\]{height:var(--cell-size)}.h-\[1\.25rem\]{height:1.25rem}.h-\[1px\]{height:1px}.h-\[250px\]{height:250px}.h-\[300px\]{height:300px}.h-\[400px\]{height:400px}.h-\[calc\(100vh-200px\)\]{height:calc(100vh - 200px)}.h-\[calc\(100vh-240px\)\]{height:calc(100vh - 240px)}.h-\[calc\(100vh-260px\)\]{height:calc(100vh - 260px)}.h-\[calc\(100vh-280px\)\]{height:calc(100vh - 280px)}.h-\[calc\(100vh-4rem\)\]{height:calc(100vh - 4rem)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\[--radix-context-menu-content-available-height\]{max-height:var(--radix-context-menu-content-available-height)}.max-h-\[--radix-select-content-available-height\]{max-height:var(--radix-select-content-available-height)}.max-h-\[300px\]{max-height:300px}.max-h-\[80vh\]{max-height:80vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(90vh-120px\)\]{max-height:calc(90vh - 120px)}.max-h-\[calc\(90vh-8rem\)\]{max-height:calc(90vh - 8rem)}.max-h-screen{max-height:100vh}.min-h-10{min-height:2.5rem}.min-h-\[100px\]{min-height:100px}.min-h-\[300px\]{min-height:300px}.min-h-\[60px\]{min-height:60px}.min-h-screen{min-height:100vh}.w-0{width:0px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-1\/4{width:25%}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-72{width:18rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-96{width:24rem}.w-\[--cell-size\]{width:var(--cell-size)}.w-\[120px\]{width:120px}.w-\[140px\]{width:140px}.w-\[1px\]{width:1px}.w-\[70px\]{width:70px}.w-\[95vw\]{width:95vw}.w-auto{width:auto}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[--cell-size\]{min-width:var(--cell-size)}.min-w-\[80px\]{min-width:80px}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-\[200px\]{max-width:200px}.max-w-\[60px\]{max-width:60px}.max-w-\[95vw\]{max-width:95vw}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.origin-\[--radix-context-menu-content-transform-origin\]{transform-origin:var(--radix-context-menu-content-transform-origin)}.origin-\[--radix-popover-content-transform-origin\]{transform-origin:var(--radix-popover-content-transform-origin)}.origin-\[--radix-select-content-transform-origin\]{transform-origin:var(--radix-select-content-transform-origin)}.origin-\[--radix-tooltip-content-transform-origin\]{transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.resize{resize:both}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.rounded-l-md{border-top-left-radius:calc(var(--radius) - 2px);border-bottom-left-radius:calc(var(--radius) - 2px)}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.rounded-r-md{border-top-right-radius:calc(var(--radius) - 2px);border-bottom-right-radius:calc(var(--radius) - 2px)}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-4{border-width:4px}.border-\[1\.5px\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[--color-border\]{border-color:var(--color-border)}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border) / .5)}.border-current{border-color:currentColor}.border-gray-800{--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.border-input{border-color:hsl(var(--input))}.border-muted{border-color:hsl(var(--muted))}.border-orange-600{--tw-border-opacity: 1;border-color:rgb(234 88 12 / var(--tw-border-opacity, 1))}.border-primary{border-color:hsl(var(--primary))}.border-primary\/20{border-color:hsl(var(--primary) / .2)}.border-primary\/30{border-color:hsl(var(--primary) / .3)}.border-primary\/50{border-color:hsl(var(--primary) / .5)}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-yellow-200{--tw-border-opacity: 1;border-color:rgb(254 240 138 / var(--tw-border-opacity, 1))}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-\[--color-bg\]{background-color:var(--color-bg)}.bg-accent{background-color:hsl(var(--accent))}.bg-background{background-color:hsl(var(--background))}.bg-background\/50{background-color:hsl(var(--background) / .5)}.bg-background\/95{background-color:hsl(var(--background) / .95)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-black\/80{background-color:#000c}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-900\/20{background-color:#1e3a8a33}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-card\/80{background-color:hsl(var(--card) / .8)}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-800\/20{background-color:#1f293733}.bg-gray-800\/30{background-color:#1f29374d}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-orange-50{--tw-bg-opacity: 1;background-color:rgb(255 247 237 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-orange-600{--tw-bg-opacity: 1;background-color:rgb(234 88 12 / var(--tw-bg-opacity, 1))}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/20{background-color:hsl(var(--primary) / .2)}.bg-primary\/5{background-color:hsl(var(--primary) / .05)}.bg-purple-500{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-red-900\/20{background-color:#7f1d1d33}.bg-red-900\/30{background-color:#7f1d1d4d}.bg-secondary{background-color:hsl(var(--secondary))}.bg-secondary\/5{background-color:hsl(var(--secondary) / .05)}.bg-slate-200{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.bg-slate-300{--tw-bg-opacity: 1;background-color:rgb(203 213 225 / var(--tw-bg-opacity, 1))}.bg-slate-400{--tw-bg-opacity: 1;background-color:rgb(148 163 184 / var(--tw-bg-opacity, 1))}.bg-slate-700{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-200{--tw-bg-opacity: 1;background-color:rgb(254 240 138 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-yellow-900\/20{background-color:#713f1233}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-blue-500{--tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-500{--tw-gradient-from: #22c55e var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-500{--tw-gradient-from: #f97316 var(--tw-gradient-from-position);--tw-gradient-to: rgb(249 115 22 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-primary\/5{--tw-gradient-from: hsl(var(--primary) / .05) var(--tw-gradient-from-position);--tw-gradient-to: hsl(var(--primary) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-500{--tw-gradient-from: #ef4444 var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 68 68 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-200{--tw-gradient-from: #e2e8f0 var(--tw-gradient-from-position);--tw-gradient-to: rgb(226 232 240 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-300{--tw-gradient-from: #cbd5e1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(203 213 225 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-400{--tw-gradient-from: #94a3b8 var(--tw-gradient-from-position);--tw-gradient-to: rgb(148 163 184 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-background{--tw-gradient-to: hsl(var(--background) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), hsl(var(--background)) var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-cyan-500{--tw-gradient-to: #06b6d4 var(--tw-gradient-to-position)}.to-emerald-500{--tw-gradient-to: #10b981 var(--tw-gradient-to-position)}.to-orange-500{--tw-gradient-to: #f97316 var(--tw-gradient-to-position)}.to-pink-500{--tw-gradient-to: #ec4899 var(--tw-gradient-to-position)}.to-primary\/10{--tw-gradient-to: hsl(var(--primary) / .1) var(--tw-gradient-to-position)}.to-purple-500{--tw-gradient-to: #a855f7 var(--tw-gradient-to-position)}.to-secondary\/5{--tw-gradient-to: hsl(var(--secondary) / .05) var(--tw-gradient-to-position)}.to-slate-700{--tw-gradient-to: #334155 var(--tw-gradient-to-position)}.to-slate-800{--tw-gradient-to: #1e293b var(--tw-gradient-to-position)}.to-slate-900{--tw-gradient-to: #0f172a var(--tw-gradient-to-position)}.fill-current{fill:currentColor}.fill-yellow-400{fill:#facc15}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-\[1px\]{padding:1px}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[--cell-size\]{padding-left:var(--cell-size);padding-right:var(--cell-size)}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0{padding-bottom:0}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pl-10{padding-left:2.5rem}.pl-11{padding-left:2.75rem}.pl-2{padding-left:.5rem}.pl-4{padding-left:1rem}.pl-6{padding-left:1.5rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-1{padding-right:.25rem}.pr-10{padding-right:2.5rem}.pr-16{padding-right:4rem}.pr-2{padding-right:.5rem}.pr-4{padding-right:1rem}.pr-6{padding-right:1.5rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[10px\]{font-size:10px}.text-\[150px\]{font-size:150px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-blue-900{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-foreground\/50{color:hsl(var(--foreground) / .5)}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/50{color:hsl(var(--muted-foreground) / .5)}.text-muted-foreground\/60{color:hsl(var(--muted-foreground) / .6)}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-orange-800{--tw-text-opacity: 1;color:rgb(154 52 18 / var(--tw-text-opacity, 1))}.text-orange-900{--tw-text-opacity: 1;color:rgb(124 45 18 / var(--tw-text-opacity, 1))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-primary\/10{color:hsl(var(--primary) / .1)}.text-primary\/30{color:hsl(var(--primary) / .3)}.text-primary\/60{color:hsl(var(--primary) / .6)}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-800{--tw-text-opacity: 1;color:rgb(133 77 14 / var(--tw-text-opacity, 1))}.text-yellow-900{--tw-text-opacity: 1;color:rgb(113 63 18 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.blur-3xl{--tw-blur: blur(64px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.text-primary-gradient{color:hsl(var(--primary))}.has-gradient .text-primary-gradient{background:var(--primary-gradient);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}.\[--cell-size\:2rem\]{--cell-size: 2rem}.no-animations *,.no-animations *:before,.no-animations *:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}.no-animations *:hover{transition-duration:.01ms!important}::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}::view-transition-old(root){z-index:1}::view-transition-new(root){z-index:999}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:text-foreground::file-selector-button{color:hsl(var(--foreground))}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:border-primary\/50:hover{border-color:hsl(var(--primary) / .5)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-accent\/50:hover{background-color:hsl(var(--accent) / .5)}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-orange-700:hover{--tw-bg-opacity: 1;background-color:rgb(194 65 12 / var(--tw-bg-opacity, 1))}.hover\:bg-primary\/80:hover{background-color:hsl(var(--primary) / .8)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-secondary:hover{background-color:hsl(var(--secondary))}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:bg-secondary\/90:hover{background-color:hsl(var(--secondary) / .9)}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-primary\/80:hover{color:hsl(var(--primary) / .8)}.hover\:text-yellow-300:hover{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:bg-gray-100:focus{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-0:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-red-500:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background))}.active\:border-primary\/70:active{border-color:hsl(var(--primary) / .7)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group[open] .group-open\:rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:opacity-100{opacity:1}.group.destructive .group-\[\.destructive\]\:border-muted\/40{border-color:hsl(var(--muted) / .4)}.group.destructive .group-\[\.destructive\]\:text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:text-red-50:hover{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-red-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-offset-red-600:focus{--tw-ring-offset-color: #dc2626}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}.aria-selected\:text-muted-foreground[aria-selected=true]{color:hsl(var(--muted-foreground))}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true],.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=checked\]\:translate-x-4[data-state=checked]{--tw-translate-x: 1rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked],.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe=end]{--tw-translate-x: var(--radix-toast-swipe-end-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move]{--tw-translate-x: var(--radix-toast-swipe-move-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[range-end\=true\]\:rounded-md[data-range-end=true]{border-radius:calc(var(--radius) - 2px)}.data-\[range-middle\=true\]\:rounded-none[data-range-middle=true]{border-radius:0}.data-\[range-start\=true\]\:rounded-md[data-range-start=true]{border-radius:calc(var(--radius) - 2px)}.data-\[selected\=true\]\:rounded-none[data-selected=true]{border-radius:0}.data-\[range-end\=true\]\:bg-primary[data-range-end=true]{background-color:hsl(var(--primary))}.data-\[range-middle\=true\]\:bg-accent[data-range-middle=true]{background-color:hsl(var(--accent))}.data-\[range-start\=true\]\:bg-primary[data-range-start=true],.data-\[selected-single\=true\]\:bg-primary[data-selected-single=true]{background-color:hsl(var(--primary))}.data-\[selected\=true\]\:bg-accent[data-selected=true]{background-color:hsl(var(--accent))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:hsl(var(--muted-foreground))}.data-\[range-end\=true\]\:text-primary-foreground[data-range-end=true]{color:hsl(var(--primary-foreground))}.data-\[range-middle\=true\]\:text-accent-foreground[data-range-middle=true]{color:hsl(var(--accent-foreground))}.data-\[range-start\=true\]\:text-primary-foreground[data-range-start=true],.data-\[selected-single\=true\]\:text-primary-foreground[data-selected-single=true]{color:hsl(var(--primary-foreground))}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:hsl(var(--accent-foreground))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[state\=open\]\:text-accent-foreground[data-state=open]{color:hsl(var(--accent-foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[disabled\=true\]\:opacity-50[data-disabled=true],.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[swipe\=move\]\:transition-none[data-swipe=move]{transition-property:none}.data-\[state\=active\]\:duration-300[data-state=active]{transition-duration:.3s}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:relative{position:relative}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:z-10{z-index:10}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:border-ring{border-color:hsl(var(--ring))}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-\[3px\]{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-ring\/50{--tw-ring-color: hsl(var(--ring) / .5)}.dark\:border-blue-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 64 175 / var(--tw-border-opacity, 1))}.dark\:border-blue-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 58 138 / var(--tw-border-opacity, 1))}.dark\:border-gray-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(17 24 39 / var(--tw-border-opacity, 1))}.dark\:border-yellow-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(113 63 18 / var(--tw-border-opacity, 1))}.dark\:bg-blue-500\/20:is(.dark *){background-color:#3b82f633}.dark\:bg-blue-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 58 138 / var(--tw-bg-opacity, 1))}.dark\:bg-blue-950\/20:is(.dark *){background-color:#17255433}.dark\:bg-blue-950\/30:is(.dark *){background-color:#1725544d}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800\/30:is(.dark *){background-color:#1f29374d}.dark\:bg-gray-800\/50:is(.dark *){background-color:#1f293780}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-orange-950\/20:is(.dark *){background-color:#43140733}.dark\:bg-red-500\/20:is(.dark *){background-color:#ef444433}.dark\:bg-red-600\/30:is(.dark *){background-color:#dc26264d}.dark\:bg-red-950\/50:is(.dark *){background-color:#450a0a80}.dark\:bg-yellow-500\/20:is(.dark *){background-color:#eab30833}.dark\:bg-yellow-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(113 63 18 / var(--tw-bg-opacity, 1))}.dark\:bg-yellow-950\/30:is(.dark *){background-color:#4220064d}.dark\:text-blue-100:is(.dark *){--tw-text-opacity: 1;color:rgb(219 234 254 / var(--tw-text-opacity, 1))}.dark\:text-blue-200:is(.dark *){--tw-text-opacity: 1;color:rgb(191 219 254 / var(--tw-text-opacity, 1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-cyan-500:is(.dark *){--tw-text-opacity: 1;color:rgb(6 182 212 / var(--tw-text-opacity, 1))}.dark\:text-gray-100:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-gray-600:is(.dark *){--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-orange-100:is(.dark *){--tw-text-opacity: 1;color:rgb(255 237 213 / var(--tw-text-opacity, 1))}.dark\:text-orange-200:is(.dark *){--tw-text-opacity: 1;color:rgb(254 215 170 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-red-500:is(.dark *){--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.dark\:text-yellow-200:is(.dark *){--tw-text-opacity: 1;color:rgb(254 240 138 / var(--tw-text-opacity, 1))}.dark\:text-yellow-300:is(.dark *){--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.dark\:text-yellow-500:is(.dark *){--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.dark\:hover\:bg-gray-800:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:focus\:bg-gray-800:focus:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}@media(min-width:640px){.sm\:bottom-0{bottom:0}.sm\:right-0{right:0}.sm\:right-2{right:.5rem}.sm\:right-3{right:.75rem}.sm\:top-2{top:.5rem}.sm\:top-3{top:.75rem}.sm\:top-auto{top:auto}.sm\:order-1{order:1}.sm\:order-2{order:2}.sm\:col-span-2{grid-column:span 2 / span 2}.sm\:mx-0{margin-left:0;margin-right:0}.sm\:mb-3{margin-bottom:.75rem}.sm\:mb-4{margin-bottom:1rem}.sm\:mb-6{margin-bottom:1.5rem}.sm\:ml-1{margin-left:.25rem}.sm\:mr-1{margin-right:.25rem}.sm\:mr-2{margin-right:.5rem}.sm\:mt-0{margin-top:0}.sm\:mt-2{margin-top:.5rem}.sm\:mt-3{margin-top:.75rem}.sm\:mt-6{margin-top:1.5rem}.sm\:block{display:block}.sm\:inline{display:inline}.sm\:flex{display:flex}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:h-10{height:2.5rem}.sm\:h-12{height:3rem}.sm\:h-2{height:.5rem}.sm\:h-24{height:6rem}.sm\:h-3{height:.75rem}.sm\:h-4{height:1rem}.sm\:h-8{height:2rem}.sm\:h-\[300px\]{height:300px}.sm\:h-\[400px\]{height:400px}.sm\:h-\[500px\]{height:500px}.sm\:h-\[calc\(100vh-280px\)\]{height:calc(100vh - 280px)}.sm\:h-\[calc\(100vh-320px\)\]{height:calc(100vh - 320px)}.sm\:w-10{width:2.5rem}.sm\:w-2{width:.5rem}.sm\:w-24{width:6rem}.sm\:w-3{width:.75rem}.sm\:w-4{width:1rem}.sm\:w-8{width:2rem}.sm\:w-\[140px\]{width:140px}.sm\:w-\[160px\]{width:160px}.sm\:w-\[200px\]{width:200px}.sm\:w-\[500px\]{width:500px}.sm\:w-auto{width:auto}.sm\:w-full{width:100%}.sm\:max-w-2xl{max-width:42rem}.sm\:max-w-\[900px\]{max-width:900px}.sm\:max-w-md{max-width:28rem}.sm\:max-w-sm{max-width:24rem}.sm\:flex-1{flex:1 1 0%}.sm\:flex-none{flex:none}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:flex-col{flex-direction:column}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-start{align-items:flex-start}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:justify-between{justify-content:space-between}.sm\:gap-0{gap:0px}.sm\:gap-1{gap:.25rem}.sm\:gap-2{gap:.5rem}.sm\:gap-3{gap:.75rem}.sm\:gap-4{gap:1rem}.sm\:gap-6{gap:1.5rem}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.sm\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.sm\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.sm\:space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:p-3{padding:.75rem}.sm\:p-4{padding:1rem}.sm\:p-6{padding:1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-3{padding-left:.75rem;padding-right:.75rem}.sm\:text-left{text-align:left}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}.sm\:text-3xl{font-size:1.875rem;line-height:2.25rem}.sm\:text-\[200px\]{font-size:200px}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:text-lg{font-size:1.125rem;line-height:1.75rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}.sm\:text-xs{font-size:.75rem;line-height:1rem}}@media(min-width:768px){.md\:top-4{top:1rem}.md\:mb-4{margin-bottom:1rem}.md\:mb-6{margin-bottom:1.5rem}.md\:mb-8{margin-bottom:2rem}.md\:mt-8{margin-top:2rem}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-16{height:4rem}.md\:h-4{height:1rem}.md\:h-5{height:1.25rem}.md\:h-8{height:2rem}.md\:h-96{height:24rem}.md\:h-\[500px\]{height:500px}.md\:min-h-\[400px\]{min-height:400px}.md\:w-16{width:4rem}.md\:w-4{width:1rem}.md\:w-5{width:1.25rem}.md\:w-8{width:2rem}.md\:w-96{width:24rem}.md\:max-w-\[420px\]{max-width:420px}.md\:max-w-none{max-width:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:gap-2{gap:.5rem}.md\:gap-3{gap:.75rem}.md\:gap-4{gap:1rem}.md\:gap-6{gap:1.5rem}.md\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.md\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.md\:whitespace-normal{white-space:normal}.md\:p-12{padding:3rem}.md\:p-4{padding:1rem}.md\:p-6{padding:1.5rem}.md\:p-8{padding:2rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:text-xs{font-size:.75rem;line-height:1rem}}@media(min-width:1024px){.lg\:invisible{visibility:hidden}.lg\:relative{position:relative}.lg\:z-0{z-index:0}.lg\:mb-1{margin-bottom:.25rem}.lg\:block{display:block}.lg\:hidden{display:none}.lg\:h-\[calc\(100vh-400px\)\]{height:calc(100vh - 400px)}.lg\:w-16{width:4rem}.lg\:w-64{width:16rem}.lg\:w-8{width:2rem}.lg\:w-\[150px\]{width:150px}.lg\:w-\[180px\]{width:180px}.lg\:w-\[200px\]{width:200px}.lg\:w-\[240px\]{width:240px}.lg\:w-\[80px\]{width:80px}.lg\:w-auto{width:auto}.lg\:max-w-0{max-width:0px}.lg\:flex-1{flex:1 1 0%}.lg\:flex-none{flex:none}.lg\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:justify-center{justify-content:center}.lg\:gap-0{gap:0px}.lg\:space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.lg\:overflow-hidden{overflow:hidden}.lg\:p-4{padding:1rem}.lg\:p-6{padding:1.5rem}.lg\:px-0{padding-left:0;padding-right:0}.lg\:text-3xl{font-size:1.875rem;line-height:2.25rem}.lg\:text-sm{font-size:.875rem;line-height:1.25rem}.lg\:opacity-0{opacity:0}}.\[\&\+div\]\:text-xs+div{font-size:.75rem;line-height:1rem}.\[\&\:first-child\[data-selected\=true\]_button\]\:rounded-l-md:first-child[data-selected=true] button{border-top-left-radius:calc(var(--radius) - 2px);border-bottom-left-radius:calc(var(--radius) - 2px)}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\:last-child\[data-selected\=true\]_button\]\:rounded-r-md:last-child[data-selected=true] button{border-top-right-radius:calc(var(--radius) - 2px);border-bottom-right-radius:calc(var(--radius) - 2px)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&\>span\]\:text-xs>span{font-size:.75rem;line-height:1rem}.\[\&\>span\]\:opacity-70>span{opacity:.7}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:left-4>svg{left:1rem}.\[\&\>svg\]\:top-4>svg{top:1rem}.\[\&\>svg\]\:size-3\.5>svg{width:.875rem;height:.875rem}.\[\&\>svg\]\:h-2\.5>svg{height:.625rem}.\[\&\>svg\]\:h-3>svg{height:.75rem}.\[\&\>svg\]\:w-2\.5>svg{width:.625rem}.\[\&\>svg\]\:w-3>svg{width:.75rem}.\[\&\>svg\]\:text-foreground>svg{color:hsl(var(--foreground))}.\[\&\>svg\]\:text-muted-foreground>svg{color:hsl(var(--muted-foreground))}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:1.75rem}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&_\.recharts-cartesian-axis-tick_text\]\:fill-muted-foreground .recharts-cartesian-axis-tick text{fill:hsl(var(--muted-foreground))}.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke="#ccc"]{stroke:hsl(var(--border) / .5)}.\[\&_\.recharts-curve\.recharts-tooltip-cursor\]\:stroke-border .recharts-curve.recharts-tooltip-cursor{stroke:hsl(var(--border))}.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-dot[stroke="#fff"]{stroke:transparent}.\[\&_\.recharts-layer\]\:outline-none .recharts-layer{outline:2px solid transparent;outline-offset:2px}.\[\&_\.recharts-polar-grid_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-polar-grid [stroke="#ccc"]{stroke:hsl(var(--border))}.\[\&_\.recharts-radial-bar-background-sector\]\:fill-muted .recharts-radial-bar-background-sector,.\[\&_\.recharts-rectangle\.recharts-tooltip-cursor\]\:fill-muted .recharts-rectangle.recharts-tooltip-cursor{fill:hsl(var(--muted))}.\[\&_\.recharts-reference-line_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-reference-line [stroke="#ccc"]{stroke:hsl(var(--border))}.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-sector[stroke="#fff"]{stroke:transparent}.\[\&_\.recharts-sector\]\:outline-none .recharts-sector,.\[\&_\.recharts-surface\]\:outline-none .recharts-surface{outline:2px solid transparent;outline-offset:2px}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-top:.375rem;padding-bottom:.375rem}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:.75rem;line-height:1rem}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{font-weight:500}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:hsl(var(--muted-foreground))}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:0}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:1.25rem}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:1.25rem}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:3rem}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-top:.75rem;padding-bottom:.75rem}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:1.25rem}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:1.25rem}.\[\&_p\]\:leading-relaxed p{line-height:1.625}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:invisible svg{visibility:hidden}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}[data-slot=card-content] .\[\[data-slot\=card-content\]_\&\]\:bg-transparent,[data-slot=popover-content] .\[\[data-slot\=popover-content\]_\&\]\:bg-transparent{background-color:transparent}@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2) format("woff2"),url(/assets/KaTeX_AMS-Regular-DMm9YOAa.woff) format("woff"),url(/assets/KaTeX_AMS-Regular-DRggAlZN.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff) format("woff"),url(/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff) format("woff"),url(/assets/KaTeX_Fraktur-Regular-CB_wures.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Main-Bold-Cx986IdX.woff2) format("woff2"),url(/assets/KaTeX_Main-Bold-Jm3AIy58.woff) format("woff"),url(/assets/KaTeX_Main-Bold-waoOVXN0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2) format("woff2"),url(/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff) format("woff"),url(/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2) format("woff2"),url(/assets/KaTeX_Main-Italic-BMLOBm91.woff) format("woff"),url(/assets/KaTeX_Main-Italic-3WenGoN9.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Main-Regular-B22Nviop.woff2) format("woff2"),url(/assets/KaTeX_Main-Regular-Dr94JaBh.woff) format("woff"),url(/assets/KaTeX_Main-Regular-ypZvNtVU.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2) format("woff2"),url(/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff) format("woff"),url(/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Math-Italic-t53AETM-.woff2) format("woff2"),url(/assets/KaTeX_Math-Italic-DA0__PXp.woff) format("woff"),url(/assets/KaTeX_Math-Italic-flOr_0UB.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:700;src:url(/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff) format("woff"),url(/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:italic;font-weight:400;src:url(/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff) format("woff"),url(/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:400;src:url(/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff) format("woff"),url(/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Script-Regular-D3wIWfF6.woff2) format("woff2"),url(/assets/KaTeX_Script-Regular-D5yQViql.woff) format("woff"),url(/assets/KaTeX_Script-Regular-C5JkGWo-.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2) format("woff2"),url(/assets/KaTeX_Size1-Regular-C195tn64.woff) format("woff"),url(/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2) format("woff2"),url(/assets/KaTeX_Size2-Regular-oD1tc_U0.woff) format("woff"),url(/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA4oAA4AAAAAHbQAAA3TAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQIDgmcDBEICo1oijYBNgIkA14LMgAEIAWJAAeBHAyBHBvbGiMRdnO0IkRRkiYDgr9KsJ1NUAf2kILNxgUmgqIgq1P89vcbIcmsQbRps3vCcXdYOKSWEPEKgZgQkprQQsxIXUgq0DqpGKmIvrgkeVGtEQD9DzAO29fM9jYhxZEsL2FeURH2JN4MIcTdO049NCVdxQ/w9NrSYFEBKTDKpLKfNkCGDc1RwjZLQcm3vqJ2UW9Xfa3tgAHz6ivp6vgC2yD4/6352ndnN0X0TL7seypkjZlMsjmZnf0Mm5Q+JykRWQBKCVCVPbARPXWyQtb5VgLB6Biq7/Uixcj2WGqdI8tGSgkuRG+t910GKP2D7AQH0DB9FMDW/obJZ8giFI3Wg8Cvevz0M+5m0rTh7XDBlvo9Y4vm13EXmfttwI4mBo1EG15fxJhUiCLbiiyCf/ZA6MFAhg3pGIZGdGIVjtPn6UcMk9A/UUr9PhoNsCENw1APAq0gpH73e+M+0ueyHbabc3vkbcdtzcf/fiy+NxQEjf9ud/ELBHAXJ0nk4z+MXH2Ev/kWyV4k7SkvpPc9Qr38F6RPWnM9cN6DJ0AdD1BhtgABtmoRoFCvPsBAumNm6soZG2Gk5GyVTo2sJncSyp0jQTYoR6WDvTwaaEcHsxHfvuWhHA3a6bN7twRKtcGok6NsCi7jYRrM2jExsUFMxMQYuJbMhuWNOumEJy9hi29Dmg5zMp/A5+hhPG19j1vBrq8JTLr8ki5VLPmG/PynJHVul440bxg5xuymHUFPBshC+nA9I1FmwbRBTNHAcik3Oae0cxKoI3MOriM42UrPe51nsaGxJ+WfXubAsP84aabUlQSJ1IiE0iPETLUU4CATgfXSCSpuRFRmCGbO+wSpAnzaeaCYW1VNEysRtuXCEL1kUFUbbtMv3Tilt/1c11jt3Q5bbMa84cpWipp8Elw3MZhOHsOlwwVUQM3lAR35JiFQbaYCRnMF2lxAWoOg2gyoIV4PouX8HytNIfLhqpJtXB4vjiViUI8IJ7bkC4ikkQvKksnOTKICwnqWSZ9YS5f0WCxmpgjbIq7EJcM4aI2nmhLNY2JIUgOjXZFWBHb+x5oh6cwb0Tv1ackHdKi0I9OO2wE9aogIOn540CCCziyhN+IaejtgAONKznHlHyutPrHGwCx9S6B8kfS4Mfi4Eyv7OU730bT1SCBjt834cXsf43zVjPUqqJjgrjeGnBxSG4aYAKFuVbeCfkDIjAqMb6yLNIbCuvXhMH2/+k2vkNpkORhR59N1CkzoOENvneIosjYmuTxlhUzaGEJQ/iWqx4dmwpmKjrwTiTGTCVozNAYqk/zXOndWxuWSmJkQpJw3pK5KX6QrLt5LATMqpmPAQhkhK6PUjzHUn7E0gHE0kPE0iKkolgkUx9SZmVAdDgpffdyJKg3k7VmzYGCwVXGz/tXmkOIp+vcWs+EMuhhvN0h9uhfzWJziBQmCREGSIFmQIkgVpAnSBRmC//6hkLZwaVhwxlrJSOdqlFtOYxlau9F2QN5Y98xmIAsiM1HVp2VFX+DHHGg6Ecjh3vmqtidX3qHI2qycTk/iwxSt5UzTmEP92ZBnEWTk4Mx8Mpl78ZDokxg/KWb+Q0QkvdKVmq3TMW+RXEgrsziSAfNXFMhDc60N5N9jQzjfO0kBKpUZl0ZmwJ41j/B9Hz6wmRaJB84niNmQrzp9eSlQCDDzazGDdVi3P36VZQ+Jy4f9UBNp+3zTjqI4abaFAm+GShVaXlsGdF3FYzZcDI6cori4kMxUECl9IjJZpzkvitAoxKue+90pDMvcKRxLl53TmOKCmV/xRolNKSqqUxc6LStOETmFOiLZZptlZepcKiAzteG8PEdpnQpbOMNcMsR4RR2Bs0cKFEvSmIjAFcnarqwUL4lDhHmnVkwu1IwshbiCcgvOheZuYyOteufZZwlcTlLgnZ3o/WcYdzZHW/WGaqaVfmTZ1aWCceJjkbZqsfbkOtcFlUZM/jy+hXHDbaUobWqqXaeWobbLO99yG5N3U4wxco0rQGGcOLASFMXeJoham8M+/x6O2WywK2l4HGbq1CoUyC/IZikQhdq3SiuNrvAEj0AVu9x2x3lp/xWzahaxidezFVtdcb5uEnzyl0ZmYiuKI0exvCd4Xc9CV1KB0db00z92wDPde0kukbvZIWN6jUWFTmPIC/Y4UPCm8UfDTFZpZNon1qLFTkBhxzB+FjQRA2Q/YRJT8pQigslMaUpFyAG8TMlXigiqmAZX4xgijKjRlGpLE0GdplRfCaJo0JQaSxNBk6ZmMzcya0FmrcisDdn0Q3HI2sWSppYigmlM1XT/kLQZSNpMJG0WkjYbSZuDpM1F0uYhFc1HxU4m1QJjDK6iL0S5uSj5rgXc3RejEigtcRBtqYPQsiTskmO5vosV+q4VGIKbOkDg0jtRrq+Em1YloaTFar3EGr1EUC8R0kus1Uus00usL97ABr2BjXoDm/QGNhuWtMVBKOwg/i78lT7hBsAvDmwHc/ao3vmUbBmhjeYySZNWvGkfZAgISDSaDo1SVpzGDsAEkF8B+gEapViUoZgUWXcRIGFZNm6gWbAKk0bp0k1MHG9fLYtV4iS2SmLEQFARzRcnf9PUS0LVn05/J9MiRRBU3v2IrvW974v4N00L7ZMk0wXP1409CHo/an8zTRHD3eSJ6m8D4YMkZNl3M79sqeuAsr/m3f+8/yl7A50aiAEJgeBeMWzu7ui9UfUBCe2TIqZIoOd/3/udRBOQidQZUERzb2/VwZN1H/Sju82ew2H2Wfr6qvfVf3hqwDvAIpkQVFy4B9Pe9e4/XvPeceu7h3dvO56iJPf0+A6cqA2ip18ER+iFgggiuOkvj24bby0N9j2UHIkgqIt+sVgfodC4YghLSMjSZbH0VR/6dMDrYJeKHilKTemt6v6kvzvn3/RrdWtr0GoN/xL+Sex/cPYLUpepx9cz/D46UPU5KXgAQa+NDps1v6J3xP1i2HtaDB0M9aX2deA7SYff//+gUCovMmIK/qfsFcOk+4Y5ZN97XlG6zebqtMbKgeRFi51vnxTQYBUik2rS/Cn6PC8ADR8FGxsRPB82dzfND90gIcshOcYUkfjherBz53odpm6TP8txlwOZ71xmfHHOvq053qFF/MRlS3jP0ELudrf2OeN8DHvp6ZceLe8qKYvWz/7yp0u4dKPfli3CYq0O13Ih71mylJ80tOi10On8wi+F4+LWgDPeJ30msSQt9/vkmHq9/Lvo2b461mP801v3W4xTcs6CbvF9UDdrSt+A8OUbpSh55qAUFXWznBBfdeJ8a4d7ugT5tvxUza3h9m4H7ptTqiG4z0g5dc0X29OcGlhpGFMpQo9ytTS+NViZpNdvU4kWx+LKxNY10kQ1yqGXrhe4/1nvP7E+nd5A92TtaRplbHSqoIdOqtRWti+fkB5/n1+/VvCmz12pG1kpQWsfi1ftlBobm0bpngs16CHkbIwdLnParxtTV3QYRlfJ0KFskH7pdN/YDn+yRuSd7sNH3aO0DYPggk6uWuXrfOc+fa3VTxFVvKaNxHsiHmsXyCLIE5yuOeN3/Jdf8HBL/5M6shjyhxHx9BjB1O0+4NLOnjLLSxwO7ukN4jMbOIcD879KLSi6Pk61Oqm2377n8079PXEEQ7cy7OKEC9nbpet118fxweTafpt69x/Bt8UqGzNQt7aelpc44dn5cqhwf71+qKp/Zf/+a0zcizOUWpl/iBcSXip0pplkatCchoH5c5aUM8I7/dWxAej8WicPL1URFZ9BDJelUwEwTkGqUhgSlydVes95YdXvhh9Gfz/aeFWvgVb4tuLbcv4+wLdutVZv/cUonwBD/6eDlE0aSiKK/uoH3+J1wDE/jMVqY2ysGufN84oIXB0sPzy8ollX/LegY74DgJXJR57sn+VGza0x3DnuIgABFM15LmajjjsNlYj+JEZGbuRYcAMOWxFkPN2w6Wd46xo4gVWQR/X4lyI/R6K/YK0110GzudPRW7Y+UOBGTfNNzHeYT0fiH0taunBpq9HEW8OKSaBGj21L0MqenEmNRWBAWDWAk4CpNoEZJ2tTaPFgbQYj8HxtFilErs3BTRwT8uO1NXQaWfIotchmPkAF5mMBAliEmZiOGVgCG9LgRzpscMAOOwowlT3JhusdazXGSC/hxR3UlmWVwWHpOIKheqONvjyhSiTHIkVUco5bnji8m//zL7PKaT1Vl5I6UE609f+gkr6MZKVyKc7zJRmCahLsdlyA5fdQkRSan9LgnnLEyGSkaKJCJog0wAgvepWBt80+1yKln1bMVtCljfNWDueKLsWwaEbBSfSPTEmVRsUcYYMnEjcjeyCZzBXK9E9BYBXLKjOSpUDR+nEV3TFSUdQaz+ot98QxgXwx0GQ+EEUAKB2qZPkQQ0GqFD8UPFMqyaCHM24BZmSGic9EYMagKizOw9Hz50DMrDLrqqLkTAhplMictiCAx5S3BIUQdeJeLnBy2CNtMfz6cV4u8XKoFZQesbf9YZiIERiHjaNodDW6LgcirX/mPnJIkBGDUpTBhSa0EIr38D5hCIszhCM8URGBqImoWjpvpt1ebu/v3Gl3qJfMnNM+9V+kiRFyROTPHQWOcs1dNW94/ukKMPZBvDi55i5CttdeJz84DLngLqjcdwEZ87bFFR8CIG35OAkDVN6VRDZ7aq67NteYqZ2lpT8oYB2CytoBd6VuAx4WgiAsnuj3WohG+LugzXiQRDeM3XYXlULv4dp5VFYC) format("woff2"),url(/assets/KaTeX_Size3-Regular-CTq5MqoE.woff) format("woff"),url(/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2) format("woff2"),url(/assets/KaTeX_Size4-Regular-BF-4gkZK.woff) format("woff"),url(/assets/KaTeX_Size4-Regular-DWFBv043.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2) format("woff2"),url(/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff) format("woff"),url(/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf) format("truetype")}.katex{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.25"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/webui/dist/assets/index-Cga6iLH3.js b/webui/dist/assets/index-Cga6iLH3.js deleted file mode 100644 index 85f669a3..00000000 --- a/webui/dist/assets/index-Cga6iLH3.js +++ /dev/null @@ -1,359 +0,0 @@ -import{r as S,j as a,u as ba,R as Ue,d as MI,L as AI,e as EI,f as Xr,g as _I,h as DI,O as c9,b as RI,k as zI}from"./router-BWgTyY51.js";import{a as PI,b as LI,g as u9}from"./react-vendor-Dtc2IqVY.js";import{c as d9,R as BI,T as II,L as qI,a as FI,C as Vm,X as Wm,Y as Ch,b as QI,B as fy,d as Gm,P as $I,e as HI,f as UI,_ as VI,g as WI}from"./charts-B1JvyJzO.js";import{c as Hi,a as tx,u as Oi,P as Yt,b as $e,d as Cn,e as Vf,f as So,g as es,h as Ls,i as h9,j as F4,k as Q4,S as GI,l as f9,m as m9,R as p9,O as nx,n as $4,C as rx,o as H4,T as U4,D as V4,p as W4,q as g9,r as x9,W as XI,s as v9,I as YI,t as y9,v as b9,w as KI,x as w9,V as ZI,L as S9,y as k9,z as JI,A as eq,B as O9,E as tq,F as nq,G as lo,H as sx,J as wd,K as j9,M as N9,N as C9,Q as T9,U as G4,X as X4,Y as ix,Z as ax,_ as Y4,$ as M9,a0 as rq,a1 as A9,a2 as sq,a3 as iq,a4 as E9,a5 as aq}from"./ui-vendor-nTGLnMlb.js";import{R as Ii,A as lq,D as oq,a as cq,Z as uf,C as uc,M as Wf,T as uq,X as Gf,P as _9,S as dq,b as dc,I as oo,c as Hu,d as hc,e as Xb,E as Yb,f as Fi,g as ua,h as Kb,i as hq,j as Zb,k as Jb,L as lO,K as fq,l as xc,m as mq,n as pq,F as io,o as gq,B as xq,U as D9,p as K4,q as vq,r as yq,s as Ps,H as hg,t as R9,u as df,v as e2,w as hf,x as bq,y as wq,z as lx,G as Z4,J as Wr,N as Ht,O as fg,Q as nd,V as Xf,W as Tc,Y as Mc,_ as Yf,$ as Sq,a0 as oO,a1 as kq,a2 as fc,a3 as t2,a4 as rd,a5 as cO,a6 as mg,a7 as Oq,a8 as uO,a9 as jq,aa as Nq,ab as Zl,ac as my,ad as dO,ae as Cq,af as Yh,ag as pg,ah as z9,ai as P9,aj as L9,ak as Tq,al as Mq,am as hO,an as Aq,ao as Eq,ap as fO,aq as _q}from"./icons-D6w7t-x9.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&r(l)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();var py={exports:{}},Th={},gy={exports:{}},xy={};var mO;function Dq(){return mO||(mO=1,(function(t){function e(H,ae){var ne=H.length;H.push(ae);e:for(;0>>1,R=H[ue];if(0>>1;ues(P,ne))Ks($,P)?(H[ue]=$,H[K]=ne,ue=K):(H[ue]=P,H[Y]=ne,ue=Y);else if(Ks($,ne))H[ue]=$,H[K]=ne,ue=K;else break e}}return ae}function s(H,ae){var ne=H.sortIndex-ae.sortIndex;return ne!==0?ne:H.id-ae.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,c=l.now();t.unstable_now=function(){return l.now()-c}}var d=[],h=[],m=1,p=null,x=3,v=!1,b=!1,k=!1,O=!1,j=typeof setTimeout=="function"?setTimeout:null,T=typeof clearTimeout=="function"?clearTimeout:null,M=typeof setImmediate<"u"?setImmediate:null;function _(H){for(var ae=n(h);ae!==null;){if(ae.callback===null)r(h);else if(ae.startTime<=H)r(h),ae.sortIndex=ae.expirationTime,e(d,ae);else break;ae=n(h)}}function D(H){if(k=!1,_(H),!b)if(n(d)!==null)b=!0,E||(E=!0,V());else{var ae=n(h);ae!==null&&J(D,ae.startTime-H)}}var E=!1,z=-1,Q=5,F=-1;function B(){return O?!0:!(t.unstable_now()-FH&&B());){var ue=p.callback;if(typeof ue=="function"){p.callback=null,x=p.priorityLevel;var R=ue(p.expirationTime<=H);if(H=t.unstable_now(),typeof R=="function"){p.callback=R,_(H),ae=!0;break t}p===n(d)&&r(d),_(H)}else r(d);p=n(d)}if(p!==null)ae=!0;else{var me=n(h);me!==null&&J(D,me.startTime-H),ae=!1}}break e}finally{p=null,x=ne,v=!1}ae=void 0}}finally{ae?V():E=!1}}}var V;if(typeof M=="function")V=function(){M(U)};else if(typeof MessageChannel<"u"){var ce=new MessageChannel,W=ce.port2;ce.port1.onmessage=U,V=function(){W.postMessage(null)}}else V=function(){j(U,0)};function J(H,ae){z=j(function(){H(t.unstable_now())},ae)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(H){H.callback=null},t.unstable_forceFrameRate=function(H){0>H||125ue?(H.sortIndex=ne,e(h,H),n(d)===null&&H===n(h)&&(k?(T(z),z=-1):k=!0,J(D,ne-ue))):(H.sortIndex=R,e(d,H),b||v||(b=!0,E||(E=!0,V()))),H},t.unstable_shouldYield=B,t.unstable_wrapCallback=function(H){var ae=x;return function(){var ne=x;x=ae;try{return H.apply(this,arguments)}finally{x=ne}}}})(xy)),xy}var pO;function Rq(){return pO||(pO=1,gy.exports=Dq()),gy.exports}var gO;function zq(){if(gO)return Th;gO=1;var t=Rq(),e=PI(),n=LI();function r(o){var u="https://react.dev/errors/"+o;if(1R||(o.current=ue[R],ue[R]=null,R--)}function P(o,u){R++,ue[R]=o.current,o.current=u}var K=me(null),$=me(null),fe=me(null),ve=me(null);function Re(o,u){switch(P(fe,u),P($,o),P(K,null),u.nodeType){case 9:case 11:o=(o=u.documentElement)&&(o=o.namespaceURI)?Ak(o):0;break;default:if(o=u.tagName,u=u.namespaceURI)u=Ak(u),o=Ek(u,o);else switch(o){case"svg":o=1;break;case"math":o=2;break;default:o=0}}Y(K),P(K,o)}function de(){Y(K),Y($),Y(fe)}function We(o){o.memoizedState!==null&&P(ve,o);var u=K.current,f=Ek(u,o.type);u!==f&&(P($,o),P(K,f))}function ct(o){$.current===o&&(Y(K),Y($)),ve.current===o&&(Y(ve),kh._currentValue=ne)}var Oe,nt;function ut(o){if(Oe===void 0)try{throw Error()}catch(f){var u=f.stack.trim().match(/\n( *(at )?)/);Oe=u&&u[1]||"",nt=-1)":-1y||Z[g]!==xe[y]){var je=` -`+Z[g].replace(" at new "," at ");return o.displayName&&je.includes("")&&(je=je.replace("",o.displayName)),je}while(1<=g&&0<=y);break}}}finally{Ct=!1,Error.prepareStackTrace=f}return(f=o?o.displayName||o.name:"")?ut(f):""}function Tn(o,u){switch(o.tag){case 26:case 27:case 5:return ut(o.type);case 16:return ut("Lazy");case 13:return o.child!==u&&u!==null?ut("Suspense Fallback"):ut("Suspense");case 19:return ut("SuspenseList");case 0:case 15:return Bn(o.type,!1);case 11:return Bn(o.type.render,!1);case 1:return Bn(o.type,!0);case 31:return ut("Activity");default:return""}}function Jn(o){try{var u="",f=null;do u+=Tn(o,f),f=o,o=o.return;while(o);return u}catch(g){return` -Error generating stack: `+g.message+` -`+g.stack}}var nn=Object.prototype.hasOwnProperty,_t=t.unstable_scheduleCallback,Yr=t.unstable_cancelCallback,In=t.unstable_shouldYield,or=t.unstable_requestPaint,yn=t.unstable_now,ft=t.unstable_getCurrentPriorityLevel,ee=t.unstable_ImmediatePriority,Se=t.unstable_UserBlockingPriority,Le=t.unstable_NormalPriority,rt=t.unstable_LowPriority,Tt=t.unstable_IdlePriority,cr=t.log,Kr=t.unstable_setDisableYieldValue,re=null,Me=null;function pt(o){if(typeof cr=="function"&&Kr(o),Me&&typeof Me.setStrictMode=="function")try{Me.setStrictMode(re,o)}catch{}}var vt=Math.clz32?Math.clz32:zn,vs=Math.log,dt=Math.LN2;function zn(o){return o>>>=0,o===0?32:31-(vs(o)/dt|0)|0}var mt=256,rn=262144,Ar=4194304;function Mt(o){var u=o&42;if(u!==0)return u;switch(o&-o){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return o&261888;case 262144:case 524288:case 1048576:case 2097152:return o&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return o&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return o}}function Ic(o,u,f){var g=o.pendingLanes;if(g===0)return 0;var y=0,w=o.suspendedLanes,A=o.pingedLanes;o=o.warmLanes;var I=g&134217727;return I!==0?(g=I&~w,g!==0?y=Mt(g):(A&=I,A!==0?y=Mt(A):f||(f=I&~o,f!==0&&(y=Mt(f))))):(I=g&~w,I!==0?y=Mt(I):A!==0?y=Mt(A):f||(f=g&~o,f!==0&&(y=Mt(f)))),y===0?0:u!==0&&u!==y&&(u&w)===0&&(w=y&-y,f=u&-u,w>=f||w===32&&(f&4194048)!==0)?u:y}function Eo(o,u){return(o.pendingLanes&~(o.suspendedLanes&~o.pingedLanes)&u)===0}function t1(o,u){switch(o){case 1:case 2:case 4:case 8:case 64:return u+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return u+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function qc(){var o=Ar;return Ar<<=1,(Ar&62914560)===0&&(Ar=4194304),o}function _o(o){for(var u=[],f=0;31>f;f++)u.push(o);return u}function Ld(o,u){o.pendingLanes|=u,u!==268435456&&(o.suspendedLanes=0,o.pingedLanes=0,o.warmLanes=0)}function xL(o,u,f,g,y,w){var A=o.pendingLanes;o.pendingLanes=f,o.suspendedLanes=0,o.pingedLanes=0,o.warmLanes=0,o.expiredLanes&=f,o.entangledLanes&=f,o.errorRecoveryDisabledLanes&=f,o.shellSuspendCounter=0;var I=o.entanglements,Z=o.expirationTimes,xe=o.hiddenUpdates;for(f=A&~f;0"u")return null;try{return o.activeElement||o.body}catch{return o.body}}var kL=/[\n"\\]/g;function oi(o){return o.replace(kL,function(u){return"\\"+u.charCodeAt(0).toString(16)+" "})}function l1(o,u,f,g,y,w,A,I){o.name="",A!=null&&typeof A!="function"&&typeof A!="symbol"&&typeof A!="boolean"?o.type=A:o.removeAttribute("type"),u!=null?A==="number"?(u===0&&o.value===""||o.value!=u)&&(o.value=""+li(u)):o.value!==""+li(u)&&(o.value=""+li(u)):A!=="submit"&&A!=="reset"||o.removeAttribute("value"),u!=null?o1(o,A,li(u)):f!=null?o1(o,A,li(f)):g!=null&&o.removeAttribute("value"),y==null&&w!=null&&(o.defaultChecked=!!w),y!=null&&(o.checked=y&&typeof y!="function"&&typeof y!="symbol"),I!=null&&typeof I!="function"&&typeof I!="symbol"&&typeof I!="boolean"?o.name=""+li(I):o.removeAttribute("name")}function O3(o,u,f,g,y,w,A,I){if(w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"&&(o.type=w),u!=null||f!=null){if(!(w!=="submit"&&w!=="reset"||u!=null)){a1(o);return}f=f!=null?""+li(f):"",u=u!=null?""+li(u):f,I||u===o.value||(o.value=u),o.defaultValue=u}g=g??y,g=typeof g!="function"&&typeof g!="symbol"&&!!g,o.checked=I?o.checked:!!g,o.defaultChecked=!!g,A!=null&&typeof A!="function"&&typeof A!="symbol"&&typeof A!="boolean"&&(o.name=A),a1(o)}function o1(o,u,f){u==="number"&&P0(o.ownerDocument)===o||o.defaultValue===""+f||(o.defaultValue=""+f)}function Vc(o,u,f,g){if(o=o.options,u){u={};for(var y=0;y"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),f1=!1;if(_a)try{var Fd={};Object.defineProperty(Fd,"passive",{get:function(){f1=!0}}),window.addEventListener("test",Fd,Fd),window.removeEventListener("test",Fd,Fd)}catch{f1=!1}var Ol=null,m1=null,B0=null;function E3(){if(B0)return B0;var o,u=m1,f=u.length,g,y="value"in Ol?Ol.value:Ol.textContent,w=y.length;for(o=0;o=Hd),L3=" ",B3=!1;function I3(o,u){switch(o){case"keyup":return KL.indexOf(u.keyCode)!==-1;case"keydown":return u.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function q3(o){return o=o.detail,typeof o=="object"&&"data"in o?o.data:null}var Yc=!1;function JL(o,u){switch(o){case"compositionend":return q3(u);case"keypress":return u.which!==32?null:(B3=!0,L3);case"textInput":return o=u.data,o===L3&&B3?null:o;default:return null}}function eB(o,u){if(Yc)return o==="compositionend"||!y1&&I3(o,u)?(o=E3(),B0=m1=Ol=null,Yc=!1,o):null;switch(o){case"paste":return null;case"keypress":if(!(u.ctrlKey||u.altKey||u.metaKey)||u.ctrlKey&&u.altKey){if(u.char&&1=u)return{node:f,offset:u-o};o=g}e:{for(;f;){if(f.nextSibling){f=f.nextSibling;break e}f=f.parentNode}f=void 0}f=G3(f)}}function Y3(o,u){return o&&u?o===u?!0:o&&o.nodeType===3?!1:u&&u.nodeType===3?Y3(o,u.parentNode):"contains"in o?o.contains(u):o.compareDocumentPosition?!!(o.compareDocumentPosition(u)&16):!1:!1}function K3(o){o=o!=null&&o.ownerDocument!=null&&o.ownerDocument.defaultView!=null?o.ownerDocument.defaultView:window;for(var u=P0(o.document);u instanceof o.HTMLIFrameElement;){try{var f=typeof u.contentWindow.location.href=="string"}catch{f=!1}if(f)o=u.contentWindow;else break;u=P0(o.document)}return u}function S1(o){var u=o&&o.nodeName&&o.nodeName.toLowerCase();return u&&(u==="input"&&(o.type==="text"||o.type==="search"||o.type==="tel"||o.type==="url"||o.type==="password")||u==="textarea"||o.contentEditable==="true")}var oB=_a&&"documentMode"in document&&11>=document.documentMode,Kc=null,k1=null,Gd=null,O1=!1;function Z3(o,u,f){var g=f.window===f?f.document:f.nodeType===9?f:f.ownerDocument;O1||Kc==null||Kc!==P0(g)||(g=Kc,"selectionStart"in g&&S1(g)?g={start:g.selectionStart,end:g.selectionEnd}:(g=(g.ownerDocument&&g.ownerDocument.defaultView||window).getSelection(),g={anchorNode:g.anchorNode,anchorOffset:g.anchorOffset,focusNode:g.focusNode,focusOffset:g.focusOffset}),Gd&&Wd(Gd,g)||(Gd=g,g=Em(k1,"onSelect"),0>=A,y-=A,Gi=1<<32-vt(u)+y|f<kt?(Qt=Ke,Ke=null):Qt=Ke.sibling;var Zt=be(oe,Ke,pe[kt],Ne);if(Zt===null){Ke===null&&(Ke=Qt);break}o&&Ke&&Zt.alternate===null&&u(oe,Ke),se=w(Zt,se,kt),Kt===null?tt=Zt:Kt.sibling=Zt,Kt=Zt,Ke=Qt}if(kt===pe.length)return f(oe,Ke),Ut&&Ra(oe,kt),tt;if(Ke===null){for(;ktkt?(Qt=Ke,Ke=null):Qt=Ke.sibling;var Vl=be(oe,Ke,Zt.value,Ne);if(Vl===null){Ke===null&&(Ke=Qt);break}o&&Ke&&Vl.alternate===null&&u(oe,Ke),se=w(Vl,se,kt),Kt===null?tt=Vl:Kt.sibling=Vl,Kt=Vl,Ke=Qt}if(Zt.done)return f(oe,Ke),Ut&&Ra(oe,kt),tt;if(Ke===null){for(;!Zt.done;kt++,Zt=pe.next())Zt=Te(oe,Zt.value,Ne),Zt!==null&&(se=w(Zt,se,kt),Kt===null?tt=Zt:Kt.sibling=Zt,Kt=Zt);return Ut&&Ra(oe,kt),tt}for(Ke=g(Ke);!Zt.done;kt++,Zt=pe.next())Zt=ke(Ke,oe,kt,Zt.value,Ne),Zt!==null&&(o&&Zt.alternate!==null&&Ke.delete(Zt.key===null?kt:Zt.key),se=w(Zt,se,kt),Kt===null?tt=Zt:Kt.sibling=Zt,Kt=Zt);return o&&Ke.forEach(function(TI){return u(oe,TI)}),Ut&&Ra(oe,kt),tt}function Sn(oe,se,pe,Ne){if(typeof pe=="object"&&pe!==null&&pe.type===k&&pe.key===null&&(pe=pe.props.children),typeof pe=="object"&&pe!==null){switch(pe.$$typeof){case v:e:{for(var tt=pe.key;se!==null;){if(se.key===tt){if(tt=pe.type,tt===k){if(se.tag===7){f(oe,se.sibling),Ne=y(se,pe.props.children),Ne.return=oe,oe=Ne;break e}}else if(se.elementType===tt||typeof tt=="object"&&tt!==null&&tt.$$typeof===Q&&$o(tt)===se.type){f(oe,se.sibling),Ne=y(se,pe.props),eh(Ne,pe),Ne.return=oe,oe=Ne;break e}f(oe,se);break}else u(oe,se);se=se.sibling}pe.type===k?(Ne=Bo(pe.props.children,oe.mode,Ne,pe.key),Ne.return=oe,oe=Ne):(Ne=G0(pe.type,pe.key,pe.props,null,oe.mode,Ne),eh(Ne,pe),Ne.return=oe,oe=Ne)}return A(oe);case b:e:{for(tt=pe.key;se!==null;){if(se.key===tt)if(se.tag===4&&se.stateNode.containerInfo===pe.containerInfo&&se.stateNode.implementation===pe.implementation){f(oe,se.sibling),Ne=y(se,pe.children||[]),Ne.return=oe,oe=Ne;break e}else{f(oe,se);break}else u(oe,se);se=se.sibling}Ne=E1(pe,oe.mode,Ne),Ne.return=oe,oe=Ne}return A(oe);case Q:return pe=$o(pe),Sn(oe,se,pe,Ne)}if(J(pe))return Ge(oe,se,pe,Ne);if(V(pe)){if(tt=V(pe),typeof tt!="function")throw Error(r(150));return pe=tt.call(pe),lt(oe,se,pe,Ne)}if(typeof pe.then=="function")return Sn(oe,se,tm(pe),Ne);if(pe.$$typeof===M)return Sn(oe,se,K0(oe,pe),Ne);nm(oe,pe)}return typeof pe=="string"&&pe!==""||typeof pe=="number"||typeof pe=="bigint"?(pe=""+pe,se!==null&&se.tag===6?(f(oe,se.sibling),Ne=y(se,pe),Ne.return=oe,oe=Ne):(f(oe,se),Ne=A1(pe,oe.mode,Ne),Ne.return=oe,oe=Ne),A(oe)):f(oe,se)}return function(oe,se,pe,Ne){try{Jd=0;var tt=Sn(oe,se,pe,Ne);return ou=null,tt}catch(Ke){if(Ke===lu||Ke===J0)throw Ke;var Kt=$s(29,Ke,null,oe.mode);return Kt.lanes=Ne,Kt.return=oe,Kt}finally{}}}var Uo=w6(!0),S6=w6(!1),Ml=!1;function $1(o){o.updateQueue={baseState:o.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function H1(o,u){o=o.updateQueue,u.updateQueue===o&&(u.updateQueue={baseState:o.baseState,firstBaseUpdate:o.firstBaseUpdate,lastBaseUpdate:o.lastBaseUpdate,shared:o.shared,callbacks:null})}function Al(o){return{lane:o,tag:0,payload:null,callback:null,next:null}}function El(o,u,f){var g=o.updateQueue;if(g===null)return null;if(g=g.shared,(sn&2)!==0){var y=g.pending;return y===null?u.next=u:(u.next=y.next,y.next=u),g.pending=u,u=W0(o),i6(o,null,f),u}return V0(o,g,u,f),W0(o)}function th(o,u,f){if(u=u.updateQueue,u!==null&&(u=u.shared,(f&4194048)!==0)){var g=u.lanes;g&=o.pendingLanes,f|=g,u.lanes=f,f3(o,f)}}function U1(o,u){var f=o.updateQueue,g=o.alternate;if(g!==null&&(g=g.updateQueue,f===g)){var y=null,w=null;if(f=f.firstBaseUpdate,f!==null){do{var A={lane:f.lane,tag:f.tag,payload:f.payload,callback:null,next:null};w===null?y=w=A:w=w.next=A,f=f.next}while(f!==null);w===null?y=w=u:w=w.next=u}else y=w=u;f={baseState:g.baseState,firstBaseUpdate:y,lastBaseUpdate:w,shared:g.shared,callbacks:g.callbacks},o.updateQueue=f;return}o=f.lastBaseUpdate,o===null?f.firstBaseUpdate=u:o.next=u,f.lastBaseUpdate=u}var V1=!1;function nh(){if(V1){var o=au;if(o!==null)throw o}}function rh(o,u,f,g){V1=!1;var y=o.updateQueue;Ml=!1;var w=y.firstBaseUpdate,A=y.lastBaseUpdate,I=y.shared.pending;if(I!==null){y.shared.pending=null;var Z=I,xe=Z.next;Z.next=null,A===null?w=xe:A.next=xe,A=Z;var je=o.alternate;je!==null&&(je=je.updateQueue,I=je.lastBaseUpdate,I!==A&&(I===null?je.firstBaseUpdate=xe:I.next=xe,je.lastBaseUpdate=Z))}if(w!==null){var Te=y.baseState;A=0,je=xe=Z=null,I=w;do{var be=I.lane&-536870913,ke=be!==I.lane;if(ke?(Ft&be)===be:(g&be)===be){be!==0&&be===iu&&(V1=!0),je!==null&&(je=je.next={lane:0,tag:I.tag,payload:I.payload,callback:null,next:null});e:{var Ge=o,lt=I;be=u;var Sn=f;switch(lt.tag){case 1:if(Ge=lt.payload,typeof Ge=="function"){Te=Ge.call(Sn,Te,be);break e}Te=Ge;break e;case 3:Ge.flags=Ge.flags&-65537|128;case 0:if(Ge=lt.payload,be=typeof Ge=="function"?Ge.call(Sn,Te,be):Ge,be==null)break e;Te=p({},Te,be);break e;case 2:Ml=!0}}be=I.callback,be!==null&&(o.flags|=64,ke&&(o.flags|=8192),ke=y.callbacks,ke===null?y.callbacks=[be]:ke.push(be))}else ke={lane:be,tag:I.tag,payload:I.payload,callback:I.callback,next:null},je===null?(xe=je=ke,Z=Te):je=je.next=ke,A|=be;if(I=I.next,I===null){if(I=y.shared.pending,I===null)break;ke=I,I=ke.next,ke.next=null,y.lastBaseUpdate=ke,y.shared.pending=null}}while(!0);je===null&&(Z=Te),y.baseState=Z,y.firstBaseUpdate=xe,y.lastBaseUpdate=je,w===null&&(y.shared.lanes=0),Pl|=A,o.lanes=A,o.memoizedState=Te}}function k6(o,u){if(typeof o!="function")throw Error(r(191,o));o.call(u)}function O6(o,u){var f=o.callbacks;if(f!==null)for(o.callbacks=null,o=0;ow?w:8;var A=H.T,I={};H.T=I,dv(o,!1,u,f);try{var Z=y(),xe=H.S;if(xe!==null&&xe(I,Z),Z!==null&&typeof Z=="object"&&typeof Z.then=="function"){var je=xB(Z,g);ah(o,u,je,Gs(o))}else ah(o,u,g,Gs(o))}catch(Te){ah(o,u,{then:function(){},status:"rejected",reason:Te},Gs())}finally{ae.p=w,A!==null&&I.types!==null&&(A.types=I.types),H.T=A}}function kB(){}function cv(o,u,f,g){if(o.tag!==5)throw Error(r(476));var y=nS(o).queue;tS(o,y,u,ne,f===null?kB:function(){return rS(o),f(g)})}function nS(o){var u=o.memoizedState;if(u!==null)return u;u={memoizedState:ne,baseState:ne,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ba,lastRenderedState:ne},next:null};var f={};return u.next={memoizedState:f,baseState:f,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ba,lastRenderedState:f},next:null},o.memoizedState=u,o=o.alternate,o!==null&&(o.memoizedState=u),u}function rS(o){var u=nS(o);u.next===null&&(u=o.alternate.memoizedState),ah(o,u.next.queue,{},Gs())}function uv(){return qr(kh)}function sS(){return sr().memoizedState}function iS(){return sr().memoizedState}function OB(o){for(var u=o.return;u!==null;){switch(u.tag){case 24:case 3:var f=Gs();o=Al(f);var g=El(u,o,f);g!==null&&(js(g,u,f),th(g,u,f)),u={cache:I1()},o.payload=u;return}u=u.return}}function jB(o,u,f){var g=Gs();f={lane:g,revertLane:0,gesture:null,action:f,hasEagerState:!1,eagerState:null,next:null},hm(o)?lS(u,f):(f=T1(o,u,f,g),f!==null&&(js(f,o,g),oS(f,u,g)))}function aS(o,u,f){var g=Gs();ah(o,u,f,g)}function ah(o,u,f,g){var y={lane:g,revertLane:0,gesture:null,action:f,hasEagerState:!1,eagerState:null,next:null};if(hm(o))lS(u,y);else{var w=o.alternate;if(o.lanes===0&&(w===null||w.lanes===0)&&(w=u.lastRenderedReducer,w!==null))try{var A=u.lastRenderedState,I=w(A,f);if(y.hasEagerState=!0,y.eagerState=I,Qs(I,A))return V0(o,u,y,0),Mn===null&&U0(),!1}catch{}finally{}if(f=T1(o,u,y,g),f!==null)return js(f,o,g),oS(f,u,g),!0}return!1}function dv(o,u,f,g){if(g={lane:2,revertLane:$v(),gesture:null,action:g,hasEagerState:!1,eagerState:null,next:null},hm(o)){if(u)throw Error(r(479))}else u=T1(o,f,g,2),u!==null&&js(u,o,2)}function hm(o){var u=o.alternate;return o===wt||u!==null&&u===wt}function lS(o,u){uu=im=!0;var f=o.pending;f===null?u.next=u:(u.next=f.next,f.next=u),o.pending=u}function oS(o,u,f){if((f&4194048)!==0){var g=u.lanes;g&=o.pendingLanes,f|=g,u.lanes=f,f3(o,f)}}var lh={readContext:qr,use:om,useCallback:er,useContext:er,useEffect:er,useImperativeHandle:er,useLayoutEffect:er,useInsertionEffect:er,useMemo:er,useReducer:er,useRef:er,useState:er,useDebugValue:er,useDeferredValue:er,useTransition:er,useSyncExternalStore:er,useId:er,useHostTransitionStatus:er,useFormState:er,useActionState:er,useOptimistic:er,useMemoCache:er,useCacheRefresh:er};lh.useEffectEvent=er;var cS={readContext:qr,use:om,useCallback:function(o,u){return os().memoizedState=[o,u===void 0?null:u],o},useContext:qr,useEffect:V6,useImperativeHandle:function(o,u,f){f=f!=null?f.concat([o]):null,um(4194308,4,Y6.bind(null,u,o),f)},useLayoutEffect:function(o,u){return um(4194308,4,o,u)},useInsertionEffect:function(o,u){um(4,2,o,u)},useMemo:function(o,u){var f=os();u=u===void 0?null:u;var g=o();if(Vo){pt(!0);try{o()}finally{pt(!1)}}return f.memoizedState=[g,u],g},useReducer:function(o,u,f){var g=os();if(f!==void 0){var y=f(u);if(Vo){pt(!0);try{f(u)}finally{pt(!1)}}}else y=u;return g.memoizedState=g.baseState=y,o={pending:null,lanes:0,dispatch:null,lastRenderedReducer:o,lastRenderedState:y},g.queue=o,o=o.dispatch=jB.bind(null,wt,o),[g.memoizedState,o]},useRef:function(o){var u=os();return o={current:o},u.memoizedState=o},useState:function(o){o=sv(o);var u=o.queue,f=aS.bind(null,wt,u);return u.dispatch=f,[o.memoizedState,f]},useDebugValue:lv,useDeferredValue:function(o,u){var f=os();return ov(f,o,u)},useTransition:function(){var o=sv(!1);return o=tS.bind(null,wt,o.queue,!0,!1),os().memoizedState=o,[!1,o]},useSyncExternalStore:function(o,u,f){var g=wt,y=os();if(Ut){if(f===void 0)throw Error(r(407));f=f()}else{if(f=u(),Mn===null)throw Error(r(349));(Ft&127)!==0||A6(g,u,f)}y.memoizedState=f;var w={value:f,getSnapshot:u};return y.queue=w,V6(_6.bind(null,g,w,o),[o]),g.flags|=2048,hu(9,{destroy:void 0},E6.bind(null,g,w,f,u),null),f},useId:function(){var o=os(),u=Mn.identifierPrefix;if(Ut){var f=Xi,g=Gi;f=(g&~(1<<32-vt(g)-1)).toString(32)+f,u="_"+u+"R_"+f,f=am++,0<\/script>",w=w.removeChild(w.firstChild);break;case"select":w=typeof g.is=="string"?A.createElement("select",{is:g.is}):A.createElement("select"),g.multiple?w.multiple=!0:g.size&&(w.size=g.size);break;default:w=typeof g.is=="string"?A.createElement(y,{is:g.is}):A.createElement(y)}}w[Br]=u,w[ys]=g;e:for(A=u.child;A!==null;){if(A.tag===5||A.tag===6)w.appendChild(A.stateNode);else if(A.tag!==4&&A.tag!==27&&A.child!==null){A.child.return=A,A=A.child;continue}if(A===u)break e;for(;A.sibling===null;){if(A.return===null||A.return===u)break e;A=A.return}A.sibling.return=A.return,A=A.sibling}u.stateNode=w;e:switch(Qr(w,y,g),y){case"button":case"input":case"select":case"textarea":g=!!g.autoFocus;break e;case"img":g=!0;break e;default:g=!1}g&&qa(u)}}return Fn(u),jv(u,u.type,o===null?null:o.memoizedProps,u.pendingProps,f),null;case 6:if(o&&u.stateNode!=null)o.memoizedProps!==g&&qa(u);else{if(typeof g!="string"&&u.stateNode===null)throw Error(r(166));if(o=fe.current,ru(u)){if(o=u.stateNode,f=u.memoizedProps,g=null,y=Ir,y!==null)switch(y.tag){case 27:case 5:g=y.memoizedProps}o[Br]=u,o=!!(o.nodeValue===f||g!==null&&g.suppressHydrationWarning===!0||Tk(o.nodeValue,f)),o||Cl(u,!0)}else o=_m(o).createTextNode(g),o[Br]=u,u.stateNode=o}return Fn(u),null;case 31:if(f=u.memoizedState,o===null||o.memoizedState!==null){if(g=ru(u),f!==null){if(o===null){if(!g)throw Error(r(318));if(o=u.memoizedState,o=o!==null?o.dehydrated:null,!o)throw Error(r(557));o[Br]=u}else Io(),(u.flags&128)===0&&(u.memoizedState=null),u.flags|=4;Fn(u),o=!1}else f=z1(),o!==null&&o.memoizedState!==null&&(o.memoizedState.hydrationErrors=f),o=!0;if(!o)return u.flags&256?(Us(u),u):(Us(u),null);if((u.flags&128)!==0)throw Error(r(558))}return Fn(u),null;case 13:if(g=u.memoizedState,o===null||o.memoizedState!==null&&o.memoizedState.dehydrated!==null){if(y=ru(u),g!==null&&g.dehydrated!==null){if(o===null){if(!y)throw Error(r(318));if(y=u.memoizedState,y=y!==null?y.dehydrated:null,!y)throw Error(r(317));y[Br]=u}else Io(),(u.flags&128)===0&&(u.memoizedState=null),u.flags|=4;Fn(u),y=!1}else y=z1(),o!==null&&o.memoizedState!==null&&(o.memoizedState.hydrationErrors=y),y=!0;if(!y)return u.flags&256?(Us(u),u):(Us(u),null)}return Us(u),(u.flags&128)!==0?(u.lanes=f,u):(f=g!==null,o=o!==null&&o.memoizedState!==null,f&&(g=u.child,y=null,g.alternate!==null&&g.alternate.memoizedState!==null&&g.alternate.memoizedState.cachePool!==null&&(y=g.alternate.memoizedState.cachePool.pool),w=null,g.memoizedState!==null&&g.memoizedState.cachePool!==null&&(w=g.memoizedState.cachePool.pool),w!==y&&(g.flags|=2048)),f!==o&&f&&(u.child.flags|=8192),xm(u,u.updateQueue),Fn(u),null);case 4:return de(),o===null&&Wv(u.stateNode.containerInfo),Fn(u),null;case 10:return Pa(u.type),Fn(u),null;case 19:if(Y(rr),g=u.memoizedState,g===null)return Fn(u),null;if(y=(u.flags&128)!==0,w=g.rendering,w===null)if(y)ch(g,!1);else{if(tr!==0||o!==null&&(o.flags&128)!==0)for(o=u.child;o!==null;){if(w=sm(o),w!==null){for(u.flags|=128,ch(g,!1),o=w.updateQueue,u.updateQueue=o,xm(u,o),u.subtreeFlags=0,o=f,f=u.child;f!==null;)a6(f,o),f=f.sibling;return P(rr,rr.current&1|2),Ut&&Ra(u,g.treeForkCount),u.child}o=o.sibling}g.tail!==null&&yn()>Sm&&(u.flags|=128,y=!0,ch(g,!1),u.lanes=4194304)}else{if(!y)if(o=sm(w),o!==null){if(u.flags|=128,y=!0,o=o.updateQueue,u.updateQueue=o,xm(u,o),ch(g,!0),g.tail===null&&g.tailMode==="hidden"&&!w.alternate&&!Ut)return Fn(u),null}else 2*yn()-g.renderingStartTime>Sm&&f!==536870912&&(u.flags|=128,y=!0,ch(g,!1),u.lanes=4194304);g.isBackwards?(w.sibling=u.child,u.child=w):(o=g.last,o!==null?o.sibling=w:u.child=w,g.last=w)}return g.tail!==null?(o=g.tail,g.rendering=o,g.tail=o.sibling,g.renderingStartTime=yn(),o.sibling=null,f=rr.current,P(rr,y?f&1|2:f&1),Ut&&Ra(u,g.treeForkCount),o):(Fn(u),null);case 22:case 23:return Us(u),G1(),g=u.memoizedState!==null,o!==null?o.memoizedState!==null!==g&&(u.flags|=8192):g&&(u.flags|=8192),g?(f&536870912)!==0&&(u.flags&128)===0&&(Fn(u),u.subtreeFlags&6&&(u.flags|=8192)):Fn(u),f=u.updateQueue,f!==null&&xm(u,f.retryQueue),f=null,o!==null&&o.memoizedState!==null&&o.memoizedState.cachePool!==null&&(f=o.memoizedState.cachePool.pool),g=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(g=u.memoizedState.cachePool.pool),g!==f&&(u.flags|=2048),o!==null&&Y(Qo),null;case 24:return f=null,o!==null&&(f=o.memoizedState.cache),u.memoizedState.cache!==f&&(u.flags|=2048),Pa(ur),Fn(u),null;case 25:return null;case 30:return null}throw Error(r(156,u.tag))}function AB(o,u){switch(D1(u),u.tag){case 1:return o=u.flags,o&65536?(u.flags=o&-65537|128,u):null;case 3:return Pa(ur),de(),o=u.flags,(o&65536)!==0&&(o&128)===0?(u.flags=o&-65537|128,u):null;case 26:case 27:case 5:return ct(u),null;case 31:if(u.memoizedState!==null){if(Us(u),u.alternate===null)throw Error(r(340));Io()}return o=u.flags,o&65536?(u.flags=o&-65537|128,u):null;case 13:if(Us(u),o=u.memoizedState,o!==null&&o.dehydrated!==null){if(u.alternate===null)throw Error(r(340));Io()}return o=u.flags,o&65536?(u.flags=o&-65537|128,u):null;case 19:return Y(rr),null;case 4:return de(),null;case 10:return Pa(u.type),null;case 22:case 23:return Us(u),G1(),o!==null&&Y(Qo),o=u.flags,o&65536?(u.flags=o&-65537|128,u):null;case 24:return Pa(ur),null;case 25:return null;default:return null}}function DS(o,u){switch(D1(u),u.tag){case 3:Pa(ur),de();break;case 26:case 27:case 5:ct(u);break;case 4:de();break;case 31:u.memoizedState!==null&&Us(u);break;case 13:Us(u);break;case 19:Y(rr);break;case 10:Pa(u.type);break;case 22:case 23:Us(u),G1(),o!==null&&Y(Qo);break;case 24:Pa(ur)}}function uh(o,u){try{var f=u.updateQueue,g=f!==null?f.lastEffect:null;if(g!==null){var y=g.next;f=y;do{if((f.tag&o)===o){g=void 0;var w=f.create,A=f.inst;g=w(),A.destroy=g}f=f.next}while(f!==y)}}catch(I){gn(u,u.return,I)}}function Rl(o,u,f){try{var g=u.updateQueue,y=g!==null?g.lastEffect:null;if(y!==null){var w=y.next;g=w;do{if((g.tag&o)===o){var A=g.inst,I=A.destroy;if(I!==void 0){A.destroy=void 0,y=u;var Z=f,xe=I;try{xe()}catch(je){gn(y,Z,je)}}}g=g.next}while(g!==w)}}catch(je){gn(u,u.return,je)}}function RS(o){var u=o.updateQueue;if(u!==null){var f=o.stateNode;try{O6(u,f)}catch(g){gn(o,o.return,g)}}}function zS(o,u,f){f.props=Wo(o.type,o.memoizedProps),f.state=o.memoizedState;try{f.componentWillUnmount()}catch(g){gn(o,u,g)}}function dh(o,u){try{var f=o.ref;if(f!==null){switch(o.tag){case 26:case 27:case 5:var g=o.stateNode;break;case 30:g=o.stateNode;break;default:g=o.stateNode}typeof f=="function"?o.refCleanup=f(g):f.current=g}}catch(y){gn(o,u,y)}}function Yi(o,u){var f=o.ref,g=o.refCleanup;if(f!==null)if(typeof g=="function")try{g()}catch(y){gn(o,u,y)}finally{o.refCleanup=null,o=o.alternate,o!=null&&(o.refCleanup=null)}else if(typeof f=="function")try{f(null)}catch(y){gn(o,u,y)}else f.current=null}function PS(o){var u=o.type,f=o.memoizedProps,g=o.stateNode;try{e:switch(u){case"button":case"input":case"select":case"textarea":f.autoFocus&&g.focus();break e;case"img":f.src?g.src=f.src:f.srcSet&&(g.srcset=f.srcSet)}}catch(y){gn(o,o.return,y)}}function Nv(o,u,f){try{var g=o.stateNode;ZB(g,o.type,f,u),g[ys]=u}catch(y){gn(o,o.return,y)}}function LS(o){return o.tag===5||o.tag===3||o.tag===26||o.tag===27&&Fl(o.type)||o.tag===4}function Cv(o){e:for(;;){for(;o.sibling===null;){if(o.return===null||LS(o.return))return null;o=o.return}for(o.sibling.return=o.return,o=o.sibling;o.tag!==5&&o.tag!==6&&o.tag!==18;){if(o.tag===27&&Fl(o.type)||o.flags&2||o.child===null||o.tag===4)continue e;o.child.return=o,o=o.child}if(!(o.flags&2))return o.stateNode}}function Tv(o,u,f){var g=o.tag;if(g===5||g===6)o=o.stateNode,u?(f.nodeType===9?f.body:f.nodeName==="HTML"?f.ownerDocument.body:f).insertBefore(o,u):(u=f.nodeType===9?f.body:f.nodeName==="HTML"?f.ownerDocument.body:f,u.appendChild(o),f=f._reactRootContainer,f!=null||u.onclick!==null||(u.onclick=Ea));else if(g!==4&&(g===27&&Fl(o.type)&&(f=o.stateNode,u=null),o=o.child,o!==null))for(Tv(o,u,f),o=o.sibling;o!==null;)Tv(o,u,f),o=o.sibling}function vm(o,u,f){var g=o.tag;if(g===5||g===6)o=o.stateNode,u?f.insertBefore(o,u):f.appendChild(o);else if(g!==4&&(g===27&&Fl(o.type)&&(f=o.stateNode),o=o.child,o!==null))for(vm(o,u,f),o=o.sibling;o!==null;)vm(o,u,f),o=o.sibling}function BS(o){var u=o.stateNode,f=o.memoizedProps;try{for(var g=o.type,y=u.attributes;y.length;)u.removeAttributeNode(y[0]);Qr(u,g,f),u[Br]=o,u[ys]=f}catch(w){gn(o,o.return,w)}}var Fa=!1,fr=!1,Mv=!1,IS=typeof WeakSet=="function"?WeakSet:Set,_r=null;function EB(o,u){if(o=o.containerInfo,Yv=Im,o=K3(o),S1(o)){if("selectionStart"in o)var f={start:o.selectionStart,end:o.selectionEnd};else e:{f=(f=o.ownerDocument)&&f.defaultView||window;var g=f.getSelection&&f.getSelection();if(g&&g.rangeCount!==0){f=g.anchorNode;var y=g.anchorOffset,w=g.focusNode;g=g.focusOffset;try{f.nodeType,w.nodeType}catch{f=null;break e}var A=0,I=-1,Z=-1,xe=0,je=0,Te=o,be=null;t:for(;;){for(var ke;Te!==f||y!==0&&Te.nodeType!==3||(I=A+y),Te!==w||g!==0&&Te.nodeType!==3||(Z=A+g),Te.nodeType===3&&(A+=Te.nodeValue.length),(ke=Te.firstChild)!==null;)be=Te,Te=ke;for(;;){if(Te===o)break t;if(be===f&&++xe===y&&(I=A),be===w&&++je===g&&(Z=A),(ke=Te.nextSibling)!==null)break;Te=be,be=Te.parentNode}Te=ke}f=I===-1||Z===-1?null:{start:I,end:Z}}else f=null}f=f||{start:0,end:0}}else f=null;for(Kv={focusedElem:o,selectionRange:f},Im=!1,_r=u;_r!==null;)if(u=_r,o=u.child,(u.subtreeFlags&1028)!==0&&o!==null)o.return=u,_r=o;else for(;_r!==null;){switch(u=_r,w=u.alternate,o=u.flags,u.tag){case 0:if((o&4)!==0&&(o=u.updateQueue,o=o!==null?o.events:null,o!==null))for(f=0;f title"))),Qr(w,g,f),w[Br]=o,Er(w),g=w;break e;case"link":var A=Uk("link","href",y).get(g+(f.href||""));if(A){for(var I=0;ISn&&(A=Sn,Sn=lt,lt=A);var oe=X3(I,lt),se=X3(I,Sn);if(oe&&se&&(ke.rangeCount!==1||ke.anchorNode!==oe.node||ke.anchorOffset!==oe.offset||ke.focusNode!==se.node||ke.focusOffset!==se.offset)){var pe=Te.createRange();pe.setStart(oe.node,oe.offset),ke.removeAllRanges(),lt>Sn?(ke.addRange(pe),ke.extend(se.node,se.offset)):(pe.setEnd(se.node,se.offset),ke.addRange(pe))}}}}for(Te=[],ke=I;ke=ke.parentNode;)ke.nodeType===1&&Te.push({element:ke,left:ke.scrollLeft,top:ke.scrollTop});for(typeof I.focus=="function"&&I.focus(),I=0;If?32:f,H.T=null,f=Pv,Pv=null;var w=Bl,A=Va;if(br=0,xu=Bl=null,Va=0,(sn&6)!==0)throw Error(r(331));var I=sn;if(sn|=4,YS(w.current),WS(w,w.current,A,f),sn=I,xh(0,!1),Me&&typeof Me.onPostCommitFiberRoot=="function")try{Me.onPostCommitFiberRoot(re,w)}catch{}return!0}finally{ae.p=y,H.T=g,mk(o,u)}}function gk(o,u,f){u=ui(f,u),u=pv(o.stateNode,u,2),o=El(o,u,2),o!==null&&(Ld(o,2),Ki(o))}function gn(o,u,f){if(o.tag===3)gk(o,o,f);else for(;u!==null;){if(u.tag===3){gk(u,o,f);break}else if(u.tag===1){var g=u.stateNode;if(typeof u.type.getDerivedStateFromError=="function"||typeof g.componentDidCatch=="function"&&(Ll===null||!Ll.has(g))){o=ui(f,o),f=xS(2),g=El(u,f,2),g!==null&&(vS(f,g,u,o),Ld(g,2),Ki(g));break}}u=u.return}}function qv(o,u,f){var g=o.pingCache;if(g===null){g=o.pingCache=new RB;var y=new Set;g.set(u,y)}else y=g.get(u),y===void 0&&(y=new Set,g.set(u,y));y.has(f)||(_v=!0,y.add(f),o=IB.bind(null,o,u,f),u.then(o,o))}function IB(o,u,f){var g=o.pingCache;g!==null&&g.delete(u),o.pingedLanes|=o.suspendedLanes&f,o.warmLanes&=~f,Mn===o&&(Ft&f)===f&&(tr===4||tr===3&&(Ft&62914560)===Ft&&300>yn()-wm?(sn&2)===0&&vu(o,0):Dv|=f,gu===Ft&&(gu=0)),Ki(o)}function xk(o,u){u===0&&(u=qc()),o=Lo(o,u),o!==null&&(Ld(o,u),Ki(o))}function qB(o){var u=o.memoizedState,f=0;u!==null&&(f=u.retryLane),xk(o,f)}function FB(o,u){var f=0;switch(o.tag){case 31:case 13:var g=o.stateNode,y=o.memoizedState;y!==null&&(f=y.retryLane);break;case 19:g=o.stateNode;break;case 22:g=o.stateNode._retryCache;break;default:throw Error(r(314))}g!==null&&g.delete(u),xk(o,f)}function QB(o,u){return _t(o,u)}var Tm=null,bu=null,Fv=!1,Mm=!1,Qv=!1,ql=0;function Ki(o){o!==bu&&o.next===null&&(bu===null?Tm=bu=o:bu=bu.next=o),Mm=!0,Fv||(Fv=!0,HB())}function xh(o,u){if(!Qv&&Mm){Qv=!0;do for(var f=!1,g=Tm;g!==null;){if(o!==0){var y=g.pendingLanes;if(y===0)var w=0;else{var A=g.suspendedLanes,I=g.pingedLanes;w=(1<<31-vt(42|o)+1)-1,w&=y&~(A&~I),w=w&201326741?w&201326741|1:w?w|2:0}w!==0&&(f=!0,wk(g,w))}else w=Ft,w=Ic(g,g===Mn?w:0,g.cancelPendingCommit!==null||g.timeoutHandle!==-1),(w&3)===0||Eo(g,w)||(f=!0,wk(g,w));g=g.next}while(f);Qv=!1}}function $B(){vk()}function vk(){Mm=Fv=!1;var o=0;ql!==0&&eI()&&(o=ql);for(var u=yn(),f=null,g=Tm;g!==null;){var y=g.next,w=yk(g,u);w===0?(g.next=null,f===null?Tm=y:f.next=y,y===null&&(bu=f)):(f=g,(o!==0||(w&3)!==0)&&(Mm=!0)),g=y}br!==0&&br!==5||xh(o),ql!==0&&(ql=0)}function yk(o,u){for(var f=o.suspendedLanes,g=o.pingedLanes,y=o.expirationTimes,w=o.pendingLanes&-62914561;0I)break;var je=Z.transferSize,Te=Z.initiatorType;je&&Mk(Te)&&(Z=Z.responseEnd,A+=je*(Z"u"?null:document;function Fk(o,u,f){var g=wu;if(g&&typeof u=="string"&&u){var y=oi(u);y='link[rel="'+o+'"][href="'+y+'"]',typeof f=="string"&&(y+='[crossorigin="'+f+'"]'),qk.has(y)||(qk.add(y),o={rel:o,crossOrigin:f,href:u},g.querySelector(y)===null&&(u=g.createElement("link"),Qr(u,"link",o),Er(u),g.head.appendChild(u)))}}function cI(o){Wa.D(o),Fk("dns-prefetch",o,null)}function uI(o,u){Wa.C(o,u),Fk("preconnect",o,u)}function dI(o,u,f){Wa.L(o,u,f);var g=wu;if(g&&o&&u){var y='link[rel="preload"][as="'+oi(u)+'"]';u==="image"&&f&&f.imageSrcSet?(y+='[imagesrcset="'+oi(f.imageSrcSet)+'"]',typeof f.imageSizes=="string"&&(y+='[imagesizes="'+oi(f.imageSizes)+'"]')):y+='[href="'+oi(o)+'"]';var w=y;switch(u){case"style":w=Su(o);break;case"script":w=ku(o)}gi.has(w)||(o=p({rel:"preload",href:u==="image"&&f&&f.imageSrcSet?void 0:o,as:u},f),gi.set(w,o),g.querySelector(y)!==null||u==="style"&&g.querySelector(wh(w))||u==="script"&&g.querySelector(Sh(w))||(u=g.createElement("link"),Qr(u,"link",o),Er(u),g.head.appendChild(u)))}}function hI(o,u){Wa.m(o,u);var f=wu;if(f&&o){var g=u&&typeof u.as=="string"?u.as:"script",y='link[rel="modulepreload"][as="'+oi(g)+'"][href="'+oi(o)+'"]',w=y;switch(g){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":w=ku(o)}if(!gi.has(w)&&(o=p({rel:"modulepreload",href:o},u),gi.set(w,o),f.querySelector(y)===null)){switch(g){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(f.querySelector(Sh(w)))return}g=f.createElement("link"),Qr(g,"link",o),Er(g),f.head.appendChild(g)}}}function fI(o,u,f){Wa.S(o,u,f);var g=wu;if(g&&o){var y=Hc(g).hoistableStyles,w=Su(o);u=u||"default";var A=y.get(w);if(!A){var I={loading:0,preload:null};if(A=g.querySelector(wh(w)))I.loading=5;else{o=p({rel:"stylesheet",href:o,"data-precedence":u},f),(f=gi.get(w))&&sy(o,f);var Z=A=g.createElement("link");Er(Z),Qr(Z,"link",o),Z._p=new Promise(function(xe,je){Z.onload=xe,Z.onerror=je}),Z.addEventListener("load",function(){I.loading|=1}),Z.addEventListener("error",function(){I.loading|=2}),I.loading|=4,Rm(A,u,g)}A={type:"stylesheet",instance:A,count:1,state:I},y.set(w,A)}}}function mI(o,u){Wa.X(o,u);var f=wu;if(f&&o){var g=Hc(f).hoistableScripts,y=ku(o),w=g.get(y);w||(w=f.querySelector(Sh(y)),w||(o=p({src:o,async:!0},u),(u=gi.get(y))&&iy(o,u),w=f.createElement("script"),Er(w),Qr(w,"link",o),f.head.appendChild(w)),w={type:"script",instance:w,count:1,state:null},g.set(y,w))}}function pI(o,u){Wa.M(o,u);var f=wu;if(f&&o){var g=Hc(f).hoistableScripts,y=ku(o),w=g.get(y);w||(w=f.querySelector(Sh(y)),w||(o=p({src:o,async:!0,type:"module"},u),(u=gi.get(y))&&iy(o,u),w=f.createElement("script"),Er(w),Qr(w,"link",o),f.head.appendChild(w)),w={type:"script",instance:w,count:1,state:null},g.set(y,w))}}function Qk(o,u,f,g){var y=(y=fe.current)?Dm(y):null;if(!y)throw Error(r(446));switch(o){case"meta":case"title":return null;case"style":return typeof f.precedence=="string"&&typeof f.href=="string"?(u=Su(f.href),f=Hc(y).hoistableStyles,g=f.get(u),g||(g={type:"style",instance:null,count:0,state:null},f.set(u,g)),g):{type:"void",instance:null,count:0,state:null};case"link":if(f.rel==="stylesheet"&&typeof f.href=="string"&&typeof f.precedence=="string"){o=Su(f.href);var w=Hc(y).hoistableStyles,A=w.get(o);if(A||(y=y.ownerDocument||y,A={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},w.set(o,A),(w=y.querySelector(wh(o)))&&!w._p&&(A.instance=w,A.state.loading=5),gi.has(o)||(f={rel:"preload",as:"style",href:f.href,crossOrigin:f.crossOrigin,integrity:f.integrity,media:f.media,hrefLang:f.hrefLang,referrerPolicy:f.referrerPolicy},gi.set(o,f),w||gI(y,o,f,A.state))),u&&g===null)throw Error(r(528,""));return A}if(u&&g!==null)throw Error(r(529,""));return null;case"script":return u=f.async,f=f.src,typeof f=="string"&&u&&typeof u!="function"&&typeof u!="symbol"?(u=ku(f),f=Hc(y).hoistableScripts,g=f.get(u),g||(g={type:"script",instance:null,count:0,state:null},f.set(u,g)),g):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,o))}}function Su(o){return'href="'+oi(o)+'"'}function wh(o){return'link[rel="stylesheet"]['+o+"]"}function $k(o){return p({},o,{"data-precedence":o.precedence,precedence:null})}function gI(o,u,f,g){o.querySelector('link[rel="preload"][as="style"]['+u+"]")?g.loading=1:(u=o.createElement("link"),g.preload=u,u.addEventListener("load",function(){return g.loading|=1}),u.addEventListener("error",function(){return g.loading|=2}),Qr(u,"link",f),Er(u),o.head.appendChild(u))}function ku(o){return'[src="'+oi(o)+'"]'}function Sh(o){return"script[async]"+o}function Hk(o,u,f){if(u.count++,u.instance===null)switch(u.type){case"style":var g=o.querySelector('style[data-href~="'+oi(f.href)+'"]');if(g)return u.instance=g,Er(g),g;var y=p({},f,{"data-href":f.href,"data-precedence":f.precedence,href:null,precedence:null});return g=(o.ownerDocument||o).createElement("style"),Er(g),Qr(g,"style",y),Rm(g,f.precedence,o),u.instance=g;case"stylesheet":y=Su(f.href);var w=o.querySelector(wh(y));if(w)return u.state.loading|=4,u.instance=w,Er(w),w;g=$k(f),(y=gi.get(y))&&sy(g,y),w=(o.ownerDocument||o).createElement("link"),Er(w);var A=w;return A._p=new Promise(function(I,Z){A.onload=I,A.onerror=Z}),Qr(w,"link",g),u.state.loading|=4,Rm(w,f.precedence,o),u.instance=w;case"script":return w=ku(f.src),(y=o.querySelector(Sh(w)))?(u.instance=y,Er(y),y):(g=f,(y=gi.get(w))&&(g=p({},f),iy(g,y)),o=o.ownerDocument||o,y=o.createElement("script"),Er(y),Qr(y,"link",g),o.head.appendChild(y),u.instance=y);case"void":return null;default:throw Error(r(443,u.type))}else u.type==="stylesheet"&&(u.state.loading&4)===0&&(g=u.instance,u.state.loading|=4,Rm(g,f.precedence,o));return u.instance}function Rm(o,u,f){for(var g=f.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),y=g.length?g[g.length-1]:null,w=y,A=0;A title"):null)}function xI(o,u,f){if(f===1||u.itemProp!=null)return!1;switch(o){case"meta":case"title":return!0;case"style":if(typeof u.precedence!="string"||typeof u.href!="string"||u.href==="")break;return!0;case"link":if(typeof u.rel!="string"||typeof u.href!="string"||u.href===""||u.onLoad||u.onError)break;switch(u.rel){case"stylesheet":return o=u.disabled,typeof u.precedence=="string"&&o==null;default:return!0}case"script":if(u.async&&typeof u.async!="function"&&typeof u.async!="symbol"&&!u.onLoad&&!u.onError&&u.src&&typeof u.src=="string")return!0}return!1}function Wk(o){return!(o.type==="stylesheet"&&(o.state.loading&3)===0)}function vI(o,u,f,g){if(f.type==="stylesheet"&&(typeof g.media!="string"||matchMedia(g.media).matches!==!1)&&(f.state.loading&4)===0){if(f.instance===null){var y=Su(g.href),w=u.querySelector(wh(y));if(w){u=w._p,u!==null&&typeof u=="object"&&typeof u.then=="function"&&(o.count++,o=Pm.bind(o),u.then(o,o)),f.state.loading|=4,f.instance=w,Er(w);return}w=u.ownerDocument||u,g=$k(g),(y=gi.get(y))&&sy(g,y),w=w.createElement("link"),Er(w);var A=w;A._p=new Promise(function(I,Z){A.onload=I,A.onerror=Z}),Qr(w,"link",g),f.instance=w}o.stylesheets===null&&(o.stylesheets=new Map),o.stylesheets.set(f,u),(u=f.state.preload)&&(f.state.loading&3)===0&&(o.count++,f=Pm.bind(o),u.addEventListener("load",f),u.addEventListener("error",f))}}var ay=0;function yI(o,u){return o.stylesheets&&o.count===0&&Bm(o,o.stylesheets),0ay?50:800)+u);return o.unsuspend=f,function(){o.unsuspend=null,clearTimeout(g),clearTimeout(y)}}:null}function Pm(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Bm(this,this.stylesheets);else if(this.unsuspend){var o=this.unsuspend;this.unsuspend=null,o()}}}var Lm=null;function Bm(o,u){o.stylesheets=null,o.unsuspend!==null&&(o.count++,Lm=new Map,u.forEach(bI,o),Lm=null,Pm.call(o))}function bI(o,u){if(!(u.state.loading&4)){var f=Lm.get(o);if(f)var g=f.get(null);else{f=new Map,Lm.set(o,f);for(var y=o.querySelectorAll("link[data-precedence],style[data-precedence]"),w=0;w"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),py.exports=zq(),py.exports}var Lq=Pq();function B9(t,e){return function(){return t.apply(e,arguments)}}const{toString:Bq}=Object.prototype,{getPrototypeOf:J4}=Object,{iterator:ox,toStringTag:I9}=Symbol,cx=(t=>e=>{const n=Bq.call(e);return t[n]||(t[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),Ui=t=>(t=t.toLowerCase(),e=>cx(e)===t),ux=t=>e=>typeof e===t,{isArray:Sd}=Array,sd=ux("undefined");function Kf(t){return t!==null&&!sd(t)&&t.constructor!==null&&!sd(t.constructor)&&Ds(t.constructor.isBuffer)&&t.constructor.isBuffer(t)}const q9=Ui("ArrayBuffer");function Iq(t){let e;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?e=ArrayBuffer.isView(t):e=t&&t.buffer&&q9(t.buffer),e}const qq=ux("string"),Ds=ux("function"),F9=ux("number"),Zf=t=>t!==null&&typeof t=="object",Fq=t=>t===!0||t===!1,$p=t=>{if(cx(t)!=="object")return!1;const e=J4(t);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(I9 in t)&&!(ox in t)},Qq=t=>{if(!Zf(t)||Kf(t))return!1;try{return Object.keys(t).length===0&&Object.getPrototypeOf(t)===Object.prototype}catch{return!1}},$q=Ui("Date"),Hq=Ui("File"),Uq=Ui("Blob"),Vq=Ui("FileList"),Wq=t=>Zf(t)&&Ds(t.pipe),Gq=t=>{let e;return t&&(typeof FormData=="function"&&t instanceof FormData||Ds(t.append)&&((e=cx(t))==="formdata"||e==="object"&&Ds(t.toString)&&t.toString()==="[object FormData]"))},Xq=Ui("URLSearchParams"),[Yq,Kq,Zq,Jq]=["ReadableStream","Request","Response","Headers"].map(Ui),eF=t=>t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Jf(t,e,{allOwnKeys:n=!1}={}){if(t===null||typeof t>"u")return;let r,s;if(typeof t!="object"&&(t=[t]),Sd(t))for(r=0,s=t.length;r0;)if(s=n[r],e===s.toLowerCase())return s;return null}const ic=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,$9=t=>!sd(t)&&t!==ic;function n2(){const{caseless:t,skipUndefined:e}=$9(this)&&this||{},n={},r=(s,i)=>{const l=t&&Q9(n,i)||i;$p(n[l])&&$p(s)?n[l]=n2(n[l],s):$p(s)?n[l]=n2({},s):Sd(s)?n[l]=s.slice():(!e||!sd(s))&&(n[l]=s)};for(let s=0,i=arguments.length;s(Jf(e,(s,i)=>{n&&Ds(s)?t[i]=B9(s,n):t[i]=s},{allOwnKeys:r}),t),nF=t=>(t.charCodeAt(0)===65279&&(t=t.slice(1)),t),rF=(t,e,n,r)=>{t.prototype=Object.create(e.prototype,r),t.prototype.constructor=t,Object.defineProperty(t,"super",{value:e.prototype}),n&&Object.assign(t.prototype,n)},sF=(t,e,n,r)=>{let s,i,l;const c={};if(e=e||{},t==null)return e;do{for(s=Object.getOwnPropertyNames(t),i=s.length;i-- >0;)l=s[i],(!r||r(l,t,e))&&!c[l]&&(e[l]=t[l],c[l]=!0);t=n!==!1&&J4(t)}while(t&&(!n||n(t,e))&&t!==Object.prototype);return e},iF=(t,e,n)=>{t=String(t),(n===void 0||n>t.length)&&(n=t.length),n-=e.length;const r=t.indexOf(e,n);return r!==-1&&r===n},aF=t=>{if(!t)return null;if(Sd(t))return t;let e=t.length;if(!F9(e))return null;const n=new Array(e);for(;e-- >0;)n[e]=t[e];return n},lF=(t=>e=>t&&e instanceof t)(typeof Uint8Array<"u"&&J4(Uint8Array)),oF=(t,e)=>{const r=(t&&t[ox]).call(t);let s;for(;(s=r.next())&&!s.done;){const i=s.value;e.call(t,i[0],i[1])}},cF=(t,e)=>{let n;const r=[];for(;(n=t.exec(e))!==null;)r.push(n);return r},uF=Ui("HTMLFormElement"),dF=t=>t.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,s){return r.toUpperCase()+s}),vO=(({hasOwnProperty:t})=>(e,n)=>t.call(e,n))(Object.prototype),hF=Ui("RegExp"),H9=(t,e)=>{const n=Object.getOwnPropertyDescriptors(t),r={};Jf(n,(s,i)=>{let l;(l=e(s,i,t))!==!1&&(r[i]=l||s)}),Object.defineProperties(t,r)},fF=t=>{H9(t,(e,n)=>{if(Ds(t)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=t[n];if(Ds(r)){if(e.enumerable=!1,"writable"in e){e.writable=!1;return}e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},mF=(t,e)=>{const n={},r=s=>{s.forEach(i=>{n[i]=!0})};return Sd(t)?r(t):r(String(t).split(e)),n},pF=()=>{},gF=(t,e)=>t!=null&&Number.isFinite(t=+t)?t:e;function xF(t){return!!(t&&Ds(t.append)&&t[I9]==="FormData"&&t[ox])}const vF=t=>{const e=new Array(10),n=(r,s)=>{if(Zf(r)){if(e.indexOf(r)>=0)return;if(Kf(r))return r;if(!("toJSON"in r)){e[s]=r;const i=Sd(r)?[]:{};return Jf(r,(l,c)=>{const d=n(l,s+1);!sd(d)&&(i[c]=d)}),e[s]=void 0,i}}return r};return n(t,0)},yF=Ui("AsyncFunction"),bF=t=>t&&(Zf(t)||Ds(t))&&Ds(t.then)&&Ds(t.catch),U9=((t,e)=>t?setImmediate:e?((n,r)=>(ic.addEventListener("message",({source:s,data:i})=>{s===ic&&i===n&&r.length&&r.shift()()},!1),s=>{r.push(s),ic.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",Ds(ic.postMessage)),wF=typeof queueMicrotask<"u"?queueMicrotask.bind(ic):typeof process<"u"&&process.nextTick||U9,SF=t=>t!=null&&Ds(t[ox]),we={isArray:Sd,isArrayBuffer:q9,isBuffer:Kf,isFormData:Gq,isArrayBufferView:Iq,isString:qq,isNumber:F9,isBoolean:Fq,isObject:Zf,isPlainObject:$p,isEmptyObject:Qq,isReadableStream:Yq,isRequest:Kq,isResponse:Zq,isHeaders:Jq,isUndefined:sd,isDate:$q,isFile:Hq,isBlob:Uq,isRegExp:hF,isFunction:Ds,isStream:Wq,isURLSearchParams:Xq,isTypedArray:lF,isFileList:Vq,forEach:Jf,merge:n2,extend:tF,trim:eF,stripBOM:nF,inherits:rF,toFlatObject:sF,kindOf:cx,kindOfTest:Ui,endsWith:iF,toArray:aF,forEachEntry:oF,matchAll:cF,isHTMLForm:uF,hasOwnProperty:vO,hasOwnProp:vO,reduceDescriptors:H9,freezeMethods:fF,toObjectSet:mF,toCamelCase:dF,noop:pF,toFiniteNumber:gF,findKey:Q9,global:ic,isContextDefined:$9,isSpecCompliantForm:xF,toJSONObject:vF,isAsyncFn:yF,isThenable:bF,setImmediate:U9,asap:wF,isIterable:SF};function St(t,e,n,r,s){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=t,this.name="AxiosError",e&&(this.code=e),n&&(this.config=n),r&&(this.request=r),s&&(this.response=s,this.status=s.status?s.status:null)}we.inherits(St,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:we.toJSONObject(this.config),code:this.code,status:this.status}}});const V9=St.prototype,W9={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(t=>{W9[t]={value:t}});Object.defineProperties(St,W9);Object.defineProperty(V9,"isAxiosError",{value:!0});St.from=(t,e,n,r,s,i)=>{const l=Object.create(V9);we.toFlatObject(t,l,function(m){return m!==Error.prototype},h=>h!=="isAxiosError");const c=t&&t.message?t.message:"Error",d=e==null&&t?t.code:e;return St.call(l,c,d,n,r,s),t&&l.cause==null&&Object.defineProperty(l,"cause",{value:t,configurable:!0}),l.name=t&&t.name||"Error",i&&Object.assign(l,i),l};const kF=null;function r2(t){return we.isPlainObject(t)||we.isArray(t)}function G9(t){return we.endsWith(t,"[]")?t.slice(0,-2):t}function yO(t,e,n){return t?t.concat(e).map(function(s,i){return s=G9(s),!n&&i?"["+s+"]":s}).join(n?".":""):e}function OF(t){return we.isArray(t)&&!t.some(r2)}const jF=we.toFlatObject(we,{},null,function(e){return/^is[A-Z]/.test(e)});function dx(t,e,n){if(!we.isObject(t))throw new TypeError("target must be an object");e=e||new FormData,n=we.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(k,O){return!we.isUndefined(O[k])});const r=n.metaTokens,s=n.visitor||m,i=n.dots,l=n.indexes,d=(n.Blob||typeof Blob<"u"&&Blob)&&we.isSpecCompliantForm(e);if(!we.isFunction(s))throw new TypeError("visitor must be a function");function h(b){if(b===null)return"";if(we.isDate(b))return b.toISOString();if(we.isBoolean(b))return b.toString();if(!d&&we.isBlob(b))throw new St("Blob is not supported. Use a Buffer instead.");return we.isArrayBuffer(b)||we.isTypedArray(b)?d&&typeof Blob=="function"?new Blob([b]):Buffer.from(b):b}function m(b,k,O){let j=b;if(b&&!O&&typeof b=="object"){if(we.endsWith(k,"{}"))k=r?k:k.slice(0,-2),b=JSON.stringify(b);else if(we.isArray(b)&&OF(b)||(we.isFileList(b)||we.endsWith(k,"[]"))&&(j=we.toArray(b)))return k=G9(k),j.forEach(function(M,_){!(we.isUndefined(M)||M===null)&&e.append(l===!0?yO([k],_,i):l===null?k:k+"[]",h(M))}),!1}return r2(b)?!0:(e.append(yO(O,k,i),h(b)),!1)}const p=[],x=Object.assign(jF,{defaultVisitor:m,convertValue:h,isVisitable:r2});function v(b,k){if(!we.isUndefined(b)){if(p.indexOf(b)!==-1)throw Error("Circular reference detected in "+k.join("."));p.push(b),we.forEach(b,function(j,T){(!(we.isUndefined(j)||j===null)&&s.call(e,j,we.isString(T)?T.trim():T,k,x))===!0&&v(j,k?k.concat(T):[T])}),p.pop()}}if(!we.isObject(t))throw new TypeError("data must be an object");return v(t),e}function bO(t){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(t).replace(/[!'()~]|%20|%00/g,function(r){return e[r]})}function ew(t,e){this._pairs=[],t&&dx(t,this,e)}const X9=ew.prototype;X9.append=function(e,n){this._pairs.push([e,n])};X9.toString=function(e){const n=e?function(r){return e.call(this,r,bO)}:bO;return this._pairs.map(function(s){return n(s[0])+"="+n(s[1])},"").join("&")};function NF(t){return encodeURIComponent(t).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Y9(t,e,n){if(!e)return t;const r=n&&n.encode||NF;we.isFunction(n)&&(n={serialize:n});const s=n&&n.serialize;let i;if(s?i=s(e,n):i=we.isURLSearchParams(e)?e.toString():new ew(e,n).toString(r),i){const l=t.indexOf("#");l!==-1&&(t=t.slice(0,l)),t+=(t.indexOf("?")===-1?"?":"&")+i}return t}class wO{constructor(){this.handlers=[]}use(e,n,r){return this.handlers.push({fulfilled:e,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){we.forEach(this.handlers,function(r){r!==null&&e(r)})}}const K9={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},CF=typeof URLSearchParams<"u"?URLSearchParams:ew,TF=typeof FormData<"u"?FormData:null,MF=typeof Blob<"u"?Blob:null,AF={isBrowser:!0,classes:{URLSearchParams:CF,FormData:TF,Blob:MF},protocols:["http","https","file","blob","url","data"]},tw=typeof window<"u"&&typeof document<"u",s2=typeof navigator=="object"&&navigator||void 0,EF=tw&&(!s2||["ReactNative","NativeScript","NS"].indexOf(s2.product)<0),_F=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",DF=tw&&window.location.href||"http://localhost",RF=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:tw,hasStandardBrowserEnv:EF,hasStandardBrowserWebWorkerEnv:_F,navigator:s2,origin:DF},Symbol.toStringTag,{value:"Module"})),ts={...RF,...AF};function zF(t,e){return dx(t,new ts.classes.URLSearchParams,{visitor:function(n,r,s,i){return ts.isNode&&we.isBuffer(n)?(this.append(r,n.toString("base64")),!1):i.defaultVisitor.apply(this,arguments)},...e})}function PF(t){return we.matchAll(/\w+|\[(\w*)]/g,t).map(e=>e[0]==="[]"?"":e[1]||e[0])}function LF(t){const e={},n=Object.keys(t);let r;const s=n.length;let i;for(r=0;r=n.length;return l=!l&&we.isArray(s)?s.length:l,d?(we.hasOwnProp(s,l)?s[l]=[s[l],r]:s[l]=r,!c):((!s[l]||!we.isObject(s[l]))&&(s[l]=[]),e(n,r,s[l],i)&&we.isArray(s[l])&&(s[l]=LF(s[l])),!c)}if(we.isFormData(t)&&we.isFunction(t.entries)){const n={};return we.forEachEntry(t,(r,s)=>{e(PF(r),s,n,0)}),n}return null}function BF(t,e,n){if(we.isString(t))try{return(e||JSON.parse)(t),we.trim(t)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(t)}const e0={transitional:K9,adapter:["xhr","http","fetch"],transformRequest:[function(e,n){const r=n.getContentType()||"",s=r.indexOf("application/json")>-1,i=we.isObject(e);if(i&&we.isHTMLForm(e)&&(e=new FormData(e)),we.isFormData(e))return s?JSON.stringify(Z9(e)):e;if(we.isArrayBuffer(e)||we.isBuffer(e)||we.isStream(e)||we.isFile(e)||we.isBlob(e)||we.isReadableStream(e))return e;if(we.isArrayBufferView(e))return e.buffer;if(we.isURLSearchParams(e))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let c;if(i){if(r.indexOf("application/x-www-form-urlencoded")>-1)return zF(e,this.formSerializer).toString();if((c=we.isFileList(e))||r.indexOf("multipart/form-data")>-1){const d=this.env&&this.env.FormData;return dx(c?{"files[]":e}:e,d&&new d,this.formSerializer)}}return i||s?(n.setContentType("application/json",!1),BF(e)):e}],transformResponse:[function(e){const n=this.transitional||e0.transitional,r=n&&n.forcedJSONParsing,s=this.responseType==="json";if(we.isResponse(e)||we.isReadableStream(e))return e;if(e&&we.isString(e)&&(r&&!this.responseType||s)){const l=!(n&&n.silentJSONParsing)&&s;try{return JSON.parse(e,this.parseReviver)}catch(c){if(l)throw c.name==="SyntaxError"?St.from(c,St.ERR_BAD_RESPONSE,this,null,this.response):c}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ts.classes.FormData,Blob:ts.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};we.forEach(["delete","get","head","post","put","patch"],t=>{e0.headers[t]={}});const IF=we.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),qF=t=>{const e={};let n,r,s;return t&&t.split(` -`).forEach(function(l){s=l.indexOf(":"),n=l.substring(0,s).trim().toLowerCase(),r=l.substring(s+1).trim(),!(!n||e[n]&&IF[n])&&(n==="set-cookie"?e[n]?e[n].push(r):e[n]=[r]:e[n]=e[n]?e[n]+", "+r:r)}),e},SO=Symbol("internals");function Mh(t){return t&&String(t).trim().toLowerCase()}function Hp(t){return t===!1||t==null?t:we.isArray(t)?t.map(Hp):String(t)}function FF(t){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(t);)e[r[1]]=r[2];return e}const QF=t=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(t.trim());function vy(t,e,n,r,s){if(we.isFunction(r))return r.call(this,e,n);if(s&&(e=n),!!we.isString(e)){if(we.isString(r))return e.indexOf(r)!==-1;if(we.isRegExp(r))return r.test(e)}}function $F(t){return t.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,n,r)=>n.toUpperCase()+r)}function HF(t,e){const n=we.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(t,r+n,{value:function(s,i,l){return this[r].call(this,e,s,i,l)},configurable:!0})})}let Rs=class{constructor(e){e&&this.set(e)}set(e,n,r){const s=this;function i(c,d,h){const m=Mh(d);if(!m)throw new Error("header name must be a non-empty string");const p=we.findKey(s,m);(!p||s[p]===void 0||h===!0||h===void 0&&s[p]!==!1)&&(s[p||d]=Hp(c))}const l=(c,d)=>we.forEach(c,(h,m)=>i(h,m,d));if(we.isPlainObject(e)||e instanceof this.constructor)l(e,n);else if(we.isString(e)&&(e=e.trim())&&!QF(e))l(qF(e),n);else if(we.isObject(e)&&we.isIterable(e)){let c={},d,h;for(const m of e){if(!we.isArray(m))throw TypeError("Object iterator must return a key-value pair");c[h=m[0]]=(d=c[h])?we.isArray(d)?[...d,m[1]]:[d,m[1]]:m[1]}l(c,n)}else e!=null&&i(n,e,r);return this}get(e,n){if(e=Mh(e),e){const r=we.findKey(this,e);if(r){const s=this[r];if(!n)return s;if(n===!0)return FF(s);if(we.isFunction(n))return n.call(this,s,r);if(we.isRegExp(n))return n.exec(s);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,n){if(e=Mh(e),e){const r=we.findKey(this,e);return!!(r&&this[r]!==void 0&&(!n||vy(this,this[r],r,n)))}return!1}delete(e,n){const r=this;let s=!1;function i(l){if(l=Mh(l),l){const c=we.findKey(r,l);c&&(!n||vy(r,r[c],c,n))&&(delete r[c],s=!0)}}return we.isArray(e)?e.forEach(i):i(e),s}clear(e){const n=Object.keys(this);let r=n.length,s=!1;for(;r--;){const i=n[r];(!e||vy(this,this[i],i,e,!0))&&(delete this[i],s=!0)}return s}normalize(e){const n=this,r={};return we.forEach(this,(s,i)=>{const l=we.findKey(r,i);if(l){n[l]=Hp(s),delete n[i];return}const c=e?$F(i):String(i).trim();c!==i&&delete n[i],n[c]=Hp(s),r[c]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const n=Object.create(null);return we.forEach(this,(r,s)=>{r!=null&&r!==!1&&(n[s]=e&&we.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,n])=>e+": "+n).join(` -`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...n){const r=new this(e);return n.forEach(s=>r.set(s)),r}static accessor(e){const r=(this[SO]=this[SO]={accessors:{}}).accessors,s=this.prototype;function i(l){const c=Mh(l);r[c]||(HF(s,l),r[c]=!0)}return we.isArray(e)?e.forEach(i):i(e),this}};Rs.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);we.reduceDescriptors(Rs.prototype,({value:t},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(r){this[n]=r}}});we.freezeMethods(Rs);function yy(t,e){const n=this||e0,r=e||n,s=Rs.from(r.headers);let i=r.data;return we.forEach(t,function(c){i=c.call(n,i,s.normalize(),e?e.status:void 0)}),s.normalize(),i}function J9(t){return!!(t&&t.__CANCEL__)}function kd(t,e,n){St.call(this,t??"canceled",St.ERR_CANCELED,e,n),this.name="CanceledError"}we.inherits(kd,St,{__CANCEL__:!0});function eC(t,e,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?t(n):e(new St("Request failed with status code "+n.status,[St.ERR_BAD_REQUEST,St.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function UF(t){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}function VF(t,e){t=t||10;const n=new Array(t),r=new Array(t);let s=0,i=0,l;return e=e!==void 0?e:1e3,function(d){const h=Date.now(),m=r[i];l||(l=h),n[s]=d,r[s]=h;let p=i,x=0;for(;p!==s;)x+=n[p++],p=p%t;if(s=(s+1)%t,s===i&&(i=(i+1)%t),h-l{n=m,s=null,i&&(clearTimeout(i),i=null),t(...h)};return[(...h)=>{const m=Date.now(),p=m-n;p>=r?l(h,m):(s=h,i||(i=setTimeout(()=>{i=null,l(s)},r-p)))},()=>s&&l(s)]}const gg=(t,e,n=3)=>{let r=0;const s=VF(50,250);return WF(i=>{const l=i.loaded,c=i.lengthComputable?i.total:void 0,d=l-r,h=s(d),m=l<=c;r=l;const p={loaded:l,total:c,progress:c?l/c:void 0,bytes:d,rate:h||void 0,estimated:h&&c&&m?(c-l)/h:void 0,event:i,lengthComputable:c!=null,[e?"download":"upload"]:!0};t(p)},n)},kO=(t,e)=>{const n=t!=null;return[r=>e[0]({lengthComputable:n,total:t,loaded:r}),e[1]]},OO=t=>(...e)=>we.asap(()=>t(...e)),GF=ts.hasStandardBrowserEnv?((t,e)=>n=>(n=new URL(n,ts.origin),t.protocol===n.protocol&&t.host===n.host&&(e||t.port===n.port)))(new URL(ts.origin),ts.navigator&&/(msie|trident)/i.test(ts.navigator.userAgent)):()=>!0,XF=ts.hasStandardBrowserEnv?{write(t,e,n,r,s,i,l){if(typeof document>"u")return;const c=[`${t}=${encodeURIComponent(e)}`];we.isNumber(n)&&c.push(`expires=${new Date(n).toUTCString()}`),we.isString(r)&&c.push(`path=${r}`),we.isString(s)&&c.push(`domain=${s}`),i===!0&&c.push("secure"),we.isString(l)&&c.push(`SameSite=${l}`),document.cookie=c.join("; ")},read(t){if(typeof document>"u")return null;const e=document.cookie.match(new RegExp("(?:^|; )"+t+"=([^;]*)"));return e?decodeURIComponent(e[1]):null},remove(t){this.write(t,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function YF(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)}function KF(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}function tC(t,e,n){let r=!YF(e);return t&&(r||n==!1)?KF(t,e):e}const jO=t=>t instanceof Rs?{...t}:t;function vc(t,e){e=e||{};const n={};function r(h,m,p,x){return we.isPlainObject(h)&&we.isPlainObject(m)?we.merge.call({caseless:x},h,m):we.isPlainObject(m)?we.merge({},m):we.isArray(m)?m.slice():m}function s(h,m,p,x){if(we.isUndefined(m)){if(!we.isUndefined(h))return r(void 0,h,p,x)}else return r(h,m,p,x)}function i(h,m){if(!we.isUndefined(m))return r(void 0,m)}function l(h,m){if(we.isUndefined(m)){if(!we.isUndefined(h))return r(void 0,h)}else return r(void 0,m)}function c(h,m,p){if(p in e)return r(h,m);if(p in t)return r(void 0,h)}const d={url:i,method:i,data:i,baseURL:l,transformRequest:l,transformResponse:l,paramsSerializer:l,timeout:l,timeoutMessage:l,withCredentials:l,withXSRFToken:l,adapter:l,responseType:l,xsrfCookieName:l,xsrfHeaderName:l,onUploadProgress:l,onDownloadProgress:l,decompress:l,maxContentLength:l,maxBodyLength:l,beforeRedirect:l,transport:l,httpAgent:l,httpsAgent:l,cancelToken:l,socketPath:l,responseEncoding:l,validateStatus:c,headers:(h,m,p)=>s(jO(h),jO(m),p,!0)};return we.forEach(Object.keys({...t,...e}),function(m){const p=d[m]||s,x=p(t[m],e[m],m);we.isUndefined(x)&&p!==c||(n[m]=x)}),n}const nC=t=>{const e=vc({},t);let{data:n,withXSRFToken:r,xsrfHeaderName:s,xsrfCookieName:i,headers:l,auth:c}=e;if(e.headers=l=Rs.from(l),e.url=Y9(tC(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),c&&l.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(encodeURIComponent(c.password)):""))),we.isFormData(n)){if(ts.hasStandardBrowserEnv||ts.hasStandardBrowserWebWorkerEnv)l.setContentType(void 0);else if(we.isFunction(n.getHeaders)){const d=n.getHeaders(),h=["content-type","content-length"];Object.entries(d).forEach(([m,p])=>{h.includes(m.toLowerCase())&&l.set(m,p)})}}if(ts.hasStandardBrowserEnv&&(r&&we.isFunction(r)&&(r=r(e)),r||r!==!1&&GF(e.url))){const d=s&&i&&XF.read(i);d&&l.set(s,d)}return e},ZF=typeof XMLHttpRequest<"u",JF=ZF&&function(t){return new Promise(function(n,r){const s=nC(t);let i=s.data;const l=Rs.from(s.headers).normalize();let{responseType:c,onUploadProgress:d,onDownloadProgress:h}=s,m,p,x,v,b;function k(){v&&v(),b&&b(),s.cancelToken&&s.cancelToken.unsubscribe(m),s.signal&&s.signal.removeEventListener("abort",m)}let O=new XMLHttpRequest;O.open(s.method.toUpperCase(),s.url,!0),O.timeout=s.timeout;function j(){if(!O)return;const M=Rs.from("getAllResponseHeaders"in O&&O.getAllResponseHeaders()),D={data:!c||c==="text"||c==="json"?O.responseText:O.response,status:O.status,statusText:O.statusText,headers:M,config:t,request:O};eC(function(z){n(z),k()},function(z){r(z),k()},D),O=null}"onloadend"in O?O.onloadend=j:O.onreadystatechange=function(){!O||O.readyState!==4||O.status===0&&!(O.responseURL&&O.responseURL.indexOf("file:")===0)||setTimeout(j)},O.onabort=function(){O&&(r(new St("Request aborted",St.ECONNABORTED,t,O)),O=null)},O.onerror=function(_){const D=_&&_.message?_.message:"Network Error",E=new St(D,St.ERR_NETWORK,t,O);E.event=_||null,r(E),O=null},O.ontimeout=function(){let _=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded";const D=s.transitional||K9;s.timeoutErrorMessage&&(_=s.timeoutErrorMessage),r(new St(_,D.clarifyTimeoutError?St.ETIMEDOUT:St.ECONNABORTED,t,O)),O=null},i===void 0&&l.setContentType(null),"setRequestHeader"in O&&we.forEach(l.toJSON(),function(_,D){O.setRequestHeader(D,_)}),we.isUndefined(s.withCredentials)||(O.withCredentials=!!s.withCredentials),c&&c!=="json"&&(O.responseType=s.responseType),h&&([x,b]=gg(h,!0),O.addEventListener("progress",x)),d&&O.upload&&([p,v]=gg(d),O.upload.addEventListener("progress",p),O.upload.addEventListener("loadend",v)),(s.cancelToken||s.signal)&&(m=M=>{O&&(r(!M||M.type?new kd(null,t,O):M),O.abort(),O=null)},s.cancelToken&&s.cancelToken.subscribe(m),s.signal&&(s.signal.aborted?m():s.signal.addEventListener("abort",m)));const T=UF(s.url);if(T&&ts.protocols.indexOf(T)===-1){r(new St("Unsupported protocol "+T+":",St.ERR_BAD_REQUEST,t));return}O.send(i||null)})},eQ=(t,e)=>{const{length:n}=t=t?t.filter(Boolean):[];if(e||n){let r=new AbortController,s;const i=function(h){if(!s){s=!0,c();const m=h instanceof Error?h:this.reason;r.abort(m instanceof St?m:new kd(m instanceof Error?m.message:m))}};let l=e&&setTimeout(()=>{l=null,i(new St(`timeout ${e} of ms exceeded`,St.ETIMEDOUT))},e);const c=()=>{t&&(l&&clearTimeout(l),l=null,t.forEach(h=>{h.unsubscribe?h.unsubscribe(i):h.removeEventListener("abort",i)}),t=null)};t.forEach(h=>h.addEventListener("abort",i));const{signal:d}=r;return d.unsubscribe=()=>we.asap(c),d}},tQ=function*(t,e){let n=t.byteLength;if(n{const s=nQ(t,e);let i=0,l,c=d=>{l||(l=!0,r&&r(d))};return new ReadableStream({async pull(d){try{const{done:h,value:m}=await s.next();if(h){c(),d.close();return}let p=m.byteLength;if(n){let x=i+=p;n(x)}d.enqueue(new Uint8Array(m))}catch(h){throw c(h),h}},cancel(d){return c(d),s.return()}},{highWaterMark:2})},CO=64*1024,{isFunction:Xm}=we,sQ=(({Request:t,Response:e})=>({Request:t,Response:e}))(we.global),{ReadableStream:TO,TextEncoder:MO}=we.global,AO=(t,...e)=>{try{return!!t(...e)}catch{return!1}},iQ=t=>{t=we.merge.call({skipUndefined:!0},sQ,t);const{fetch:e,Request:n,Response:r}=t,s=e?Xm(e):typeof fetch=="function",i=Xm(n),l=Xm(r);if(!s)return!1;const c=s&&Xm(TO),d=s&&(typeof MO=="function"?(b=>k=>b.encode(k))(new MO):async b=>new Uint8Array(await new n(b).arrayBuffer())),h=i&&c&&AO(()=>{let b=!1;const k=new n(ts.origin,{body:new TO,method:"POST",get duplex(){return b=!0,"half"}}).headers.has("Content-Type");return b&&!k}),m=l&&c&&AO(()=>we.isReadableStream(new r("").body)),p={stream:m&&(b=>b.body)};s&&["text","arrayBuffer","blob","formData","stream"].forEach(b=>{!p[b]&&(p[b]=(k,O)=>{let j=k&&k[b];if(j)return j.call(k);throw new St(`Response type '${b}' is not supported`,St.ERR_NOT_SUPPORT,O)})});const x=async b=>{if(b==null)return 0;if(we.isBlob(b))return b.size;if(we.isSpecCompliantForm(b))return(await new n(ts.origin,{method:"POST",body:b}).arrayBuffer()).byteLength;if(we.isArrayBufferView(b)||we.isArrayBuffer(b))return b.byteLength;if(we.isURLSearchParams(b)&&(b=b+""),we.isString(b))return(await d(b)).byteLength},v=async(b,k)=>{const O=we.toFiniteNumber(b.getContentLength());return O??x(k)};return async b=>{let{url:k,method:O,data:j,signal:T,cancelToken:M,timeout:_,onDownloadProgress:D,onUploadProgress:E,responseType:z,headers:Q,withCredentials:F="same-origin",fetchOptions:B}=nC(b),U=e||fetch;z=z?(z+"").toLowerCase():"text";let V=eQ([T,M&&M.toAbortSignal()],_),ce=null;const W=V&&V.unsubscribe&&(()=>{V.unsubscribe()});let J;try{if(E&&h&&O!=="get"&&O!=="head"&&(J=await v(Q,j))!==0){let me=new n(k,{method:"POST",body:j,duplex:"half"}),Y;if(we.isFormData(j)&&(Y=me.headers.get("content-type"))&&Q.setContentType(Y),me.body){const[P,K]=kO(J,gg(OO(E)));j=NO(me.body,CO,P,K)}}we.isString(F)||(F=F?"include":"omit");const H=i&&"credentials"in n.prototype,ae={...B,signal:V,method:O.toUpperCase(),headers:Q.normalize().toJSON(),body:j,duplex:"half",credentials:H?F:void 0};ce=i&&new n(k,ae);let ne=await(i?U(ce,B):U(k,ae));const ue=m&&(z==="stream"||z==="response");if(m&&(D||ue&&W)){const me={};["status","statusText","headers"].forEach($=>{me[$]=ne[$]});const Y=we.toFiniteNumber(ne.headers.get("content-length")),[P,K]=D&&kO(Y,gg(OO(D),!0))||[];ne=new r(NO(ne.body,CO,P,()=>{K&&K(),W&&W()}),me)}z=z||"text";let R=await p[we.findKey(p,z)||"text"](ne,b);return!ue&&W&&W(),await new Promise((me,Y)=>{eC(me,Y,{data:R,headers:Rs.from(ne.headers),status:ne.status,statusText:ne.statusText,config:b,request:ce})})}catch(H){throw W&&W(),H&&H.name==="TypeError"&&/Load failed|fetch/i.test(H.message)?Object.assign(new St("Network Error",St.ERR_NETWORK,b,ce),{cause:H.cause||H}):St.from(H,H&&H.code,b,ce)}}},aQ=new Map,rC=t=>{let e=t&&t.env||{};const{fetch:n,Request:r,Response:s}=e,i=[r,s,n];let l=i.length,c=l,d,h,m=aQ;for(;c--;)d=i[c],h=m.get(d),h===void 0&&m.set(d,h=c?new Map:iQ(e)),m=h;return h};rC();const nw={http:kF,xhr:JF,fetch:{get:rC}};we.forEach(nw,(t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch{}Object.defineProperty(t,"adapterName",{value:e})}});const EO=t=>`- ${t}`,lQ=t=>we.isFunction(t)||t===null||t===!1;function oQ(t,e){t=we.isArray(t)?t:[t];const{length:n}=t;let r,s;const i={};for(let l=0;l`adapter ${d} `+(h===!1?"is not supported by the environment":"is not available in the build"));let c=n?l.length>1?`since : -`+l.map(EO).join(` -`):" "+EO(l[0]):"as no adapter specified";throw new St("There is no suitable adapter to dispatch the request "+c,"ERR_NOT_SUPPORT")}return s}const sC={getAdapter:oQ,adapters:nw};function by(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new kd(null,t)}function _O(t){return by(t),t.headers=Rs.from(t.headers),t.data=yy.call(t,t.transformRequest),["post","put","patch"].indexOf(t.method)!==-1&&t.headers.setContentType("application/x-www-form-urlencoded",!1),sC.getAdapter(t.adapter||e0.adapter,t)(t).then(function(r){return by(t),r.data=yy.call(t,t.transformResponse,r),r.headers=Rs.from(r.headers),r},function(r){return J9(r)||(by(t),r&&r.response&&(r.response.data=yy.call(t,t.transformResponse,r.response),r.response.headers=Rs.from(r.response.headers))),Promise.reject(r)})}const iC="1.13.2",hx={};["object","boolean","number","function","string","symbol"].forEach((t,e)=>{hx[t]=function(r){return typeof r===t||"a"+(e<1?"n ":" ")+t}});const DO={};hx.transitional=function(e,n,r){function s(i,l){return"[Axios v"+iC+"] Transitional option '"+i+"'"+l+(r?". "+r:"")}return(i,l,c)=>{if(e===!1)throw new St(s(l," has been removed"+(n?" in "+n:"")),St.ERR_DEPRECATED);return n&&!DO[l]&&(DO[l]=!0,console.warn(s(l," has been deprecated since v"+n+" and will be removed in the near future"))),e?e(i,l,c):!0}};hx.spelling=function(e){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function cQ(t,e,n){if(typeof t!="object")throw new St("options must be an object",St.ERR_BAD_OPTION_VALUE);const r=Object.keys(t);let s=r.length;for(;s-- >0;){const i=r[s],l=e[i];if(l){const c=t[i],d=c===void 0||l(c,i,t);if(d!==!0)throw new St("option "+i+" must be "+d,St.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new St("Unknown option "+i,St.ERR_BAD_OPTION)}}const Up={assertOptions:cQ,validators:hx},Zi=Up.validators;let mc=class{constructor(e){this.defaults=e||{},this.interceptors={request:new wO,response:new wO}}async request(e,n){try{return await this._request(e,n)}catch(r){if(r instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const i=s.stack?s.stack.replace(/^.+\n/,""):"";try{r.stack?i&&!String(r.stack).endsWith(i.replace(/^.+\n.+\n/,""))&&(r.stack+=` -`+i):r.stack=i}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=vc(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:i}=n;r!==void 0&&Up.assertOptions(r,{silentJSONParsing:Zi.transitional(Zi.boolean),forcedJSONParsing:Zi.transitional(Zi.boolean),clarifyTimeoutError:Zi.transitional(Zi.boolean)},!1),s!=null&&(we.isFunction(s)?n.paramsSerializer={serialize:s}:Up.assertOptions(s,{encode:Zi.function,serialize:Zi.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Up.assertOptions(n,{baseUrl:Zi.spelling("baseURL"),withXsrfToken:Zi.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let l=i&&we.merge(i.common,i[n.method]);i&&we.forEach(["delete","get","head","post","put","patch","common"],b=>{delete i[b]}),n.headers=Rs.concat(l,i);const c=[];let d=!0;this.interceptors.request.forEach(function(k){typeof k.runWhen=="function"&&k.runWhen(n)===!1||(d=d&&k.synchronous,c.unshift(k.fulfilled,k.rejected))});const h=[];this.interceptors.response.forEach(function(k){h.push(k.fulfilled,k.rejected)});let m,p=0,x;if(!d){const b=[_O.bind(this),void 0];for(b.unshift(...c),b.push(...h),x=b.length,m=Promise.resolve(n);p{if(!r._listeners)return;let i=r._listeners.length;for(;i-- >0;)r._listeners[i](s);r._listeners=null}),this.promise.then=s=>{let i;const l=new Promise(c=>{r.subscribe(c),i=c}).then(s);return l.cancel=function(){r.unsubscribe(i)},l},e(function(i,l,c){r.reason||(r.reason=new kd(i,l,c),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new aC(function(s){e=s}),cancel:e}}};function dQ(t){return function(n){return t.apply(null,n)}}function hQ(t){return we.isObject(t)&&t.isAxiosError===!0}const i2={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(i2).forEach(([t,e])=>{i2[e]=t});function lC(t){const e=new mc(t),n=B9(mc.prototype.request,e);return we.extend(n,mc.prototype,e,{allOwnKeys:!0}),we.extend(n,e,null,{allOwnKeys:!0}),n.create=function(s){return lC(vc(t,s))},n}const Zn=lC(e0);Zn.Axios=mc;Zn.CanceledError=kd;Zn.CancelToken=uQ;Zn.isCancel=J9;Zn.VERSION=iC;Zn.toFormData=dx;Zn.AxiosError=St;Zn.Cancel=Zn.CanceledError;Zn.all=function(e){return Promise.all(e)};Zn.spread=dQ;Zn.isAxiosError=hQ;Zn.mergeConfig=vc;Zn.AxiosHeaders=Rs;Zn.formToJSON=t=>Z9(we.isHTMLForm(t)?new FormData(t):t);Zn.getAdapter=sC.getAdapter;Zn.HttpStatusCode=i2;Zn.default=Zn;const{Axios:Nxe,AxiosError:Cxe,CanceledError:Txe,isCancel:Mxe,CancelToken:Axe,VERSION:Exe,all:_xe,Cancel:Dxe,isAxiosError:Rxe,spread:zxe,toFormData:Pxe,AxiosHeaders:Lxe,HttpStatusCode:Bxe,formToJSON:Ixe,getAdapter:qxe,mergeConfig:Fxe}=Zn,fQ=(t,e)=>{const n=new Array(t.length+e.length);for(let r=0;r({classGroupId:t,validator:e}),oC=(t=new Map,e=null,n)=>({nextPart:t,validators:e,classGroupId:n}),xg="-",RO=[],pQ="arbitrary..",gQ=t=>{const e=vQ(t),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=t;return{getClassGroupId:l=>{if(l.startsWith("[")&&l.endsWith("]"))return xQ(l);const c=l.split(xg),d=c[0]===""&&c.length>1?1:0;return cC(c,d,e)},getConflictingClassGroupIds:(l,c)=>{if(c){const d=r[l],h=n[l];return d?h?fQ(h,d):d:h||RO}return n[l]||RO}}},cC=(t,e,n)=>{if(t.length-e===0)return n.classGroupId;const s=t[e],i=n.nextPart.get(s);if(i){const h=cC(t,e+1,i);if(h)return h}const l=n.validators;if(l===null)return;const c=e===0?t.join(xg):t.slice(e).join(xg),d=l.length;for(let h=0;ht.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const e=t.slice(1,-1),n=e.indexOf(":"),r=e.slice(0,n);return r?pQ+r:void 0})(),vQ=t=>{const{theme:e,classGroups:n}=t;return yQ(n,e)},yQ=(t,e)=>{const n=oC();for(const r in t){const s=t[r];rw(s,n,r,e)}return n},rw=(t,e,n,r)=>{const s=t.length;for(let i=0;i{if(typeof t=="string"){wQ(t,e,n);return}if(typeof t=="function"){SQ(t,e,n,r);return}kQ(t,e,n,r)},wQ=(t,e,n)=>{const r=t===""?e:uC(e,t);r.classGroupId=n},SQ=(t,e,n,r)=>{if(OQ(t)){rw(t(r),e,n,r);return}e.validators===null&&(e.validators=[]),e.validators.push(mQ(n,t))},kQ=(t,e,n,r)=>{const s=Object.entries(t),i=s.length;for(let l=0;l{let n=t;const r=e.split(xg),s=r.length;for(let i=0;i"isThemeGetter"in t&&t.isThemeGetter===!0,jQ=t=>{if(t<1)return{get:()=>{},set:()=>{}};let e=0,n=Object.create(null),r=Object.create(null);const s=(i,l)=>{n[i]=l,e++,e>t&&(e=0,r=n,n=Object.create(null))};return{get(i){let l=n[i];if(l!==void 0)return l;if((l=r[i])!==void 0)return s(i,l),l},set(i,l){i in n?n[i]=l:s(i,l)}}},a2="!",zO=":",NQ=[],PO=(t,e,n,r,s)=>({modifiers:t,hasImportantModifier:e,baseClassName:n,maybePostfixModifierPosition:r,isExternal:s}),CQ=t=>{const{prefix:e,experimentalParseClassName:n}=t;let r=s=>{const i=[];let l=0,c=0,d=0,h;const m=s.length;for(let k=0;kd?h-d:void 0;return PO(i,v,x,b)};if(e){const s=e+zO,i=r;r=l=>l.startsWith(s)?i(l.slice(s.length)):PO(NQ,!1,l,void 0,!0)}if(n){const s=r;r=i=>n({className:i,parseClassName:s})}return r},TQ=t=>{const e=new Map;return t.orderSensitiveModifiers.forEach((n,r)=>{e.set(n,1e6+r)}),n=>{const r=[];let s=[];for(let i=0;i0&&(s.sort(),r.push(...s),s=[]),r.push(l)):s.push(l)}return s.length>0&&(s.sort(),r.push(...s)),r}},MQ=t=>({cache:jQ(t.cacheSize),parseClassName:CQ(t),sortModifiers:TQ(t),...gQ(t)}),AQ=/\s+/,EQ=(t,e)=>{const{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:s,sortModifiers:i}=e,l=[],c=t.trim().split(AQ);let d="";for(let h=c.length-1;h>=0;h-=1){const m=c[h],{isExternal:p,modifiers:x,hasImportantModifier:v,baseClassName:b,maybePostfixModifierPosition:k}=n(m);if(p){d=m+(d.length>0?" "+d:d);continue}let O=!!k,j=r(O?b.substring(0,k):b);if(!j){if(!O){d=m+(d.length>0?" "+d:d);continue}if(j=r(b),!j){d=m+(d.length>0?" "+d:d);continue}O=!1}const T=x.length===0?"":x.length===1?x[0]:i(x).join(":"),M=v?T+a2:T,_=M+j;if(l.indexOf(_)>-1)continue;l.push(_);const D=s(j,O);for(let E=0;E0?" "+d:d)}return d},_Q=(...t)=>{let e=0,n,r,s="";for(;e{if(typeof t=="string")return t;let e,n="";for(let r=0;r{let n,r,s,i;const l=d=>{const h=e.reduce((m,p)=>p(m),t());return n=MQ(h),r=n.cache.get,s=n.cache.set,i=c,c(d)},c=d=>{const h=r(d);if(h)return h;const m=EQ(d,n);return s(d,m),m};return i=l,(...d)=>i(_Q(...d))},RQ=[],wr=t=>{const e=n=>n[t]||RQ;return e.isThemeGetter=!0,e},hC=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,fC=/^\((?:(\w[\w-]*):)?(.+)\)$/i,zQ=/^\d+\/\d+$/,PQ=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,LQ=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,BQ=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,IQ=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,qQ=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,ju=t=>zQ.test(t),At=t=>!!t&&!Number.isNaN(Number(t)),Wl=t=>!!t&&Number.isInteger(Number(t)),wy=t=>t.endsWith("%")&&At(t.slice(0,-1)),Ga=t=>PQ.test(t),FQ=()=>!0,QQ=t=>LQ.test(t)&&!BQ.test(t),mC=()=>!1,$Q=t=>IQ.test(t),HQ=t=>qQ.test(t),UQ=t=>!Xe(t)&&!Ye(t),VQ=t=>Od(t,xC,mC),Xe=t=>hC.test(t),Yo=t=>Od(t,vC,QQ),Sy=t=>Od(t,KQ,At),LO=t=>Od(t,pC,mC),WQ=t=>Od(t,gC,HQ),Ym=t=>Od(t,yC,$Q),Ye=t=>fC.test(t),Ah=t=>jd(t,vC),GQ=t=>jd(t,ZQ),BO=t=>jd(t,pC),XQ=t=>jd(t,xC),YQ=t=>jd(t,gC),Km=t=>jd(t,yC,!0),Od=(t,e,n)=>{const r=hC.exec(t);return r?r[1]?e(r[1]):n(r[2]):!1},jd=(t,e,n=!1)=>{const r=fC.exec(t);return r?r[1]?e(r[1]):n:!1},pC=t=>t==="position"||t==="percentage",gC=t=>t==="image"||t==="url",xC=t=>t==="length"||t==="size"||t==="bg-size",vC=t=>t==="length",KQ=t=>t==="number",ZQ=t=>t==="family-name",yC=t=>t==="shadow",JQ=()=>{const t=wr("color"),e=wr("font"),n=wr("text"),r=wr("font-weight"),s=wr("tracking"),i=wr("leading"),l=wr("breakpoint"),c=wr("container"),d=wr("spacing"),h=wr("radius"),m=wr("shadow"),p=wr("inset-shadow"),x=wr("text-shadow"),v=wr("drop-shadow"),b=wr("blur"),k=wr("perspective"),O=wr("aspect"),j=wr("ease"),T=wr("animate"),M=()=>["auto","avoid","all","avoid-page","page","left","right","column"],_=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],D=()=>[..._(),Ye,Xe],E=()=>["auto","hidden","clip","visible","scroll"],z=()=>["auto","contain","none"],Q=()=>[Ye,Xe,d],F=()=>[ju,"full","auto",...Q()],B=()=>[Wl,"none","subgrid",Ye,Xe],U=()=>["auto",{span:["full",Wl,Ye,Xe]},Wl,Ye,Xe],V=()=>[Wl,"auto",Ye,Xe],ce=()=>["auto","min","max","fr",Ye,Xe],W=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],J=()=>["start","end","center","stretch","center-safe","end-safe"],H=()=>["auto",...Q()],ae=()=>[ju,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...Q()],ne=()=>[t,Ye,Xe],ue=()=>[..._(),BO,LO,{position:[Ye,Xe]}],R=()=>["no-repeat",{repeat:["","x","y","space","round"]}],me=()=>["auto","cover","contain",XQ,VQ,{size:[Ye,Xe]}],Y=()=>[wy,Ah,Yo],P=()=>["","none","full",h,Ye,Xe],K=()=>["",At,Ah,Yo],$=()=>["solid","dashed","dotted","double"],fe=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],ve=()=>[At,wy,BO,LO],Re=()=>["","none",b,Ye,Xe],de=()=>["none",At,Ye,Xe],We=()=>["none",At,Ye,Xe],ct=()=>[At,Ye,Xe],Oe=()=>[ju,"full",...Q()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Ga],breakpoint:[Ga],color:[FQ],container:[Ga],"drop-shadow":[Ga],ease:["in","out","in-out"],font:[UQ],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Ga],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Ga],shadow:[Ga],spacing:["px",At],text:[Ga],"text-shadow":[Ga],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",ju,Xe,Ye,O]}],container:["container"],columns:[{columns:[At,Xe,Ye,c]}],"break-after":[{"break-after":M()}],"break-before":[{"break-before":M()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:D()}],overflow:[{overflow:E()}],"overflow-x":[{"overflow-x":E()}],"overflow-y":[{"overflow-y":E()}],overscroll:[{overscroll:z()}],"overscroll-x":[{"overscroll-x":z()}],"overscroll-y":[{"overscroll-y":z()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:F()}],"inset-x":[{"inset-x":F()}],"inset-y":[{"inset-y":F()}],start:[{start:F()}],end:[{end:F()}],top:[{top:F()}],right:[{right:F()}],bottom:[{bottom:F()}],left:[{left:F()}],visibility:["visible","invisible","collapse"],z:[{z:[Wl,"auto",Ye,Xe]}],basis:[{basis:[ju,"full","auto",c,...Q()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[At,ju,"auto","initial","none",Xe]}],grow:[{grow:["",At,Ye,Xe]}],shrink:[{shrink:["",At,Ye,Xe]}],order:[{order:[Wl,"first","last","none",Ye,Xe]}],"grid-cols":[{"grid-cols":B()}],"col-start-end":[{col:U()}],"col-start":[{"col-start":V()}],"col-end":[{"col-end":V()}],"grid-rows":[{"grid-rows":B()}],"row-start-end":[{row:U()}],"row-start":[{"row-start":V()}],"row-end":[{"row-end":V()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":ce()}],"auto-rows":[{"auto-rows":ce()}],gap:[{gap:Q()}],"gap-x":[{"gap-x":Q()}],"gap-y":[{"gap-y":Q()}],"justify-content":[{justify:[...W(),"normal"]}],"justify-items":[{"justify-items":[...J(),"normal"]}],"justify-self":[{"justify-self":["auto",...J()]}],"align-content":[{content:["normal",...W()]}],"align-items":[{items:[...J(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...J(),{baseline:["","last"]}]}],"place-content":[{"place-content":W()}],"place-items":[{"place-items":[...J(),"baseline"]}],"place-self":[{"place-self":["auto",...J()]}],p:[{p:Q()}],px:[{px:Q()}],py:[{py:Q()}],ps:[{ps:Q()}],pe:[{pe:Q()}],pt:[{pt:Q()}],pr:[{pr:Q()}],pb:[{pb:Q()}],pl:[{pl:Q()}],m:[{m:H()}],mx:[{mx:H()}],my:[{my:H()}],ms:[{ms:H()}],me:[{me:H()}],mt:[{mt:H()}],mr:[{mr:H()}],mb:[{mb:H()}],ml:[{ml:H()}],"space-x":[{"space-x":Q()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":Q()}],"space-y-reverse":["space-y-reverse"],size:[{size:ae()}],w:[{w:[c,"screen",...ae()]}],"min-w":[{"min-w":[c,"screen","none",...ae()]}],"max-w":[{"max-w":[c,"screen","none","prose",{screen:[l]},...ae()]}],h:[{h:["screen","lh",...ae()]}],"min-h":[{"min-h":["screen","lh","none",...ae()]}],"max-h":[{"max-h":["screen","lh",...ae()]}],"font-size":[{text:["base",n,Ah,Yo]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[r,Ye,Sy]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",wy,Xe]}],"font-family":[{font:[GQ,Xe,e]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[s,Ye,Xe]}],"line-clamp":[{"line-clamp":[At,"none",Ye,Sy]}],leading:[{leading:[i,...Q()]}],"list-image":[{"list-image":["none",Ye,Xe]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",Ye,Xe]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:ne()}],"text-color":[{text:ne()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...$(),"wavy"]}],"text-decoration-thickness":[{decoration:[At,"from-font","auto",Ye,Yo]}],"text-decoration-color":[{decoration:ne()}],"underline-offset":[{"underline-offset":[At,"auto",Ye,Xe]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:Q()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",Ye,Xe]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",Ye,Xe]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ue()}],"bg-repeat":[{bg:R()}],"bg-size":[{bg:me()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Wl,Ye,Xe],radial:["",Ye,Xe],conic:[Wl,Ye,Xe]},YQ,WQ]}],"bg-color":[{bg:ne()}],"gradient-from-pos":[{from:Y()}],"gradient-via-pos":[{via:Y()}],"gradient-to-pos":[{to:Y()}],"gradient-from":[{from:ne()}],"gradient-via":[{via:ne()}],"gradient-to":[{to:ne()}],rounded:[{rounded:P()}],"rounded-s":[{"rounded-s":P()}],"rounded-e":[{"rounded-e":P()}],"rounded-t":[{"rounded-t":P()}],"rounded-r":[{"rounded-r":P()}],"rounded-b":[{"rounded-b":P()}],"rounded-l":[{"rounded-l":P()}],"rounded-ss":[{"rounded-ss":P()}],"rounded-se":[{"rounded-se":P()}],"rounded-ee":[{"rounded-ee":P()}],"rounded-es":[{"rounded-es":P()}],"rounded-tl":[{"rounded-tl":P()}],"rounded-tr":[{"rounded-tr":P()}],"rounded-br":[{"rounded-br":P()}],"rounded-bl":[{"rounded-bl":P()}],"border-w":[{border:K()}],"border-w-x":[{"border-x":K()}],"border-w-y":[{"border-y":K()}],"border-w-s":[{"border-s":K()}],"border-w-e":[{"border-e":K()}],"border-w-t":[{"border-t":K()}],"border-w-r":[{"border-r":K()}],"border-w-b":[{"border-b":K()}],"border-w-l":[{"border-l":K()}],"divide-x":[{"divide-x":K()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":K()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...$(),"hidden","none"]}],"divide-style":[{divide:[...$(),"hidden","none"]}],"border-color":[{border:ne()}],"border-color-x":[{"border-x":ne()}],"border-color-y":[{"border-y":ne()}],"border-color-s":[{"border-s":ne()}],"border-color-e":[{"border-e":ne()}],"border-color-t":[{"border-t":ne()}],"border-color-r":[{"border-r":ne()}],"border-color-b":[{"border-b":ne()}],"border-color-l":[{"border-l":ne()}],"divide-color":[{divide:ne()}],"outline-style":[{outline:[...$(),"none","hidden"]}],"outline-offset":[{"outline-offset":[At,Ye,Xe]}],"outline-w":[{outline:["",At,Ah,Yo]}],"outline-color":[{outline:ne()}],shadow:[{shadow:["","none",m,Km,Ym]}],"shadow-color":[{shadow:ne()}],"inset-shadow":[{"inset-shadow":["none",p,Km,Ym]}],"inset-shadow-color":[{"inset-shadow":ne()}],"ring-w":[{ring:K()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:ne()}],"ring-offset-w":[{"ring-offset":[At,Yo]}],"ring-offset-color":[{"ring-offset":ne()}],"inset-ring-w":[{"inset-ring":K()}],"inset-ring-color":[{"inset-ring":ne()}],"text-shadow":[{"text-shadow":["none",x,Km,Ym]}],"text-shadow-color":[{"text-shadow":ne()}],opacity:[{opacity:[At,Ye,Xe]}],"mix-blend":[{"mix-blend":[...fe(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":fe()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[At]}],"mask-image-linear-from-pos":[{"mask-linear-from":ve()}],"mask-image-linear-to-pos":[{"mask-linear-to":ve()}],"mask-image-linear-from-color":[{"mask-linear-from":ne()}],"mask-image-linear-to-color":[{"mask-linear-to":ne()}],"mask-image-t-from-pos":[{"mask-t-from":ve()}],"mask-image-t-to-pos":[{"mask-t-to":ve()}],"mask-image-t-from-color":[{"mask-t-from":ne()}],"mask-image-t-to-color":[{"mask-t-to":ne()}],"mask-image-r-from-pos":[{"mask-r-from":ve()}],"mask-image-r-to-pos":[{"mask-r-to":ve()}],"mask-image-r-from-color":[{"mask-r-from":ne()}],"mask-image-r-to-color":[{"mask-r-to":ne()}],"mask-image-b-from-pos":[{"mask-b-from":ve()}],"mask-image-b-to-pos":[{"mask-b-to":ve()}],"mask-image-b-from-color":[{"mask-b-from":ne()}],"mask-image-b-to-color":[{"mask-b-to":ne()}],"mask-image-l-from-pos":[{"mask-l-from":ve()}],"mask-image-l-to-pos":[{"mask-l-to":ve()}],"mask-image-l-from-color":[{"mask-l-from":ne()}],"mask-image-l-to-color":[{"mask-l-to":ne()}],"mask-image-x-from-pos":[{"mask-x-from":ve()}],"mask-image-x-to-pos":[{"mask-x-to":ve()}],"mask-image-x-from-color":[{"mask-x-from":ne()}],"mask-image-x-to-color":[{"mask-x-to":ne()}],"mask-image-y-from-pos":[{"mask-y-from":ve()}],"mask-image-y-to-pos":[{"mask-y-to":ve()}],"mask-image-y-from-color":[{"mask-y-from":ne()}],"mask-image-y-to-color":[{"mask-y-to":ne()}],"mask-image-radial":[{"mask-radial":[Ye,Xe]}],"mask-image-radial-from-pos":[{"mask-radial-from":ve()}],"mask-image-radial-to-pos":[{"mask-radial-to":ve()}],"mask-image-radial-from-color":[{"mask-radial-from":ne()}],"mask-image-radial-to-color":[{"mask-radial-to":ne()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":_()}],"mask-image-conic-pos":[{"mask-conic":[At]}],"mask-image-conic-from-pos":[{"mask-conic-from":ve()}],"mask-image-conic-to-pos":[{"mask-conic-to":ve()}],"mask-image-conic-from-color":[{"mask-conic-from":ne()}],"mask-image-conic-to-color":[{"mask-conic-to":ne()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ue()}],"mask-repeat":[{mask:R()}],"mask-size":[{mask:me()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",Ye,Xe]}],filter:[{filter:["","none",Ye,Xe]}],blur:[{blur:Re()}],brightness:[{brightness:[At,Ye,Xe]}],contrast:[{contrast:[At,Ye,Xe]}],"drop-shadow":[{"drop-shadow":["","none",v,Km,Ym]}],"drop-shadow-color":[{"drop-shadow":ne()}],grayscale:[{grayscale:["",At,Ye,Xe]}],"hue-rotate":[{"hue-rotate":[At,Ye,Xe]}],invert:[{invert:["",At,Ye,Xe]}],saturate:[{saturate:[At,Ye,Xe]}],sepia:[{sepia:["",At,Ye,Xe]}],"backdrop-filter":[{"backdrop-filter":["","none",Ye,Xe]}],"backdrop-blur":[{"backdrop-blur":Re()}],"backdrop-brightness":[{"backdrop-brightness":[At,Ye,Xe]}],"backdrop-contrast":[{"backdrop-contrast":[At,Ye,Xe]}],"backdrop-grayscale":[{"backdrop-grayscale":["",At,Ye,Xe]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[At,Ye,Xe]}],"backdrop-invert":[{"backdrop-invert":["",At,Ye,Xe]}],"backdrop-opacity":[{"backdrop-opacity":[At,Ye,Xe]}],"backdrop-saturate":[{"backdrop-saturate":[At,Ye,Xe]}],"backdrop-sepia":[{"backdrop-sepia":["",At,Ye,Xe]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":Q()}],"border-spacing-x":[{"border-spacing-x":Q()}],"border-spacing-y":[{"border-spacing-y":Q()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",Ye,Xe]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[At,"initial",Ye,Xe]}],ease:[{ease:["linear","initial",j,Ye,Xe]}],delay:[{delay:[At,Ye,Xe]}],animate:[{animate:["none",T,Ye,Xe]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[k,Ye,Xe]}],"perspective-origin":[{"perspective-origin":D()}],rotate:[{rotate:de()}],"rotate-x":[{"rotate-x":de()}],"rotate-y":[{"rotate-y":de()}],"rotate-z":[{"rotate-z":de()}],scale:[{scale:We()}],"scale-x":[{"scale-x":We()}],"scale-y":[{"scale-y":We()}],"scale-z":[{"scale-z":We()}],"scale-3d":["scale-3d"],skew:[{skew:ct()}],"skew-x":[{"skew-x":ct()}],"skew-y":[{"skew-y":ct()}],transform:[{transform:[Ye,Xe,"","none","gpu","cpu"]}],"transform-origin":[{origin:D()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:Oe()}],"translate-x":[{"translate-x":Oe()}],"translate-y":[{"translate-y":Oe()}],"translate-z":[{"translate-z":Oe()}],"translate-none":["translate-none"],accent:[{accent:ne()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:ne()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",Ye,Xe]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":Q()}],"scroll-mx":[{"scroll-mx":Q()}],"scroll-my":[{"scroll-my":Q()}],"scroll-ms":[{"scroll-ms":Q()}],"scroll-me":[{"scroll-me":Q()}],"scroll-mt":[{"scroll-mt":Q()}],"scroll-mr":[{"scroll-mr":Q()}],"scroll-mb":[{"scroll-mb":Q()}],"scroll-ml":[{"scroll-ml":Q()}],"scroll-p":[{"scroll-p":Q()}],"scroll-px":[{"scroll-px":Q()}],"scroll-py":[{"scroll-py":Q()}],"scroll-ps":[{"scroll-ps":Q()}],"scroll-pe":[{"scroll-pe":Q()}],"scroll-pt":[{"scroll-pt":Q()}],"scroll-pr":[{"scroll-pr":Q()}],"scroll-pb":[{"scroll-pb":Q()}],"scroll-pl":[{"scroll-pl":Q()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",Ye,Xe]}],fill:[{fill:["none",...ne()]}],"stroke-w":[{stroke:[At,Ah,Yo,Sy]}],stroke:[{stroke:["none",...ne()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},e$=DQ(JQ);function ye(...t){return e$(d9(t))}const yt=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("rounded-xl border bg-card text-card-foreground shadow",t),...e}));yt.displayName="Card";const Jt=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("flex flex-col space-y-1.5 p-6",t),...e}));Jt.displayName="CardHeader";const en=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("font-semibold leading-none tracking-tight",t),...e}));en.displayName="CardTitle";const Sr=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("text-sm text-muted-foreground",t),...e}));Sr.displayName="CardDescription";const vn=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("p-6 pt-0",t),...e}));vn.displayName="CardContent";const bC=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("flex items-center p-6 pt-0",t),...e}));bC.displayName="CardFooter";var ky="rovingFocusGroup.onEntryFocus",t$={bubbles:!1,cancelable:!0},t0="RovingFocusGroup",[l2,wC,n$]=tx(t0),[r$,fx]=Hi(t0,[n$]),[s$,i$]=r$(t0),SC=S.forwardRef((t,e)=>a.jsx(l2.Provider,{scope:t.__scopeRovingFocusGroup,children:a.jsx(l2.Slot,{scope:t.__scopeRovingFocusGroup,children:a.jsx(a$,{...t,ref:e})})}));SC.displayName=t0;var a$=S.forwardRef((t,e)=>{const{__scopeRovingFocusGroup:n,orientation:r,loop:s=!1,dir:i,currentTabStopId:l,defaultCurrentTabStopId:c,onCurrentTabStopIdChange:d,onEntryFocus:h,preventScrollOnEntryFocus:m=!1,...p}=t,x=S.useRef(null),v=Cn(e,x),b=Vf(i),[k,O]=So({prop:l,defaultProp:c??null,onChange:d,caller:t0}),[j,T]=S.useState(!1),M=es(h),_=wC(n),D=S.useRef(!1),[E,z]=S.useState(0);return S.useEffect(()=>{const Q=x.current;if(Q)return Q.addEventListener(ky,M),()=>Q.removeEventListener(ky,M)},[M]),a.jsx(s$,{scope:n,orientation:r,dir:b,loop:s,currentTabStopId:k,onItemFocus:S.useCallback(Q=>O(Q),[O]),onItemShiftTab:S.useCallback(()=>T(!0),[]),onFocusableItemAdd:S.useCallback(()=>z(Q=>Q+1),[]),onFocusableItemRemove:S.useCallback(()=>z(Q=>Q-1),[]),children:a.jsx(Yt.div,{tabIndex:j||E===0?-1:0,"data-orientation":r,...p,ref:v,style:{outline:"none",...t.style},onMouseDown:$e(t.onMouseDown,()=>{D.current=!0}),onFocus:$e(t.onFocus,Q=>{const F=!D.current;if(Q.target===Q.currentTarget&&F&&!j){const B=new CustomEvent(ky,t$);if(Q.currentTarget.dispatchEvent(B),!B.defaultPrevented){const U=_().filter(H=>H.focusable),V=U.find(H=>H.active),ce=U.find(H=>H.id===k),J=[V,ce,...U].filter(Boolean).map(H=>H.ref.current);jC(J,m)}}D.current=!1}),onBlur:$e(t.onBlur,()=>T(!1))})})}),kC="RovingFocusGroupItem",OC=S.forwardRef((t,e)=>{const{__scopeRovingFocusGroup:n,focusable:r=!0,active:s=!1,tabStopId:i,children:l,...c}=t,d=Oi(),h=i||d,m=i$(kC,n),p=m.currentTabStopId===h,x=wC(n),{onFocusableItemAdd:v,onFocusableItemRemove:b,currentTabStopId:k}=m;return S.useEffect(()=>{if(r)return v(),()=>b()},[r,v,b]),a.jsx(l2.ItemSlot,{scope:n,id:h,focusable:r,active:s,children:a.jsx(Yt.span,{tabIndex:p?0:-1,"data-orientation":m.orientation,...c,ref:e,onMouseDown:$e(t.onMouseDown,O=>{r?m.onItemFocus(h):O.preventDefault()}),onFocus:$e(t.onFocus,()=>m.onItemFocus(h)),onKeyDown:$e(t.onKeyDown,O=>{if(O.key==="Tab"&&O.shiftKey){m.onItemShiftTab();return}if(O.target!==O.currentTarget)return;const j=c$(O,m.orientation,m.dir);if(j!==void 0){if(O.metaKey||O.ctrlKey||O.altKey||O.shiftKey)return;O.preventDefault();let M=x().filter(_=>_.focusable).map(_=>_.ref.current);if(j==="last")M.reverse();else if(j==="prev"||j==="next"){j==="prev"&&M.reverse();const _=M.indexOf(O.currentTarget);M=m.loop?u$(M,_+1):M.slice(_+1)}setTimeout(()=>jC(M))}}),children:typeof l=="function"?l({isCurrentTabStop:p,hasTabStop:k!=null}):l})})});OC.displayName=kC;var l$={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function o$(t,e){return e!=="rtl"?t:t==="ArrowLeft"?"ArrowRight":t==="ArrowRight"?"ArrowLeft":t}function c$(t,e,n){const r=o$(t.key,n);if(!(e==="vertical"&&["ArrowLeft","ArrowRight"].includes(r))&&!(e==="horizontal"&&["ArrowUp","ArrowDown"].includes(r)))return l$[r]}function jC(t,e=!1){const n=document.activeElement;for(const r of t)if(r===n||(r.focus({preventScroll:e}),document.activeElement!==n))return}function u$(t,e){return t.map((n,r)=>t[(e+r)%t.length])}var NC=SC,CC=OC,mx="Tabs",[d$]=Hi(mx,[fx]),TC=fx(),[h$,sw]=d$(mx),MC=S.forwardRef((t,e)=>{const{__scopeTabs:n,value:r,onValueChange:s,defaultValue:i,orientation:l="horizontal",dir:c,activationMode:d="automatic",...h}=t,m=Vf(c),[p,x]=So({prop:r,onChange:s,defaultProp:i??"",caller:mx});return a.jsx(h$,{scope:n,baseId:Oi(),value:p,onValueChange:x,orientation:l,dir:m,activationMode:d,children:a.jsx(Yt.div,{dir:m,"data-orientation":l,...h,ref:e})})});MC.displayName=mx;var AC="TabsList",EC=S.forwardRef((t,e)=>{const{__scopeTabs:n,loop:r=!0,...s}=t,i=sw(AC,n),l=TC(n);return a.jsx(NC,{asChild:!0,...l,orientation:i.orientation,dir:i.dir,loop:r,children:a.jsx(Yt.div,{role:"tablist","aria-orientation":i.orientation,...s,ref:e})})});EC.displayName=AC;var _C="TabsTrigger",DC=S.forwardRef((t,e)=>{const{__scopeTabs:n,value:r,disabled:s=!1,...i}=t,l=sw(_C,n),c=TC(n),d=PC(l.baseId,r),h=LC(l.baseId,r),m=r===l.value;return a.jsx(CC,{asChild:!0,...c,focusable:!s,active:m,children:a.jsx(Yt.button,{type:"button",role:"tab","aria-selected":m,"aria-controls":h,"data-state":m?"active":"inactive","data-disabled":s?"":void 0,disabled:s,id:d,...i,ref:e,onMouseDown:$e(t.onMouseDown,p=>{!s&&p.button===0&&p.ctrlKey===!1?l.onValueChange(r):p.preventDefault()}),onKeyDown:$e(t.onKeyDown,p=>{[" ","Enter"].includes(p.key)&&l.onValueChange(r)}),onFocus:$e(t.onFocus,()=>{const p=l.activationMode!=="manual";!m&&!s&&p&&l.onValueChange(r)})})})});DC.displayName=_C;var RC="TabsContent",zC=S.forwardRef((t,e)=>{const{__scopeTabs:n,value:r,forceMount:s,children:i,...l}=t,c=sw(RC,n),d=PC(c.baseId,r),h=LC(c.baseId,r),m=r===c.value,p=S.useRef(m);return S.useEffect(()=>{const x=requestAnimationFrame(()=>p.current=!1);return()=>cancelAnimationFrame(x)},[]),a.jsx(Ls,{present:s||m,children:({present:x})=>a.jsx(Yt.div,{"data-state":m?"active":"inactive","data-orientation":c.orientation,role:"tabpanel","aria-labelledby":d,hidden:!x,id:h,tabIndex:0,...l,ref:e,style:{...t.style,animationDuration:p.current?"0s":void 0},children:x&&i})})});zC.displayName=RC;function PC(t,e){return`${t}-trigger-${e}`}function LC(t,e){return`${t}-content-${e}`}var f$=MC,BC=EC,IC=DC,qC=zC;const dl=f$,va=S.forwardRef(({className:t,...e},n)=>a.jsx(BC,{ref:n,className:ye("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",t),...e}));va.displayName=BC.displayName;const $t=S.forwardRef(({className:t,...e},n)=>a.jsx(IC,{ref:n,className:ye("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",t),...e}));$t.displayName=IC.displayName;const kn=S.forwardRef(({className:t,...e},n)=>a.jsx(qC,{ref:n,className:ye("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 data-[state=active]:animate-in data-[state=active]:fade-in data-[state=active]:duration-300",t),...e}));kn.displayName=qC.displayName;function m$(t,e){return S.useReducer((n,r)=>e[n][r]??n,t)}var iw="ScrollArea",[FC]=Hi(iw),[p$,Ai]=FC(iw),QC=S.forwardRef((t,e)=>{const{__scopeScrollArea:n,type:r="hover",dir:s,scrollHideDelay:i=600,...l}=t,[c,d]=S.useState(null),[h,m]=S.useState(null),[p,x]=S.useState(null),[v,b]=S.useState(null),[k,O]=S.useState(null),[j,T]=S.useState(0),[M,_]=S.useState(0),[D,E]=S.useState(!1),[z,Q]=S.useState(!1),F=Cn(e,U=>d(U)),B=Vf(s);return a.jsx(p$,{scope:n,type:r,dir:B,scrollHideDelay:i,scrollArea:c,viewport:h,onViewportChange:m,content:p,onContentChange:x,scrollbarX:v,onScrollbarXChange:b,scrollbarXEnabled:D,onScrollbarXEnabledChange:E,scrollbarY:k,onScrollbarYChange:O,scrollbarYEnabled:z,onScrollbarYEnabledChange:Q,onCornerWidthChange:T,onCornerHeightChange:_,children:a.jsx(Yt.div,{dir:B,...l,ref:F,style:{position:"relative","--radix-scroll-area-corner-width":j+"px","--radix-scroll-area-corner-height":M+"px",...t.style}})})});QC.displayName=iw;var $C="ScrollAreaViewport",HC=S.forwardRef((t,e)=>{const{__scopeScrollArea:n,children:r,nonce:s,...i}=t,l=Ai($C,n),c=S.useRef(null),d=Cn(e,c,l.onViewportChange);return a.jsxs(a.Fragment,{children:[a.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce:s}),a.jsx(Yt.div,{"data-radix-scroll-area-viewport":"",...i,ref:d,style:{overflowX:l.scrollbarXEnabled?"scroll":"hidden",overflowY:l.scrollbarYEnabled?"scroll":"hidden",...t.style},children:a.jsx("div",{ref:l.onContentChange,style:{minWidth:"100%",display:"table"},children:r})})]})});HC.displayName=$C;var wa="ScrollAreaScrollbar",aw=S.forwardRef((t,e)=>{const{forceMount:n,...r}=t,s=Ai(wa,t.__scopeScrollArea),{onScrollbarXEnabledChange:i,onScrollbarYEnabledChange:l}=s,c=t.orientation==="horizontal";return S.useEffect(()=>(c?i(!0):l(!0),()=>{c?i(!1):l(!1)}),[c,i,l]),s.type==="hover"?a.jsx(g$,{...r,ref:e,forceMount:n}):s.type==="scroll"?a.jsx(x$,{...r,ref:e,forceMount:n}):s.type==="auto"?a.jsx(UC,{...r,ref:e,forceMount:n}):s.type==="always"?a.jsx(lw,{...r,ref:e}):null});aw.displayName=wa;var g$=S.forwardRef((t,e)=>{const{forceMount:n,...r}=t,s=Ai(wa,t.__scopeScrollArea),[i,l]=S.useState(!1);return S.useEffect(()=>{const c=s.scrollArea;let d=0;if(c){const h=()=>{window.clearTimeout(d),l(!0)},m=()=>{d=window.setTimeout(()=>l(!1),s.scrollHideDelay)};return c.addEventListener("pointerenter",h),c.addEventListener("pointerleave",m),()=>{window.clearTimeout(d),c.removeEventListener("pointerenter",h),c.removeEventListener("pointerleave",m)}}},[s.scrollArea,s.scrollHideDelay]),a.jsx(Ls,{present:n||i,children:a.jsx(UC,{"data-state":i?"visible":"hidden",...r,ref:e})})}),x$=S.forwardRef((t,e)=>{const{forceMount:n,...r}=t,s=Ai(wa,t.__scopeScrollArea),i=t.orientation==="horizontal",l=gx(()=>d("SCROLL_END"),100),[c,d]=m$("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return S.useEffect(()=>{if(c==="idle"){const h=window.setTimeout(()=>d("HIDE"),s.scrollHideDelay);return()=>window.clearTimeout(h)}},[c,s.scrollHideDelay,d]),S.useEffect(()=>{const h=s.viewport,m=i?"scrollLeft":"scrollTop";if(h){let p=h[m];const x=()=>{const v=h[m];p!==v&&(d("SCROLL"),l()),p=v};return h.addEventListener("scroll",x),()=>h.removeEventListener("scroll",x)}},[s.viewport,i,d,l]),a.jsx(Ls,{present:n||c!=="hidden",children:a.jsx(lw,{"data-state":c==="hidden"?"hidden":"visible",...r,ref:e,onPointerEnter:$e(t.onPointerEnter,()=>d("POINTER_ENTER")),onPointerLeave:$e(t.onPointerLeave,()=>d("POINTER_LEAVE"))})})}),UC=S.forwardRef((t,e)=>{const n=Ai(wa,t.__scopeScrollArea),{forceMount:r,...s}=t,[i,l]=S.useState(!1),c=t.orientation==="horizontal",d=gx(()=>{if(n.viewport){const h=n.viewport.offsetWidth{const{orientation:n="vertical",...r}=t,s=Ai(wa,t.__scopeScrollArea),i=S.useRef(null),l=S.useRef(0),[c,d]=S.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),h=YC(c.viewport,c.content),m={...r,sizes:c,onSizesChange:d,hasThumb:h>0&&h<1,onThumbChange:x=>i.current=x,onThumbPointerUp:()=>l.current=0,onThumbPointerDown:x=>l.current=x};function p(x,v){return k$(x,l.current,c,v)}return n==="horizontal"?a.jsx(v$,{...m,ref:e,onThumbPositionChange:()=>{if(s.viewport&&i.current){const x=s.viewport.scrollLeft,v=IO(x,c,s.dir);i.current.style.transform=`translate3d(${v}px, 0, 0)`}},onWheelScroll:x=>{s.viewport&&(s.viewport.scrollLeft=x)},onDragScroll:x=>{s.viewport&&(s.viewport.scrollLeft=p(x,s.dir))}}):n==="vertical"?a.jsx(y$,{...m,ref:e,onThumbPositionChange:()=>{if(s.viewport&&i.current){const x=s.viewport.scrollTop,v=IO(x,c);i.current.style.transform=`translate3d(0, ${v}px, 0)`}},onWheelScroll:x=>{s.viewport&&(s.viewport.scrollTop=x)},onDragScroll:x=>{s.viewport&&(s.viewport.scrollTop=p(x))}}):null}),v$=S.forwardRef((t,e)=>{const{sizes:n,onSizesChange:r,...s}=t,i=Ai(wa,t.__scopeScrollArea),[l,c]=S.useState(),d=S.useRef(null),h=Cn(e,d,i.onScrollbarXChange);return S.useEffect(()=>{d.current&&c(getComputedStyle(d.current))},[d]),a.jsx(WC,{"data-orientation":"horizontal",...s,ref:h,sizes:n,style:{bottom:0,left:i.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:i.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":px(n)+"px",...t.style},onThumbPointerDown:m=>t.onThumbPointerDown(m.x),onDragScroll:m=>t.onDragScroll(m.x),onWheelScroll:(m,p)=>{if(i.viewport){const x=i.viewport.scrollLeft+m.deltaX;t.onWheelScroll(x),ZC(x,p)&&m.preventDefault()}},onResize:()=>{d.current&&i.viewport&&l&&r({content:i.viewport.scrollWidth,viewport:i.viewport.offsetWidth,scrollbar:{size:d.current.clientWidth,paddingStart:yg(l.paddingLeft),paddingEnd:yg(l.paddingRight)}})}})}),y$=S.forwardRef((t,e)=>{const{sizes:n,onSizesChange:r,...s}=t,i=Ai(wa,t.__scopeScrollArea),[l,c]=S.useState(),d=S.useRef(null),h=Cn(e,d,i.onScrollbarYChange);return S.useEffect(()=>{d.current&&c(getComputedStyle(d.current))},[d]),a.jsx(WC,{"data-orientation":"vertical",...s,ref:h,sizes:n,style:{top:0,right:i.dir==="ltr"?0:void 0,left:i.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":px(n)+"px",...t.style},onThumbPointerDown:m=>t.onThumbPointerDown(m.y),onDragScroll:m=>t.onDragScroll(m.y),onWheelScroll:(m,p)=>{if(i.viewport){const x=i.viewport.scrollTop+m.deltaY;t.onWheelScroll(x),ZC(x,p)&&m.preventDefault()}},onResize:()=>{d.current&&i.viewport&&l&&r({content:i.viewport.scrollHeight,viewport:i.viewport.offsetHeight,scrollbar:{size:d.current.clientHeight,paddingStart:yg(l.paddingTop),paddingEnd:yg(l.paddingBottom)}})}})}),[b$,VC]=FC(wa),WC=S.forwardRef((t,e)=>{const{__scopeScrollArea:n,sizes:r,hasThumb:s,onThumbChange:i,onThumbPointerUp:l,onThumbPointerDown:c,onThumbPositionChange:d,onDragScroll:h,onWheelScroll:m,onResize:p,...x}=t,v=Ai(wa,n),[b,k]=S.useState(null),O=Cn(e,F=>k(F)),j=S.useRef(null),T=S.useRef(""),M=v.viewport,_=r.content-r.viewport,D=es(m),E=es(d),z=gx(p,10);function Q(F){if(j.current){const B=F.clientX-j.current.left,U=F.clientY-j.current.top;h({x:B,y:U})}}return S.useEffect(()=>{const F=B=>{const U=B.target;b?.contains(U)&&D(B,_)};return document.addEventListener("wheel",F,{passive:!1}),()=>document.removeEventListener("wheel",F,{passive:!1})},[M,b,_,D]),S.useEffect(E,[r,E]),id(b,z),id(v.content,z),a.jsx(b$,{scope:n,scrollbar:b,hasThumb:s,onThumbChange:es(i),onThumbPointerUp:es(l),onThumbPositionChange:E,onThumbPointerDown:es(c),children:a.jsx(Yt.div,{...x,ref:O,style:{position:"absolute",...x.style},onPointerDown:$e(t.onPointerDown,F=>{F.button===0&&(F.target.setPointerCapture(F.pointerId),j.current=b.getBoundingClientRect(),T.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",v.viewport&&(v.viewport.style.scrollBehavior="auto"),Q(F))}),onPointerMove:$e(t.onPointerMove,Q),onPointerUp:$e(t.onPointerUp,F=>{const B=F.target;B.hasPointerCapture(F.pointerId)&&B.releasePointerCapture(F.pointerId),document.body.style.webkitUserSelect=T.current,v.viewport&&(v.viewport.style.scrollBehavior=""),j.current=null})})})}),vg="ScrollAreaThumb",GC=S.forwardRef((t,e)=>{const{forceMount:n,...r}=t,s=VC(vg,t.__scopeScrollArea);return a.jsx(Ls,{present:n||s.hasThumb,children:a.jsx(w$,{ref:e,...r})})}),w$=S.forwardRef((t,e)=>{const{__scopeScrollArea:n,style:r,...s}=t,i=Ai(vg,n),l=VC(vg,n),{onThumbPositionChange:c}=l,d=Cn(e,p=>l.onThumbChange(p)),h=S.useRef(void 0),m=gx(()=>{h.current&&(h.current(),h.current=void 0)},100);return S.useEffect(()=>{const p=i.viewport;if(p){const x=()=>{if(m(),!h.current){const v=O$(p,c);h.current=v,c()}};return c(),p.addEventListener("scroll",x),()=>p.removeEventListener("scroll",x)}},[i.viewport,m,c]),a.jsx(Yt.div,{"data-state":l.hasThumb?"visible":"hidden",...s,ref:d,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...r},onPointerDownCapture:$e(t.onPointerDownCapture,p=>{const v=p.target.getBoundingClientRect(),b=p.clientX-v.left,k=p.clientY-v.top;l.onThumbPointerDown({x:b,y:k})}),onPointerUp:$e(t.onPointerUp,l.onThumbPointerUp)})});GC.displayName=vg;var ow="ScrollAreaCorner",XC=S.forwardRef((t,e)=>{const n=Ai(ow,t.__scopeScrollArea),r=!!(n.scrollbarX&&n.scrollbarY);return n.type!=="scroll"&&r?a.jsx(S$,{...t,ref:e}):null});XC.displayName=ow;var S$=S.forwardRef((t,e)=>{const{__scopeScrollArea:n,...r}=t,s=Ai(ow,n),[i,l]=S.useState(0),[c,d]=S.useState(0),h=!!(i&&c);return id(s.scrollbarX,()=>{const m=s.scrollbarX?.offsetHeight||0;s.onCornerHeightChange(m),d(m)}),id(s.scrollbarY,()=>{const m=s.scrollbarY?.offsetWidth||0;s.onCornerWidthChange(m),l(m)}),h?a.jsx(Yt.div,{...r,ref:e,style:{width:i,height:c,position:"absolute",right:s.dir==="ltr"?0:void 0,left:s.dir==="rtl"?0:void 0,bottom:0,...t.style}}):null});function yg(t){return t?parseInt(t,10):0}function YC(t,e){const n=t/e;return isNaN(n)?0:n}function px(t){const e=YC(t.viewport,t.content),n=t.scrollbar.paddingStart+t.scrollbar.paddingEnd,r=(t.scrollbar.size-n)*e;return Math.max(r,18)}function k$(t,e,n,r="ltr"){const s=px(n),i=s/2,l=e||i,c=s-l,d=n.scrollbar.paddingStart+l,h=n.scrollbar.size-n.scrollbar.paddingEnd-c,m=n.content-n.viewport,p=r==="ltr"?[0,m]:[m*-1,0];return KC([d,h],p)(t)}function IO(t,e,n="ltr"){const r=px(e),s=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,i=e.scrollbar.size-s,l=e.content-e.viewport,c=i-r,d=n==="ltr"?[0,l]:[l*-1,0],h=F4(t,d);return KC([0,l],[0,c])(h)}function KC(t,e){return n=>{if(t[0]===t[1]||e[0]===e[1])return e[0];const r=(e[1]-e[0])/(t[1]-t[0]);return e[0]+r*(n-t[0])}}function ZC(t,e){return t>0&&t{})=>{let n={left:t.scrollLeft,top:t.scrollTop},r=0;return(function s(){const i={left:t.scrollLeft,top:t.scrollTop},l=n.left!==i.left,c=n.top!==i.top;(l||c)&&e(),n=i,r=window.requestAnimationFrame(s)})(),()=>window.cancelAnimationFrame(r)};function gx(t,e){const n=es(t),r=S.useRef(0);return S.useEffect(()=>()=>window.clearTimeout(r.current),[]),S.useCallback(()=>{window.clearTimeout(r.current),r.current=window.setTimeout(n,e)},[n,e])}function id(t,e){const n=es(e);h9(()=>{let r=0;if(t){const s=new ResizeObserver(()=>{cancelAnimationFrame(r),r=window.requestAnimationFrame(n)});return s.observe(t),()=>{window.cancelAnimationFrame(r),s.unobserve(t)}}},[t,n])}var JC=QC,j$=HC,N$=XC;const fn=S.forwardRef(({className:t,children:e,...n},r)=>a.jsxs(JC,{ref:r,className:ye("relative overflow-hidden",t),...n,children:[a.jsx(j$,{className:"h-full w-full rounded-[inherit]",children:e}),a.jsx(eT,{}),a.jsx(N$,{})]}));fn.displayName=JC.displayName;const eT=S.forwardRef(({className:t,orientation:e="vertical",...n},r)=>a.jsx(aw,{ref:r,orientation:e,className:ye("flex touch-none select-none transition-colors",e==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",e==="horizontal"&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",t),...n,children:a.jsx(GC,{className:"relative flex-1 rounded-full bg-border"})}));eT.displayName=aw.displayName;function qO({className:t,...e}){return a.jsx("div",{className:ye("animate-pulse rounded-md bg-primary/10",t),...e})}function C$(t,e=[]){let n=[];function r(i,l){const c=S.createContext(l);c.displayName=i+"Context";const d=n.length;n=[...n,l];const h=p=>{const{scope:x,children:v,...b}=p,k=x?.[t]?.[d]||c,O=S.useMemo(()=>b,Object.values(b));return a.jsx(k.Provider,{value:O,children:v})};h.displayName=i+"Provider";function m(p,x){const v=x?.[t]?.[d]||c,b=S.useContext(v);if(b)return b;if(l!==void 0)return l;throw new Error(`\`${p}\` must be used within \`${i}\``)}return[h,m]}const s=()=>{const i=n.map(l=>S.createContext(l));return function(c){const d=c?.[t]||i;return S.useMemo(()=>({[`__scope${t}`]:{...c,[t]:d}}),[c,d])}};return s.scopeName=t,[r,T$(s,...e)]}function T$(...t){const e=t[0];if(t.length===1)return e;const n=()=>{const r=t.map(s=>({useScope:s(),scopeName:s.scopeName}));return function(i){const l=r.reduce((c,{useScope:d,scopeName:h})=>{const p=d(i)[`__scope${h}`];return{...c,...p}},{});return S.useMemo(()=>({[`__scope${e.scopeName}`]:l}),[l])}};return n.scopeName=e.scopeName,n}var M$=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],tT=M$.reduce((t,e)=>{const n=Q4(`Primitive.${e}`),r=S.forwardRef((s,i)=>{const{asChild:l,...c}=s,d=l?n:e;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),a.jsx(d,{...c,ref:i})});return r.displayName=`Primitive.${e}`,{...t,[e]:r}},{}),cw="Progress",uw=100,[A$]=C$(cw),[E$,_$]=A$(cw),nT=S.forwardRef((t,e)=>{const{__scopeProgress:n,value:r=null,max:s,getValueLabel:i=D$,...l}=t;(s||s===0)&&!FO(s)&&console.error(R$(`${s}`,"Progress"));const c=FO(s)?s:uw;r!==null&&!QO(r,c)&&console.error(z$(`${r}`,"Progress"));const d=QO(r,c)?r:null,h=bg(d)?i(d,c):void 0;return a.jsx(E$,{scope:n,value:d,max:c,children:a.jsx(tT.div,{"aria-valuemax":c,"aria-valuemin":0,"aria-valuenow":bg(d)?d:void 0,"aria-valuetext":h,role:"progressbar","data-state":iT(d,c),"data-value":d??void 0,"data-max":c,...l,ref:e})})});nT.displayName=cw;var rT="ProgressIndicator",sT=S.forwardRef((t,e)=>{const{__scopeProgress:n,...r}=t,s=_$(rT,n);return a.jsx(tT.div,{"data-state":iT(s.value,s.max),"data-value":s.value??void 0,"data-max":s.max,...r,ref:e})});sT.displayName=rT;function D$(t,e){return`${Math.round(t/e*100)}%`}function iT(t,e){return t==null?"indeterminate":t===e?"complete":"loading"}function bg(t){return typeof t=="number"}function FO(t){return bg(t)&&!isNaN(t)&&t>0}function QO(t,e){return bg(t)&&!isNaN(t)&&t<=e&&t>=0}function R$(t,e){return`Invalid prop \`max\` of value \`${t}\` supplied to \`${e}\`. Only numbers greater than 0 are valid max values. Defaulting to \`${uw}\`.`}function z$(t,e){return`Invalid prop \`value\` of value \`${t}\` supplied to \`${e}\`. The \`value\` prop must be: - - a positive number - - less than the value passed to \`max\` (or ${uw} if no \`max\` prop is set) - - \`null\` or \`undefined\` if the progress is indeterminate. - -Defaulting to \`null\`.`}var aT=nT,P$=sT;const n0=S.forwardRef(({className:t,value:e,...n},r)=>a.jsx(aT,{ref:r,className:ye("relative h-2 w-full overflow-hidden rounded-full bg-primary/20",t),...n,children:a.jsx(P$,{className:"h-full w-full flex-1 bg-primary transition-all",style:{transform:`translateX(-${100-(e||0)}%)`}})}));n0.displayName=aT.displayName;const L$={light:"",dark:".dark"},lT=S.createContext(null);function oT(){const t=S.useContext(lT);if(!t)throw new Error("useChart must be used within a ");return t}const Eu=S.forwardRef(({id:t,className:e,children:n,config:r,...s},i)=>{const l=S.useId(),c=`chart-${t||l.replace(/:/g,"")}`;return a.jsx(lT.Provider,{value:{config:r},children:a.jsxs("div",{"data-chart":c,ref:i,className:ye("flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",e),...s,children:[a.jsx(B$,{id:c,config:r}),a.jsx(BI,{children:n})]})})});Eu.displayName="Chart";const B$=({id:t,config:e})=>{const n=Object.entries(e).filter(([,r])=>r.theme||r.color);return n.length?a.jsx("style",{dangerouslySetInnerHTML:{__html:Object.entries(L$).map(([r,s])=>` -${s} [data-chart=${t}] { -${n.map(([i,l])=>{const c=l.theme?.[r]||l.color;return c?` --color-${i}: ${c};`:null}).join(` -`)} -} -`).join(` -`)}}):null},Eh=II,_u=S.forwardRef(({active:t,payload:e,className:n,indicator:r="dot",hideLabel:s=!1,hideIndicator:i=!1,label:l,labelFormatter:c,labelClassName:d,formatter:h,color:m,nameKey:p,labelKey:x},v)=>{const{config:b}=oT(),k=S.useMemo(()=>{if(s||!e?.length)return null;const[j]=e,T=`${x||j?.dataKey||j?.name||"value"}`,M=o2(b,j,T),_=!x&&typeof l=="string"?b[l]?.label||l:M?.label;return c?a.jsx("div",{className:ye("font-medium",d),children:c(_,e)}):_?a.jsx("div",{className:ye("font-medium",d),children:_}):null},[l,c,e,s,d,b,x]);if(!t||!e?.length)return null;const O=e.length===1&&r!=="dot";return a.jsxs("div",{ref:v,className:ye("grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",n),children:[O?null:k,a.jsx("div",{className:"grid gap-1.5",children:e.filter(j=>j.type!=="none").map((j,T)=>{const M=`${p||j.name||j.dataKey||"value"}`,_=o2(b,j,M),D=m||j.payload.fill||j.color;return a.jsx("div",{className:ye("flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",r==="dot"&&"items-center"),children:h&&j?.value!==void 0&&j.name?h(j.value,j.name,j,T,j.payload):a.jsxs(a.Fragment,{children:[_?.icon?a.jsx(_.icon,{}):!i&&a.jsx("div",{className:ye("shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",{"h-2.5 w-2.5":r==="dot","w-1":r==="line","w-0 border-[1.5px] border-dashed bg-transparent":r==="dashed","my-0.5":O&&r==="dashed"}),style:{"--color-bg":D,"--color-border":D}}),a.jsxs("div",{className:ye("flex flex-1 justify-between leading-none",O?"items-end":"items-center"),children:[a.jsxs("div",{className:"grid gap-1.5",children:[O?k:null,a.jsx("span",{className:"text-muted-foreground",children:_?.label||j.name})]}),j.value&&a.jsx("span",{className:"font-mono font-medium tabular-nums text-foreground",children:j.value.toLocaleString()})]})]})},j.dataKey)})})]})});_u.displayName="ChartTooltip";const I$=qI,cT=S.forwardRef(({className:t,hideIcon:e=!1,payload:n,verticalAlign:r="bottom",nameKey:s},i)=>{const{config:l}=oT();return n?.length?a.jsx("div",{ref:i,className:ye("flex items-center justify-center gap-4",r==="top"?"pb-3":"pt-3",t),children:n.filter(c=>c.type!=="none").map(c=>{const d=`${s||c.dataKey||"value"}`,h=o2(l,c,d);return a.jsxs("div",{className:ye("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"),children:[h?.icon&&!e?a.jsx(h.icon,{}):a.jsx("div",{className:"h-2 w-2 shrink-0 rounded-[2px]",style:{backgroundColor:c.color}}),h?.label]},c.value)})}):null});cT.displayName="ChartLegend";function o2(t,e,n){if(typeof e!="object"||e===null)return;const r="payload"in e&&typeof e.payload=="object"&&e.payload!==null?e.payload:void 0;let s=n;return n in e&&typeof e[n]=="string"?s=e[n]:r&&n in r&&typeof r[n]=="string"&&(s=r[n]),s in t?t[s]:t[n]}const $O=t=>typeof t=="boolean"?`${t}`:t===0?"0":t,HO=d9,Nd=(t,e)=>n=>{var r;if(e?.variants==null)return HO(t,n?.class,n?.className);const{variants:s,defaultVariants:i}=e,l=Object.keys(s).map(h=>{const m=n?.[h],p=i?.[h];if(m===null)return null;const x=$O(m)||$O(p);return s[h][x]}),c=n&&Object.entries(n).reduce((h,m)=>{let[p,x]=m;return x===void 0||(h[p]=x),h},{}),d=e==null||(r=e.compoundVariants)===null||r===void 0?void 0:r.reduce((h,m)=>{let{class:p,className:x,...v}=m;return Object.entries(v).every(b=>{let[k,O]=b;return Array.isArray(O)?O.includes({...i,...c}[k]):{...i,...c}[k]===O})?[...h,p,x]:h},[]);return HO(t,l,d,n?.class,n?.className)},ff=Nd("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground shadow hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",outline:"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-md px-3 text-xs",lg:"h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),ie=S.forwardRef(({className:t,variant:e,size:n,asChild:r=!1,...s},i)=>{const l=r?GI:"button";return a.jsx(l,{className:ye(ff({variant:e,size:n,className:t})),ref:i,...s})});ie.displayName="Button";function q$(){const[t,e]=S.useState(null),[n,r]=S.useState(!0),[s,i]=S.useState(0),[l,c]=S.useState(24),[d,h]=S.useState(!0),[m,p]=S.useState(null),[x,v]=S.useState(!0),b=S.useCallback(async()=>{try{v(!0);const F=await Zn.get("https://v1.hitokoto.cn/?c=a&c=b&c=c&c=d&c=h&c=i&c=k");p({hitokoto:F.data.hitokoto,from:F.data.from||F.data.from_who||"未知"})}catch(F){console.error("获取一言失败:",F),p({hitokoto:"人生就像一盒巧克力,你永远不知道下一颗是什么味道。",from:"阿甘正传"})}finally{v(!1)}},[]),k=S.useCallback(async()=>{try{const F=localStorage.getItem("access-token"),B=await Zn.get(`/api/webui/statistics/dashboard?hours=${l}`,{headers:{Authorization:`Bearer ${F}`}});e(B.data),r(!1),i(100)}catch(F){console.error("Failed to fetch dashboard data:",F),r(!1),i(100)}},[l]);if(S.useEffect(()=>{if(!n)return;i(0);const F=setTimeout(()=>i(15),200),B=setTimeout(()=>i(30),800),U=setTimeout(()=>i(45),2e3),V=setTimeout(()=>i(60),4e3),ce=setTimeout(()=>i(75),6500),W=setTimeout(()=>i(85),9e3),J=setTimeout(()=>i(92),11e3);return()=>{clearTimeout(F),clearTimeout(B),clearTimeout(U),clearTimeout(V),clearTimeout(ce),clearTimeout(W),clearTimeout(J)}},[n]),S.useEffect(()=>{k(),b()},[k,b]),S.useEffect(()=>{if(!d)return;const F=setInterval(()=>{k()},3e4);return()=>clearInterval(F)},[d,k]),n||!t)return a.jsx("div",{className:"flex items-center justify-center h-[calc(100vh-200px)]",children:a.jsxs("div",{className:"text-center space-y-6 w-full max-w-md px-4",children:[a.jsx(Ii,{className:"h-12 w-12 animate-spin mx-auto text-primary"}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-lg font-medium",children:"加载统计数据中..."}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"正在获取麦麦运行数据"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(n0,{value:s,className:"h-2"}),a.jsxs("p",{className:"text-xs text-muted-foreground",children:[s,"%"]})]})]})});const{summary:O,model_stats:j,hourly_data:T,daily_data:M,recent_activity:_}=t,D=F=>{const B=Math.floor(F/3600),U=Math.floor(F%3600/60);return`${B}小时${U}分钟`},E=F=>new Date(F).toLocaleString("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}),z=j.slice(0,6).map(F=>({name:F.model_name,value:F.request_count,fill:`hsl(var(--chart-${j.indexOf(F)%5+1}))`})),Q={requests:{label:"请求数",color:"hsl(var(--chart-1))"},cost:{label:"花费(¥)",color:"hsl(var(--chart-2))"},tokens:{label:"Tokens",color:"hsl(var(--chart-3))"}};return a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"实时监控面板"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"麦麦运行状态和统计数据一览"})]}),a.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[a.jsx(dl,{value:l.toString(),onValueChange:F=>c(Number(F)),children:a.jsxs(va,{className:"grid grid-cols-3 w-full sm:w-auto",children:[a.jsx($t,{value:"24",children:"24小时"}),a.jsx($t,{value:"168",children:"7天"}),a.jsx($t,{value:"720",children:"30天"})]})}),a.jsxs(ie,{variant:d?"default":"outline",size:"sm",onClick:()=>h(!d),className:"gap-2",children:[a.jsx(Ii,{className:`h-4 w-4 ${d?"animate-spin":""}`}),a.jsx("span",{className:"hidden sm:inline",children:"自动刷新"})]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:k,children:a.jsx(Ii,{className:"h-4 w-4"})})]})]}),a.jsxs("div",{className:"grid gap-4 grid-cols-1 xs:grid-cols-2 lg:grid-cols-4",children:[a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"总请求数"}),a.jsx(lq,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-2xl font-bold",children:O.total_requests.toLocaleString()}),a.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["最近",l<48?l+"小时":Math.floor(l/24)+"天"]})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"总花费"}),a.jsx(oq,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsxs("div",{className:"text-2xl font-bold",children:["¥",O.total_cost.toFixed(2)]}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:O.cost_per_hour>0?`¥${O.cost_per_hour.toFixed(2)}/小时`:"暂无数据"})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"Token消耗"}),a.jsx(cq,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsxs("div",{className:"text-2xl font-bold",children:[(O.total_tokens/1e3).toFixed(1),"K"]}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:O.tokens_per_hour>0?`${(O.tokens_per_hour/1e3).toFixed(1)}K/小时`:"暂无数据"})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"平均响应"}),a.jsx(uf,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsxs("div",{className:"text-2xl font-bold",children:[O.avg_response_time.toFixed(2),"s"]}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"API平均耗时"})]})]})]}),a.jsxs("div",{className:"grid gap-4 grid-cols-1 sm:grid-cols-3",children:[a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"在线时长"}),a.jsx(uc,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsx(vn,{children:a.jsx("div",{className:"text-xl font-bold",children:D(O.online_time)})})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"消息处理"}),a.jsx(Wf,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-xl font-bold",children:O.total_messages.toLocaleString()}),a.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["回复 ",O.total_replies.toLocaleString()," 条"]})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"成本效率"}),a.jsx(uq,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-xl font-bold",children:O.total_messages>0?`¥${(O.total_cost/O.total_messages*100).toFixed(2)}`:"¥0.00"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"每100条消息"})]})]})]}),a.jsxs(dl,{defaultValue:"trends",className:"space-y-4",children:[a.jsxs(va,{className:"grid w-full grid-cols-2 sm:grid-cols-4",children:[a.jsx($t,{value:"trends",children:"趋势"}),a.jsx($t,{value:"models",children:"模型"}),a.jsx($t,{value:"activity",children:"活动"}),a.jsx($t,{value:"daily",children:"日统计"})]}),a.jsxs(kn,{value:"trends",className:"space-y-4",children:[a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"请求趋势"}),a.jsxs(Sr,{children:["最近",l,"小时的请求量变化"]})]}),a.jsx(vn,{children:a.jsx(Eu,{config:Q,className:"h-[300px] sm:h-[400px] w-full aspect-auto",children:a.jsxs(FI,{data:T,children:[a.jsx(Vm,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),a.jsx(Wm,{dataKey:"timestamp",tickFormatter:F=>E(F),angle:-45,textAnchor:"end",height:60,stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Ch,{stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Eh,{content:a.jsx(_u,{labelFormatter:F=>E(F)})}),a.jsx(QI,{type:"monotone",dataKey:"requests",stroke:"var(--color-requests)",strokeWidth:2})]})})})]}),a.jsxs("div",{className:"grid gap-4 grid-cols-1 lg:grid-cols-2",children:[a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"花费趋势"}),a.jsx(Sr,{children:"API调用成本变化"})]}),a.jsx(vn,{children:a.jsx(Eu,{config:Q,className:"h-[250px] sm:h-[300px] w-full aspect-auto",children:a.jsxs(fy,{data:T,children:[a.jsx(Vm,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),a.jsx(Wm,{dataKey:"timestamp",tickFormatter:F=>E(F),angle:-45,textAnchor:"end",height:60,stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Ch,{stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Eh,{content:a.jsx(_u,{labelFormatter:F=>E(F)})}),a.jsx(Gm,{dataKey:"cost",fill:"var(--color-cost)"})]})})})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"Token消耗"}),a.jsx(Sr,{children:"Token使用量变化"})]}),a.jsx(vn,{children:a.jsx(Eu,{config:Q,className:"h-[250px] sm:h-[300px] w-full aspect-auto",children:a.jsxs(fy,{data:T,children:[a.jsx(Vm,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),a.jsx(Wm,{dataKey:"timestamp",tickFormatter:F=>E(F),angle:-45,textAnchor:"end",height:60,stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Ch,{stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Eh,{content:a.jsx(_u,{labelFormatter:F=>E(F)})}),a.jsx(Gm,{dataKey:"tokens",fill:"var(--color-tokens)"})]})})})]})]})]}),a.jsx(kn,{value:"models",className:"space-y-4",children:a.jsxs("div",{className:"grid gap-4 grid-cols-1 lg:grid-cols-2",children:[a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"模型请求分布"}),a.jsx(Sr,{children:"各模型使用占比"})]}),a.jsx(vn,{children:a.jsx(Eu,{config:Object.fromEntries(j.slice(0,6).map((F,B)=>[F.model_name,{label:F.model_name,color:`hsl(var(--chart-${B%5+1}))`}])),className:"h-[300px] sm:h-[400px] w-full aspect-auto",children:a.jsxs($I,{children:[a.jsx(Eh,{content:a.jsx(_u,{})}),a.jsx(HI,{data:z,cx:"50%",cy:"50%",labelLine:!1,label:({name:F,percent:B})=>`${F} ${B?(B*100).toFixed(0):0}%`,outerRadius:100,dataKey:"value",children:z.map((F,B)=>a.jsx(UI,{fill:F.fill},`cell-${B}`))})]})})})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"模型详细统计"}),a.jsx(Sr,{children:"请求数、花费和性能"})]}),a.jsx(vn,{children:a.jsx(fn,{className:"h-[300px] sm:h-[400px]",children:a.jsx("div",{className:"space-y-3",children:j.map((F,B)=>a.jsxs("div",{className:"p-4 rounded-lg border bg-card hover:bg-accent/50 transition-colors",children:[a.jsxs("div",{className:"flex items-center justify-between mb-2",children:[a.jsx("h4",{className:"font-semibold text-sm truncate flex-1 min-w-0",children:F.model_name}),a.jsx("div",{className:"w-3 h-3 rounded-full ml-2 flex-shrink-0",style:{backgroundColor:`hsl(var(--chart-${B%5+1}))`}})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 text-xs",children:[a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"请求数:"}),a.jsx("span",{className:"ml-1 font-medium",children:F.request_count.toLocaleString()})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"花费:"}),a.jsxs("span",{className:"ml-1 font-medium",children:["¥",F.total_cost.toFixed(2)]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"Tokens:"}),a.jsxs("span",{className:"ml-1 font-medium",children:[(F.total_tokens/1e3).toFixed(1),"K"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"平均耗时:"}),a.jsxs("span",{className:"ml-1 font-medium",children:[F.avg_response_time.toFixed(2),"s"]})]})]})]},B))})})})]})]})}),a.jsx(kn,{value:"activity",children:a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"最近活动"}),a.jsx(Sr,{children:"最新的API调用记录"})]}),a.jsx(vn,{children:a.jsx(fn,{className:"h-[400px] sm:h-[500px]",children:a.jsx("div",{className:"space-y-2",children:_.map((F,B)=>a.jsxs("div",{className:"p-3 sm:p-4 rounded-lg border bg-card hover:bg-accent/50 transition-colors",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-2 mb-2",children:[a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:"font-medium text-sm truncate",children:F.model}),a.jsx("div",{className:"text-xs text-muted-foreground",children:F.request_type})]}),a.jsx("div",{className:"text-xs text-muted-foreground flex-shrink-0",children:E(F.timestamp)})]}),a.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs",children:[a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"Tokens:"}),a.jsx("span",{className:"ml-1",children:F.tokens})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"花费:"}),a.jsxs("span",{className:"ml-1",children:["¥",F.cost.toFixed(4)]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"耗时:"}),a.jsxs("span",{className:"ml-1",children:[F.time_cost.toFixed(2),"s"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground",children:"状态:"}),a.jsx("span",{className:`ml-1 ${F.status==="success"?"text-green-600":"text-red-600"}`,children:F.status})]})]})]},B))})})})]})}),a.jsx(kn,{value:"daily",children:a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"每日统计"}),a.jsx(Sr,{children:"最近7天的数据汇总"})]}),a.jsx(vn,{children:a.jsx(Eu,{config:{requests:{label:"请求数",color:"hsl(var(--chart-1))"},cost:{label:"花费(¥)",color:"hsl(var(--chart-2))"}},className:"h-[400px] sm:h-[500px] w-full aspect-auto",children:a.jsxs(fy,{data:M,children:[a.jsx(Vm,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),a.jsx(Wm,{dataKey:"timestamp",tickFormatter:F=>{const B=new Date(F);return`${B.getMonth()+1}/${B.getDate()}`},stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Ch,{yAxisId:"left",stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Ch,{yAxisId:"right",orientation:"right",stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),a.jsx(Eh,{content:a.jsx(_u,{labelFormatter:F=>new Date(F).toLocaleDateString("zh-CN")})}),a.jsx(I$,{content:a.jsx(cT,{})}),a.jsx(Gm,{yAxisId:"left",dataKey:"requests",fill:"var(--color-requests)"}),a.jsx(Gm,{yAxisId:"right",dataKey:"cost",fill:"var(--color-cost)"})]})})})]})})]}),a.jsxs(yt,{className:"border-2 border-primary/20",children:[a.jsx(Jt,{className:"pb-3",children:a.jsx(en,{className:"text-lg",children:"每日一言"})}),a.jsx(vn,{children:x?a.jsxs("div",{className:"space-y-2",children:[a.jsx(qO,{className:"h-6 w-3/4"}),a.jsx(qO,{className:"h-4 w-1/4"})]}):m?a.jsxs("div",{className:"space-y-2",children:[a.jsxs("p",{className:"text-lg font-medium leading-relaxed italic",children:['"',m.hitokoto,'"']}),a.jsxs("p",{className:"text-sm text-muted-foreground text-right",children:["—— ",m.from]})]}):null})]})]})})}const F$={theme:"system",setTheme:()=>null},uT=S.createContext(F$),dw=()=>{const t=S.useContext(uT);if(t===void 0)throw new Error("useTheme must be used within a ThemeProvider");return t},Q$=(t,e,n)=>{const r=document.documentElement.classList.contains("no-animations");if(!document.startViewTransition||r){e(t);return}const s=n.clientX,i=n.clientY,l=Math.hypot(Math.max(s,innerWidth-s),Math.max(i,innerHeight-i));document.startViewTransition(()=>{e(t)}).ready.then(()=>{document.documentElement.animate({clipPath:[`circle(0px at ${s}px ${i}px)`,`circle(${l}px at ${s}px ${i}px)`]},{duration:500,easing:"ease-in-out",pseudoElement:"::view-transition-new(root)"})})},dT=S.createContext(void 0),hT=()=>{const t=S.useContext(dT);if(t===void 0)throw new Error("useAnimation must be used within an AnimationProvider");return t};var xx="Switch",[$$]=Hi(xx),[H$,U$]=$$(xx),fT=S.forwardRef((t,e)=>{const{__scopeSwitch:n,name:r,checked:s,defaultChecked:i,required:l,disabled:c,value:d="on",onCheckedChange:h,form:m,...p}=t,[x,v]=S.useState(null),b=Cn(e,M=>v(M)),k=S.useRef(!1),O=x?m||!!x.closest("form"):!0,[j,T]=So({prop:s,defaultProp:i??!1,onChange:h,caller:xx});return a.jsxs(H$,{scope:n,checked:j,disabled:c,children:[a.jsx(Yt.button,{type:"button",role:"switch","aria-checked":j,"aria-required":l,"data-state":xT(j),"data-disabled":c?"":void 0,disabled:c,value:d,...p,ref:b,onClick:$e(t.onClick,M=>{T(_=>!_),O&&(k.current=M.isPropagationStopped(),k.current||M.stopPropagation())})}),O&&a.jsx(gT,{control:x,bubbles:!k.current,name:r,value:d,checked:j,required:l,disabled:c,form:m,style:{transform:"translateX(-100%)"}})]})});fT.displayName=xx;var mT="SwitchThumb",pT=S.forwardRef((t,e)=>{const{__scopeSwitch:n,...r}=t,s=U$(mT,n);return a.jsx(Yt.span,{"data-state":xT(s.checked),"data-disabled":s.disabled?"":void 0,...r,ref:e})});pT.displayName=mT;var V$="SwitchBubbleInput",gT=S.forwardRef(({__scopeSwitch:t,control:e,checked:n,bubbles:r=!0,...s},i)=>{const l=S.useRef(null),c=Cn(l,i),d=f9(n),h=m9(e);return S.useEffect(()=>{const m=l.current;if(!m)return;const p=window.HTMLInputElement.prototype,v=Object.getOwnPropertyDescriptor(p,"checked").set;if(d!==n&&v){const b=new Event("click",{bubbles:r});v.call(m,n),m.dispatchEvent(b)}},[d,n,r]),a.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:n,...s,tabIndex:-1,ref:c,style:{...s.style,...h,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});gT.displayName=V$;function xT(t){return t?"checked":"unchecked"}var vT=fT,W$=pT;const jt=S.forwardRef(({className:t,...e},n)=>a.jsx(vT,{className:ye("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",t),...e,ref:n,children:a.jsx(W$,{className:ye("pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0")})}));jt.displayName=vT.displayName;const G$=Nd("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),te=S.forwardRef(({className:t,...e},n)=>a.jsx(p9,{ref:n,className:ye(G$(),t),...e}));te.displayName=p9.displayName;const Ae=S.forwardRef(({className:t,type:e,...n},r)=>a.jsx("input",{type:e,className:ye("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:r,...n}));Ae.displayName="Input";const X$=1,Y$=1e6;let Oy=0;function K$(){return Oy=(Oy+1)%Number.MAX_SAFE_INTEGER,Oy.toString()}const jy=new Map,UO=t=>{if(jy.has(t))return;const e=setTimeout(()=>{jy.delete(t),Kh({type:"REMOVE_TOAST",toastId:t})},Y$);jy.set(t,e)},Z$=(t,e)=>{switch(e.type){case"ADD_TOAST":return{...t,toasts:[e.toast,...t.toasts].slice(0,X$)};case"UPDATE_TOAST":return{...t,toasts:t.toasts.map(n=>n.id===e.toast.id?{...n,...e.toast}:n)};case"DISMISS_TOAST":{const{toastId:n}=e;return n?UO(n):t.toasts.forEach(r=>{UO(r.id)}),{...t,toasts:t.toasts.map(r=>r.id===n||n===void 0?{...r,open:!1}:r)}}case"REMOVE_TOAST":return e.toastId===void 0?{...t,toasts:[]}:{...t,toasts:t.toasts.filter(n=>n.id!==e.toastId)}}},Vp=[];let Wp={toasts:[]};function Kh(t){Wp=Z$(Wp,t),Vp.forEach(e=>{e(Wp)})}function J$({...t}){const e=K$(),n=s=>Kh({type:"UPDATE_TOAST",toast:{...s,id:e}}),r=()=>Kh({type:"DISMISS_TOAST",toastId:e});return Kh({type:"ADD_TOAST",toast:{...t,id:e,open:!0,onOpenChange:s=>{s||r()}}}),{id:e,dismiss:r,update:n}}function Pr(){const[t,e]=S.useState(Wp);return S.useEffect(()=>(Vp.push(e),()=>{const n=Vp.indexOf(e);n>-1&&Vp.splice(n,1)}),[t]),{...t,toast:J$,dismiss:n=>Kh({type:"DISMISS_TOAST",toastId:n})}}const eH=[{id:"minLength",label:"长度至少 10 位",description:"Token 长度必须大于等于 10 个字符",validate:t=>t.length>=10},{id:"hasUppercase",label:"包含大写字母",description:"至少包含一个大写字母 (A-Z)",validate:t=>/[A-Z]/.test(t)},{id:"hasLowercase",label:"包含小写字母",description:"至少包含一个小写字母 (a-z)",validate:t=>/[a-z]/.test(t)},{id:"hasSpecialChar",label:"包含特殊符号",description:"至少包含一个特殊符号 (!@#$%^&*()_+-=[]{}|;:,.<>?/)",validate:t=>/[!@#$%^&*()_+\-=[\]{}|;:,.<>?/]/.test(t)}];function tH(t){const e=eH.map(r=>({id:r.id,label:r.label,description:r.description,passed:r.validate(t)}));return{isValid:e.every(r=>r.passed),rules:e}}const hw="0.11.5",fw="MaiBot Dashboard",nH=`${fw} v${hw}`,rH=(t="v")=>`${t}${hw}`,Rr=W4,mw=g9,sH=$4,yT=S.forwardRef(({className:t,...e},n)=>a.jsx(nx,{ref:n,className:ye("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...e}));yT.displayName=nx.displayName;const Nr=S.forwardRef(({className:t,children:e,...n},r)=>a.jsxs(sH,{children:[a.jsx(yT,{}),a.jsxs(rx,{ref:r,className:ye("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",t),...n,children:[e,a.jsxs(H4,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[a.jsx(Gf,{className:"h-4 w-4"}),a.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));Nr.displayName=rx.displayName;const Cr=({className:t,...e})=>a.jsx("div",{className:ye("flex flex-col space-y-1.5 text-center sm:text-left",t),...e});Cr.displayName="DialogHeader";const ps=({className:t,...e})=>a.jsx("div",{className:ye("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...e});ps.displayName="DialogFooter";const Tr=S.forwardRef(({className:t,...e},n)=>a.jsx(U4,{ref:n,className:ye("text-lg font-semibold leading-none tracking-tight",t),...e}));Tr.displayName=U4.displayName;const Gr=S.forwardRef(({className:t,...e},n)=>a.jsx(V4,{ref:n,className:ye("text-sm text-muted-foreground",t),...e}));Gr.displayName=V4.displayName;var iH=Symbol("radix.slottable");function aH(t){const e=({children:n})=>a.jsx(a.Fragment,{children:n});return e.displayName=`${t}.Slottable`,e.__radixId=iH,e}var bT="AlertDialog",[lH]=Hi(bT,[x9]),yl=x9(),wT=t=>{const{__scopeAlertDialog:e,...n}=t,r=yl(e);return a.jsx(W4,{...r,...n,modal:!0})};wT.displayName=bT;var oH="AlertDialogTrigger",ST=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,...r}=t,s=yl(n);return a.jsx(g9,{...s,...r,ref:e})});ST.displayName=oH;var cH="AlertDialogPortal",kT=t=>{const{__scopeAlertDialog:e,...n}=t,r=yl(e);return a.jsx($4,{...r,...n})};kT.displayName=cH;var uH="AlertDialogOverlay",OT=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,...r}=t,s=yl(n);return a.jsx(nx,{...s,...r,ref:e})});OT.displayName=uH;var Uu="AlertDialogContent",[dH,hH]=lH(Uu),fH=aH("AlertDialogContent"),jT=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,children:r,...s}=t,i=yl(n),l=S.useRef(null),c=Cn(e,l),d=S.useRef(null);return a.jsx(XI,{contentName:Uu,titleName:NT,docsSlug:"alert-dialog",children:a.jsx(dH,{scope:n,cancelRef:d,children:a.jsxs(rx,{role:"alertdialog",...i,...s,ref:c,onOpenAutoFocus:$e(s.onOpenAutoFocus,h=>{h.preventDefault(),d.current?.focus({preventScroll:!0})}),onPointerDownOutside:h=>h.preventDefault(),onInteractOutside:h=>h.preventDefault(),children:[a.jsx(fH,{children:r}),a.jsx(pH,{contentRef:l})]})})})});jT.displayName=Uu;var NT="AlertDialogTitle",CT=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,...r}=t,s=yl(n);return a.jsx(U4,{...s,...r,ref:e})});CT.displayName=NT;var TT="AlertDialogDescription",MT=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,...r}=t,s=yl(n);return a.jsx(V4,{...s,...r,ref:e})});MT.displayName=TT;var mH="AlertDialogAction",AT=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,...r}=t,s=yl(n);return a.jsx(H4,{...s,...r,ref:e})});AT.displayName=mH;var ET="AlertDialogCancel",_T=S.forwardRef((t,e)=>{const{__scopeAlertDialog:n,...r}=t,{cancelRef:s}=hH(ET,n),i=yl(n),l=Cn(e,s);return a.jsx(H4,{...i,...r,ref:l})});_T.displayName=ET;var pH=({contentRef:t})=>{const e=`\`${Uu}\` requires a description for the component to be accessible for screen reader users. - -You can add a description to the \`${Uu}\` by passing a \`${TT}\` component as a child, which also benefits sighted users by adding visible context to the dialog. - -Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${Uu}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component. - -For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;return S.useEffect(()=>{document.getElementById(t.current?.getAttribute("aria-describedby"))||console.warn(e)},[e,t]),null},gH=wT,xH=ST,vH=kT,DT=OT,RT=jT,zT=AT,PT=_T,LT=CT,BT=MT;const mn=gH,jr=xH,yH=vH,IT=S.forwardRef(({className:t,...e},n)=>a.jsx(DT,{className:ye("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...e,ref:n}));IT.displayName=DT.displayName;const an=S.forwardRef(({className:t,...e},n)=>a.jsxs(yH,{children:[a.jsx(IT,{}),a.jsx(RT,{ref:n,className:ye("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",t),...e})]}));an.displayName=RT.displayName;const ln=({className:t,...e})=>a.jsx("div",{className:ye("flex flex-col space-y-2 text-center sm:text-left",t),...e});ln.displayName="AlertDialogHeader";const on=({className:t,...e})=>a.jsx("div",{className:ye("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...e});on.displayName="AlertDialogFooter";const cn=S.forwardRef(({className:t,...e},n)=>a.jsx(LT,{ref:n,className:ye("text-lg font-semibold",t),...e}));cn.displayName=LT.displayName;const un=S.forwardRef(({className:t,...e},n)=>a.jsx(BT,{ref:n,className:ye("text-sm text-muted-foreground",t),...e}));un.displayName=BT.displayName;const dn=S.forwardRef(({className:t,...e},n)=>a.jsx(zT,{ref:n,className:ye(ff(),t),...e}));dn.displayName=zT.displayName;const hn=S.forwardRef(({className:t,...e},n)=>a.jsx(PT,{ref:n,className:ye(ff({variant:"outline"}),"mt-2 sm:mt-0",t),...e}));hn.displayName=PT.displayName;function bH(){return a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"系统设置"}),a.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理您的应用偏好设置"})]})}),a.jsxs(dl,{defaultValue:"appearance",className:"w-full",children:[a.jsxs(va,{className:"grid w-full grid-cols-2 sm:grid-cols-4 gap-0.5 sm:gap-1 h-auto p-1",children:[a.jsxs($t,{value:"appearance",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[a.jsx(_9,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),a.jsx("span",{children:"外观"})]}),a.jsxs($t,{value:"security",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[a.jsx(dq,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),a.jsx("span",{children:"安全"})]}),a.jsxs($t,{value:"other",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[a.jsx(dc,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),a.jsx("span",{children:"其他"})]}),a.jsxs($t,{value:"about",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[a.jsx(oo,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),a.jsx("span",{children:"关于"})]})]}),a.jsxs(fn,{className:"h-[calc(100vh-240px)] sm:h-[calc(100vh-280px)] mt-4 sm:mt-6",children:[a.jsx(kn,{value:"appearance",className:"mt-0",children:a.jsx(wH,{})}),a.jsx(kn,{value:"security",className:"mt-0",children:a.jsx(SH,{})}),a.jsx(kn,{value:"other",className:"mt-0",children:a.jsx(kH,{})}),a.jsx(kn,{value:"about",className:"mt-0",children:a.jsx(OH,{})})]})]})]})}function VO(t){const e=document.documentElement,r={blue:{hsl:"221.2 83.2% 53.3%",darkHsl:"217.2 91.2% 59.8%",gradient:null},purple:{hsl:"271 91% 65%",darkHsl:"270 95% 75%",gradient:null},green:{hsl:"142 71% 45%",darkHsl:"142 76% 36%",gradient:null},orange:{hsl:"25 95% 53%",darkHsl:"20 90% 48%",gradient:null},pink:{hsl:"330 81% 60%",darkHsl:"330 85% 70%",gradient:null},red:{hsl:"0 84% 60%",darkHsl:"0 90% 70%",gradient:null},"gradient-sunset":{hsl:"15 95% 60%",darkHsl:"15 95% 65%",gradient:"linear-gradient(135deg, hsl(25 95% 53%) 0%, hsl(330 81% 60%) 100%)"},"gradient-ocean":{hsl:"200 90% 55%",darkHsl:"200 90% 60%",gradient:"linear-gradient(135deg, hsl(221.2 83.2% 53.3%) 0%, hsl(189 94% 43%) 100%)"},"gradient-forest":{hsl:"150 70% 45%",darkHsl:"150 75% 40%",gradient:"linear-gradient(135deg, hsl(142 71% 45%) 0%, hsl(158 64% 52%) 100%)"},"gradient-aurora":{hsl:"310 85% 65%",darkHsl:"310 90% 70%",gradient:"linear-gradient(135deg, hsl(271 91% 65%) 0%, hsl(330 81% 60%) 100%)"},"gradient-fire":{hsl:"15 95% 55%",darkHsl:"15 95% 60%",gradient:"linear-gradient(135deg, hsl(0 84% 60%) 0%, hsl(25 95% 53%) 100%)"},"gradient-twilight":{hsl:"250 90% 60%",darkHsl:"250 95% 65%",gradient:"linear-gradient(135deg, hsl(239 84% 67%) 0%, hsl(271 91% 65%) 100%)"}}[t];if(r)e.style.setProperty("--primary",r.hsl),r.gradient?(e.style.setProperty("--primary-gradient",r.gradient),e.classList.add("has-gradient")):(e.style.removeProperty("--primary-gradient"),e.classList.remove("has-gradient"));else if(t.startsWith("#")){const s=i=>{i=i.replace("#","");const l=parseInt(i.substring(0,2),16)/255,c=parseInt(i.substring(2,4),16)/255,d=parseInt(i.substring(4,6),16)/255,h=Math.max(l,c,d),m=Math.min(l,c,d);let p=0,x=0;const v=(h+m)/2;if(h!==m){const b=h-m;switch(x=v>.5?b/(2-h-m):b/(h+m),h){case l:p=((c-d)/b+(clocalStorage.getItem("accent-color")||"blue");S.useEffect(()=>{const h=localStorage.getItem("accent-color")||"blue";VO(h)},[]);const d=h=>{c(h),localStorage.setItem("accent-color",h),VO(h)};return a.jsxs("div",{className:"space-y-6 sm:space-y-8",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"主题模式"}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3 sm:gap-4",children:[a.jsx(Ny,{value:"light",current:t,onChange:e,label:"浅色",description:"始终使用浅色主题"}),a.jsx(Ny,{value:"dark",current:t,onChange:e,label:"深色",description:"始终使用深色主题"}),a.jsx(Ny,{value:"system",current:t,onChange:e,label:"跟随系统",description:"根据系统设置自动切换"})]})]}),a.jsxs("div",{children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"主题色"}),a.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[a.jsxs("div",{children:[a.jsx("h4",{className:"text-xs sm:text-sm font-medium mb-2 sm:mb-3",children:"单色"}),a.jsxs("div",{className:"grid grid-cols-3 sm:grid-cols-6 gap-2 sm:gap-3",children:[a.jsx(xi,{value:"blue",current:l,onChange:d,label:"蓝色",colorClass:"bg-blue-500"}),a.jsx(xi,{value:"purple",current:l,onChange:d,label:"紫色",colorClass:"bg-purple-500"}),a.jsx(xi,{value:"green",current:l,onChange:d,label:"绿色",colorClass:"bg-green-500"}),a.jsx(xi,{value:"orange",current:l,onChange:d,label:"橙色",colorClass:"bg-orange-500"}),a.jsx(xi,{value:"pink",current:l,onChange:d,label:"粉色",colorClass:"bg-pink-500"}),a.jsx(xi,{value:"red",current:l,onChange:d,label:"红色",colorClass:"bg-red-500"})]})]}),a.jsxs("div",{children:[a.jsx("h4",{className:"text-xs sm:text-sm font-medium mb-2 sm:mb-3",children:"渐变色"}),a.jsxs("div",{className:"grid grid-cols-3 sm:grid-cols-6 gap-2 sm:gap-3",children:[a.jsx(xi,{value:"gradient-sunset",current:l,onChange:d,label:"日落",colorClass:"bg-gradient-to-r from-orange-500 to-pink-500"}),a.jsx(xi,{value:"gradient-ocean",current:l,onChange:d,label:"海洋",colorClass:"bg-gradient-to-r from-blue-500 to-cyan-500"}),a.jsx(xi,{value:"gradient-forest",current:l,onChange:d,label:"森林",colorClass:"bg-gradient-to-r from-green-500 to-emerald-500"}),a.jsx(xi,{value:"gradient-aurora",current:l,onChange:d,label:"极光",colorClass:"bg-gradient-to-r from-purple-500 to-pink-500"}),a.jsx(xi,{value:"gradient-fire",current:l,onChange:d,label:"烈焰",colorClass:"bg-gradient-to-r from-red-500 to-orange-500"}),a.jsx(xi,{value:"gradient-twilight",current:l,onChange:d,label:"暮光",colorClass:"bg-gradient-to-r from-indigo-500 to-purple-500"})]})]}),a.jsxs("div",{children:[a.jsx("h4",{className:"text-xs sm:text-sm font-medium mb-2 sm:mb-3",children:"自定义颜色"}),a.jsxs("div",{className:"flex flex-col sm:flex-row gap-3 sm:gap-4",children:[a.jsx("div",{className:"flex-1",children:a.jsx("input",{type:"color",value:l.startsWith("#")?l:"#3b82f6",onChange:h=>d(h.target.value),className:"h-10 sm:h-12 w-full rounded-lg border-2 border-border cursor-pointer",title:"选择自定义颜色"})}),a.jsx("div",{className:"flex-1",children:a.jsx(Ae,{type:"text",value:l,onChange:h=>d(h.target.value),placeholder:"#3b82f6",className:"font-mono text-sm"})})]}),a.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground mt-2",children:"点击色块选择颜色,或手动输入 HEX 颜色代码"})]})]})]}),a.jsxs("div",{children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"动画效果"}),a.jsxs("div",{className:"space-y-2 sm:space-y-3",children:[a.jsx("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5 flex-1",children:[a.jsx(te,{htmlFor:"animations",className:"text-base font-medium cursor-pointer",children:"启用动画效果"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"关闭后将禁用所有过渡动画和特效,提升性能"})]}),a.jsx(jt,{id:"animations",checked:n,onCheckedChange:r})]})}),a.jsx("div",{className:"rounded-lg border bg-card p-4",children:a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5 flex-1",children:[a.jsx(te,{htmlFor:"waves-background",className:"text-base font-medium cursor-pointer",children:"登录页波浪背景"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"关闭后登录页将使用纯色背景,适合低性能设备"})]}),a.jsx(jt,{id:"waves-background",checked:s,onCheckedChange:i})]})})]})]})]})}function SH(){const t=ba(),[e,n]=S.useState(""),[r,s]=S.useState(""),[i,l]=S.useState(!1),[c,d]=S.useState(!1),[h,m]=S.useState(!1),[p,x]=S.useState(!1),[v,b]=S.useState(!1),[k,O]=S.useState(!1),[j,T]=S.useState(""),[M,_]=S.useState(!1),{toast:D}=Pr(),E=S.useMemo(()=>tH(r),[r]),z=()=>localStorage.getItem("access-token")||"",Q=async W=>{try{await navigator.clipboard.writeText(W),b(!0),D({title:"复制成功",description:"Token 已复制到剪贴板"}),setTimeout(()=>b(!1),2e3)}catch{D({title:"复制失败",description:"请手动复制 Token",variant:"destructive"})}},F=async()=>{if(!r.trim()){D({title:"输入错误",description:"请输入新的 Token",variant:"destructive"});return}if(!E.isValid){const W=E.rules.filter(J=>!J.passed).map(J=>J.label).join(", ");D({title:"格式错误",description:`Token 不符合要求: ${W}`,variant:"destructive"});return}m(!0);try{const W=z(),J=await fetch("/api/webui/auth/update",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${W}`},body:JSON.stringify({new_token:r.trim()})}),H=await J.json();J.ok&&H.success?(localStorage.setItem("access-token",r.trim()),s(""),e&&n(r.trim()),D({title:"更新成功",description:"Access Token 已更新,即将跳转到登录页"}),setTimeout(()=>{localStorage.removeItem("access-token"),t({to:"/auth"})},1500)):D({title:"更新失败",description:H.message||"无法更新 Token",variant:"destructive"})}catch(W){console.error("更新 Token 错误:",W),D({title:"更新失败",description:"连接服务器失败",variant:"destructive"})}finally{m(!1)}},B=async()=>{x(!0);try{const W=z(),J=await fetch("/api/webui/auth/regenerate",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${W}`}}),H=await J.json();J.ok&&H.success?(localStorage.setItem("access-token",H.token),n(H.token),T(H.token),O(!0),_(!1),D({title:"生成成功",description:"新的 Access Token 已生成,请及时保存"})):D({title:"生成失败",description:H.message||"无法生成新 Token",variant:"destructive"})}catch(W){console.error("生成 Token 错误:",W),D({title:"生成失败",description:"连接服务器失败",variant:"destructive"})}finally{x(!1)}},U=async()=>{try{await navigator.clipboard.writeText(j),_(!0),D({title:"复制成功",description:"Token 已复制到剪贴板"})}catch{D({title:"复制失败",description:"请手动复制 Token",variant:"destructive"})}},V=()=>{O(!1),setTimeout(()=>{T(""),_(!1)},300),setTimeout(()=>{localStorage.removeItem("access-token"),t({to:"/auth"})},500)},ce=W=>{W||V()};return a.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[a.jsx(Rr,{open:k,onOpenChange:ce,children:a.jsxs(Nr,{className:"sm:max-w-md",children:[a.jsxs(Cr,{children:[a.jsxs(Tr,{className:"flex items-center gap-2",children:[a.jsx(Hu,{className:"h-5 w-5 text-yellow-500"}),"新的 Access Token"]}),a.jsx(Gr,{children:"这是您的新 Token,请立即保存。关闭此窗口后将跳转到登录页面。"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"rounded-lg border-2 border-primary/20 bg-primary/5 p-4",children:[a.jsx(te,{className:"text-xs text-muted-foreground mb-2 block",children:"您的新 Token (64位安全令牌)"}),a.jsx("div",{className:"font-mono text-sm break-all select-all bg-background p-3 rounded border",children:j})]}),a.jsx("div",{className:"rounded-lg border border-yellow-200 dark:border-yellow-900 bg-yellow-50 dark:bg-yellow-950/30 p-3",children:a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Hu,{className:"h-4 w-4 text-yellow-600 dark:text-yellow-500 flex-shrink-0 mt-0.5"}),a.jsxs("div",{className:"text-sm text-yellow-800 dark:text-yellow-300 space-y-1",children:[a.jsx("p",{className:"font-semibold",children:"重要提示"}),a.jsxs("ul",{className:"list-disc list-inside space-y-0.5 text-xs",children:[a.jsx("li",{children:"此 Token 仅显示一次,关闭后无法再查看"}),a.jsx("li",{children:"请立即复制并保存到安全的位置"}),a.jsx("li",{children:"关闭窗口后将自动跳转到登录页面"}),a.jsx("li",{children:"请使用新 Token 重新登录系统"})]})]})]})})]}),a.jsxs(ps,{className:"gap-2 sm:gap-0",children:[a.jsx(ie,{variant:"outline",onClick:U,className:"gap-2",children:M?a.jsxs(a.Fragment,{children:[a.jsx(hc,{className:"h-4 w-4 text-green-500"}),"已复制"]}):a.jsxs(a.Fragment,{children:[a.jsx(Xb,{className:"h-4 w-4"}),"复制 Token"]})}),a.jsx(ie,{onClick:V,children:"我已保存,关闭"})]})]})}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"当前 Access Token"}),a.jsx("div",{className:"space-y-3 sm:space-y-4",children:a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"current-token",className:"text-sm",children:"您的访问令牌"}),a.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[a.jsxs("div",{className:"relative flex-1",children:[a.jsx(Ae,{id:"current-token",type:i?"text":"password",value:e||z(),readOnly:!0,className:"pr-10 font-mono text-sm",placeholder:"点击查看按钮显示 Token"}),a.jsx("button",{onClick:()=>{e||n(z()),l(!i)},className:"absolute right-2 top-1/2 -translate-y-1/2 p-1.5 hover:bg-accent rounded",title:i?"隐藏":"显示",children:i?a.jsx(Yb,{className:"h-4 w-4 text-muted-foreground"}):a.jsx(Fi,{className:"h-4 w-4 text-muted-foreground"})})]}),a.jsxs("div",{className:"flex gap-2 w-full sm:w-auto",children:[a.jsx(ie,{variant:"outline",size:"icon",onClick:()=>Q(z()),title:"复制到剪贴板",className:"flex-shrink-0",children:v?a.jsx(hc,{className:"h-4 w-4 text-green-500"}):a.jsx(Xb,{className:"h-4 w-4"})}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsxs(ie,{variant:"outline",disabled:p,className:"gap-2 flex-1 sm:flex-none",children:[a.jsx(Ii,{className:ye("h-4 w-4",p&&"animate-spin")}),a.jsx("span",{className:"hidden sm:inline",children:"重新生成"}),a.jsx("span",{className:"sm:hidden",children:"生成"})]})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认重新生成 Token"}),a.jsx(un,{children:"这将生成一个新的 64 位安全令牌,并使当前 Token 立即失效。 您需要使用新 Token 重新登录系统。此操作不可撤销,确定要继续吗?"})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:B,children:"确认生成"})]})]})]})]})]}),a.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground",children:"请妥善保管您的 Access Token,不要泄露给他人"})]})})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"自定义 Access Token"}),a.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"new-token",className:"text-sm",children:"新的访问令牌"}),a.jsxs("div",{className:"relative",children:[a.jsx(Ae,{id:"new-token",type:c?"text":"password",value:r,onChange:W=>s(W.target.value),className:"pr-10 font-mono text-sm",placeholder:"输入自定义 Token"}),a.jsx("button",{onClick:()=>d(!c),className:"absolute right-2 top-1/2 -translate-y-1/2 p-1.5 hover:bg-accent rounded",title:c?"隐藏":"显示",children:c?a.jsx(Yb,{className:"h-4 w-4 text-muted-foreground"}):a.jsx(Fi,{className:"h-4 w-4 text-muted-foreground"})})]}),r&&a.jsxs("div",{className:"mt-3 space-y-2 p-3 rounded-lg bg-muted/50",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"Token 安全要求:"}),a.jsx("div",{className:"space-y-1.5",children:E.rules.map(W=>a.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[W.passed?a.jsx(ua,{className:"h-4 w-4 text-green-500 flex-shrink-0"}):a.jsx(Kb,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),a.jsx("span",{className:ye(W.passed?"text-green-600 dark:text-green-400":"text-muted-foreground"),children:W.label})]},W.id))}),E.isValid&&a.jsx("div",{className:"mt-2 pt-2 border-t border-border",children:a.jsxs("div",{className:"flex items-center gap-2 text-sm text-green-600 dark:text-green-400",children:[a.jsx(hc,{className:"h-4 w-4"}),a.jsx("span",{className:"font-medium",children:"Token 格式正确,可以使用"})]})})]})]}),a.jsx(ie,{onClick:F,disabled:h||!E.isValid||!r,className:"w-full sm:w-auto",children:h?"更新中...":"更新自定义 Token"})]})]}),a.jsxs("div",{className:"rounded-lg border border-yellow-200 dark:border-yellow-900 bg-yellow-50 dark:bg-yellow-950/30 p-3 sm:p-4",children:[a.jsx("h4",{className:"text-sm sm:text-base font-semibold text-yellow-900 dark:text-yellow-200 mb-2",children:"安全提示"}),a.jsxs("ul",{className:"text-xs sm:text-sm text-yellow-800 dark:text-yellow-300 space-y-1 list-disc list-inside",children:[a.jsx("li",{children:"重新生成 Token 会创建系统随机生成的 64 位安全令牌"}),a.jsx("li",{children:"自定义 Token 必须满足所有安全要求才能使用"}),a.jsx("li",{children:"更新 Token 后,旧的 Token 将立即失效"}),a.jsx("li",{children:"请在安全的环境下查看和复制 Token"}),a.jsx("li",{children:"如果怀疑 Token 泄露,请立即重新生成或更新"}),a.jsx("li",{children:"建议使用系统生成的 Token 以获得最高安全性"})]})]})]})}function kH(){const t=ba(),{toast:e}=Pr(),[n,r]=S.useState(!1),s=async()=>{r(!0);try{const i=localStorage.getItem("access-token"),l=await fetch("/api/webui/setup/reset",{method:"POST",headers:{Authorization:`Bearer ${i}`}}),c=await l.json();l.ok&&c.success?(e({title:"重置成功",description:"即将进入初次配置向导"}),setTimeout(()=>{t({to:"/setup"})},1e3)):e({title:"重置失败",description:c.message||"无法重置配置状态",variant:"destructive"})}catch(i){console.error("重置配置状态错误:",i),e({title:"重置失败",description:"连接服务器失败",variant:"destructive"})}finally{r(!1)}};return a.jsx("div",{className:"space-y-4 sm:space-y-6",children:a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"配置向导"}),a.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[a.jsx("div",{className:"space-y-2",children:a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"重新进行初次配置向导,可以帮助您重新设置系统的基础配置。"})}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsxs(ie,{variant:"outline",disabled:n,className:"gap-2",children:[a.jsx(hq,{className:ye("h-4 w-4",n&&"animate-spin")}),"重新进行初次配置"]})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认重新配置"}),a.jsx(un,{children:"这将带您重新进入初次配置向导。您可以重新设置系统的基础配置项。确定要继续吗?"})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:s,children:"确认重置"})]})]})]})]})]})})}function OH(){return a.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[a.jsx("div",{className:"rounded-lg border-2 border-primary/30 bg-gradient-to-r from-primary/5 to-primary/10 p-4 sm:p-6",children:a.jsxs("div",{className:"flex items-start gap-3 sm:gap-4",children:[a.jsx("div",{className:"flex-shrink-0 rounded-lg bg-primary/10 p-2 sm:p-3",children:a.jsx("svg",{className:"h-6 w-6 sm:h-8 sm:w-8 text-primary",fill:"currentColor",viewBox:"0 0 24 24","aria-hidden":"true",children:a.jsx("path",{fillRule:"evenodd",d:"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z",clipRule:"evenodd"})})}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("h3",{className:"text-lg sm:text-xl font-bold text-foreground mb-2",children:"开源项目"}),a.jsx("p",{className:"text-sm sm:text-base text-muted-foreground mb-3",children:"本项目在 GitHub 开源,欢迎 Star ⭐ 支持!"}),a.jsxs("a",{href:"https://github.com/Mai-with-u/MaiBot-Dashboard",target:"_blank",rel:"noopener noreferrer",className:ye("inline-flex items-center gap-2 px-4 py-2 rounded-lg","bg-primary text-primary-foreground font-medium text-sm","hover:bg-primary/90 transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"),children:[a.jsx("svg",{className:"h-4 w-4",fill:"currentColor",viewBox:"0 0 24 24","aria-hidden":"true",children:a.jsx("path",{fillRule:"evenodd",d:"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z",clipRule:"evenodd"})}),"前往 GitHub",a.jsx("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:a.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"})})]})]})]})}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsxs("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:["关于 ",fw]}),a.jsxs("div",{className:"space-y-2 text-xs sm:text-sm text-muted-foreground",children:[a.jsxs("p",{children:["版本: ",hw]}),a.jsx("p",{children:"麦麦(MaiBot)的现代化 Web 管理界面"})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"作者"}),a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx("p",{className:"text-sm font-medium",children:"MaiBot 核心"}),a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"Mai-with-u"})]}),a.jsxs("div",{className:"space-y-1",children:[a.jsx("p",{className:"text-sm font-medium",children:"WebUI"}),a.jsxs("p",{className:"text-xs sm:text-sm text-muted-foreground",children:["Mai-with-u ",a.jsx("a",{href:"https://github.com/DrSmoothl",target:"_blank",rel:"noopener noreferrer",className:"text-primary underline",children:"@MotricSeven"})]})]})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"技术栈"}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 text-xs sm:text-sm text-muted-foreground",children:[a.jsxs("div",{className:"space-y-1.5",children:[a.jsx("p",{className:"font-medium text-foreground",children:"前端框架"}),a.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[a.jsx("li",{children:"React 19.2.0"}),a.jsx("li",{children:"TypeScript 5.7.2"}),a.jsx("li",{children:"Vite 6.0.7"}),a.jsx("li",{children:"TanStack Router 1.94.2"})]})]}),a.jsxs("div",{className:"space-y-1.5",children:[a.jsx("p",{className:"font-medium text-foreground",children:"UI 组件"}),a.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[a.jsx("li",{children:"shadcn/ui"}),a.jsx("li",{children:"Radix UI"}),a.jsx("li",{children:"Tailwind CSS 3.4.17"}),a.jsx("li",{children:"Lucide Icons"})]})]}),a.jsxs("div",{className:"space-y-1.5",children:[a.jsx("p",{className:"font-medium text-foreground",children:"后端"}),a.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[a.jsx("li",{children:"Python 3.12+"}),a.jsx("li",{children:"FastAPI"}),a.jsx("li",{children:"Uvicorn"}),a.jsx("li",{children:"WebSocket"})]})]}),a.jsxs("div",{className:"space-y-1.5",children:[a.jsx("p",{className:"font-medium text-foreground",children:"构建工具"}),a.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[a.jsx("li",{children:"Bun / npm"}),a.jsx("li",{children:"ESLint 9.17.0"}),a.jsx("li",{children:"PostCSS"})]})]})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"开源库感谢"}),a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground mb-3",children:"本项目使用了以下优秀的开源库,感谢他们的贡献:"}),a.jsx(fn,{className:"h-[300px] sm:h-[400px]",children:a.jsxs("div",{className:"space-y-4 pr-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"UI 框架与组件"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"React",description:"用户界面构建库",license:"MIT"}),a.jsx(Gn,{name:"shadcn/ui",description:"优雅的 React 组件库",license:"MIT"}),a.jsx(Gn,{name:"Radix UI",description:"无样式的可访问组件库",license:"MIT"}),a.jsx(Gn,{name:"Tailwind CSS",description:"实用优先的 CSS 框架",license:"MIT"}),a.jsx(Gn,{name:"Lucide React",description:"精美的图标库",license:"ISC"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"路由与状态管理"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"TanStack Router",description:"类型安全的路由库",license:"MIT"}),a.jsx(Gn,{name:"Zustand",description:"轻量级状态管理",license:"MIT"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"表单处理"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"React Hook Form",description:"高性能表单库",license:"MIT"}),a.jsx(Gn,{name:"Zod",description:"TypeScript 优先的 schema 验证",license:"MIT"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"工具库"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"clsx",description:"条件 className 构建工具",license:"MIT"}),a.jsx(Gn,{name:"tailwind-merge",description:"Tailwind 类名合并工具",license:"MIT"}),a.jsx(Gn,{name:"class-variance-authority",description:"组件变体管理",license:"Apache-2.0"}),a.jsx(Gn,{name:"date-fns",description:"现代化日期处理库",license:"MIT"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"动画效果"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"Framer Motion",description:"React 动画库",license:"MIT"}),a.jsx(Gn,{name:"vaul",description:"抽屉组件动画",license:"MIT"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"后端框架"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"FastAPI",description:"现代化 Python Web 框架",license:"MIT"}),a.jsx(Gn,{name:"Uvicorn",description:"ASGI 服务器",license:"BSD-3-Clause"}),a.jsx(Gn,{name:"Pydantic",description:"数据验证库",license:"MIT"}),a.jsx(Gn,{name:"python-multipart",description:"文件上传支持",license:"Apache-2.0"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("p",{className:"text-sm font-medium text-foreground",children:"开发工具"}),a.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[a.jsx(Gn,{name:"TypeScript",description:"JavaScript 的超集",license:"Apache-2.0"}),a.jsx(Gn,{name:"Vite",description:"下一代前端构建工具",license:"MIT"}),a.jsx(Gn,{name:"ESLint",description:"JavaScript 代码检查工具",license:"MIT"}),a.jsx(Gn,{name:"PostCSS",description:"CSS 转换工具",license:"MIT"})]})]})]})})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[a.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"开源许可"}),a.jsxs("div",{className:"space-y-3",children:[a.jsx("div",{className:"rounded-lg bg-primary/5 border border-primary/20 p-3 sm:p-4",children:a.jsxs("div",{className:"flex items-start gap-2 sm:gap-3",children:[a.jsx("div",{className:"flex-shrink-0 mt-0.5",children:a.jsx("div",{className:"rounded-md bg-primary/10 px-2 py-1",children:a.jsx("span",{className:"text-xs sm:text-sm font-bold text-primary",children:"GPLv3"})})}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("p",{className:"text-sm sm:text-base font-semibold text-foreground mb-1",children:"MaiBot WebUI"}),a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"本项目采用 GNU General Public License v3.0 开源许可证。 您可以自由地使用、修改和分发本软件,但必须保持相同的开源许可。"})]})]})}),a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"本项目依赖的所有开源库均遵循各自的开源许可证(MIT、Apache-2.0、BSD 等)。 感谢所有开源贡献者的无私奉献。"})]})]})]})}function Gn({name:t,description:e,license:n}){return a.jsxs("div",{className:"flex items-start justify-between gap-2 rounded-lg border bg-muted/30 p-2.5 sm:p-3",children:[a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("p",{className:"font-medium text-foreground truncate",children:t}),a.jsx("p",{className:"text-muted-foreground text-xs mt-0.5",children:e})]}),a.jsx("span",{className:"inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary flex-shrink-0",children:n})]})}function Ny({value:t,current:e,onChange:n,label:r,description:s}){const i=e===t;return a.jsxs("button",{onClick:()=>n(t),className:ye("relative rounded-lg border-2 p-3 sm:p-4 text-left transition-all","hover:border-primary/50 hover:bg-accent/50",i?"border-primary bg-accent":"border-border"),children:[i&&a.jsx("div",{className:"absolute top-2 right-2 sm:top-3 sm:right-3 h-2 w-2 rounded-full bg-primary"}),a.jsxs("div",{className:"space-y-1",children:[a.jsx("div",{className:"text-sm sm:text-base font-medium",children:r}),a.jsx("div",{className:"text-[10px] sm:text-xs text-muted-foreground",children:s})]}),a.jsxs("div",{className:"mt-2 sm:mt-3 flex gap-1",children:[t==="light"&&a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-200"}),a.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-300"}),a.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-400"})]}),t==="dark"&&a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-700"}),a.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-800"}),a.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-900"})]}),t==="system"&&a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"h-2 w-2 rounded-full bg-gradient-to-r from-slate-200 to-slate-700"}),a.jsx("div",{className:"h-2 w-2 rounded-full bg-gradient-to-r from-slate-300 to-slate-800"}),a.jsx("div",{className:"h-2 w-2 rounded-full bg-gradient-to-r from-slate-400 to-slate-900"})]})]})]})}function xi({value:t,current:e,onChange:n,label:r,colorClass:s}){const i=e===t;return a.jsxs("button",{onClick:()=>n(t),className:ye("relative rounded-lg border-2 p-2 sm:p-3 text-left transition-all","hover:border-primary/50 hover:bg-accent/50",i?"border-primary bg-accent":"border-border"),children:[i&&a.jsx("div",{className:"absolute top-1.5 right-1.5 sm:top-2 sm:right-2 h-1.5 w-1.5 sm:h-2 sm:w-2 rounded-full bg-primary"}),a.jsxs("div",{className:"flex flex-col items-center gap-1.5 sm:gap-2",children:[a.jsx("div",{className:ye("h-8 w-8 sm:h-10 sm:w-10 rounded-full",s)}),a.jsx("div",{className:"text-[10px] sm:text-xs font-medium text-center",children:r})]})]})}class jH{grad3;p;perm;constructor(e=0){this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.p=[];for(let n=0;n<256;n++)this.p[n]=Math.floor(Math.random()*256);this.perm=[];for(let n=0;n<512;n++)this.perm[n]=this.p[n&255]}dot(e,n,r){return e[0]*n+e[1]*r}mix(e,n,r){return(1-r)*e+r*n}fade(e){return e*e*e*(e*(e*6-15)+10)}perlin2(e,n){const r=Math.floor(e)&255,s=Math.floor(n)&255;e-=Math.floor(e),n-=Math.floor(n);const i=this.fade(e),l=this.fade(n),c=this.perm[r]+s,d=this.perm[c],h=this.perm[c+1],m=this.perm[r+1]+s,p=this.perm[m],x=this.perm[m+1];return this.mix(this.mix(this.dot(this.grad3[d%12],e,n),this.dot(this.grad3[p%12],e-1,n),i),this.mix(this.dot(this.grad3[h%12],e,n-1),this.dot(this.grad3[x%12],e-1,n-1),i),l)}}function NH(){const t=S.useRef(null),e=S.useRef(null),n=S.useRef(void 0),r=S.useRef({mouse:{x:-10,y:0,lx:0,ly:0,sx:0,sy:0,v:0,vs:0,a:0,set:!1},lines:[],paths:[],noise:new jH(Math.random()),bounding:null});return S.useEffect(()=>{const s=e.current,i=t.current;if(!s||!i)return;const l=r.current,c=()=>{const k=s.getBoundingClientRect();l.bounding=k,i.style.width=`${k.width}px`,i.style.height=`${k.height}px`},d=()=>{if(!l.bounding)return;const{width:k,height:O}=l.bounding;l.lines=[],l.paths.forEach(F=>F.remove()),l.paths=[];const j=10,T=32,M=k+200,_=O+30,D=Math.ceil(M/j),E=Math.ceil(_/T),z=(k-j*D)/2,Q=(O-T*E)/2;for(let F=0;F<=D;F++){const B=[];for(let V=0;V<=E;V++){const ce={x:z+j*F,y:Q+T*V,wave:{x:0,y:0},cursor:{x:0,y:0,vx:0,vy:0}};B.push(ce)}const U=document.createElementNS("http://www.w3.org/2000/svg","path");i.appendChild(U),l.paths.push(U),l.lines.push(B)}},h=k=>{const{lines:O,mouse:j,noise:T}=l;O.forEach(M=>{M.forEach(_=>{const D=T.perlin2((_.x+k*.0125)*.002,(_.y+k*.005)*.0015)*12;_.wave.x=Math.cos(D)*32,_.wave.y=Math.sin(D)*16;const E=_.x-j.sx,z=_.y-j.sy,Q=Math.hypot(E,z),F=Math.max(175,j.vs);if(Q{const j={x:k.x+k.wave.x+(O?k.cursor.x:0),y:k.y+k.wave.y+(O?k.cursor.y:0)};return j.x=Math.round(j.x*10)/10,j.y=Math.round(j.y*10)/10,j},p=()=>{const{lines:k,paths:O}=l;k.forEach((j,T)=>{let M=m(j[0],!1),_=`M ${M.x} ${M.y}`;j.forEach((D,E)=>{const z=E===j.length-1;M=m(D,!z),_+=`L ${M.x} ${M.y}`}),O[T].setAttribute("d",_)})},x=k=>{const{mouse:O}=l;O.sx+=(O.x-O.sx)*.1,O.sy+=(O.y-O.sy)*.1;const j=O.x-O.lx,T=O.y-O.ly,M=Math.hypot(j,T);O.v=M,O.vs+=(M-O.vs)*.1,O.vs=Math.min(100,O.vs),O.lx=O.x,O.ly=O.y,O.a=Math.atan2(T,j),s&&(s.style.setProperty("--x",`${O.sx}px`),s.style.setProperty("--y",`${O.sy}px`)),h(k),p(),n.current=requestAnimationFrame(x)},v=k=>{if(!l.bounding)return;const{mouse:O}=l;O.x=k.pageX-l.bounding.left,O.y=k.pageY-l.bounding.top+window.scrollY,O.set||(O.sx=O.x,O.sy=O.y,O.lx=O.x,O.ly=O.y,O.set=!0)},b=()=>{c(),d()};return c(),d(),window.addEventListener("resize",b),window.addEventListener("mousemove",v),n.current=requestAnimationFrame(x),()=>{window.removeEventListener("resize",b),window.removeEventListener("mousemove",v),n.current&&cancelAnimationFrame(n.current)}},[]),a.jsxs("div",{ref:e,className:"waves-background",style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",overflow:"hidden",pointerEvents:"none"},children:[a.jsx("div",{className:"waves-cursor",style:{position:"absolute",top:0,left:0,width:"0.5rem",height:"0.5rem",background:"hsl(var(--primary) / 0.3)",borderRadius:"50%",transform:"translate3d(calc(var(--x, -0.5rem) - 50%), calc(var(--y, 50%) - 50%), 0)",willChange:"transform",pointerEvents:"none"}}),a.jsx("svg",{ref:t,style:{display:"block",width:"100%",height:"100%"},children:a.jsx("style",{children:` - path { - fill: none; - stroke: hsl(var(--primary) / 0.20); - stroke-width: 1px; - } - `})})]})}function CH(){const t=ba();S.useEffect(()=>{localStorage.getItem("access-token")||t({to:"/auth"})},[t])}function qT(){return!!localStorage.getItem("access-token")}function TH(){const[t,e]=S.useState(""),[n,r]=S.useState(!1),[s,i]=S.useState(""),l=ba(),{enableWavesBackground:c,setEnableWavesBackground:d}=hT(),{theme:h,setTheme:m}=dw();S.useEffect(()=>{qT()&&l({to:"/"})},[l]);const x=h==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":h,v=()=>{m(x==="dark"?"light":"dark")},b=async k=>{if(k.preventDefault(),i(""),!t.trim()){i("请输入 Access Token");return}r(!0);try{const O=await fetch("/api/webui/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t.trim()})}),j=await O.json();if(O.ok&&j.valid){localStorage.setItem("access-token",t.trim());const T=await fetch("/api/webui/setup/status",{method:"GET",headers:{Authorization:`Bearer ${t.trim()}`}}),M=await T.json();T.ok&&M.is_first_setup?l({to:"/setup"}):l({to:"/"})}else i(j.message||"Token 验证失败,请检查后重试")}catch(O){console.error("Token 验证错误:",O),i("连接服务器失败,请检查网络连接")}finally{r(!1)}};return a.jsxs("div",{className:"relative flex min-h-screen items-center justify-center overflow-hidden bg-background p-4",children:[c&&a.jsx(NH,{}),a.jsxs(yt,{className:"relative z-10 w-full max-w-md shadow-2xl backdrop-blur-xl bg-card/80 border-border/50",children:[a.jsx("button",{onClick:v,className:"absolute right-4 top-4 rounded-lg p-2 hover:bg-accent transition-colors z-10 text-foreground",title:x==="dark"?"切换到浅色模式":"切换到深色模式",children:x==="dark"?a.jsx(Zb,{className:"h-5 w-5",strokeWidth:2.5,fill:"none"}):a.jsx(Jb,{className:"h-5 w-5",strokeWidth:2.5,fill:"none"})}),a.jsxs(Jt,{className:"space-y-4 text-center",children:[a.jsx("div",{className:"mx-auto flex h-16 w-16 items-center justify-center rounded-2xl bg-primary/10",children:a.jsx(lO,{className:"h-8 w-8 text-primary",strokeWidth:2,fill:"none"})}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(en,{className:"text-2xl font-bold",children:"欢迎使用 MaiBot"}),a.jsx(Sr,{className:"text-base",children:"请输入您的 Access Token 以继续访问系统"})]})]}),a.jsx(vn,{children:a.jsxs("form",{onSubmit:b,className:"space-y-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"token",className:"text-sm font-medium",children:"Access Token"}),a.jsxs("div",{className:"relative",children:[a.jsx(fq,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground",strokeWidth:2,fill:"none"}),a.jsx(Ae,{id:"token",type:"password",placeholder:"请输入您的 Access Token",value:t,onChange:k=>e(k.target.value),className:ye("pl-10",s&&"border-red-500 focus-visible:ring-red-500"),disabled:n,autoFocus:!0,autoComplete:"off"})]})]}),s&&a.jsxs("div",{className:"flex items-center gap-2 rounded-md bg-red-50 p-3 text-sm text-red-600 dark:bg-red-950/50 dark:text-red-400",children:[a.jsx(xc,{className:"h-4 w-4 flex-shrink-0",strokeWidth:2,fill:"none"}),a.jsx("span",{children:s})]}),a.jsx(ie,{type:"submit",className:"w-full",disabled:n,children:n?a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"}),"验证中..."]}):"验证并进入"}),a.jsxs(Rr,{children:[a.jsx(mw,{asChild:!0,children:a.jsxs("button",{className:"w-full text-center text-sm text-primary hover:text-primary/80 transition-colors underline-offset-4 hover:underline flex items-center justify-center gap-1",children:[a.jsx(mq,{className:"h-4 w-4",strokeWidth:2,fill:"none"}),"我没有 Token,我该去哪里获得 Token?"]})}),a.jsxs(Nr,{className:"sm:max-w-md",children:[a.jsxs(Cr,{children:[a.jsxs(Tr,{className:"flex items-center gap-2",children:[a.jsx(lO,{className:"h-5 w-5 text-primary",strokeWidth:2,fill:"none"}),"如何获取 Access Token"]}),a.jsx(Gr,{children:"Access Token 是访问 MaiBot WebUI 的唯一凭证,请按以下方式获取"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsx("div",{className:"rounded-lg border bg-muted/50 p-4 space-y-2",children:a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx(pq,{className:"h-5 w-5 text-primary flex-shrink-0 mt-0.5",strokeWidth:2,fill:"none"}),a.jsxs("div",{className:"flex-1 space-y-2",children:[a.jsx("h4",{className:"font-semibold text-sm",children:"方式一:查看启动日志"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"在 MaiBot 启动时,控制台会显示 WebUI Access Token。"}),a.jsxs("div",{className:"rounded bg-background p-2 font-mono text-xs",children:[a.jsx("p",{className:"text-muted-foreground",children:"🔑 WebUI Access Token: abc123..."}),a.jsx("p",{className:"text-muted-foreground",children:"💡 请使用此 Token 登录 WebUI"})]})]})]})}),a.jsx("div",{className:"rounded-lg border bg-muted/50 p-4 space-y-2",children:a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx(io,{className:"h-5 w-5 text-primary flex-shrink-0 mt-0.5",strokeWidth:2,fill:"none"}),a.jsxs("div",{className:"flex-1 space-y-2",children:[a.jsx("h4",{className:"font-semibold text-sm",children:"方式二:查看配置文件"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"Token 保存在项目根目录的配置文件中:"}),a.jsx("div",{className:"rounded bg-background p-2 font-mono text-xs break-all",children:a.jsx("code",{className:"text-primary",children:"data/webui.json"})}),a.jsxs("p",{className:"text-xs text-muted-foreground",children:["打开此文件,复制 ",a.jsx("code",{className:"px-1 py-0.5 bg-background rounded",children:"access_token"})," 字段的值"]})]})]})}),a.jsx("div",{className:"rounded-lg border border-yellow-200 dark:border-yellow-900 bg-yellow-50 dark:bg-yellow-950/30 p-3",children:a.jsxs("div",{className:"flex gap-2",children:[a.jsx(xc,{className:"h-4 w-4 text-yellow-600 dark:text-yellow-500 flex-shrink-0 mt-0.5",strokeWidth:2,fill:"none"}),a.jsxs("div",{className:"text-sm text-yellow-800 dark:text-yellow-300 space-y-1",children:[a.jsx("p",{className:"font-semibold",children:"安全提示"}),a.jsxs("ul",{className:"list-disc list-inside space-y-0.5 text-xs",children:[a.jsx("li",{children:"请妥善保管您的 Token,不要泄露给他人"}),a.jsx("li",{children:"如需重置 Token,请在登录后前往系统设置"})]})]})]})})]})]})]}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsxs("button",{className:"w-full text-center text-sm text-muted-foreground hover:text-foreground transition-colors underline-offset-4 hover:underline flex items-center justify-center gap-1",children:[a.jsx(uf,{className:"h-4 w-4",strokeWidth:2,fill:"none"}),"我觉得这个界面很卡怎么办?"]})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsxs(cn,{className:"flex items-center gap-2",children:[a.jsx(uf,{className:"h-5 w-5 text-primary",strokeWidth:2,fill:"none"}),"关闭背景动画"]}),a.jsx(un,{children:"背景动画可能会在低性能设备上造成卡顿。关闭动画可以显著提升界面流畅度。"})]}),a.jsx("div",{className:"rounded-lg border bg-muted/50 p-4 space-y-2",children:a.jsx("p",{className:"text-sm text-muted-foreground",children:"关闭动画后,背景将变为纯色,但不影响任何功能的使用。您可以随时在系统设置中重新开启动画。"})}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>d(!1),children:"关闭动画"})]})]})]})]})})]}),a.jsx("div",{className:"absolute bottom-4 left-0 right-0 text-center text-xs text-muted-foreground",children:a.jsx("p",{children:nH})})]})}const On=S.forwardRef(({className:t,...e},n)=>a.jsx("textarea",{className:ye("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:n,...e}));On.displayName="Textarea";var MH=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],AH=MH.reduce((t,e)=>{const n=Q4(`Primitive.${e}`),r=S.forwardRef((s,i)=>{const{asChild:l,...c}=s,d=l?n:e;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),a.jsx(d,{...c,ref:i})});return r.displayName=`Primitive.${e}`,{...t,[e]:r}},{}),EH="Separator",WO="horizontal",_H=["horizontal","vertical"],FT=S.forwardRef((t,e)=>{const{decorative:n,orientation:r=WO,...s}=t,i=DH(r)?r:WO,c=n?{role:"none"}:{"aria-orientation":i==="vertical"?i:void 0,role:"separator"};return a.jsx(AH.div,{"data-orientation":i,...c,...s,ref:e})});FT.displayName=EH;function DH(t){return _H.includes(t)}var QT=FT;const mf=S.forwardRef(({className:t,orientation:e="horizontal",decorative:n=!0,...r},s)=>a.jsx(QT,{ref:s,decorative:n,orientation:e,className:ye("shrink-0 bg-border",e==="horizontal"?"h-[1px] w-full":"h-full w-[1px]",t),...r}));mf.displayName=QT.displayName;const RH=Nd("inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",outline:"text-foreground"}},defaultVariants:{variant:"default"}});function $n({className:t,variant:e,...n}){return a.jsx("div",{className:ye(RH({variant:e}),t),...n})}function zH({config:t,onChange:e}){const n=s=>{s.trim()&&!t.alias_names.includes(s.trim())&&e({...t,alias_names:[...t.alias_names,s.trim()]})},r=s=>{e({...t,alias_names:t.alias_names.filter((i,l)=>l!==s)})};return a.jsxs("div",{className:"space-y-6",children:[a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"qq_account",children:"QQ账号 *"}),a.jsx(Ae,{id:"qq_account",type:"number",placeholder:"请输入机器人的QQ账号",value:t.qq_account||"",onChange:s=>e({...t,qq_account:Number(s.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人登录使用的QQ账号"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"nickname",children:"昵称 *"}),a.jsx(Ae,{id:"nickname",placeholder:"请输入机器人的昵称",value:t.nickname,onChange:s=>e({...t,nickname:s.target.value})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人的主要称呼名称"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{children:"别名"}),a.jsx("div",{className:"flex flex-wrap gap-2 mb-2",children:t.alias_names.map((s,i)=>a.jsxs($n,{variant:"secondary",className:"gap-1",children:[s,a.jsx("button",{type:"button",onClick:()=>r(i),className:"ml-1 hover:text-destructive",children:a.jsx(Gf,{className:"h-3 w-3"})})]},i))}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{id:"alias_input",placeholder:"输入别名后按回车添加",onKeyPress:s=>{s.key==="Enter"&&(n(s.target.value),s.target.value="")}}),a.jsx(ie,{type:"button",variant:"outline",onClick:()=>{const s=document.getElementById("alias_input");s&&(n(s.value),s.value="")},children:"添加"})]}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人的其他称呼,可以添加多个"})]})]})}function PH({config:t,onChange:e}){return a.jsxs("div",{className:"space-y-6",children:[a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"personality",children:"人格特征 *"}),a.jsx(On,{id:"personality",placeholder:"描述机器人的人格特质和身份特征(建议120字以内)",value:t.personality,onChange:n=>e({...t,personality:n.target.value}),rows:3}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"例如:是一个女大学生,现在在读大二,会刷贴吧"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"reply_style",children:"表达风格 *"}),a.jsx(On,{id:"reply_style",placeholder:"描述机器人说话的表达风格、表达习惯",value:t.reply_style,onChange:n=>e({...t,reply_style:n.target.value}),rows:3}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"例如:回复平淡一些,简短一些,说中文,参考贴吧、知乎和微博的回复风格"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"interest",children:"兴趣 *"}),a.jsx(On,{id:"interest",placeholder:"描述机器人感兴趣的话题",value:t.interest,onChange:n=>e({...t,interest:n.target.value}),rows:2}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"会影响机器人对什么话题进行回复"})]}),a.jsx(mf,{}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"plan_style",children:"群聊说话规则 *"}),a.jsx(On,{id:"plan_style",placeholder:"机器人在群聊中的行为风格和规则",value:t.plan_style,onChange:n=>e({...t,plan_style:n.target.value}),rows:4}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"定义机器人在群聊中如何行动,例如回复频率、条件等"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"private_plan_style",children:"私聊说话规则 *"}),a.jsx(On,{id:"private_plan_style",placeholder:"机器人在私聊中的行为风格和规则",value:t.private_plan_style,onChange:n=>e({...t,private_plan_style:n.target.value}),rows:3}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"定义机器人在私聊中的行为方式"})]})]})}function LH({config:t,onChange:e}){return a.jsxs("div",{className:"space-y-6",children:[a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{htmlFor:"emoji_chance",children:"表情包激活概率"}),a.jsxs("span",{className:"text-sm text-muted-foreground",children:[(t.emoji_chance*100).toFixed(0),"%"]})]}),a.jsx(Ae,{id:"emoji_chance",type:"range",min:"0",max:"1",step:"0.1",value:t.emoji_chance,onChange:n=>e({...t,emoji_chance:Number(n.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人发送表情包的概率"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"max_reg_num",children:"最大表情包数量"}),a.jsx(Ae,{id:"max_reg_num",type:"number",min:"1",max:"200",value:t.max_reg_num,onChange:n=>e({...t,max_reg_num:Number(n.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人最多保存的表情包数量"})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx(te,{htmlFor:"do_replace",children:"达到最大数量时替换"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"开启后会删除旧表情包,关闭则不再收集新表情包"})]}),a.jsx(jt,{id:"do_replace",checked:t.do_replace,onCheckedChange:n=>e({...t,do_replace:n})})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"check_interval",children:"检查间隔(分钟)"}),a.jsx(Ae,{id:"check_interval",type:"number",min:"1",max:"120",value:t.check_interval,onChange:n=>e({...t,check_interval:Number(n.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"检查表情包注册、破损、删除的时间间隔"})]}),a.jsx(mf,{}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx(te,{htmlFor:"steal_emoji",children:"偷取表情包"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"允许机器人将一些表情包据为己有"})]}),a.jsx(jt,{id:"steal_emoji",checked:t.steal_emoji,onCheckedChange:n=>e({...t,steal_emoji:n})})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx(te,{htmlFor:"content_filtration",children:"启用表情包过滤"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"只保存符合要求的表情包"})]}),a.jsx(jt,{id:"content_filtration",checked:t.content_filtration,onCheckedChange:n=>e({...t,content_filtration:n})})]}),t.content_filtration&&a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"filtration_prompt",children:"过滤要求"}),a.jsx(Ae,{id:"filtration_prompt",placeholder:"例如:符合公序良俗",value:t.filtration_prompt,onChange:n=>e({...t,filtration_prompt:n.target.value})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"描述表情包应该符合的要求"})]})]})}function BH({config:t,onChange:e}){return a.jsxs("div",{className:"space-y-6",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx(te,{htmlFor:"enable_tool",children:"启用工具系统"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"允许机器人使用各种工具增强功能"})]}),a.jsx(jt,{id:"enable_tool",checked:t.enable_tool,onCheckedChange:n=>e({...t,enable_tool:n})})]}),a.jsx(mf,{}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx(te,{htmlFor:"enable_mood",children:"启用情绪系统"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"让机器人具有情绪变化能力"})]}),a.jsx(jt,{id:"enable_mood",checked:t.enable_mood,onCheckedChange:n=>e({...t,enable_mood:n})})]}),t.enable_mood&&a.jsxs("div",{className:"ml-6 space-y-6 border-l-2 border-primary/20 pl-6",children:[a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"mood_update_threshold",children:"情绪更新阈值"}),a.jsx(Ae,{id:"mood_update_threshold",type:"number",min:"0.1",max:"10",step:"0.1",value:t.mood_update_threshold||1,onChange:n=>e({...t,mood_update_threshold:Number(n.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"值越高,情绪更新越慢"})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsx(te,{htmlFor:"emotion_style",children:"情感特征"}),a.jsx(On,{id:"emotion_style",placeholder:"描述情绪的变化情况,例如:情绪较为稳定,但遭遇特定事件时起伏较大",value:t.emotion_style||"",onChange:n=>e({...t,emotion_style:n.target.value}),rows:2}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"影响机器人的情绪变化方式"})]})]}),a.jsx(mf,{}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx(te,{htmlFor:"all_global",children:"启用全局黑话模式"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"允许机器人学习和使用群组黑话"})]}),a.jsx(jt,{id:"all_global",checked:t.all_global,onCheckedChange:n=>e({...t,all_global:n})})]})]})}async function ot(t,e){const n=await fetch(t,e);if(n.status===401)throw localStorage.removeItem("access-token"),window.location.href="/auth",new Error("认证失败,请重新登录");return n}function bt(){return{"Content-Type":"application/json",Authorization:`Bearer ${localStorage.getItem("access-token")}`}}async function IH(){const t=await ot("/api/webui/config/bot",{method:"GET",headers:bt()});if(!t.ok)throw new Error("读取Bot配置失败");const n=(await t.json()).config.bot||{};return{qq_account:n.qq_account||0,nickname:n.nickname||"",alias_names:n.alias_names||[]}}async function qH(){const t=await ot("/api/webui/config/bot",{method:"GET",headers:bt()});if(!t.ok)throw new Error("读取人格配置失败");const n=(await t.json()).config.personality||{};return{personality:n.personality||"",reply_style:n.reply_style||"",interest:n.interest||"",plan_style:n.plan_style||"",private_plan_style:n.private_plan_style||""}}async function FH(){const t=await ot("/api/webui/config/bot",{method:"GET",headers:bt()});if(!t.ok)throw new Error("读取表情包配置失败");const n=(await t.json()).config.emoji||{};return{emoji_chance:n.emoji_chance??.4,max_reg_num:n.max_reg_num??40,do_replace:n.do_replace??!0,check_interval:n.check_interval??10,steal_emoji:n.steal_emoji??!0,content_filtration:n.content_filtration??!1,filtration_prompt:n.filtration_prompt||""}}async function QH(){const t=await ot("/api/webui/config/bot",{method:"GET",headers:bt()});if(!t.ok)throw new Error("读取其他配置失败");const n=(await t.json()).config,r=n.tool||{},s=n.mood||{},i=n.jargon||{};return{enable_tool:r.enable_tool??!0,enable_mood:s.enable_mood??!1,mood_update_threshold:s.mood_update_threshold,emotion_style:s.emotion_style,all_global:i.all_global??!0}}async function $H(t){const e=await ot("/api/webui/config/bot/section/bot",{method:"POST",headers:bt(),body:JSON.stringify(t)});if(!e.ok){const n=await e.json();throw new Error(n.detail||"保存Bot基础配置失败")}return await e.json()}async function HH(t){const e=await ot("/api/webui/config/bot/section/personality",{method:"POST",headers:bt(),body:JSON.stringify(t)});if(!e.ok){const n=await e.json();throw new Error(n.detail||"保存人格配置失败")}return await e.json()}async function UH(t){const e=await ot("/api/webui/config/bot/section/emoji",{method:"POST",headers:bt(),body:JSON.stringify(t)});if(!e.ok){const n=await e.json();throw new Error(n.detail||"保存表情包配置失败")}return await e.json()}async function VH(t){const e=[];e.push(ot("/api/webui/config/bot/section/tool",{method:"POST",headers:bt(),body:JSON.stringify({enable_tool:t.enable_tool})})),e.push(ot("/api/webui/config/bot/section/jargon",{method:"POST",headers:bt(),body:JSON.stringify({all_global:t.all_global})}));const n={enable_mood:t.enable_mood};t.enable_mood&&(n.mood_update_threshold=t.mood_update_threshold||1,n.emotion_style=t.emotion_style||""),e.push(ot("/api/webui/config/bot/section/mood",{method:"POST",headers:bt(),body:JSON.stringify(n)}));const r=await Promise.all(e);for(const s of r)if(!s.ok){const i=await s.json();throw new Error(i.detail||"保存其他配置失败")}return{success:!0}}async function GO(){const t=localStorage.getItem("access-token"),e=await ot("/api/webui/setup/complete",{method:"POST",headers:{Authorization:`Bearer ${t}`}});if(!e.ok){const n=await e.json();throw new Error(n.message||"标记配置完成失败")}return await e.json()}function WH(){const t=ba(),{toast:e}=Pr(),[n,r]=S.useState(0),[s,i]=S.useState(!1),[l,c]=S.useState(!1),[d,h]=S.useState(!0),[m,p]=S.useState({qq_account:0,nickname:"",alias_names:[]}),[x,v]=S.useState({personality:"是一个女大学生,现在在读大二,会刷贴吧。",reply_style:"请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。",interest:"对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题",plan_style:`1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 -2.如果相同的内容已经被执行,请不要重复执行 -3.请控制你的发言频率,不要太过频繁的发言 -4.如果有人对你感到厌烦,请减少回复 -5.如果有人对你进行攻击,或者情绪激动,请你以合适的方法应对`,private_plan_style:`1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 -2.如果相同的内容已经被执行,请不要重复执行 -3.某句话如果已经被回复过,不要重复回复`}),[b,k]=S.useState({emoji_chance:.4,max_reg_num:40,do_replace:!0,check_interval:10,steal_emoji:!0,content_filtration:!1,filtration_prompt:"符合公序良俗"}),[O,j]=S.useState({enable_tool:!0,enable_mood:!1,mood_update_threshold:1,emotion_style:"情绪较为稳定,但遭遇特定事件的时候起伏较大",all_global:!0}),T=[{id:"bot-basic",title:"Bot基础",description:"配置机器人的基本信息",icon:xq},{id:"personality",title:"人格配置",description:"定义机器人的性格和说话风格",icon:D9},{id:"emoji",title:"表情包",description:"配置表情包相关设置",icon:K4},{id:"other",title:"其他设置",description:"工具、情绪系统等配置",icon:dc},{id:"complete",title:"完成设置",description:"后续配置提示",icon:uf}],M=(n+1)/T.length*100;S.useEffect(()=>{(async()=>{try{h(!0);const[U,V,ce,W]=await Promise.all([IH(),qH(),FH(),QH()]);p(U),v(V),k(ce),j(W)}catch(U){e({title:"加载配置失败",description:U instanceof Error?U.message:"无法加载现有配置,将使用默认值",variant:"destructive"})}finally{h(!1)}})()},[e]);const _=async()=>{c(!0);try{switch(n){case 0:await $H(m);break;case 1:await HH(x);break;case 2:await UH(b);break;case 3:await VH(O);break}return e({title:"保存成功",description:`${T[n].title}配置已保存`}),!0}catch(B){return e({title:"保存失败",description:B instanceof Error?B.message:"未知错误",variant:"destructive"}),!1}finally{c(!1)}},D=async()=>{await _()&&n{n>0&&r(n-1)},z=async()=>{i(!0);try{if(!await _()){i(!1);return}await GO(),e({title:"配置完成",description:"所有配置已保存,正在跳转..."}),setTimeout(()=>{t({to:"/"})},500)}catch(B){e({title:"完成失败",description:B instanceof Error?B.message:"未知错误",variant:"destructive"})}finally{i(!1)}},Q=async()=>{try{await GO(),t({to:"/"})}catch(B){e({title:"跳过失败",description:B instanceof Error?B.message:"未知错误",variant:"destructive"})}},F=()=>{switch(n){case 0:return a.jsx(zH,{config:m,onChange:p});case 1:return a.jsx(PH,{config:x,onChange:v});case 2:return a.jsx(LH,{config:b,onChange:k});case 3:return a.jsx(BH,{config:O,onChange:j});case 4:return a.jsxs("div",{className:"space-y-6 text-center py-8",children:[a.jsx("div",{className:"mx-auto w-16 h-16 rounded-full bg-primary/10 flex items-center justify-center",children:a.jsx(uf,{className:"h-8 w-8 text-primary",strokeWidth:2})}),a.jsxs("div",{className:"space-y-3",children:[a.jsx("h3",{className:"text-xl font-semibold",children:"模型配置"}),a.jsx("p",{className:"text-muted-foreground max-w-md mx-auto",children:"为了让机器人正常工作,您需要配置 AI 模型提供商和模型。"})]}),a.jsxs("div",{className:"rounded-lg border bg-muted/50 p-6 max-w-md mx-auto text-left space-y-4",children:[a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx("div",{className:"mt-0.5",children:a.jsx("div",{className:"h-6 w-6 rounded-full bg-primary/20 flex items-center justify-center text-primary text-sm font-semibold",children:"1"})}),a.jsxs("div",{children:[a.jsx("p",{className:"font-medium",children:"配置 API 提供商"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:'在"系统设置 → 模型配置 → API 提供商"中添加您的 API 提供商信息'})]})]}),a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx("div",{className:"mt-0.5",children:a.jsx("div",{className:"h-6 w-6 rounded-full bg-primary/20 flex items-center justify-center text-primary text-sm font-semibold",children:"2"})}),a.jsxs("div",{children:[a.jsx("p",{className:"font-medium",children:"添加模型"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:'在"系统设置 → 模型配置 → 模型列表"中添加需要使用的模型'})]})]}),a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx("div",{className:"mt-0.5",children:a.jsx("div",{className:"h-6 w-6 rounded-full bg-primary/20 flex items-center justify-center text-primary text-sm font-semibold",children:"3"})}),a.jsxs("div",{children:[a.jsx("p",{className:"font-medium",children:"配置模型任务"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:'在"系统设置 → 模型配置 → 模型任务配置"中为不同任务分配模型'})]})]})]}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"💡 提示:完成向导后,您可以在系统设置中进行详细的模型配置"})]});default:return null}};return a.jsxs("div",{className:"relative flex min-h-screen flex-col items-center justify-center overflow-hidden bg-gradient-to-br from-primary/5 via-background to-secondary/5 p-4 md:p-6",children:[a.jsxs("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:[a.jsx("div",{className:"absolute left-1/4 top-1/4 h-64 w-64 md:h-96 md:w-96 rounded-full bg-primary/5 blur-3xl"}),a.jsx("div",{className:"absolute right-1/4 bottom-1/4 h-64 w-64 md:h-96 md:w-96 rounded-full bg-secondary/5 blur-3xl"})]}),d?a.jsxs("div",{className:"relative z-10 text-center",children:[a.jsx("div",{className:"mx-auto mb-4 flex h-16 w-16 items-center justify-center",children:a.jsx("div",{className:"h-12 w-12 animate-spin rounded-full border-4 border-primary border-t-transparent"})}),a.jsx("p",{className:"text-lg font-medium",children:"加载配置中..."}),a.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:"正在读取现有配置"})]}):a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"relative z-10 w-full max-w-4xl",children:[a.jsxs("div",{className:"mb-6 md:mb-8 text-center",children:[a.jsx("div",{className:"mx-auto mb-4 flex h-12 w-12 md:h-16 md:w-16 items-center justify-center rounded-2xl bg-primary/10",children:a.jsx(gq,{className:"h-6 w-6 md:h-8 md:w-8 text-primary",strokeWidth:2,fill:"none"})}),a.jsx("h1",{className:"mb-2 text-2xl md:text-3xl font-bold",children:"首次配置向导"}),a.jsxs("p",{className:"text-sm md:text-base text-muted-foreground",children:["让我们一起完成 ",fw," 的初始配置"]})]}),a.jsxs("div",{className:"mb-6 md:mb-8",children:[a.jsxs("div",{className:"mb-2 flex items-center justify-between text-xs md:text-sm",children:[a.jsxs("span",{className:"text-muted-foreground",children:["步骤 ",n+1," / ",T.length]}),a.jsxs("span",{className:"font-medium text-primary",children:[Math.round(M),"%"]})]}),a.jsx(n0,{value:M,className:"h-2"})]}),a.jsx("div",{className:"mb-6 md:mb-8 flex justify-between",children:T.map((B,U)=>{const V=B.icon;return a.jsxs("div",{className:ye("flex flex-1 flex-col items-center gap-1 md:gap-2",Ut({to:"/"}),className:"gap-2 w-full sm:w-auto",children:[a.jsx(hg,{className:"h-4 w-4"}),"返回首页"]}),a.jsxs(ie,{size:"lg",variant:"outline",onClick:()=>window.history.back(),className:"gap-2 w-full sm:w-auto",children:[a.jsx(R9,{className:"h-4 w-4"}),"返回上一页"]})]}),a.jsx("div",{className:"mt-12 pt-8 border-t border-border",children:a.jsx("p",{className:"text-sm text-muted-foreground",children:"如果您认为这是一个错误,请联系系统管理员"})})]})})}var HT=["PageUp","PageDown"],UT=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],VT={"from-left":["Home","PageDown","ArrowDown","ArrowLeft"],"from-right":["Home","PageDown","ArrowDown","ArrowRight"],"from-bottom":["Home","PageDown","ArrowDown","ArrowLeft"],"from-top":["Home","PageDown","ArrowUp","ArrowLeft"]},Cd="Slider",[c2,GH,XH]=tx(Cd),[WT]=Hi(Cd,[XH]),[YH,vx]=WT(Cd),GT=S.forwardRef((t,e)=>{const{name:n,min:r=0,max:s=100,step:i=1,orientation:l="horizontal",disabled:c=!1,minStepsBetweenThumbs:d=0,defaultValue:h=[r],value:m,onValueChange:p=()=>{},onValueCommit:x=()=>{},inverted:v=!1,form:b,...k}=t,O=S.useRef(new Set),j=S.useRef(0),M=l==="horizontal"?KH:ZH,[_=[],D]=So({prop:m,defaultProp:h,onChange:U=>{[...O.current][j.current]?.focus(),p(U)}}),E=S.useRef(_);function z(U){const V=rU(_,U);B(U,V)}function Q(U){B(U,j.current)}function F(){const U=E.current[j.current];_[j.current]!==U&&x(_)}function B(U,V,{commit:ce}={commit:!1}){const W=lU(i),J=oU(Math.round((U-r)/i)*i+r,W),H=F4(J,[r,s]);D((ae=[])=>{const ne=tU(ae,H,V);if(aU(ne,d*i)){j.current=ne.indexOf(H);const ue=String(ne)!==String(ae);return ue&&ce&&x(ne),ue?ne:ae}else return ae})}return a.jsx(YH,{scope:t.__scopeSlider,name:n,disabled:c,min:r,max:s,valueIndexToChangeRef:j,thumbs:O.current,values:_,orientation:l,form:b,children:a.jsx(c2.Provider,{scope:t.__scopeSlider,children:a.jsx(c2.Slot,{scope:t.__scopeSlider,children:a.jsx(M,{"aria-disabled":c,"data-disabled":c?"":void 0,...k,ref:e,onPointerDown:$e(k.onPointerDown,()=>{c||(E.current=_)}),min:r,max:s,inverted:v,onSlideStart:c?void 0:z,onSlideMove:c?void 0:Q,onSlideEnd:c?void 0:F,onHomeKeyDown:()=>!c&&B(r,0,{commit:!0}),onEndKeyDown:()=>!c&&B(s,_.length-1,{commit:!0}),onStepKeyDown:({event:U,direction:V})=>{if(!c){const J=HT.includes(U.key)||U.shiftKey&&UT.includes(U.key)?10:1,H=j.current,ae=_[H],ne=i*J*V;B(ae+ne,H,{commit:!0})}}})})})})});GT.displayName=Cd;var[XT,YT]=WT(Cd,{startEdge:"left",endEdge:"right",size:"width",direction:1}),KH=S.forwardRef((t,e)=>{const{min:n,max:r,dir:s,inverted:i,onSlideStart:l,onSlideMove:c,onSlideEnd:d,onStepKeyDown:h,...m}=t,[p,x]=S.useState(null),v=Cn(e,M=>x(M)),b=S.useRef(void 0),k=Vf(s),O=k==="ltr",j=O&&!i||!O&&i;function T(M){const _=b.current||p.getBoundingClientRect(),D=[0,_.width],z=pw(D,j?[n,r]:[r,n]);return b.current=_,z(M-_.left)}return a.jsx(XT,{scope:t.__scopeSlider,startEdge:j?"left":"right",endEdge:j?"right":"left",direction:j?1:-1,size:"width",children:a.jsx(KT,{dir:k,"data-orientation":"horizontal",...m,ref:v,style:{...m.style,"--radix-slider-thumb-transform":"translateX(-50%)"},onSlideStart:M=>{const _=T(M.clientX);l?.(_)},onSlideMove:M=>{const _=T(M.clientX);c?.(_)},onSlideEnd:()=>{b.current=void 0,d?.()},onStepKeyDown:M=>{const D=VT[j?"from-left":"from-right"].includes(M.key);h?.({event:M,direction:D?-1:1})}})})}),ZH=S.forwardRef((t,e)=>{const{min:n,max:r,inverted:s,onSlideStart:i,onSlideMove:l,onSlideEnd:c,onStepKeyDown:d,...h}=t,m=S.useRef(null),p=Cn(e,m),x=S.useRef(void 0),v=!s;function b(k){const O=x.current||m.current.getBoundingClientRect(),j=[0,O.height],M=pw(j,v?[r,n]:[n,r]);return x.current=O,M(k-O.top)}return a.jsx(XT,{scope:t.__scopeSlider,startEdge:v?"bottom":"top",endEdge:v?"top":"bottom",size:"height",direction:v?1:-1,children:a.jsx(KT,{"data-orientation":"vertical",...h,ref:p,style:{...h.style,"--radix-slider-thumb-transform":"translateY(50%)"},onSlideStart:k=>{const O=b(k.clientY);i?.(O)},onSlideMove:k=>{const O=b(k.clientY);l?.(O)},onSlideEnd:()=>{x.current=void 0,c?.()},onStepKeyDown:k=>{const j=VT[v?"from-bottom":"from-top"].includes(k.key);d?.({event:k,direction:j?-1:1})}})})}),KT=S.forwardRef((t,e)=>{const{__scopeSlider:n,onSlideStart:r,onSlideMove:s,onSlideEnd:i,onHomeKeyDown:l,onEndKeyDown:c,onStepKeyDown:d,...h}=t,m=vx(Cd,n);return a.jsx(Yt.span,{...h,ref:e,onKeyDown:$e(t.onKeyDown,p=>{p.key==="Home"?(l(p),p.preventDefault()):p.key==="End"?(c(p),p.preventDefault()):HT.concat(UT).includes(p.key)&&(d(p),p.preventDefault())}),onPointerDown:$e(t.onPointerDown,p=>{const x=p.target;x.setPointerCapture(p.pointerId),p.preventDefault(),m.thumbs.has(x)?x.focus():r(p)}),onPointerMove:$e(t.onPointerMove,p=>{p.target.hasPointerCapture(p.pointerId)&&s(p)}),onPointerUp:$e(t.onPointerUp,p=>{const x=p.target;x.hasPointerCapture(p.pointerId)&&(x.releasePointerCapture(p.pointerId),i(p))})})}),ZT="SliderTrack",JT=S.forwardRef((t,e)=>{const{__scopeSlider:n,...r}=t,s=vx(ZT,n);return a.jsx(Yt.span,{"data-disabled":s.disabled?"":void 0,"data-orientation":s.orientation,...r,ref:e})});JT.displayName=ZT;var u2="SliderRange",eM=S.forwardRef((t,e)=>{const{__scopeSlider:n,...r}=t,s=vx(u2,n),i=YT(u2,n),l=S.useRef(null),c=Cn(e,l),d=s.values.length,h=s.values.map(x=>rM(x,s.min,s.max)),m=d>1?Math.min(...h):0,p=100-Math.max(...h);return a.jsx(Yt.span,{"data-orientation":s.orientation,"data-disabled":s.disabled?"":void 0,...r,ref:c,style:{...t.style,[i.startEdge]:m+"%",[i.endEdge]:p+"%"}})});eM.displayName=u2;var d2="SliderThumb",tM=S.forwardRef((t,e)=>{const n=GH(t.__scopeSlider),[r,s]=S.useState(null),i=Cn(e,c=>s(c)),l=S.useMemo(()=>r?n().findIndex(c=>c.ref.current===r):-1,[n,r]);return a.jsx(JH,{...t,ref:i,index:l})}),JH=S.forwardRef((t,e)=>{const{__scopeSlider:n,index:r,name:s,...i}=t,l=vx(d2,n),c=YT(d2,n),[d,h]=S.useState(null),m=Cn(e,T=>h(T)),p=d?l.form||!!d.closest("form"):!0,x=m9(d),v=l.values[r],b=v===void 0?0:rM(v,l.min,l.max),k=nU(r,l.values.length),O=x?.[c.size],j=O?sU(O,b,c.direction):0;return S.useEffect(()=>{if(d)return l.thumbs.add(d),()=>{l.thumbs.delete(d)}},[d,l.thumbs]),a.jsxs("span",{style:{transform:"var(--radix-slider-thumb-transform)",position:"absolute",[c.startEdge]:`calc(${b}% + ${j}px)`},children:[a.jsx(c2.ItemSlot,{scope:t.__scopeSlider,children:a.jsx(Yt.span,{role:"slider","aria-label":t["aria-label"]||k,"aria-valuemin":l.min,"aria-valuenow":v,"aria-valuemax":l.max,"aria-orientation":l.orientation,"data-orientation":l.orientation,"data-disabled":l.disabled?"":void 0,tabIndex:l.disabled?void 0:0,...i,ref:m,style:v===void 0?{display:"none"}:t.style,onFocus:$e(t.onFocus,()=>{l.valueIndexToChangeRef.current=r})})}),p&&a.jsx(nM,{name:s??(l.name?l.name+(l.values.length>1?"[]":""):void 0),form:l.form,value:v},r)]})});tM.displayName=d2;var eU="RadioBubbleInput",nM=S.forwardRef(({__scopeSlider:t,value:e,...n},r)=>{const s=S.useRef(null),i=Cn(s,r),l=f9(e);return S.useEffect(()=>{const c=s.current;if(!c)return;const d=window.HTMLInputElement.prototype,m=Object.getOwnPropertyDescriptor(d,"value").set;if(l!==e&&m){const p=new Event("input",{bubbles:!0});m.call(c,e),c.dispatchEvent(p)}},[l,e]),a.jsx(Yt.input,{style:{display:"none"},...n,ref:i,defaultValue:e})});nM.displayName=eU;function tU(t=[],e,n){const r=[...t];return r[n]=e,r.sort((s,i)=>s-i)}function rM(t,e,n){const i=100/(n-e)*(t-e);return F4(i,[0,100])}function nU(t,e){return e>2?`Value ${t+1} of ${e}`:e===2?["Minimum","Maximum"][t]:void 0}function rU(t,e){if(t.length===1)return 0;const n=t.map(s=>Math.abs(s-e)),r=Math.min(...n);return n.indexOf(r)}function sU(t,e,n){const r=t/2,i=pw([0,50],[0,r]);return(r-i(e)*n)*n}function iU(t){return t.slice(0,-1).map((e,n)=>t[n+1]-e)}function aU(t,e){if(e>0){const n=iU(t);return Math.min(...n)>=e}return!0}function pw(t,e){return n=>{if(t[0]===t[1]||e[0]===e[1])return e[0];const r=(e[1]-e[0])/(t[1]-t[0]);return e[0]+r*(n-t[0])}}function lU(t){return(String(t).split(".")[1]||"").length}function oU(t,e){const n=Math.pow(10,e);return Math.round(t*n)/n}var sM=GT,cU=JT,uU=eM,dU=tM;const yx=S.forwardRef(({className:t,...e},n)=>a.jsxs(sM,{ref:n,className:ye("relative flex w-full touch-none select-none items-center",t),...e,children:[a.jsx(cU,{className:"relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20",children:a.jsx(uU,{className:"absolute h-full bg-primary"})}),a.jsx(dU,{className:"block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"})]}));yx.displayName=sM.displayName;const Bt=tq,It=nq,Dt=S.forwardRef(({className:t,children:e,...n},r)=>a.jsxs(v9,{ref:r,className:ye("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...n,children:[e,a.jsx(YI,{asChild:!0,children:a.jsx(df,{className:"h-4 w-4 opacity-50"})})]}));Dt.displayName=v9.displayName;const iM=S.forwardRef(({className:t,...e},n)=>a.jsx(y9,{ref:n,className:ye("flex cursor-default items-center justify-center py-1",t),...e,children:a.jsx(e2,{className:"h-4 w-4"})}));iM.displayName=y9.displayName;const aM=S.forwardRef(({className:t,...e},n)=>a.jsx(b9,{ref:n,className:ye("flex cursor-default items-center justify-center py-1",t),...e,children:a.jsx(df,{className:"h-4 w-4"})}));aM.displayName=b9.displayName;const Rt=S.forwardRef(({className:t,children:e,position:n="popper",...r},s)=>a.jsx(KI,{children:a.jsxs(w9,{ref:s,className:ye("relative z-[100] max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-hidden rounded-md border border-border bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",n==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:n,...r,children:[a.jsx(iM,{}),a.jsx(ZI,{className:ye("p-1",n==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:e}),a.jsx(aM,{})]})}));Rt.displayName=w9.displayName;const hU=S.forwardRef(({className:t,...e},n)=>a.jsx(S9,{ref:n,className:ye("px-2 py-1.5 text-sm font-semibold",t),...e}));hU.displayName=S9.displayName;const Pe=S.forwardRef(({className:t,children:e,...n},r)=>a.jsxs(k9,{ref:r,className:ye("relative flex w-full cursor-default select-none items-center rounded-sm py-2 pl-2 pr-8 text-sm outline-none bg-white dark:bg-gray-900 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-gray-800 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...n,children:[a.jsx("span",{className:"absolute right-2 flex h-3.5 w-3.5 items-center justify-center",children:a.jsx(JI,{children:a.jsx(hc,{className:"h-4 w-4"})})}),a.jsx(eq,{children:e})]}));Pe.displayName=k9.displayName;const fU=S.forwardRef(({className:t,...e},n)=>a.jsx(O9,{ref:n,className:ye("-mx-1 my-1 h-px bg-muted",t),...e}));fU.displayName=O9.displayName;function mU(t){const e=pU(t),n=S.forwardRef((r,s)=>{const{children:i,...l}=r,c=S.Children.toArray(i),d=c.find(xU);if(d){const h=d.props.children,m=c.map(p=>p===d?S.Children.count(h)>1?S.Children.only(null):S.isValidElement(h)?h.props.children:null:p);return a.jsx(e,{...l,ref:s,children:S.isValidElement(h)?S.cloneElement(h,void 0,m):null})}return a.jsx(e,{...l,ref:s,children:i})});return n.displayName=`${t}.Slot`,n}function pU(t){const e=S.forwardRef((n,r)=>{const{children:s,...i}=n;if(S.isValidElement(s)){const l=yU(s),c=vU(i,s.props);return s.type!==S.Fragment&&(c.ref=r?lo(r,l):l),S.cloneElement(s,c)}return S.Children.count(s)>1?S.Children.only(null):null});return e.displayName=`${t}.SlotClone`,e}var gU=Symbol("radix.slottable");function xU(t){return S.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===gU}function vU(t,e){const n={...e};for(const r in e){const s=t[r],i=e[r];/^on[A-Z]/.test(r)?s&&i?n[r]=(...c)=>{const d=i(...c);return s(...c),d}:s&&(n[r]=s):r==="style"?n[r]={...s,...i}:r==="className"&&(n[r]=[s,i].filter(Boolean).join(" "))}return{...t,...n}}function yU(t){let e=Object.getOwnPropertyDescriptor(t.props,"ref")?.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=Object.getOwnPropertyDescriptor(t,"ref")?.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}var bx="Popover",[lM]=Hi(bx,[wd]),r0=wd(),[bU,ko]=lM(bx),oM=t=>{const{__scopePopover:e,children:n,open:r,defaultOpen:s,onOpenChange:i,modal:l=!1}=t,c=r0(e),d=S.useRef(null),[h,m]=S.useState(!1),[p,x]=So({prop:r,defaultProp:s??!1,onChange:i,caller:bx});return a.jsx(ix,{...c,children:a.jsx(bU,{scope:e,contentId:Oi(),triggerRef:d,open:p,onOpenChange:x,onOpenToggle:S.useCallback(()=>x(v=>!v),[x]),hasCustomAnchor:h,onCustomAnchorAdd:S.useCallback(()=>m(!0),[]),onCustomAnchorRemove:S.useCallback(()=>m(!1),[]),modal:l,children:n})})};oM.displayName=bx;var cM="PopoverAnchor",wU=S.forwardRef((t,e)=>{const{__scopePopover:n,...r}=t,s=ko(cM,n),i=r0(n),{onCustomAnchorAdd:l,onCustomAnchorRemove:c}=s;return S.useEffect(()=>(l(),()=>c()),[l,c]),a.jsx(ax,{...i,...r,ref:e})});wU.displayName=cM;var uM="PopoverTrigger",dM=S.forwardRef((t,e)=>{const{__scopePopover:n,...r}=t,s=ko(uM,n),i=r0(n),l=Cn(e,s.triggerRef),c=a.jsx(Yt.button,{type:"button","aria-haspopup":"dialog","aria-expanded":s.open,"aria-controls":s.contentId,"data-state":gM(s.open),...r,ref:l,onClick:$e(t.onClick,s.onOpenToggle)});return s.hasCustomAnchor?c:a.jsx(ax,{asChild:!0,...i,children:c})});dM.displayName=uM;var gw="PopoverPortal",[SU,kU]=lM(gw,{forceMount:void 0}),hM=t=>{const{__scopePopover:e,forceMount:n,children:r,container:s}=t,i=ko(gw,e);return a.jsx(SU,{scope:e,forceMount:n,children:a.jsx(Ls,{present:n||i.open,children:a.jsx(sx,{asChild:!0,container:s,children:r})})})};hM.displayName=gw;var ad="PopoverContent",fM=S.forwardRef((t,e)=>{const n=kU(ad,t.__scopePopover),{forceMount:r=n.forceMount,...s}=t,i=ko(ad,t.__scopePopover);return a.jsx(Ls,{present:r||i.open,children:i.modal?a.jsx(jU,{...s,ref:e}):a.jsx(NU,{...s,ref:e})})});fM.displayName=ad;var OU=mU("PopoverContent.RemoveScroll"),jU=S.forwardRef((t,e)=>{const n=ko(ad,t.__scopePopover),r=S.useRef(null),s=Cn(e,r),i=S.useRef(!1);return S.useEffect(()=>{const l=r.current;if(l)return j9(l)},[]),a.jsx(N9,{as:OU,allowPinchZoom:!0,children:a.jsx(mM,{...t,ref:s,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:$e(t.onCloseAutoFocus,l=>{l.preventDefault(),i.current||n.triggerRef.current?.focus()}),onPointerDownOutside:$e(t.onPointerDownOutside,l=>{const c=l.detail.originalEvent,d=c.button===0&&c.ctrlKey===!0,h=c.button===2||d;i.current=h},{checkForDefaultPrevented:!1}),onFocusOutside:$e(t.onFocusOutside,l=>l.preventDefault(),{checkForDefaultPrevented:!1})})})}),NU=S.forwardRef((t,e)=>{const n=ko(ad,t.__scopePopover),r=S.useRef(!1),s=S.useRef(!1);return a.jsx(mM,{...t,ref:e,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:i=>{t.onCloseAutoFocus?.(i),i.defaultPrevented||(r.current||n.triggerRef.current?.focus(),i.preventDefault()),r.current=!1,s.current=!1},onInteractOutside:i=>{t.onInteractOutside?.(i),i.defaultPrevented||(r.current=!0,i.detail.originalEvent.type==="pointerdown"&&(s.current=!0));const l=i.target;n.triggerRef.current?.contains(l)&&i.preventDefault(),i.detail.originalEvent.type==="focusin"&&s.current&&i.preventDefault()}})}),mM=S.forwardRef((t,e)=>{const{__scopePopover:n,trapFocus:r,onOpenAutoFocus:s,onCloseAutoFocus:i,disableOutsidePointerEvents:l,onEscapeKeyDown:c,onPointerDownOutside:d,onFocusOutside:h,onInteractOutside:m,...p}=t,x=ko(ad,n),v=r0(n);return C9(),a.jsx(T9,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:s,onUnmountAutoFocus:i,children:a.jsx(G4,{asChild:!0,disableOutsidePointerEvents:l,onInteractOutside:m,onEscapeKeyDown:c,onPointerDownOutside:d,onFocusOutside:h,onDismiss:()=>x.onOpenChange(!1),children:a.jsx(X4,{"data-state":gM(x.open),role:"dialog",id:x.contentId,...v,...p,ref:e,style:{...p.style,"--radix-popover-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-popover-content-available-width":"var(--radix-popper-available-width)","--radix-popover-content-available-height":"var(--radix-popper-available-height)","--radix-popover-trigger-width":"var(--radix-popper-anchor-width)","--radix-popover-trigger-height":"var(--radix-popper-anchor-height)"}})})})}),pM="PopoverClose",CU=S.forwardRef((t,e)=>{const{__scopePopover:n,...r}=t,s=ko(pM,n);return a.jsx(Yt.button,{type:"button",...r,ref:e,onClick:$e(t.onClick,()=>s.onOpenChange(!1))})});CU.displayName=pM;var TU="PopoverArrow",MU=S.forwardRef((t,e)=>{const{__scopePopover:n,...r}=t,s=r0(n);return a.jsx(Y4,{...s,...r,ref:e})});MU.displayName=TU;function gM(t){return t?"open":"closed"}var AU=oM,EU=dM,_U=hM,xM=fM;const co=AU,uo=EU,hl=S.forwardRef(({className:t,align:e="center",sideOffset:n=4,...r},s)=>a.jsx(_U,{children:a.jsx(xM,{ref:s,align:e,sideOffset:n,className:ye("z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-popover-content-transform-origin]",t),...r})}));hl.displayName=xM.displayName;const Oo="/api/webui/config";async function DU(){const e=await(await ot(`${Oo}/bot`)).json();if(!e.success)throw new Error("获取配置数据失败");return e.config}async function Vu(){const e=await(await ot(`${Oo}/model`)).json();if(!e.success)throw new Error("获取模型配置数据失败");return e.config}async function XO(t){const n=await(await ot(`${Oo}/bot`,{method:"POST",headers:bt(),body:JSON.stringify(t)})).json();if(!n.success)throw new Error(n.message||"保存配置失败")}async function RU(){const e=await(await ot(`${Oo}/bot/raw`)).json();if(!e.success)throw new Error("获取配置源代码失败");return e.content}async function zU(t){const n=await(await ot(`${Oo}/bot/raw`,{method:"POST",headers:bt(),body:JSON.stringify({raw_content:t})})).json();if(!n.success)throw new Error(n.message||"保存配置失败")}async function wg(t){const n=await(await ot(`${Oo}/model`,{method:"POST",headers:bt(),body:JSON.stringify(t)})).json();if(!n.success)throw new Error(n.message||"保存配置失败")}async function PU(t,e){const r=await(await ot(`${Oo}/bot/section/${t}`,{method:"POST",headers:bt(),body:JSON.stringify(e)})).json();if(!r.success)throw new Error(r.message||`保存配置节 ${t} 失败`)}async function h2(t,e){const r=await(await ot(`${Oo}/model/section/${t}`,{method:"POST",headers:bt(),body:JSON.stringify(e)})).json();if(!r.success)throw new Error(r.message||`保存配置节 ${t} 失败`)}const LU=Zn.create({baseURL:"",timeout:1e4});async function xw(){try{return(await LU.post("/api/webui/system/restart")).data}catch(t){throw console.error("重启麦麦失败:",t),t}}const BU=Nd("relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),ld=S.forwardRef(({className:t,variant:e,...n},r)=>a.jsx("div",{ref:r,role:"alert",className:ye(BU({variant:e}),t),...n}));ld.displayName="Alert";const IU=S.forwardRef(({className:t,...e},n)=>a.jsx("h5",{ref:n,className:ye("mb-1 font-medium leading-none tracking-tight",t),...e}));IU.displayName="AlertTitle";const od=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{ref:n,className:ye("text-sm [&_p]:leading-relaxed",t),...e}));od.displayName="AlertDescription";function vw({onRestartComplete:t,onRestartFailed:e}){const[n,r]=S.useState(0),[s,i]=S.useState("restarting"),[l,c]=S.useState(0),[d,h]=S.useState(0);S.useEffect(()=>{const x=setInterval(()=>{r(k=>k>=90?k:k+1)},200),v=setInterval(()=>{c(k=>k+1)},1e3),b=setTimeout(()=>{i("checking"),m()},3e3);return()=>{clearInterval(x),clearInterval(v),clearTimeout(b)}},[]);const m=()=>{const v=async()=>{try{if(h(k=>k+1),(await fetch("/api/webui/system/status",{method:"GET",headers:{"Content-Type":"application/json"},signal:AbortSignal.timeout(3e3)})).ok)r(100),i("success"),setTimeout(()=>{t?.()},1500);else throw new Error("Status check failed")}catch{d<60?setTimeout(v,2e3):(i("failed"),e?.())}};v()},p=x=>{const v=Math.floor(x/60),b=x%60;return`${v}:${b.toString().padStart(2,"0")}`};return a.jsx("div",{className:"fixed inset-0 bg-background/95 backdrop-blur-sm z-50 flex items-center justify-center",children:a.jsxs("div",{className:"max-w-md w-full mx-4 space-y-8",children:[a.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[s==="restarting"&&a.jsxs(a.Fragment,{children:[a.jsx(hf,{className:"h-16 w-16 text-primary animate-spin"}),a.jsx("h2",{className:"text-2xl font-bold",children:"正在重启麦麦"}),a.jsx("p",{className:"text-muted-foreground text-center",children:"请稍候,麦麦正在重启中..."})]}),s==="checking"&&a.jsxs(a.Fragment,{children:[a.jsx(hf,{className:"h-16 w-16 text-primary animate-spin"}),a.jsx("h2",{className:"text-2xl font-bold",children:"检查服务状态"}),a.jsxs("p",{className:"text-muted-foreground text-center",children:["等待服务恢复... (尝试 ",d,"/60)"]})]}),s==="success"&&a.jsxs(a.Fragment,{children:[a.jsx(ua,{className:"h-16 w-16 text-green-500"}),a.jsx("h2",{className:"text-2xl font-bold",children:"重启成功"}),a.jsx("p",{className:"text-muted-foreground text-center",children:"正在跳转到登录页面..."})]}),s==="failed"&&a.jsxs(a.Fragment,{children:[a.jsx(xc,{className:"h-16 w-16 text-destructive"}),a.jsx("h2",{className:"text-2xl font-bold",children:"重启超时"}),a.jsx("p",{className:"text-muted-foreground text-center",children:"服务未能在预期时间内恢复,请手动检查或刷新页面"})]})]}),s!=="failed"&&a.jsxs("div",{className:"space-y-2",children:[a.jsx(n0,{value:n,className:"h-2"}),a.jsxs("div",{className:"flex justify-between text-sm text-muted-foreground",children:[a.jsxs("span",{children:[n,"%"]}),a.jsxs("span",{children:["已用时: ",p(l)]})]})]}),a.jsx("div",{className:"bg-muted/50 rounded-lg p-4 space-y-2",children:a.jsxs("p",{className:"text-sm text-muted-foreground",children:[s==="restarting"&&"🔄 配置已保存,正在重启主程序...",s==="checking"&&"⏳ 正在等待服务恢复,请勿关闭页面...",s==="success"&&"✅ 配置已生效,服务运行正常",s==="failed"&&"⚠️ 如果长时间无响应,请尝试手动重启"]})}),s==="failed"&&a.jsxs("div",{className:"flex gap-2",children:[a.jsx("button",{onClick:()=>window.location.reload(),className:"flex-1 px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90",children:"刷新页面"}),a.jsx("button",{onClick:()=>{i("checking"),h(0),m()},className:"flex-1 px-4 py-2 bg-secondary text-secondary-foreground rounded-md hover:bg-secondary/90",children:"重试检测"})]})]})})}let f2=[],vM=[];(()=>{let t="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,n=0;e>1;if(t=vM[r])e=r+1;else return!0;if(e==n)return!1}}function YO(t){return t>=127462&&t<=127487}const KO=8205;function FU(t,e,n=!0,r=!0){return(n?yM:QU)(t,e,r)}function yM(t,e,n){if(e==t.length)return e;e&&bM(t.charCodeAt(e))&&wM(t.charCodeAt(e-1))&&e--;let r=Cy(t,e);for(e+=ZO(r);e=0&&YO(Cy(t,l));)i++,l-=2;if(i%2==0)break;e+=2}else break}return e}function QU(t,e,n){for(;e>0;){let r=yM(t,e-2,n);if(r=56320&&t<57344}function wM(t){return t>=55296&&t<56320}function ZO(t){return t<65536?1:2}class Wt{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,n,r){[e,n]=cd(this,e,n);let s=[];return this.decompose(0,e,s,2),r.length&&r.decompose(0,r.length,s,3),this.decompose(n,this.length,s,1),Gp.from(s,this.length-(n-e)+r.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,n=this.length){[e,n]=cd(this,e,n);let r=[];return this.decompose(e,n,r,0),Gp.from(r,n-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let n=this.scanIdentical(e,1),r=this.length-this.scanIdentical(e,-1),s=new Zh(this),i=new Zh(e);for(let l=n,c=n;;){if(s.next(l),i.next(l),l=0,s.lineBreak!=i.lineBreak||s.done!=i.done||s.value!=i.value)return!1;if(c+=s.value.length,s.done||c>=r)return!0}}iter(e=1){return new Zh(this,e)}iterRange(e,n=this.length){return new SM(this,e,n)}iterLines(e,n){let r;if(e==null)r=this.iter();else{n==null&&(n=this.lines+1);let s=this.line(e).from;r=this.iterRange(s,Math.max(s,n==this.lines+1?this.length:n<=1?0:this.line(n-1).to))}return new kM(r)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?Wt.empty:e.length<=32?new ir(e):Gp.from(ir.split(e,[]))}}class ir extends Wt{constructor(e,n=$U(e)){super(),this.text=e,this.length=n}get lines(){return this.text.length}get children(){return null}lineInner(e,n,r,s){for(let i=0;;i++){let l=this.text[i],c=s+l.length;if((n?r:c)>=e)return new HU(s,c,r,l);s=c+1,r++}}decompose(e,n,r,s){let i=e<=0&&n>=this.length?this:new ir(JO(this.text,e,n),Math.min(n,this.length)-Math.max(0,e));if(s&1){let l=r.pop(),c=Xp(i.text,l.text.slice(),0,i.length);if(c.length<=32)r.push(new ir(c,l.length+i.length));else{let d=c.length>>1;r.push(new ir(c.slice(0,d)),new ir(c.slice(d)))}}else r.push(i)}replace(e,n,r){if(!(r instanceof ir))return super.replace(e,n,r);[e,n]=cd(this,e,n);let s=Xp(this.text,Xp(r.text,JO(this.text,0,e)),n),i=this.length+r.length-(n-e);return s.length<=32?new ir(s,i):Gp.from(ir.split(s,[]),i)}sliceString(e,n=this.length,r=` -`){[e,n]=cd(this,e,n);let s="";for(let i=0,l=0;i<=n&&le&&l&&(s+=r),ei&&(s+=c.slice(Math.max(0,e-i),n-i)),i=d+1}return s}flatten(e){for(let n of this.text)e.push(n)}scanIdentical(){return 0}static split(e,n){let r=[],s=-1;for(let i of e)r.push(i),s+=i.length+1,r.length==32&&(n.push(new ir(r,s)),r=[],s=-1);return s>-1&&n.push(new ir(r,s)),n}}let Gp=class Du extends Wt{constructor(e,n){super(),this.children=e,this.length=n,this.lines=0;for(let r of e)this.lines+=r.lines}lineInner(e,n,r,s){for(let i=0;;i++){let l=this.children[i],c=s+l.length,d=r+l.lines-1;if((n?d:c)>=e)return l.lineInner(e,n,r,s);s=c+1,r=d+1}}decompose(e,n,r,s){for(let i=0,l=0;l<=n&&i=l){let h=s&((l<=e?1:0)|(d>=n?2:0));l>=e&&d<=n&&!h?r.push(c):c.decompose(e-l,n-l,r,h)}l=d+1}}replace(e,n,r){if([e,n]=cd(this,e,n),r.lines=i&&n<=c){let d=l.replace(e-i,n-i,r),h=this.lines-l.lines+d.lines;if(d.lines>4&&d.lines>h>>6){let m=this.children.slice();return m[s]=d,new Du(m,this.length-(n-e)+r.length)}return super.replace(i,c,d)}i=c+1}return super.replace(e,n,r)}sliceString(e,n=this.length,r=` -`){[e,n]=cd(this,e,n);let s="";for(let i=0,l=0;ie&&i&&(s+=r),el&&(s+=c.sliceString(e-l,n-l,r)),l=d+1}return s}flatten(e){for(let n of this.children)n.flatten(e)}scanIdentical(e,n){if(!(e instanceof Du))return 0;let r=0,[s,i,l,c]=n>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=n,i+=n){if(s==l||i==c)return r;let d=this.children[s],h=e.children[i];if(d!=h)return r+d.scanIdentical(h,n);r+=d.length+1}}static from(e,n=e.reduce((r,s)=>r+s.length+1,-1)){let r=0;for(let v of e)r+=v.lines;if(r<32){let v=[];for(let b of e)b.flatten(v);return new ir(v,n)}let s=Math.max(32,r>>5),i=s<<1,l=s>>1,c=[],d=0,h=-1,m=[];function p(v){let b;if(v.lines>i&&v instanceof Du)for(let k of v.children)p(k);else v.lines>l&&(d>l||!d)?(x(),c.push(v)):v instanceof ir&&d&&(b=m[m.length-1])instanceof ir&&v.lines+b.lines<=32?(d+=v.lines,h+=v.length+1,m[m.length-1]=new ir(b.text.concat(v.text),b.length+1+v.length)):(d+v.lines>s&&x(),d+=v.lines,h+=v.length+1,m.push(v))}function x(){d!=0&&(c.push(m.length==1?m[0]:Du.from(m,h)),h=-1,d=m.length=0)}for(let v of e)p(v);return x(),c.length==1?c[0]:new Du(c,n)}};Wt.empty=new ir([""],0);function $U(t){let e=-1;for(let n of t)e+=n.length+1;return e}function Xp(t,e,n=0,r=1e9){for(let s=0,i=0,l=!0;i=n&&(d>r&&(c=c.slice(0,r-s)),s0?1:(e instanceof ir?e.text.length:e.children.length)<<1]}nextInner(e,n){for(this.done=this.lineBreak=!1;;){let r=this.nodes.length-1,s=this.nodes[r],i=this.offsets[r],l=i>>1,c=s instanceof ir?s.text.length:s.children.length;if(l==(n>0?c:0)){if(r==0)return this.done=!0,this.value="",this;n>0&&this.offsets[r-1]++,this.nodes.pop(),this.offsets.pop()}else if((i&1)==(n>0?0:1)){if(this.offsets[r]+=n,e==0)return this.lineBreak=!0,this.value=` -`,this;e--}else if(s instanceof ir){let d=s.text[l+(n<0?-1:0)];if(this.offsets[r]+=n,d.length>Math.max(0,e))return this.value=e==0?d:n>0?d.slice(e):d.slice(0,d.length-e),this;e-=d.length}else{let d=s.children[l+(n<0?-1:0)];e>d.length?(e-=d.length,this.offsets[r]+=n):(n<0&&this.offsets[r]--,this.nodes.push(d),this.offsets.push(n>0?1:(d instanceof ir?d.text.length:d.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class SM{constructor(e,n,r){this.value="",this.done=!1,this.cursor=new Zh(e,n>r?-1:1),this.pos=n>r?e.length:0,this.from=Math.min(n,r),this.to=Math.max(n,r)}nextInner(e,n){if(n<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,n<0?this.pos-this.to:this.from-this.pos);let r=n<0?this.pos-this.from:this.to-this.pos;e>r&&(e=r),r-=e;let{value:s}=this.cursor.next(e);return this.pos+=(s.length+e)*n,this.value=s.length<=r?s:n<0?s.slice(s.length-r):s.slice(0,r),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class kM{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:n,lineBreak:r,value:s}=this.inner.next(e);return n&&this.afterBreak?(this.value="",this.afterBreak=!1):n?(this.done=!0,this.value=""):r?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=s,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(Wt.prototype[Symbol.iterator]=function(){return this.iter()},Zh.prototype[Symbol.iterator]=SM.prototype[Symbol.iterator]=kM.prototype[Symbol.iterator]=function(){return this});class HU{constructor(e,n,r,s){this.from=e,this.to=n,this.number=r,this.text=s}get length(){return this.to-this.from}}function cd(t,e,n){return e=Math.max(0,Math.min(t.length,e)),[e,Math.max(e,Math.min(t.length,n))]}function Vr(t,e,n=!0,r=!0){return FU(t,e,n,r)}function UU(t){return t>=56320&&t<57344}function VU(t){return t>=55296&&t<56320}function Ms(t,e){let n=t.charCodeAt(e);if(!VU(n)||e+1==t.length)return n;let r=t.charCodeAt(e+1);return UU(r)?(n-55296<<10)+(r-56320)+65536:n}function yw(t){return t<=65535?String.fromCharCode(t):(t-=65536,String.fromCharCode((t>>10)+55296,(t&1023)+56320))}function aa(t){return t<65536?1:2}const m2=/\r\n?|\n/;var Ur=(function(t){return t[t.Simple=0]="Simple",t[t.TrackDel=1]="TrackDel",t[t.TrackBefore=2]="TrackBefore",t[t.TrackAfter=3]="TrackAfter",t})(Ur||(Ur={}));class xa{constructor(e){this.sections=e}get length(){let e=0;for(let n=0;ne)return i+(e-s);i+=c}else{if(r!=Ur.Simple&&h>=e&&(r==Ur.TrackDel&&se||r==Ur.TrackBefore&&se))return null;if(h>e||h==e&&n<0&&!c)return e==s||n<0?i:i+d;i+=d}s=h}if(e>s)throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`);return i}touchesRange(e,n=e){for(let r=0,s=0;r=0&&s<=n&&c>=e)return sn?"cover":!0;s=c}return!1}toString(){let e="";for(let n=0;n=0?":"+s:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some(n=>typeof n!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new xa(e)}static create(e){return new xa(e)}}class kr extends xa{constructor(e,n){super(e),this.inserted=n}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return p2(this,(n,r,s,i,l)=>e=e.replace(s,s+(r-n),l),!1),e}mapDesc(e,n=!1){return g2(this,e,n,!0)}invert(e){let n=this.sections.slice(),r=[];for(let s=0,i=0;s=0){n[s]=c,n[s+1]=l;let d=s>>1;for(;r.length0&&no(r,n,i.text),i.forward(m),c+=m}let h=e[l++];for(;c>1].toJSON()))}return e}static of(e,n,r){let s=[],i=[],l=0,c=null;function d(m=!1){if(!m&&!s.length)return;lx||p<0||x>n)throw new RangeError(`Invalid change range ${p} to ${x} (in doc of length ${n})`);let b=v?typeof v=="string"?Wt.of(v.split(r||m2)):v:Wt.empty,k=b.length;if(p==x&&k==0)return;pl&&Jr(s,p-l,-1),Jr(s,x-p,k),no(i,s,b),l=x}}return h(e),d(!c),c}static empty(e){return new kr(e?[e,-1]:[],[])}static fromJSON(e){if(!Array.isArray(e))throw new RangeError("Invalid JSON representation of ChangeSet");let n=[],r=[];for(let s=0;sc&&typeof l!="string"))throw new RangeError("Invalid JSON representation of ChangeSet");if(i.length==1)n.push(i[0],0);else{for(;r.length=0&&n<=0&&n==t[s+1]?t[s]+=e:s>=0&&e==0&&t[s]==0?t[s+1]+=n:r?(t[s]+=e,t[s+1]+=n):t.push(e,n)}function no(t,e,n){if(n.length==0)return;let r=e.length-2>>1;if(r>1])),!(n||l==t.sections.length||t.sections[l+1]<0);)c=t.sections[l++],d=t.sections[l++];e(s,h,i,m,p),s=h,i=m}}}function g2(t,e,n,r=!1){let s=[],i=r?[]:null,l=new pf(t),c=new pf(e);for(let d=-1;;){if(l.done&&c.len||c.done&&l.len)throw new Error("Mismatched change set lengths");if(l.ins==-1&&c.ins==-1){let h=Math.min(l.len,c.len);Jr(s,h,-1),l.forward(h),c.forward(h)}else if(c.ins>=0&&(l.ins<0||d==l.i||l.off==0&&(c.len=0&&d=0){let h=0,m=l.len;for(;m;)if(c.ins==-1){let p=Math.min(m,c.len);h+=p,m-=p,c.forward(p)}else if(c.ins==0&&c.lend||l.ins>=0&&l.len>d)&&(c||r.length>h),i.forward2(d),l.forward(d)}}}}class pf{constructor(e){this.set=e,this.i=0,this.next()}next(){let{sections:e}=this.set;this.i>1;return n>=e.length?Wt.empty:e[n]}textBit(e){let{inserted:n}=this.set,r=this.i-2>>1;return r>=n.length&&!e?Wt.empty:n[r].slice(this.off,e==null?void 0:this.off+e)}forward(e){e==this.len?this.next():(this.len-=e,this.off+=e)}forward2(e){this.ins==-1?this.forward(e):e==this.ins?this.next():(this.ins-=e,this.off+=e)}}class ac{constructor(e,n,r){this.from=e,this.to=n,this.flags=r}get anchor(){return this.flags&32?this.to:this.from}get head(){return this.flags&32?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return this.flags&8?-1:this.flags&16?1:0}get bidiLevel(){let e=this.flags&7;return e==7?null:e}get goalColumn(){let e=this.flags>>6;return e==16777215?void 0:e}map(e,n=-1){let r,s;return this.empty?r=s=e.mapPos(this.from,n):(r=e.mapPos(this.from,1),s=e.mapPos(this.to,-1)),r==this.from&&s==this.to?this:new ac(r,s,this.flags)}extend(e,n=e){if(e<=this.anchor&&n>=this.anchor)return Ce.range(e,n);let r=Math.abs(e-this.anchor)>Math.abs(n-this.anchor)?e:n;return Ce.range(this.anchor,r)}eq(e,n=!1){return this.anchor==e.anchor&&this.head==e.head&&(!n||!this.empty||this.assoc==e.assoc)}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(e){if(!e||typeof e.anchor!="number"||typeof e.head!="number")throw new RangeError("Invalid JSON representation for SelectionRange");return Ce.range(e.anchor,e.head)}static create(e,n,r){return new ac(e,n,r)}}class Ce{constructor(e,n){this.ranges=e,this.mainIndex=n}map(e,n=-1){return e.empty?this:Ce.create(this.ranges.map(r=>r.map(e,n)),this.mainIndex)}eq(e,n=!1){if(this.ranges.length!=e.ranges.length||this.mainIndex!=e.mainIndex)return!1;for(let r=0;re.toJSON()),main:this.mainIndex}}static fromJSON(e){if(!e||!Array.isArray(e.ranges)||typeof e.main!="number"||e.main>=e.ranges.length)throw new RangeError("Invalid JSON representation for EditorSelection");return new Ce(e.ranges.map(n=>ac.fromJSON(n)),e.main)}static single(e,n=e){return new Ce([Ce.range(e,n)],0)}static create(e,n=0){if(e.length==0)throw new RangeError("A selection needs at least one range");for(let r=0,s=0;se?8:0)|i)}static normalized(e,n=0){let r=e[n];e.sort((s,i)=>s.from-i.from),n=e.indexOf(r);for(let s=1;si.head?Ce.range(d,c):Ce.range(c,d))}}return new Ce(e,n)}}function jM(t,e){for(let n of t.ranges)if(n.to>e)throw new RangeError("Selection points outside of document")}let bw=0;class He{constructor(e,n,r,s,i){this.combine=e,this.compareInput=n,this.compare=r,this.isStatic=s,this.id=bw++,this.default=e([]),this.extensions=typeof i=="function"?i(this):i}get reader(){return this}static define(e={}){return new He(e.combine||(n=>n),e.compareInput||((n,r)=>n===r),e.compare||(e.combine?(n,r)=>n===r:ww),!!e.static,e.enables)}of(e){return new Yp([],this,0,e)}compute(e,n){if(this.isStatic)throw new Error("Can't compute a static facet");return new Yp(e,this,1,n)}computeN(e,n){if(this.isStatic)throw new Error("Can't compute a static facet");return new Yp(e,this,2,n)}from(e,n){return n||(n=r=>r),this.compute([e],r=>n(r.field(e)))}}function ww(t,e){return t==e||t.length==e.length&&t.every((n,r)=>n===e[r])}class Yp{constructor(e,n,r,s){this.dependencies=e,this.facet=n,this.type=r,this.value=s,this.id=bw++}dynamicSlot(e){var n;let r=this.value,s=this.facet.compareInput,i=this.id,l=e[i]>>1,c=this.type==2,d=!1,h=!1,m=[];for(let p of this.dependencies)p=="doc"?d=!0:p=="selection"?h=!0:(((n=e[p.id])!==null&&n!==void 0?n:1)&1)==0&&m.push(e[p.id]);return{create(p){return p.values[l]=r(p),1},update(p,x){if(d&&x.docChanged||h&&(x.docChanged||x.selection)||x2(p,m)){let v=r(p);if(c?!ej(v,p.values[l],s):!s(v,p.values[l]))return p.values[l]=v,1}return 0},reconfigure:(p,x)=>{let v,b=x.config.address[i];if(b!=null){let k=kg(x,b);if(this.dependencies.every(O=>O instanceof He?x.facet(O)===p.facet(O):O instanceof Lr?x.field(O,!1)==p.field(O,!1):!0)||(c?ej(v=r(p),k,s):s(v=r(p),k)))return p.values[l]=k,0}else v=r(p);return p.values[l]=v,1}}}}function ej(t,e,n){if(t.length!=e.length)return!1;for(let r=0;rt[d.id]),s=n.map(d=>d.type),i=r.filter(d=>!(d&1)),l=t[e.id]>>1;function c(d){let h=[];for(let m=0;mr===s),e);return e.provide&&(n.provides=e.provide(n)),n}create(e){let n=e.facet(Zm).find(r=>r.field==this);return(n?.create||this.createF)(e)}slot(e){let n=e[this.id]>>1;return{create:r=>(r.values[n]=this.create(r),1),update:(r,s)=>{let i=r.values[n],l=this.updateF(i,s);return this.compareF(i,l)?0:(r.values[n]=l,1)},reconfigure:(r,s)=>{let i=r.facet(Zm),l=s.facet(Zm),c;return(c=i.find(d=>d.field==this))&&c!=l.find(d=>d.field==this)?(r.values[n]=c.create(r),1):s.config.address[this.id]!=null?(r.values[n]=s.field(this),0):(r.values[n]=this.create(r),1)}}}init(e){return[this,Zm.of({field:this,create:e})]}get extension(){return this}}const rc={lowest:4,low:3,default:2,high:1,highest:0};function _h(t){return e=>new NM(e,t)}const jo={highest:_h(rc.highest),high:_h(rc.high),default:_h(rc.default),low:_h(rc.low),lowest:_h(rc.lowest)};class NM{constructor(e,n){this.inner=e,this.prec=n}}class wx{of(e){return new v2(this,e)}reconfigure(e){return wx.reconfigure.of({compartment:this,extension:e})}get(e){return e.config.compartments.get(this)}}class v2{constructor(e,n){this.compartment=e,this.inner=n}}class Sg{constructor(e,n,r,s,i,l){for(this.base=e,this.compartments=n,this.dynamicSlots=r,this.address=s,this.staticValues=i,this.facets=l,this.statusTemplate=[];this.statusTemplate.length>1]}static resolve(e,n,r){let s=[],i=Object.create(null),l=new Map;for(let x of GU(e,n,l))x instanceof Lr?s.push(x):(i[x.facet.id]||(i[x.facet.id]=[])).push(x);let c=Object.create(null),d=[],h=[];for(let x of s)c[x.id]=h.length<<1,h.push(v=>x.slot(v));let m=r?.config.facets;for(let x in i){let v=i[x],b=v[0].facet,k=m&&m[x]||[];if(v.every(O=>O.type==0))if(c[b.id]=d.length<<1|1,ww(k,v))d.push(r.facet(b));else{let O=b.combine(v.map(j=>j.value));d.push(r&&b.compare(O,r.facet(b))?r.facet(b):O)}else{for(let O of v)O.type==0?(c[O.id]=d.length<<1|1,d.push(O.value)):(c[O.id]=h.length<<1,h.push(j=>O.dynamicSlot(j)));c[b.id]=h.length<<1,h.push(O=>WU(O,b,v))}}let p=h.map(x=>x(c));return new Sg(e,l,p,c,d,i)}}function GU(t,e,n){let r=[[],[],[],[],[]],s=new Map;function i(l,c){let d=s.get(l);if(d!=null){if(d<=c)return;let h=r[d].indexOf(l);h>-1&&r[d].splice(h,1),l instanceof v2&&n.delete(l.compartment)}if(s.set(l,c),Array.isArray(l))for(let h of l)i(h,c);else if(l instanceof v2){if(n.has(l.compartment))throw new RangeError("Duplicate use of compartment in extensions");let h=e.get(l.compartment)||l.inner;n.set(l.compartment,h),i(h,c)}else if(l instanceof NM)i(l.inner,l.prec);else if(l instanceof Lr)r[c].push(l),l.provides&&i(l.provides,c);else if(l instanceof Yp)r[c].push(l),l.facet.extensions&&i(l.facet.extensions,rc.default);else{let h=l.extension;if(!h)throw new Error(`Unrecognized extension value in extension set (${l}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);i(h,c)}}return i(t,rc.default),r.reduce((l,c)=>l.concat(c))}function Jh(t,e){if(e&1)return 2;let n=e>>1,r=t.status[n];if(r==4)throw new Error("Cyclic dependency between fields and/or facets");if(r&2)return r;t.status[n]=4;let s=t.computeSlot(t,t.config.dynamicSlots[n]);return t.status[n]=2|s}function kg(t,e){return e&1?t.config.staticValues[e>>1]:t.values[e>>1]}const CM=He.define(),y2=He.define({combine:t=>t.some(e=>e),static:!0}),TM=He.define({combine:t=>t.length?t[0]:void 0,static:!0}),MM=He.define(),AM=He.define(),EM=He.define(),_M=He.define({combine:t=>t.length?t[0]:!1});class Sa{constructor(e,n){this.type=e,this.value=n}static define(){return new XU}}class XU{of(e){return new Sa(this,e)}}class YU{constructor(e){this.map=e}of(e){return new xt(this,e)}}class xt{constructor(e,n){this.type=e,this.value=n}map(e){let n=this.type.map(this.value,e);return n===void 0?void 0:n==this.value?this:new xt(this.type,n)}is(e){return this.type==e}static define(e={}){return new YU(e.map||(n=>n))}static mapEffects(e,n){if(!e.length)return e;let r=[];for(let s of e){let i=s.map(n);i&&r.push(i)}return r}}xt.reconfigure=xt.define();xt.appendConfig=xt.define();class gr{constructor(e,n,r,s,i,l){this.startState=e,this.changes=n,this.selection=r,this.effects=s,this.annotations=i,this.scrollIntoView=l,this._doc=null,this._state=null,r&&jM(r,n.newLength),i.some(c=>c.type==gr.time)||(this.annotations=i.concat(gr.time.of(Date.now())))}static create(e,n,r,s,i,l){return new gr(e,n,r,s,i,l)}get newDoc(){return this._doc||(this._doc=this.changes.apply(this.startState.doc))}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(e){for(let n of this.annotations)if(n.type==e)return n.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(e){let n=this.annotation(gr.userEvent);return!!(n&&(n==e||n.length>e.length&&n.slice(0,e.length)==e&&n[e.length]=="."))}}gr.time=Sa.define();gr.userEvent=Sa.define();gr.addToHistory=Sa.define();gr.remote=Sa.define();function KU(t,e){let n=[];for(let r=0,s=0;;){let i,l;if(r=t[r]))i=t[r++],l=t[r++];else if(s=0;s--){let i=r[s](t);i instanceof gr?t=i:Array.isArray(i)&&i.length==1&&i[0]instanceof gr?t=i[0]:t=RM(e,Wu(i),!1)}return t}function JU(t){let e=t.startState,n=e.facet(EM),r=t;for(let s=n.length-1;s>=0;s--){let i=n[s](t);i&&Object.keys(i).length&&(r=DM(r,b2(e,i,t.changes.newLength),!0))}return r==t?t:gr.create(e,t.changes,t.selection,r.effects,r.annotations,r.scrollIntoView)}const eV=[];function Wu(t){return t==null?eV:Array.isArray(t)?t:[t]}var Vn=(function(t){return t[t.Word=0]="Word",t[t.Space=1]="Space",t[t.Other=2]="Other",t})(Vn||(Vn={}));const tV=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;let w2;try{w2=new RegExp("[\\p{Alphabetic}\\p{Number}_]","u")}catch{}function nV(t){if(w2)return w2.test(t);for(let e=0;e"€"&&(n.toUpperCase()!=n.toLowerCase()||tV.test(n)))return!0}return!1}function rV(t){return e=>{if(!/\S/.test(e))return Vn.Space;if(nV(e))return Vn.Word;for(let n=0;n-1)return Vn.Word;return Vn.Other}}class Vt{constructor(e,n,r,s,i,l){this.config=e,this.doc=n,this.selection=r,this.values=s,this.status=e.statusTemplate.slice(),this.computeSlot=i,l&&(l._state=this);for(let c=0;cs.set(h,d)),n=null),s.set(c.value.compartment,c.value.extension)):c.is(xt.reconfigure)?(n=null,r=c.value):c.is(xt.appendConfig)&&(n=null,r=Wu(r).concat(c.value));let i;n?i=e.startState.values.slice():(n=Sg.resolve(r,s,this),i=new Vt(n,this.doc,this.selection,n.dynamicSlots.map(()=>null),(d,h)=>h.reconfigure(d,this),null).values);let l=e.startState.facet(y2)?e.newSelection:e.newSelection.asSingle();new Vt(n,e.newDoc,l,i,(c,d)=>d.update(c,e),e)}replaceSelection(e){return typeof e=="string"&&(e=this.toText(e)),this.changeByRange(n=>({changes:{from:n.from,to:n.to,insert:e},range:Ce.cursor(n.from+e.length)}))}changeByRange(e){let n=this.selection,r=e(n.ranges[0]),s=this.changes(r.changes),i=[r.range],l=Wu(r.effects);for(let c=1;cl.spec.fromJSON(c,d)))}}return Vt.create({doc:e.doc,selection:Ce.fromJSON(e.selection),extensions:n.extensions?s.concat([n.extensions]):s})}static create(e={}){let n=Sg.resolve(e.extensions||[],new Map),r=e.doc instanceof Wt?e.doc:Wt.of((e.doc||"").split(n.staticFacet(Vt.lineSeparator)||m2)),s=e.selection?e.selection instanceof Ce?e.selection:Ce.single(e.selection.anchor,e.selection.head):Ce.single(0);return jM(s,r.length),n.staticFacet(y2)||(s=s.asSingle()),new Vt(n,r,s,n.dynamicSlots.map(()=>null),(i,l)=>l.create(i),null)}get tabSize(){return this.facet(Vt.tabSize)}get lineBreak(){return this.facet(Vt.lineSeparator)||` -`}get readOnly(){return this.facet(_M)}phrase(e,...n){for(let r of this.facet(Vt.phrases))if(Object.prototype.hasOwnProperty.call(r,e)){e=r[e];break}return n.length&&(e=e.replace(/\$(\$|\d*)/g,(r,s)=>{if(s=="$")return"$";let i=+(s||1);return!i||i>n.length?r:n[i-1]})),e}languageDataAt(e,n,r=-1){let s=[];for(let i of this.facet(CM))for(let l of i(this,n,r))Object.prototype.hasOwnProperty.call(l,e)&&s.push(l[e]);return s}charCategorizer(e){return rV(this.languageDataAt("wordChars",e).join(""))}wordAt(e){let{text:n,from:r,length:s}=this.doc.lineAt(e),i=this.charCategorizer(e),l=e-r,c=e-r;for(;l>0;){let d=Vr(n,l,!1);if(i(n.slice(d,l))!=Vn.Word)break;l=d}for(;ct.length?t[0]:4});Vt.lineSeparator=TM;Vt.readOnly=_M;Vt.phrases=He.define({compare(t,e){let n=Object.keys(t),r=Object.keys(e);return n.length==r.length&&n.every(s=>t[s]==e[s])}});Vt.languageData=CM;Vt.changeFilter=MM;Vt.transactionFilter=AM;Vt.transactionExtender=EM;wx.reconfigure=xt.define();function ka(t,e,n={}){let r={};for(let s of t)for(let i of Object.keys(s)){let l=s[i],c=r[i];if(c===void 0)r[i]=l;else if(!(c===l||l===void 0))if(Object.hasOwnProperty.call(n,i))r[i]=n[i](c,l);else throw new Error("Config merge conflict for field "+i)}for(let s in e)r[s]===void 0&&(r[s]=e[s]);return r}class yc{eq(e){return this==e}range(e,n=e){return S2.create(e,n,this)}}yc.prototype.startSide=yc.prototype.endSide=0;yc.prototype.point=!1;yc.prototype.mapMode=Ur.TrackDel;let S2=class zM{constructor(e,n,r){this.from=e,this.to=n,this.value=r}static create(e,n,r){return new zM(e,n,r)}};function k2(t,e){return t.from-e.from||t.value.startSide-e.value.startSide}class Sw{constructor(e,n,r,s){this.from=e,this.to=n,this.value=r,this.maxPoint=s}get length(){return this.to[this.to.length-1]}findIndex(e,n,r,s=0){let i=r?this.to:this.from;for(let l=s,c=i.length;;){if(l==c)return l;let d=l+c>>1,h=i[d]-e||(r?this.value[d].endSide:this.value[d].startSide)-n;if(d==l)return h>=0?l:c;h>=0?c=d:l=d+1}}between(e,n,r,s){for(let i=this.findIndex(n,-1e9,!0),l=this.findIndex(r,1e9,!1,i);iv||x==v&&h.startSide>0&&h.endSide<=0)continue;(v-x||h.endSide-h.startSide)<0||(l<0&&(l=x),h.point&&(c=Math.max(c,v-x)),r.push(h),s.push(x-l),i.push(v-l))}return{mapped:r.length?new Sw(s,i,r,c):null,pos:l}}}class Gt{constructor(e,n,r,s){this.chunkPos=e,this.chunk=n,this.nextLayer=r,this.maxPoint=s}static create(e,n,r,s){return new Gt(e,n,r,s)}get length(){let e=this.chunk.length-1;return e<0?0:Math.max(this.chunkEnd(e),this.nextLayer.length)}get size(){if(this.isEmpty)return 0;let e=this.nextLayer.size;for(let n of this.chunk)e+=n.value.length;return e}chunkEnd(e){return this.chunkPos[e]+this.chunk[e].length}update(e){let{add:n=[],sort:r=!1,filterFrom:s=0,filterTo:i=this.length}=e,l=e.filter;if(n.length==0&&!l)return this;if(r&&(n=n.slice().sort(k2)),this.isEmpty)return n.length?Gt.of(n):this;let c=new PM(this,null,-1).goto(0),d=0,h=[],m=new fl;for(;c.value||d=0){let p=n[d++];m.addInner(p.from,p.to,p.value)||h.push(p)}else c.rangeIndex==1&&c.chunkIndexthis.chunkEnd(c.chunkIndex)||ic.to||i=i&&e<=i+l.length&&l.between(i,e-i,n-i,r)===!1)return}this.nextLayer.between(e,n,r)}}iter(e=0){return gf.from([this]).goto(e)}get isEmpty(){return this.nextLayer==this}static iter(e,n=0){return gf.from(e).goto(n)}static compare(e,n,r,s,i=-1){let l=e.filter(p=>p.maxPoint>0||!p.isEmpty&&p.maxPoint>=i),c=n.filter(p=>p.maxPoint>0||!p.isEmpty&&p.maxPoint>=i),d=tj(l,c,r),h=new Dh(l,d,i),m=new Dh(c,d,i);r.iterGaps((p,x,v)=>nj(h,p,m,x,v,s)),r.empty&&r.length==0&&nj(h,0,m,0,0,s)}static eq(e,n,r=0,s){s==null&&(s=999999999);let i=e.filter(m=>!m.isEmpty&&n.indexOf(m)<0),l=n.filter(m=>!m.isEmpty&&e.indexOf(m)<0);if(i.length!=l.length)return!1;if(!i.length)return!0;let c=tj(i,l),d=new Dh(i,c,0).goto(r),h=new Dh(l,c,0).goto(r);for(;;){if(d.to!=h.to||!O2(d.active,h.active)||d.point&&(!h.point||!d.point.eq(h.point)))return!1;if(d.to>s)return!0;d.next(),h.next()}}static spans(e,n,r,s,i=-1){let l=new Dh(e,null,i).goto(n),c=n,d=l.openStart;for(;;){let h=Math.min(l.to,r);if(l.point){let m=l.activeForPoint(l.to),p=l.pointFromc&&(s.span(c,h,l.active,d),d=l.openEnd(h));if(l.to>r)return d+(l.point&&l.to>r?1:0);c=l.to,l.next()}}static of(e,n=!1){let r=new fl;for(let s of e instanceof S2?[e]:n?sV(e):e)r.add(s.from,s.to,s.value);return r.finish()}static join(e){if(!e.length)return Gt.empty;let n=e[e.length-1];for(let r=e.length-2;r>=0;r--)for(let s=e[r];s!=Gt.empty;s=s.nextLayer)n=new Gt(s.chunkPos,s.chunk,n,Math.max(s.maxPoint,n.maxPoint));return n}}Gt.empty=new Gt([],[],null,-1);function sV(t){if(t.length>1)for(let e=t[0],n=1;n0)return t.slice().sort(k2);e=r}return t}Gt.empty.nextLayer=Gt.empty;class fl{finishChunk(e){this.chunks.push(new Sw(this.from,this.to,this.value,this.maxPoint)),this.chunkPos.push(this.chunkStart),this.chunkStart=-1,this.setMaxPoint=Math.max(this.setMaxPoint,this.maxPoint),this.maxPoint=-1,e&&(this.from=[],this.to=[],this.value=[])}constructor(){this.chunks=[],this.chunkPos=[],this.chunkStart=-1,this.last=null,this.lastFrom=-1e9,this.lastTo=-1e9,this.from=[],this.to=[],this.value=[],this.maxPoint=-1,this.setMaxPoint=-1,this.nextLayer=null}add(e,n,r){this.addInner(e,n,r)||(this.nextLayer||(this.nextLayer=new fl)).add(e,n,r)}addInner(e,n,r){let s=e-this.lastTo||r.startSide-this.last.endSide;if(s<=0&&(e-this.lastFrom||r.startSide-this.last.startSide)<0)throw new Error("Ranges must be added sorted by `from` position and `startSide`");return s<0?!1:(this.from.length==250&&this.finishChunk(!0),this.chunkStart<0&&(this.chunkStart=e),this.from.push(e-this.chunkStart),this.to.push(n-this.chunkStart),this.last=r,this.lastFrom=e,this.lastTo=n,this.value.push(r),r.point&&(this.maxPoint=Math.max(this.maxPoint,n-e)),!0)}addChunk(e,n){if((e-this.lastTo||n.value[0].startSide-this.last.endSide)<0)return!1;this.from.length&&this.finishChunk(!0),this.setMaxPoint=Math.max(this.setMaxPoint,n.maxPoint),this.chunks.push(n),this.chunkPos.push(e);let r=n.value.length-1;return this.last=n.value[r],this.lastFrom=n.from[r]+e,this.lastTo=n.to[r]+e,!0}finish(){return this.finishInner(Gt.empty)}finishInner(e){if(this.from.length&&this.finishChunk(!1),this.chunks.length==0)return e;let n=Gt.create(this.chunkPos,this.chunks,this.nextLayer?this.nextLayer.finishInner(e):e,this.setMaxPoint);return this.from=null,n}}function tj(t,e,n){let r=new Map;for(let i of t)for(let l=0;l=this.minPoint)break}}setRangeIndex(e){if(e==this.layer.chunk[this.chunkIndex].value.length){if(this.chunkIndex++,this.skip)for(;this.chunkIndex=r&&s.push(new PM(l,n,r,i));return s.length==1?s[0]:new gf(s)}get startSide(){return this.value?this.value.startSide:0}goto(e,n=-1e9){for(let r of this.heap)r.goto(e,n);for(let r=this.heap.length>>1;r>=0;r--)Ty(this.heap,r);return this.next(),this}forward(e,n){for(let r of this.heap)r.forward(e,n);for(let r=this.heap.length>>1;r>=0;r--)Ty(this.heap,r);(this.to-e||this.value.endSide-n)<0&&this.next()}next(){if(this.heap.length==0)this.from=this.to=1e9,this.value=null,this.rank=-1;else{let e=this.heap[0];this.from=e.from,this.to=e.to,this.value=e.value,this.rank=e.rank,e.value&&e.next(),Ty(this.heap,0)}}}function Ty(t,e){for(let n=t[e];;){let r=(e<<1)+1;if(r>=t.length)break;let s=t[r];if(r+1=0&&(s=t[r+1],r++),n.compare(s)<0)break;t[r]=n,t[e]=s,e=r}}class Dh{constructor(e,n,r){this.minPoint=r,this.active=[],this.activeTo=[],this.activeRank=[],this.minActive=-1,this.point=null,this.pointFrom=0,this.pointRank=0,this.to=-1e9,this.endSide=0,this.openStart=-1,this.cursor=gf.from(e,n,r)}goto(e,n=-1e9){return this.cursor.goto(e,n),this.active.length=this.activeTo.length=this.activeRank.length=0,this.minActive=-1,this.to=e,this.endSide=n,this.openStart=-1,this.next(),this}forward(e,n){for(;this.minActive>-1&&(this.activeTo[this.minActive]-e||this.active[this.minActive].endSide-n)<0;)this.removeActive(this.minActive);this.cursor.forward(e,n)}removeActive(e){Jm(this.active,e),Jm(this.activeTo,e),Jm(this.activeRank,e),this.minActive=rj(this.active,this.activeTo)}addActive(e){let n=0,{value:r,to:s,rank:i}=this.cursor;for(;n0;)n++;ep(this.active,n,r),ep(this.activeTo,n,s),ep(this.activeRank,n,i),e&&ep(e,n,this.cursor.from),this.minActive=rj(this.active,this.activeTo)}next(){let e=this.to,n=this.point;this.point=null;let r=this.openStart<0?[]:null;for(;;){let s=this.minActive;if(s>-1&&(this.activeTo[s]-this.cursor.from||this.active[s].endSide-this.cursor.startSide)<0){if(this.activeTo[s]>e){this.to=this.activeTo[s],this.endSide=this.active[s].endSide;break}this.removeActive(s),r&&Jm(r,s)}else if(this.cursor.value)if(this.cursor.from>e){this.to=this.cursor.from,this.endSide=this.cursor.startSide;break}else{let i=this.cursor.value;if(!i.point)this.addActive(r),this.cursor.next();else if(n&&this.cursor.to==this.to&&this.cursor.from=0&&r[s]=0&&!(this.activeRank[r]e||this.activeTo[r]==e&&this.active[r].endSide>=this.point.endSide)&&n.push(this.active[r]);return n.reverse()}openEnd(e){let n=0;for(let r=this.activeTo.length-1;r>=0&&this.activeTo[r]>e;r--)n++;return n}}function nj(t,e,n,r,s,i){t.goto(e),n.goto(r);let l=r+s,c=r,d=r-e;for(;;){let h=t.to+d-n.to,m=h||t.endSide-n.endSide,p=m<0?t.to+d:n.to,x=Math.min(p,l);if(t.point||n.point?t.point&&n.point&&(t.point==n.point||t.point.eq(n.point))&&O2(t.activeForPoint(t.to),n.activeForPoint(n.to))||i.comparePoint(c,x,t.point,n.point):x>c&&!O2(t.active,n.active)&&i.compareRange(c,x,t.active,n.active),p>l)break;(h||t.openEnd!=n.openEnd)&&i.boundChange&&i.boundChange(p),c=p,m<=0&&t.next(),m>=0&&n.next()}}function O2(t,e){if(t.length!=e.length)return!1;for(let n=0;n=e;r--)t[r+1]=t[r];t[e]=n}function rj(t,e){let n=-1,r=1e9;for(let s=0;s=e)return s;if(s==t.length)break;i+=t.charCodeAt(s)==9?n-i%n:1,s=Vr(t,s)}return r===!0?-1:t.length}const N2="ͼ",sj=typeof Symbol>"u"?"__"+N2:Symbol.for(N2),C2=typeof Symbol>"u"?"__styleSet"+Math.floor(Math.random()*1e8):Symbol("styleSet"),ij=typeof globalThis<"u"?globalThis:typeof window<"u"?window:{};class ho{constructor(e,n){this.rules=[];let{finish:r}=n||{};function s(l){return/^@/.test(l)?[l]:l.split(/,\s*/)}function i(l,c,d,h){let m=[],p=/^@(\w+)\b/.exec(l[0]),x=p&&p[1]=="keyframes";if(p&&c==null)return d.push(l[0]+";");for(let v in c){let b=c[v];if(/&/.test(v))i(v.split(/,\s*/).map(k=>l.map(O=>k.replace(/&/,O))).reduce((k,O)=>k.concat(O)),b,d);else if(b&&typeof b=="object"){if(!p)throw new RangeError("The value of a property ("+v+") should be a primitive value.");i(s(v),b,m,x)}else b!=null&&m.push(v.replace(/_.*/,"").replace(/[A-Z]/g,k=>"-"+k.toLowerCase())+": "+b+";")}(m.length||x)&&d.push((r&&!p&&!h?l.map(r):l).join(", ")+" {"+m.join(" ")+"}")}for(let l in e)i(s(l),e[l],this.rules)}getRules(){return this.rules.join(` -`)}static newName(){let e=ij[sj]||1;return ij[sj]=e+1,N2+e.toString(36)}static mount(e,n,r){let s=e[C2],i=r&&r.nonce;s?i&&s.setNonce(i):s=new iV(e,i),s.mount(Array.isArray(n)?n:[n],e)}}let aj=new Map;class iV{constructor(e,n){let r=e.ownerDocument||e,s=r.defaultView;if(!e.head&&e.adoptedStyleSheets&&s.CSSStyleSheet){let i=aj.get(r);if(i)return e[C2]=i;this.sheet=new s.CSSStyleSheet,aj.set(r,this)}else this.styleTag=r.createElement("style"),n&&this.styleTag.setAttribute("nonce",n);this.modules=[],e[C2]=this}mount(e,n){let r=this.sheet,s=0,i=0;for(let l=0;l-1&&(this.modules.splice(d,1),i--,d=-1),d==-1){if(this.modules.splice(i++,0,c),r)for(let h=0;h",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},aV=typeof navigator<"u"&&/Mac/.test(navigator.platform),lV=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);for(var Hr=0;Hr<10;Hr++)fo[48+Hr]=fo[96+Hr]=String(Hr);for(var Hr=1;Hr<=24;Hr++)fo[Hr+111]="F"+Hr;for(var Hr=65;Hr<=90;Hr++)fo[Hr]=String.fromCharCode(Hr+32),xf[Hr]=String.fromCharCode(Hr);for(var My in fo)xf.hasOwnProperty(My)||(xf[My]=fo[My]);function oV(t){var e=aV&&t.metaKey&&t.shiftKey&&!t.ctrlKey&&!t.altKey||lV&&t.shiftKey&&t.key&&t.key.length==1||t.key=="Unidentified",n=!e&&t.key||(t.shiftKey?xf:fo)[t.keyCode]||t.key||"Unidentified";return n=="Esc"&&(n="Escape"),n=="Del"&&(n="Delete"),n=="Left"&&(n="ArrowLeft"),n=="Up"&&(n="ArrowUp"),n=="Right"&&(n="ArrowRight"),n=="Down"&&(n="ArrowDown"),n}function An(){var t=arguments[0];typeof t=="string"&&(t=document.createElement(t));var e=1,n=arguments[1];if(n&&typeof n=="object"&&n.nodeType==null&&!Array.isArray(n)){for(var r in n)if(Object.prototype.hasOwnProperty.call(n,r)){var s=n[r];typeof s=="string"?t.setAttribute(r,s):s!=null&&(t[r]=s)}e++}for(;e2);var Fe={mac:oj||/Mac/.test(us.platform),windows:/Win/.test(us.platform),linux:/Linux|X11/.test(us.platform),ie:Sx,ie_version:BM?T2.documentMode||6:A2?+A2[1]:M2?+M2[1]:0,gecko:lj,gecko_version:lj?+(/Firefox\/(\d+)/.exec(us.userAgent)||[0,0])[1]:0,chrome:!!Ay,chrome_version:Ay?+Ay[1]:0,ios:oj,android:/Android\b/.test(us.userAgent),webkit_version:cV?+(/\bAppleWebKit\/(\d+)/.exec(us.userAgent)||[0,0])[1]:0,safari:E2,safari_version:E2?+(/\bVersion\/(\d+(\.\d+)?)/.exec(us.userAgent)||[0,0])[1]:0,tabSize:T2.documentElement.style.tabSize!=null?"tab-size":"-moz-tab-size"};function vf(t){let e;return t.nodeType==11?e=t.getSelection?t:t.ownerDocument:e=t,e.getSelection()}function _2(t,e){return e?t==e||t.contains(e.nodeType!=1?e.parentNode:e):!1}function Kp(t,e){if(!e.anchorNode)return!1;try{return _2(t,e.anchorNode)}catch{return!1}}function ud(t){return t.nodeType==3?wc(t,0,t.nodeValue.length).getClientRects():t.nodeType==1?t.getClientRects():[]}function ef(t,e,n,r){return n?cj(t,e,n,r,-1)||cj(t,e,n,r,1):!1}function bc(t){for(var e=0;;e++)if(t=t.previousSibling,!t)return e}function Og(t){return t.nodeType==1&&/^(DIV|P|LI|UL|OL|BLOCKQUOTE|DD|DT|H\d|SECTION|PRE)$/.test(t.nodeName)}function cj(t,e,n,r,s){for(;;){if(t==n&&e==r)return!0;if(e==(s<0?0:ya(t))){if(t.nodeName=="DIV")return!1;let i=t.parentNode;if(!i||i.nodeType!=1)return!1;e=bc(t)+(s<0?0:1),t=i}else if(t.nodeType==1){if(t=t.childNodes[e+(s<0?-1:0)],t.nodeType==1&&t.contentEditable=="false")return!1;e=s<0?ya(t):0}else return!1}}function ya(t){return t.nodeType==3?t.nodeValue.length:t.childNodes.length}function s0(t,e){let n=e?t.left:t.right;return{left:n,right:n,top:t.top,bottom:t.bottom}}function uV(t){let e=t.visualViewport;return e?{left:0,right:e.width,top:0,bottom:e.height}:{left:0,right:t.innerWidth,top:0,bottom:t.innerHeight}}function IM(t,e){let n=e.width/t.offsetWidth,r=e.height/t.offsetHeight;return(n>.995&&n<1.005||!isFinite(n)||Math.abs(e.width-t.offsetWidth)<1)&&(n=1),(r>.995&&r<1.005||!isFinite(r)||Math.abs(e.height-t.offsetHeight)<1)&&(r=1),{scaleX:n,scaleY:r}}function dV(t,e,n,r,s,i,l,c){let d=t.ownerDocument,h=d.defaultView||window;for(let m=t,p=!1;m&&!p;)if(m.nodeType==1){let x,v=m==d.body,b=1,k=1;if(v)x=uV(h);else{if(/^(fixed|sticky)$/.test(getComputedStyle(m).position)&&(p=!0),m.scrollHeight<=m.clientHeight&&m.scrollWidth<=m.clientWidth){m=m.assignedSlot||m.parentNode;continue}let T=m.getBoundingClientRect();({scaleX:b,scaleY:k}=IM(m,T)),x={left:T.left,right:T.left+m.clientWidth*b,top:T.top,bottom:T.top+m.clientHeight*k}}let O=0,j=0;if(s=="nearest")e.top0&&e.bottom>x.bottom+j&&(j=e.bottom-x.bottom+l)):e.bottom>x.bottom&&(j=e.bottom-x.bottom+l,n<0&&e.top-j0&&e.right>x.right+O&&(O=e.right-x.right+i)):e.right>x.right&&(O=e.right-x.right+i,n<0&&e.leftx.bottom||e.leftx.right)&&(e={left:Math.max(e.left,x.left),right:Math.min(e.right,x.right),top:Math.max(e.top,x.top),bottom:Math.min(e.bottom,x.bottom)}),m=m.assignedSlot||m.parentNode}else if(m.nodeType==11)m=m.host;else break}function hV(t){let e=t.ownerDocument,n,r;for(let s=t.parentNode;s&&!(s==e.body||n&&r);)if(s.nodeType==1)!r&&s.scrollHeight>s.clientHeight&&(r=s),!n&&s.scrollWidth>s.clientWidth&&(n=s),s=s.assignedSlot||s.parentNode;else if(s.nodeType==11)s=s.host;else break;return{x:n,y:r}}class fV{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}eq(e){return this.anchorNode==e.anchorNode&&this.anchorOffset==e.anchorOffset&&this.focusNode==e.focusNode&&this.focusOffset==e.focusOffset}setRange(e){let{anchorNode:n,focusNode:r}=e;this.set(n,Math.min(e.anchorOffset,n?ya(n):0),r,Math.min(e.focusOffset,r?ya(r):0))}set(e,n,r,s){this.anchorNode=e,this.anchorOffset=n,this.focusNode=r,this.focusOffset=s}}let tc=null;Fe.safari&&Fe.safari_version>=26&&(tc=!1);function qM(t){if(t.setActive)return t.setActive();if(tc)return t.focus(tc);let e=[];for(let n=t;n&&(e.push(n,n.scrollTop,n.scrollLeft),n!=n.ownerDocument);n=n.parentNode);if(t.focus(tc==null?{get preventScroll(){return tc={preventScroll:!0},!0}}:void 0),!tc){tc=!1;for(let n=0;nMath.max(1,t.scrollHeight-t.clientHeight-4)}function $M(t,e){for(let n=t,r=e;;){if(n.nodeType==3&&r>0)return{node:n,offset:r};if(n.nodeType==1&&r>0){if(n.contentEditable=="false")return null;n=n.childNodes[r-1],r=ya(n)}else if(n.parentNode&&!Og(n))r=bc(n),n=n.parentNode;else return null}}function HM(t,e){for(let n=t,r=e;;){if(n.nodeType==3&&rn)return p.domBoundsAround(e,n,h);if(x>=e&&s==-1&&(s=d,i=h),h>n&&p.dom.parentNode==this.dom){l=d,c=m;break}m=x,h=x+p.breakAfter}return{from:i,to:c<0?r+this.length:c,startDOM:(s?this.children[s-1].dom.nextSibling:null)||this.dom.firstChild,endDOM:l=0?this.children[l].dom:null}}markDirty(e=!1){this.flags|=2,this.markParentsDirty(e)}markParentsDirty(e){for(let n=this.parent;n;n=n.parent){if(e&&(n.flags|=2),n.flags&1)return;n.flags|=1,e=!1}}setParent(e){this.parent!=e&&(this.parent=e,this.flags&7&&this.markParentsDirty(!0))}setDOM(e){this.dom!=e&&(this.dom&&(this.dom.cmView=null),this.dom=e,e.cmView=this)}get rootView(){for(let e=this;;){let n=e.parent;if(!n)return e;e=n}}replaceChildren(e,n,r=kw){this.markDirty();for(let s=e;sthis.pos||e==this.pos&&(n>0||this.i==0||this.children[this.i-1].breakAfter))return this.off=e-this.pos,this;let r=this.children[--this.i];this.pos-=r.length+r.breakAfter}}}function VM(t,e,n,r,s,i,l,c,d){let{children:h}=t,m=h.length?h[e]:null,p=i.length?i[i.length-1]:null,x=p?p.breakAfter:l;if(!(e==r&&m&&!l&&!x&&i.length<2&&m.merge(n,s,i.length?p:null,n==0,c,d))){if(r0&&(!l&&i.length&&m.merge(n,m.length,i[0],!1,c,0)?m.breakAfter=i.shift().breakAfter:(ngV||r.flags&8)?!1:(this.text=this.text.slice(0,e)+(r?r.text:"")+this.text.slice(n),this.markDirty(),!0)}split(e){let n=new Qi(this.text.slice(e));return this.text=this.text.slice(0,e),this.markDirty(),n.flags|=this.flags&8,n}localPosFromDOM(e,n){return e==this.dom?n:n?this.text.length:0}domAtPos(e){return new ns(this.dom,e)}domBoundsAround(e,n,r){return{from:r,to:r+this.length,startDOM:this.dom,endDOM:this.dom.nextSibling}}coordsAt(e,n){return xV(this.dom,e,n)}}class ml extends jn{constructor(e,n=[],r=0){super(),this.mark=e,this.children=n,this.length=r;for(let s of n)s.setParent(this)}setAttrs(e){if(FM(e),this.mark.class&&(e.className=this.mark.class),this.mark.attrs)for(let n in this.mark.attrs)e.setAttribute(n,this.mark.attrs[n]);return e}canReuseDOM(e){return super.canReuseDOM(e)&&!((this.flags|e.flags)&8)}reuseDOM(e){e.nodeName==this.mark.tagName.toUpperCase()&&(this.setDOM(e),this.flags|=6)}sync(e,n){this.dom?this.flags&4&&this.setAttrs(this.dom):this.setDOM(this.setAttrs(document.createElement(this.mark.tagName))),super.sync(e,n)}merge(e,n,r,s,i,l){return r&&(!(r instanceof ml&&r.mark.eq(this.mark))||e&&i<=0||ne&&n.push(r=e&&(s=i),r=d,i++}let l=this.length-e;return this.length=e,s>-1&&(this.children.length=s,this.markDirty()),new ml(this.mark,n,l)}domAtPos(e){return GM(this,e)}coordsAt(e,n){return YM(this,e,n)}}function xV(t,e,n){let r=t.nodeValue.length;e>r&&(e=r);let s=e,i=e,l=0;e==0&&n<0||e==r&&n>=0?Fe.chrome||Fe.gecko||(e?(s--,l=1):i=0)?0:c.length-1];return Fe.safari&&!l&&d.width==0&&(d=Array.prototype.find.call(c,h=>h.width)||d),l?s0(d,l<0):d||null}class il extends jn{static create(e,n,r){return new il(e,n,r)}constructor(e,n,r){super(),this.widget=e,this.length=n,this.side=r,this.prevWidget=null}split(e){let n=il.create(this.widget,this.length-e,this.side);return this.length-=e,n}sync(e){(!this.dom||!this.widget.updateDOM(this.dom,e))&&(this.dom&&this.prevWidget&&this.prevWidget.destroy(this.dom),this.prevWidget=null,this.setDOM(this.widget.toDOM(e)),this.widget.editable||(this.dom.contentEditable="false"))}getSide(){return this.side}merge(e,n,r,s,i,l){return r&&(!(r instanceof il)||!this.widget.compare(r.widget)||e>0&&i<=0||n0)?ns.before(this.dom):ns.after(this.dom,e==this.length)}domBoundsAround(){return null}coordsAt(e,n){let r=this.widget.coordsAt(this.dom,e,n);if(r)return r;let s=this.dom.getClientRects(),i=null;if(!s.length)return null;let l=this.side?this.side<0:e>0;for(let c=l?s.length-1:0;i=s[c],!(e>0?c==0:c==s.length-1||i.top0?ns.before(this.dom):ns.after(this.dom)}localPosFromDOM(){return 0}domBoundsAround(){return null}coordsAt(e){return this.dom.getBoundingClientRect()}get overrideDOMText(){return Wt.empty}get isHidden(){return!0}}Qi.prototype.children=il.prototype.children=dd.prototype.children=kw;function GM(t,e){let n=t.dom,{children:r}=t,s=0;for(let i=0;si&&e0;i--){let l=r[i-1];if(l.dom.parentNode==n)return l.domAtPos(l.length)}for(let i=s;i0&&e instanceof ml&&s.length&&(r=s[s.length-1])instanceof ml&&r.mark.eq(e.mark)?XM(r,e.children[0],n-1):(s.push(e),e.setParent(t)),t.length+=e.length}function YM(t,e,n){let r=null,s=-1,i=null,l=-1;function c(h,m){for(let p=0,x=0;p=m&&(v.children.length?c(v,m-x):(!i||i.isHidden&&(n>0||yV(i,v)))&&(b>m||x==b&&v.getSide()>0)?(i=v,l=m-x):(x-1?1:0)!=s.length-(n&&s.indexOf(n)>-1?1:0))return!1;for(let i of r)if(i!=n&&(s.indexOf(i)==-1||t[i]!==e[i]))return!1;return!0}function R2(t,e,n){let r=!1;if(e)for(let s in e)n&&s in n||(r=!0,s=="style"?t.style.cssText="":t.removeAttribute(s));if(n)for(let s in n)e&&e[s]==n[s]||(r=!0,s=="style"?t.style.cssText=n[s]:t.setAttribute(s,n[s]));return r}function bV(t){let e=Object.create(null);for(let n=0;n0?3e8:-4e8:n>0?1e8:-1e8,new mo(e,n,n,r,e.widget||null,!1)}static replace(e){let n=!!e.block,r,s;if(e.isBlockGap)r=-5e8,s=4e8;else{let{start:i,end:l}=KM(e,n);r=(i?n?-3e8:-1:5e8)-1,s=(l?n?2e8:1:-6e8)+1}return new mo(e,r,s,n,e.widget||null,!0)}static line(e){return new a0(e)}static set(e,n=!1){return Gt.of(e,n)}hasHeight(){return this.widget?this.widget.estimatedHeight>-1:!1}}Je.none=Gt.empty;class i0 extends Je{constructor(e){let{start:n,end:r}=KM(e);super(n?-1:5e8,r?1:-6e8,null,e),this.tagName=e.tagName||"span",this.class=e.class||"",this.attrs=e.attributes||null}eq(e){var n,r;return this==e||e instanceof i0&&this.tagName==e.tagName&&(this.class||((n=this.attrs)===null||n===void 0?void 0:n.class))==(e.class||((r=e.attrs)===null||r===void 0?void 0:r.class))&&jg(this.attrs,e.attrs,"class")}range(e,n=e){if(e>=n)throw new RangeError("Mark decorations may not be empty");return super.range(e,n)}}i0.prototype.point=!1;class a0 extends Je{constructor(e){super(-2e8,-2e8,null,e)}eq(e){return e instanceof a0&&this.spec.class==e.spec.class&&jg(this.spec.attributes,e.spec.attributes)}range(e,n=e){if(n!=e)throw new RangeError("Line decoration ranges must be zero-length");return super.range(e,n)}}a0.prototype.mapMode=Ur.TrackBefore;a0.prototype.point=!0;class mo extends Je{constructor(e,n,r,s,i,l){super(n,r,i,e),this.block=s,this.isReplace=l,this.mapMode=s?n<=0?Ur.TrackBefore:Ur.TrackAfter:Ur.TrackDel}get type(){return this.startSide!=this.endSide?fs.WidgetRange:this.startSide<=0?fs.WidgetBefore:fs.WidgetAfter}get heightRelevant(){return this.block||!!this.widget&&(this.widget.estimatedHeight>=5||this.widget.lineBreaks>0)}eq(e){return e instanceof mo&&wV(this.widget,e.widget)&&this.block==e.block&&this.startSide==e.startSide&&this.endSide==e.endSide}range(e,n=e){if(this.isReplace&&(e>n||e==n&&this.startSide>0&&this.endSide<=0))throw new RangeError("Invalid range for replacement decoration");if(!this.isReplace&&n!=e)throw new RangeError("Widget decorations can only have zero-length ranges");return super.range(e,n)}}mo.prototype.point=!0;function KM(t,e=!1){let{inclusiveStart:n,inclusiveEnd:r}=t;return n==null&&(n=t.inclusive),r==null&&(r=t.inclusive),{start:n??e,end:r??e}}function wV(t,e){return t==e||!!(t&&e&&t.compare(e))}function Zp(t,e,n,r=0){let s=n.length-1;s>=0&&n[s]+r>=t?n[s]=Math.max(n[s],e):n.push(t,e)}class pr extends jn{constructor(){super(...arguments),this.children=[],this.length=0,this.prevAttrs=void 0,this.attrs=null,this.breakAfter=0}merge(e,n,r,s,i,l){if(r){if(!(r instanceof pr))return!1;this.dom||r.transferDOM(this)}return s&&this.setDeco(r?r.attrs:null),WM(this,e,n,r?r.children.slice():[],i,l),!0}split(e){let n=new pr;if(n.breakAfter=this.breakAfter,this.length==0)return n;let{i:r,off:s}=this.childPos(e);s&&(n.append(this.children[r].split(s),0),this.children[r].merge(s,this.children[r].length,null,!1,0,0),r++);for(let i=r;i0&&this.children[r-1].length==0;)this.children[--r].destroy();return this.children.length=r,this.markDirty(),this.length=e,n}transferDOM(e){this.dom&&(this.markDirty(),e.setDOM(this.dom),e.prevAttrs=this.prevAttrs===void 0?this.attrs:this.prevAttrs,this.prevAttrs=void 0,this.dom=null)}setDeco(e){jg(this.attrs,e)||(this.dom&&(this.prevAttrs=this.attrs,this.markDirty()),this.attrs=e)}append(e,n){XM(this,e,n)}addLineDeco(e){let n=e.spec.attributes,r=e.spec.class;n&&(this.attrs=D2(n,this.attrs||{})),r&&(this.attrs=D2({class:r},this.attrs||{}))}domAtPos(e){return GM(this,e)}reuseDOM(e){e.nodeName=="DIV"&&(this.setDOM(e),this.flags|=6)}sync(e,n){var r;this.dom?this.flags&4&&(FM(this.dom),this.dom.className="cm-line",this.prevAttrs=this.attrs?null:void 0):(this.setDOM(document.createElement("div")),this.dom.className="cm-line",this.prevAttrs=this.attrs?null:void 0),this.prevAttrs!==void 0&&(R2(this.dom,this.prevAttrs,this.attrs),this.dom.classList.add("cm-line"),this.prevAttrs=void 0),super.sync(e,n);let s=this.dom.lastChild;for(;s&&jn.get(s)instanceof ml;)s=s.lastChild;if(!s||!this.length||s.nodeName!="BR"&&((r=jn.get(s))===null||r===void 0?void 0:r.isEditable)==!1&&(!Fe.ios||!this.children.some(i=>i instanceof Qi))){let i=document.createElement("BR");i.cmIgnore=!0,this.dom.appendChild(i)}}measureTextSize(){if(this.children.length==0||this.length>20)return null;let e=0,n;for(let r of this.children){if(!(r instanceof Qi)||/[^ -~]/.test(r.text))return null;let s=ud(r.dom);if(s.length!=1)return null;e+=s[0].width,n=s[0].height}return e?{lineHeight:this.dom.getBoundingClientRect().height,charWidth:e/this.length,textHeight:n}:null}coordsAt(e,n){let r=YM(this,e,n);if(!this.children.length&&r&&this.parent){let{heightOracle:s}=this.parent.view.viewState,i=r.bottom-r.top;if(Math.abs(i-s.lineHeight)<2&&s.textHeight=n){if(i instanceof pr)return i;if(l>n)break}s=l+i.breakAfter}return null}}class ol extends jn{constructor(e,n,r){super(),this.widget=e,this.length=n,this.deco=r,this.breakAfter=0,this.prevWidget=null}merge(e,n,r,s,i,l){return r&&(!(r instanceof ol)||!this.widget.compare(r.widget)||e>0&&i<=0||n0}}class z2 extends Oa{constructor(e){super(),this.height=e}toDOM(){let e=document.createElement("div");return e.className="cm-gap",this.updateDOM(e),e}eq(e){return e.height==this.height}updateDOM(e){return e.style.height=this.height+"px",!0}get editable(){return!0}get estimatedHeight(){return this.height}ignoreEvent(){return!1}}class tf{constructor(e,n,r,s){this.doc=e,this.pos=n,this.end=r,this.disallowBlockEffectsFor=s,this.content=[],this.curLine=null,this.breakAtStart=0,this.pendingBuffer=0,this.bufferMarks=[],this.atCursorPos=!0,this.openStart=-1,this.openEnd=-1,this.text="",this.textOff=0,this.cursor=e.iter(),this.skip=n}posCovered(){if(this.content.length==0)return!this.breakAtStart&&this.doc.lineAt(this.pos).from!=this.pos;let e=this.content[this.content.length-1];return!(e.breakAfter||e instanceof ol&&e.deco.endSide<0)}getLine(){return this.curLine||(this.content.push(this.curLine=new pr),this.atCursorPos=!0),this.curLine}flushBuffer(e=this.bufferMarks){this.pendingBuffer&&(this.curLine.append(tp(new dd(-1),e),e.length),this.pendingBuffer=0)}addBlockWidget(e){this.flushBuffer(),this.curLine=null,this.content.push(e)}finish(e){this.pendingBuffer&&e<=this.bufferMarks.length?this.flushBuffer():this.pendingBuffer=0,!this.posCovered()&&!(e&&this.content.length&&this.content[this.content.length-1]instanceof ol)&&this.getLine()}buildText(e,n,r){for(;e>0;){if(this.textOff==this.text.length){let{value:l,lineBreak:c,done:d}=this.cursor.next(this.skip);if(this.skip=0,d)throw new Error("Ran out of text content when drawing inline views");if(c){this.posCovered()||this.getLine(),this.content.length?this.content[this.content.length-1].breakAfter=1:this.breakAtStart=1,this.flushBuffer(),this.curLine=null,this.atCursorPos=!0,e--;continue}else this.text=l,this.textOff=0}let s=Math.min(this.text.length-this.textOff,e),i=Math.min(s,512);this.flushBuffer(n.slice(n.length-r)),this.getLine().append(tp(new Qi(this.text.slice(this.textOff,this.textOff+i)),n),r),this.atCursorPos=!0,this.textOff+=i,e-=i,r=s<=i?0:n.length}}span(e,n,r,s){this.buildText(n-e,r,s),this.pos=n,this.openStart<0&&(this.openStart=s)}point(e,n,r,s,i,l){if(this.disallowBlockEffectsFor[l]&&r instanceof mo){if(r.block)throw new RangeError("Block decorations may not be specified via plugins");if(n>this.doc.lineAt(this.pos).to)throw new RangeError("Decorations that replace line breaks may not be specified via plugins")}let c=n-e;if(r instanceof mo)if(r.block)r.startSide>0&&!this.posCovered()&&this.getLine(),this.addBlockWidget(new ol(r.widget||hd.block,c,r));else{let d=il.create(r.widget||hd.inline,c,c?0:r.startSide),h=this.atCursorPos&&!d.isEditable&&i<=s.length&&(e0),m=!d.isEditable&&(es.length||r.startSide<=0),p=this.getLine();this.pendingBuffer==2&&!h&&!d.isEditable&&(this.pendingBuffer=0),this.flushBuffer(s),h&&(p.append(tp(new dd(1),s),i),i=s.length+Math.max(0,i-s.length)),p.append(tp(d,s),i),this.atCursorPos=m,this.pendingBuffer=m?es.length?1:2:0,this.pendingBuffer&&(this.bufferMarks=s.slice())}else this.doc.lineAt(this.pos).from==this.pos&&this.getLine().addLineDeco(r);c&&(this.textOff+c<=this.text.length?this.textOff+=c:(this.skip+=c-(this.text.length-this.textOff),this.text="",this.textOff=0),this.pos=n),this.openStart<0&&(this.openStart=i)}static build(e,n,r,s,i){let l=new tf(e,n,r,i);return l.openEnd=Gt.spans(s,n,r,l),l.openStart<0&&(l.openStart=l.openEnd),l.finish(l.openEnd),l}}function tp(t,e){for(let n of e)t=new ml(n,[t],t.length);return t}class hd extends Oa{constructor(e){super(),this.tag=e}eq(e){return e.tag==this.tag}toDOM(){return document.createElement(this.tag)}updateDOM(e){return e.nodeName.toLowerCase()==this.tag}get isHidden(){return!0}}hd.inline=new hd("span");hd.block=new hd("div");var Hn=(function(t){return t[t.LTR=0]="LTR",t[t.RTL=1]="RTL",t})(Hn||(Hn={}));const Sc=Hn.LTR,Ow=Hn.RTL;function ZM(t){let e=[];for(let n=0;n=n){if(c.level==r)return l;(i<0||(s!=0?s<0?c.fromn:e[i].level>c.level))&&(i=l)}}if(i<0)throw new RangeError("Index out of range");return i}}function eA(t,e){if(t.length!=e.length)return!1;for(let n=0;n=0;k-=3)if(Ji[k+1]==-v){let O=Ji[k+2],j=O&2?s:O&4?O&1?i:s:0;j&&(En[p]=En[Ji[k]]=j),c=k;break}}else{if(Ji.length==189)break;Ji[c++]=p,Ji[c++]=x,Ji[c++]=d}else if((b=En[p])==2||b==1){let k=b==s;d=k?0:1;for(let O=c-3;O>=0;O-=3){let j=Ji[O+2];if(j&2)break;if(k)Ji[O+2]|=2;else{if(j&4)break;Ji[O+2]|=4}}}}}function CV(t,e,n,r){for(let s=0,i=r;s<=n.length;s++){let l=s?n[s-1].to:t,c=sd;)b==O&&(b=n[--k].from,O=k?n[k-1].to:t),En[--b]=v;d=m}else i=h,d++}}}function L2(t,e,n,r,s,i,l){let c=r%2?2:1;if(r%2==s%2)for(let d=e,h=0;dd&&l.push(new ro(d,k.from,v));let O=k.direction==Sc!=!(v%2);B2(t,O?r+1:r,s,k.inner,k.from,k.to,l),d=k.to}b=k.to}else{if(b==n||(m?En[b]!=c:En[b]==c))break;b++}x?L2(t,d,b,r+1,s,x,l):de;){let m=!0,p=!1;if(!h||d>i[h-1].to){let k=En[d-1];k!=c&&(m=!1,p=k==16)}let x=!m&&c==1?[]:null,v=m?r:r+1,b=d;e:for(;;)if(h&&b==i[h-1].to){if(p)break e;let k=i[--h];if(!m)for(let O=k.from,j=h;;){if(O==e)break e;if(j&&i[j-1].to==O)O=i[--j].from;else{if(En[O-1]==c)break e;break}}if(x)x.push(k);else{k.toEn.length;)En[En.length]=256;let r=[],s=e==Sc?0:1;return B2(t,s,s,n,0,t.length,r),r}function tA(t){return[new ro(0,t,0)]}let nA="";function MV(t,e,n,r,s){var i;let l=r.head-t.from,c=ro.find(e,l,(i=r.bidiLevel)!==null&&i!==void 0?i:-1,r.assoc),d=e[c],h=d.side(s,n);if(l==h){let x=c+=s?1:-1;if(x<0||x>=e.length)return null;d=e[c=x],l=d.side(!s,n),h=d.side(s,n)}let m=Vr(t.text,l,d.forward(s,n));(md.to)&&(m=h),nA=t.text.slice(Math.min(l,m),Math.max(l,m));let p=c==(s?e.length-1:0)?null:e[c+(s?1:-1)];return p&&m==h&&p.level+(s?0:1)t.some(e=>e)}),uA=He.define({combine:t=>t.some(e=>e)}),dA=He.define();class Xu{constructor(e,n="nearest",r="nearest",s=5,i=5,l=!1){this.range=e,this.y=n,this.x=r,this.yMargin=s,this.xMargin=i,this.isSnapshot=l}map(e){return e.empty?this:new Xu(this.range.map(e),this.y,this.x,this.yMargin,this.xMargin,this.isSnapshot)}clip(e){return this.range.to<=e.doc.length?this:new Xu(Ce.cursor(e.doc.length),this.y,this.x,this.yMargin,this.xMargin,this.isSnapshot)}}const np=xt.define({map:(t,e)=>t.map(e)}),hA=xt.define();function Es(t,e,n){let r=t.facet(aA);r.length?r[0](e):window.onerror&&window.onerror(String(e),n,void 0,void 0,e)||(n?console.error(n+":",e):console.error(e))}const sl=He.define({combine:t=>t.length?t[0]:!0});let EV=0;const Fu=He.define({combine(t){return t.filter((e,n)=>{for(let r=0;r{let d=[];return l&&d.push(yf.of(h=>{let m=h.plugin(c);return m?l(m):Je.none})),i&&d.push(i(c)),d})}static fromClass(e,n){return lr.define((r,s)=>new e(r,s),n)}}class Ey{constructor(e){this.spec=e,this.mustUpdate=null,this.value=null}get plugin(){return this.spec&&this.spec.plugin}update(e){if(this.value){if(this.mustUpdate){let n=this.mustUpdate;if(this.mustUpdate=null,this.value.update)try{this.value.update(n)}catch(r){if(Es(n.state,r,"CodeMirror plugin crashed"),this.value.destroy)try{this.value.destroy()}catch{}this.deactivate()}}}else if(this.spec)try{this.value=this.spec.plugin.create(e,this.spec.arg)}catch(n){Es(e.state,n,"CodeMirror plugin crashed"),this.deactivate()}return this}destroy(e){var n;if(!((n=this.value)===null||n===void 0)&&n.destroy)try{this.value.destroy()}catch(r){Es(e.state,r,"CodeMirror plugin crashed")}}deactivate(){this.spec=this.value=null}}const fA=He.define(),Cw=He.define(),yf=He.define(),mA=He.define(),l0=He.define(),pA=He.define();function fj(t,e){let n=t.state.facet(pA);if(!n.length)return n;let r=n.map(i=>i instanceof Function?i(t):i),s=[];return Gt.spans(r,e.from,e.to,{point(){},span(i,l,c,d){let h=i-e.from,m=l-e.from,p=s;for(let x=c.length-1;x>=0;x--,d--){let v=c[x].spec.bidiIsolate,b;if(v==null&&(v=AV(e.text,h,m)),d>0&&p.length&&(b=p[p.length-1]).to==h&&b.direction==v)b.to=m,p=b.inner;else{let k={from:h,to:m,direction:v,inner:[]};p.push(k),p=k.inner}}}}),s}const gA=He.define();function Tw(t){let e=0,n=0,r=0,s=0;for(let i of t.state.facet(gA)){let l=i(t);l&&(l.left!=null&&(e=Math.max(e,l.left)),l.right!=null&&(n=Math.max(n,l.right)),l.top!=null&&(r=Math.max(r,l.top)),l.bottom!=null&&(s=Math.max(s,l.bottom)))}return{left:e,right:n,top:r,bottom:s}}const Qh=He.define();class ji{constructor(e,n,r,s){this.fromA=e,this.toA=n,this.fromB=r,this.toB=s}join(e){return new ji(Math.min(this.fromA,e.fromA),Math.max(this.toA,e.toA),Math.min(this.fromB,e.fromB),Math.max(this.toB,e.toB))}addToSet(e){let n=e.length,r=this;for(;n>0;n--){let s=e[n-1];if(!(s.fromA>r.toA)){if(s.toAm)break;i+=2}if(!d)return r;new ji(d.fromA,d.toA,d.fromB,d.toB).addToSet(r),l=d.toA,c=d.toB}}}class Ng{constructor(e,n,r){this.view=e,this.state=n,this.transactions=r,this.flags=0,this.startState=e.state,this.changes=kr.empty(this.startState.doc.length);for(let i of r)this.changes=this.changes.compose(i.changes);let s=[];this.changes.iterChangedRanges((i,l,c,d)=>s.push(new ji(i,l,c,d))),this.changedRanges=s}static create(e,n,r){return new Ng(e,n,r)}get viewportChanged(){return(this.flags&4)>0}get viewportMoved(){return(this.flags&8)>0}get heightChanged(){return(this.flags&2)>0}get geometryChanged(){return this.docChanged||(this.flags&18)>0}get focusChanged(){return(this.flags&1)>0}get docChanged(){return!this.changes.empty}get selectionSet(){return this.transactions.some(e=>e.selection)}get empty(){return this.flags==0&&this.transactions.length==0}}class mj extends jn{get length(){return this.view.state.doc.length}constructor(e){super(),this.view=e,this.decorations=[],this.dynamicDecorationMap=[!1],this.domChanged=null,this.hasComposition=null,this.markedForComposition=new Set,this.editContextFormatting=Je.none,this.lastCompositionAfterCursor=!1,this.minWidth=0,this.minWidthFrom=0,this.minWidthTo=0,this.impreciseAnchor=null,this.impreciseHead=null,this.forceSelection=!1,this.lastUpdate=Date.now(),this.setDOM(e.contentDOM),this.children=[new pr],this.children[0].setParent(this),this.updateDeco(),this.updateInner([new ji(0,0,0,e.state.doc.length)],0,null)}update(e){var n;let r=e.changedRanges;this.minWidth>0&&r.length&&(r.every(({fromA:h,toA:m})=>mthis.minWidthTo)?(this.minWidthFrom=e.changes.mapPos(this.minWidthFrom,1),this.minWidthTo=e.changes.mapPos(this.minWidthTo,1)):this.minWidth=this.minWidthFrom=this.minWidthTo=0),this.updateEditContextFormatting(e);let s=-1;this.view.inputState.composing>=0&&!this.view.observer.editContext&&(!((n=this.domChanged)===null||n===void 0)&&n.newSel?s=this.domChanged.newSel.head:!BV(e.changes,this.hasComposition)&&!e.selectionSet&&(s=e.state.selection.main.head));let i=s>-1?DV(this.view,e.changes,s):null;if(this.domChanged=null,this.hasComposition){this.markedForComposition.clear();let{from:h,to:m}=this.hasComposition;r=new ji(h,m,e.changes.mapPos(h,-1),e.changes.mapPos(m,1)).addToSet(r.slice())}this.hasComposition=i?{from:i.range.fromB,to:i.range.toB}:null,(Fe.ie||Fe.chrome)&&!i&&e&&e.state.doc.lines!=e.startState.doc.lines&&(this.forceSelection=!0);let l=this.decorations,c=this.updateDeco(),d=PV(l,c,e.changes);return r=ji.extendWithRanges(r,d),!(this.flags&7)&&r.length==0?!1:(this.updateInner(r,e.startState.doc.length,i),e.transactions.length&&(this.lastUpdate=Date.now()),!0)}updateInner(e,n,r){this.view.viewState.mustMeasureContent=!0,this.updateChildren(e,n,r);let{observer:s}=this.view;s.ignore(()=>{this.dom.style.height=this.view.viewState.contentHeight/this.view.scaleY+"px",this.dom.style.flexBasis=this.minWidth?this.minWidth+"px":"";let l=Fe.chrome||Fe.ios?{node:s.selectionRange.focusNode,written:!1}:void 0;this.sync(this.view,l),this.flags&=-8,l&&(l.written||s.selectionRange.focusNode!=l.node)&&(this.forceSelection=!0),this.dom.style.height=""}),this.markedForComposition.forEach(l=>l.flags&=-9);let i=[];if(this.view.viewport.from||this.view.viewport.to=0?s[l]:null;if(!c)break;let{fromA:d,toA:h,fromB:m,toB:p}=c,x,v,b,k;if(r&&r.range.fromBm){let _=tf.build(this.view.state.doc,m,r.range.fromB,this.decorations,this.dynamicDecorationMap),D=tf.build(this.view.state.doc,r.range.toB,p,this.decorations,this.dynamicDecorationMap);v=_.breakAtStart,b=_.openStart,k=D.openEnd;let E=this.compositionView(r);D.breakAtStart?E.breakAfter=1:D.content.length&&E.merge(E.length,E.length,D.content[0],!1,D.openStart,0)&&(E.breakAfter=D.content[0].breakAfter,D.content.shift()),_.content.length&&E.merge(0,0,_.content[_.content.length-1],!0,0,_.openEnd)&&_.content.pop(),x=_.content.concat(E).concat(D.content)}else({content:x,breakAtStart:v,openStart:b,openEnd:k}=tf.build(this.view.state.doc,m,p,this.decorations,this.dynamicDecorationMap));let{i:O,off:j}=i.findPos(h,1),{i:T,off:M}=i.findPos(d,-1);VM(this,T,M,O,j,x,v,b,k)}r&&this.fixCompositionDOM(r)}updateEditContextFormatting(e){this.editContextFormatting=this.editContextFormatting.map(e.changes);for(let n of e.transactions)for(let r of n.effects)r.is(hA)&&(this.editContextFormatting=r.value)}compositionView(e){let n=new Qi(e.text.nodeValue);n.flags|=8;for(let{deco:s}of e.marks)n=new ml(s,[n],n.length);let r=new pr;return r.append(n,0),r}fixCompositionDOM(e){let n=(i,l)=>{l.flags|=8|(l.children.some(d=>d.flags&7)?1:0),this.markedForComposition.add(l);let c=jn.get(i);c&&c!=l&&(c.dom=null),l.setDOM(i)},r=this.childPos(e.range.fromB,1),s=this.children[r.i];n(e.line,s);for(let i=e.marks.length-1;i>=-1;i--)r=s.childPos(r.off,1),s=s.children[r.i],n(i>=0?e.marks[i].node:e.text,s)}updateSelection(e=!1,n=!1){(e||!this.view.observer.selectionRange.focusNode)&&this.view.observer.readSelectionRange();let r=this.view.root.activeElement,s=r==this.dom,i=!s&&!(this.view.state.facet(sl)||this.dom.tabIndex>-1)&&Kp(this.dom,this.view.observer.selectionRange)&&!(r&&this.dom.contains(r));if(!(s||n||i))return;let l=this.forceSelection;this.forceSelection=!1;let c=this.view.state.selection.main,d=this.moveToLine(this.domAtPos(c.anchor)),h=c.empty?d:this.moveToLine(this.domAtPos(c.head));if(Fe.gecko&&c.empty&&!this.hasComposition&&_V(d)){let p=document.createTextNode("");this.view.observer.ignore(()=>d.node.insertBefore(p,d.node.childNodes[d.offset]||null)),d=h=new ns(p,0),l=!0}let m=this.view.observer.selectionRange;(l||!m.focusNode||(!ef(d.node,d.offset,m.anchorNode,m.anchorOffset)||!ef(h.node,h.offset,m.focusNode,m.focusOffset))&&!this.suppressWidgetCursorChange(m,c))&&(this.view.observer.ignore(()=>{Fe.android&&Fe.chrome&&this.dom.contains(m.focusNode)&&LV(m.focusNode,this.dom)&&(this.dom.blur(),this.dom.focus({preventScroll:!0}));let p=vf(this.view.root);if(p)if(c.empty){if(Fe.gecko){let x=RV(d.node,d.offset);if(x&&x!=3){let v=(x==1?$M:HM)(d.node,d.offset);v&&(d=new ns(v.node,v.offset))}}p.collapse(d.node,d.offset),c.bidiLevel!=null&&p.caretBidiLevel!==void 0&&(p.caretBidiLevel=c.bidiLevel)}else if(p.extend){p.collapse(d.node,d.offset);try{p.extend(h.node,h.offset)}catch{}}else{let x=document.createRange();c.anchor>c.head&&([d,h]=[h,d]),x.setEnd(h.node,h.offset),x.setStart(d.node,d.offset),p.removeAllRanges(),p.addRange(x)}i&&this.view.root.activeElement==this.dom&&(this.dom.blur(),r&&r.focus())}),this.view.observer.setSelectionRange(d,h)),this.impreciseAnchor=d.precise?null:new ns(m.anchorNode,m.anchorOffset),this.impreciseHead=h.precise?null:new ns(m.focusNode,m.focusOffset)}suppressWidgetCursorChange(e,n){return this.hasComposition&&n.empty&&ef(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset)&&this.posFromDOM(e.focusNode,e.focusOffset)==n.head}enforceCursorAssoc(){if(this.hasComposition)return;let{view:e}=this,n=e.state.selection.main,r=vf(e.root),{anchorNode:s,anchorOffset:i}=e.observer.selectionRange;if(!r||!n.empty||!n.assoc||!r.modify)return;let l=pr.find(this,n.head);if(!l)return;let c=l.posAtStart;if(n.head==c||n.head==c+l.length)return;let d=this.coordsAt(n.head,-1),h=this.coordsAt(n.head,1);if(!d||!h||d.bottom>h.top)return;let m=this.domAtPos(n.head+n.assoc);r.collapse(m.node,m.offset),r.modify("move",n.assoc<0?"forward":"backward","lineboundary"),e.observer.readSelectionRange();let p=e.observer.selectionRange;e.docView.posFromDOM(p.anchorNode,p.anchorOffset)!=n.from&&r.collapse(s,i)}moveToLine(e){let n=this.dom,r;if(e.node!=n)return e;for(let s=e.offset;!r&&s=0;s--){let i=jn.get(n.childNodes[s]);i instanceof pr&&(r=i.domAtPos(i.length))}return r?new ns(r.node,r.offset,!0):e}nearest(e){for(let n=e;n;){let r=jn.get(n);if(r&&r.rootView==this)return r;n=n.parentNode}return null}posFromDOM(e,n){let r=this.nearest(e);if(!r)throw new RangeError("Trying to find position for a DOM position outside of the document");return r.localPosFromDOM(e,n)+r.posAtStart}domAtPos(e){let{i:n,off:r}=this.childCursor().findPos(e,-1);for(;n=0;l--){let c=this.children[l],d=i-c.breakAfter,h=d-c.length;if(de||c.covers(1))&&(!r||c instanceof pr&&!(r instanceof pr&&n>=0)))r=c,s=h;else if(r&&h==e&&d==e&&c instanceof ol&&Math.abs(n)<2){if(c.deco.startSide<0)break;l&&(r=null)}i=h}return r?r.coordsAt(e-s,n):null}coordsForChar(e){let{i:n,off:r}=this.childPos(e,1),s=this.children[n];if(!(s instanceof pr))return null;for(;s.children.length;){let{i:c,off:d}=s.childPos(r,1);for(;;c++){if(c==s.children.length)return null;if((s=s.children[c]).length)break}r=d}if(!(s instanceof Qi))return null;let i=Vr(s.text,r);if(i==r)return null;let l=wc(s.dom,r,i).getClientRects();for(let c=0;cMath.max(this.view.scrollDOM.clientWidth,this.minWidth)+1,c=-1,d=this.view.textDirection==Hn.LTR;for(let h=0,m=0;ms)break;if(h>=r){let v=p.dom.getBoundingClientRect();if(n.push(v.height),l){let b=p.dom.lastChild,k=b?ud(b):[];if(k.length){let O=k[k.length-1],j=d?O.right-v.left:v.right-O.left;j>c&&(c=j,this.minWidth=i,this.minWidthFrom=h,this.minWidthTo=x)}}}h=x+p.breakAfter}return n}textDirectionAt(e){let{i:n}=this.childPos(e,1);return getComputedStyle(this.children[n].dom).direction=="rtl"?Hn.RTL:Hn.LTR}measureTextSize(){for(let i of this.children)if(i instanceof pr){let l=i.measureTextSize();if(l)return l}let e=document.createElement("div"),n,r,s;return e.className="cm-line",e.style.width="99999px",e.style.position="absolute",e.textContent="abc def ghi jkl mno pqr stu",this.view.observer.ignore(()=>{this.dom.appendChild(e);let i=ud(e.firstChild)[0];n=e.getBoundingClientRect().height,r=i?i.width/27:7,s=i?i.height:n,e.remove()}),{lineHeight:n,charWidth:r,textHeight:s}}childCursor(e=this.length){let n=this.children.length;return n&&(e-=this.children[--n].length),new UM(this.children,e,n)}computeBlockGapDeco(){let e=[],n=this.view.viewState;for(let r=0,s=0;;s++){let i=s==n.viewports.length?null:n.viewports[s],l=i?i.from-1:this.length;if(l>r){let c=(n.lineBlockAt(l).bottom-n.lineBlockAt(r).top)/this.view.scaleY;e.push(Je.replace({widget:new z2(c),block:!0,inclusive:!0,isBlockGap:!0}).range(r,l))}if(!i)break;r=i.to+1}return Je.set(e)}updateDeco(){let e=1,n=this.view.state.facet(yf).map(i=>(this.dynamicDecorationMap[e++]=typeof i=="function")?i(this.view):i),r=!1,s=this.view.state.facet(mA).map((i,l)=>{let c=typeof i=="function";return c&&(r=!0),c?i(this.view):i});for(s.length&&(this.dynamicDecorationMap[e++]=r,n.push(Gt.join(s))),this.decorations=[this.editContextFormatting,...n,this.computeBlockGapDeco(),this.view.viewState.lineGapDeco];en.anchor?-1:1),s;if(!r)return;!n.empty&&(s=this.coordsAt(n.anchor,n.anchor>n.head?-1:1))&&(r={left:Math.min(r.left,s.left),top:Math.min(r.top,s.top),right:Math.max(r.right,s.right),bottom:Math.max(r.bottom,s.bottom)});let i=Tw(this.view),l={left:r.left-i.left,top:r.top-i.top,right:r.right+i.right,bottom:r.bottom+i.bottom},{offsetWidth:c,offsetHeight:d}=this.view.scrollDOM;dV(this.view.scrollDOM,l,n.heads instanceof il||s.children.some(r);return r(this.children[n])}}function _V(t){return t.node.nodeType==1&&t.node.firstChild&&(t.offset==0||t.node.childNodes[t.offset-1].contentEditable=="false")&&(t.offset==t.node.childNodes.length||t.node.childNodes[t.offset].contentEditable=="false")}function xA(t,e){let n=t.observer.selectionRange;if(!n.focusNode)return null;let r=$M(n.focusNode,n.focusOffset),s=HM(n.focusNode,n.focusOffset),i=r||s;if(s&&r&&s.node!=r.node){let c=jn.get(s.node);if(!c||c instanceof Qi&&c.text!=s.node.nodeValue)i=s;else if(t.docView.lastCompositionAfterCursor){let d=jn.get(r.node);!d||d instanceof Qi&&d.text!=r.node.nodeValue||(i=s)}}if(t.docView.lastCompositionAfterCursor=i!=r,!i)return null;let l=e-i.offset;return{from:l,to:l+i.node.nodeValue.length,node:i.node}}function DV(t,e,n){let r=xA(t,n);if(!r)return null;let{node:s,from:i,to:l}=r,c=s.nodeValue;if(/[\n\r]/.test(c)||t.state.doc.sliceString(r.from,r.to)!=c)return null;let d=e.invertedDesc,h=new ji(d.mapPos(i),d.mapPos(l),i,l),m=[];for(let p=s.parentNode;;p=p.parentNode){let x=jn.get(p);if(x instanceof ml)m.push({node:p,deco:x.mark});else{if(x instanceof pr||p.nodeName=="DIV"&&p.parentNode==t.contentDOM)return{range:h,text:s,marks:m,line:p};if(p!=t.contentDOM)m.push({node:p,deco:new i0({inclusive:!0,attributes:bV(p),tagName:p.tagName.toLowerCase()})});else return null}}}function RV(t,e){return t.nodeType!=1?0:(e&&t.childNodes[e-1].contentEditable=="false"?1:0)|(e{re.from&&(n=!0)}),n}function IV(t,e,n=1){let r=t.charCategorizer(e),s=t.doc.lineAt(e),i=e-s.from;if(s.length==0)return Ce.cursor(e);i==0?n=1:i==s.length&&(n=-1);let l=i,c=i;n<0?l=Vr(s.text,i,!1):c=Vr(s.text,i);let d=r(s.text.slice(l,c));for(;l>0;){let h=Vr(s.text,l,!1);if(r(s.text.slice(h,l))!=d)break;l=h}for(;ct?e.left-t:Math.max(0,t-e.right)}function FV(t,e){return e.top>t?e.top-t:Math.max(0,t-e.bottom)}function _y(t,e){return t.tope.top+1}function pj(t,e){return et.bottom?{top:t.top,left:t.left,right:t.right,bottom:e}:t}function q2(t,e,n){let r,s,i,l,c=!1,d,h,m,p;for(let b=t.firstChild;b;b=b.nextSibling){let k=ud(b);for(let O=0;OM||l==M&&i>T)&&(r=b,s=j,i=T,l=M,c=T?e0:Oj.bottom&&(!m||m.bottomj.top)&&(h=b,p=j):m&&_y(m,j)?m=gj(m,j.bottom):p&&_y(p,j)&&(p=pj(p,j.top))}}if(m&&m.bottom>=n?(r=d,s=m):p&&p.top<=n&&(r=h,s=p),!r)return{node:t,offset:0};let x=Math.max(s.left,Math.min(s.right,e));if(r.nodeType==3)return xj(r,x,n);if(c&&r.contentEditable!="false")return q2(r,x,n);let v=Array.prototype.indexOf.call(t.childNodes,r)+(e>=(s.left+s.right)/2?1:0);return{node:t,offset:v}}function xj(t,e,n){let r=t.nodeValue.length,s=-1,i=1e9,l=0;for(let c=0;cn?m.top-n:n-m.bottom)-1;if(m.left-1<=e&&m.right+1>=e&&p=(m.left+m.right)/2,v=x;if(Fe.chrome||Fe.gecko){let b=wc(t,c).getBoundingClientRect();Math.abs(b.left-m.right)<.1&&(v=!x)}if(p<=0)return{node:t,offset:c+(v?1:0)};s=c+(v?1:0),i=p}}}return{node:t,offset:s>-1?s:l>0?t.nodeValue.length:0}}function vA(t,e,n,r=-1){var s,i;let l=t.contentDOM.getBoundingClientRect(),c=l.top+t.viewState.paddingTop,d,{docHeight:h}=t.viewState,{x:m,y:p}=e,x=p-c;if(x<0)return 0;if(x>h)return t.state.doc.length;for(let _=t.viewState.heightOracle.textHeight/2,D=!1;d=t.elementAtHeight(x),d.type!=fs.Text;)for(;x=r>0?d.bottom+_:d.top-_,!(x>=0&&x<=h);){if(D)return n?null:0;D=!0,r=-r}p=c+x;let v=d.from;if(vt.viewport.to)return t.viewport.to==t.state.doc.length?t.state.doc.length:n?null:vj(t,l,d,m,p);let b=t.dom.ownerDocument,k=t.root.elementFromPoint?t.root:b,O=k.elementFromPoint(m,p);O&&!t.contentDOM.contains(O)&&(O=null),O||(m=Math.max(l.left+1,Math.min(l.right-1,m)),O=k.elementFromPoint(m,p),O&&!t.contentDOM.contains(O)&&(O=null));let j,T=-1;if(O&&((s=t.docView.nearest(O))===null||s===void 0?void 0:s.isEditable)!=!1){if(b.caretPositionFromPoint){let _=b.caretPositionFromPoint(m,p);_&&({offsetNode:j,offset:T}=_)}else if(b.caretRangeFromPoint){let _=b.caretRangeFromPoint(m,p);_&&({startContainer:j,startOffset:T}=_)}j&&(!t.contentDOM.contains(j)||Fe.safari&&QV(j,T,m)||Fe.chrome&&$V(j,T,m))&&(j=void 0),j&&(T=Math.min(ya(j),T))}if(!j||!t.docView.dom.contains(j)){let _=pr.find(t.docView,v);if(!_)return x>d.top+d.height/2?d.to:d.from;({node:j,offset:T}=q2(_.dom,m,p))}let M=t.docView.nearest(j);if(!M)return null;if(M.isWidget&&((i=M.dom)===null||i===void 0?void 0:i.nodeType)==1){let _=M.dom.getBoundingClientRect();return e.y<_.top||e.y<=_.bottom&&e.x<=(_.left+_.right)/2?M.posAtStart:M.posAtEnd}else return M.localPosFromDOM(j,T)+M.posAtStart}function vj(t,e,n,r,s){let i=Math.round((r-e.left)*t.defaultCharacterWidth);if(t.lineWrapping&&n.height>t.defaultLineHeight*1.5){let c=t.viewState.heightOracle.textHeight,d=Math.floor((s-n.top-(t.defaultLineHeight-c)*.5)/c);i+=d*t.viewState.heightOracle.lineLength}let l=t.state.sliceDoc(n.from,n.to);return n.from+j2(l,i,t.state.tabSize)}function yA(t,e,n){let r,s=t;if(t.nodeType!=3||e!=(r=t.nodeValue.length))return!1;for(;;){let i=s.nextSibling;if(i){if(i.nodeName=="BR")break;return!1}else{let l=s.parentNode;if(!l||l.nodeName=="DIV")break;s=l}}return wc(t,r-1,r).getBoundingClientRect().right>n}function QV(t,e,n){return yA(t,e,n)}function $V(t,e,n){if(e!=0)return yA(t,e,n);for(let s=t;;){let i=s.parentNode;if(!i||i.nodeType!=1||i.firstChild!=s)return!1;if(i.classList.contains("cm-line"))break;s=i}let r=t.nodeType==1?t.getBoundingClientRect():wc(t,0,Math.max(t.nodeValue.length,1)).getBoundingClientRect();return n-r.left>5}function F2(t,e,n){let r=t.lineBlockAt(e);if(Array.isArray(r.type)){let s;for(let i of r.type){if(i.from>e)break;if(!(i.toe)return i;(!s||i.type==fs.Text&&(s.type!=i.type||(n<0?i.frome)))&&(s=i)}}return s||r}return r}function HV(t,e,n,r){let s=F2(t,e.head,e.assoc||-1),i=!r||s.type!=fs.Text||!(t.lineWrapping||s.widgetLineBreaks)?null:t.coordsAtPos(e.assoc<0&&e.head>s.from?e.head-1:e.head);if(i){let l=t.dom.getBoundingClientRect(),c=t.textDirectionAt(s.from),d=t.posAtCoords({x:n==(c==Hn.LTR)?l.right-1:l.left+1,y:(i.top+i.bottom)/2});if(d!=null)return Ce.cursor(d,n?-1:1)}return Ce.cursor(n?s.to:s.from,n?-1:1)}function yj(t,e,n,r){let s=t.state.doc.lineAt(e.head),i=t.bidiSpans(s),l=t.textDirectionAt(s.from);for(let c=e,d=null;;){let h=MV(s,i,l,c,n),m=nA;if(!h){if(s.number==(n?t.state.doc.lines:1))return c;m=` -`,s=t.state.doc.line(s.number+(n?1:-1)),i=t.bidiSpans(s),h=t.visualLineSide(s,!n)}if(d){if(!d(m))return c}else{if(!r)return h;d=r(m)}c=h}}function UV(t,e,n){let r=t.state.charCategorizer(e),s=r(n);return i=>{let l=r(i);return s==Vn.Space&&(s=l),s==l}}function VV(t,e,n,r){let s=e.head,i=n?1:-1;if(s==(n?t.state.doc.length:0))return Ce.cursor(s,e.assoc);let l=e.goalColumn,c,d=t.contentDOM.getBoundingClientRect(),h=t.coordsAtPos(s,e.assoc||-1),m=t.documentTop;if(h)l==null&&(l=h.left-d.left),c=i<0?h.top:h.bottom;else{let v=t.viewState.lineBlockAt(s);l==null&&(l=Math.min(d.right-d.left,t.defaultCharacterWidth*(s-v.from))),c=(i<0?v.top:v.bottom)+m}let p=d.left+l,x=r??t.viewState.heightOracle.textHeight>>1;for(let v=0;;v+=10){let b=c+(x+v)*i,k=vA(t,{x:p,y:b},!1,i);if(bd.bottom||(i<0?ks)){let O=t.docView.coordsForChar(k),j=!O||b{if(e>i&&es(t)),n.from,e.head>n.from?-1:1);return r==n.from?n:Ce.cursor(r,ri)&&!XV(l,n)&&this.lineBreak(),s=l}return this.findPointBefore(r,n),this}readTextNode(e){let n=e.nodeValue;for(let r of this.points)r.node==e&&(r.pos=this.text.length+Math.min(r.offset,n.length));for(let r=0,s=this.lineSeparator?null:/\r\n?|\n/g;;){let i=-1,l=1,c;if(this.lineSeparator?(i=n.indexOf(this.lineSeparator,r),l=this.lineSeparator.length):(c=s.exec(n))&&(i=c.index,l=c[0].length),this.append(n.slice(r,i<0?n.length:i)),i<0)break;if(this.lineBreak(),l>1)for(let d of this.points)d.node==e&&d.pos>this.text.length&&(d.pos-=l-1);r=i+l}}readNode(e){if(e.cmIgnore)return;let n=jn.get(e),r=n&&n.overrideDOMText;if(r!=null){this.findPointInside(e,r.length);for(let s=r.iter();!s.next().done;)s.lineBreak?this.lineBreak():this.append(s.value)}else e.nodeType==3?this.readTextNode(e):e.nodeName=="BR"?e.nextSibling&&this.lineBreak():e.nodeType==1&&this.readRange(e.firstChild,null)}findPointBefore(e,n){for(let r of this.points)r.node==e&&e.childNodes[r.offset]==n&&(r.pos=this.text.length)}findPointInside(e,n){for(let r of this.points)(e.nodeType==3?r.node==e:e.contains(r.node))&&(r.pos=this.text.length+(GV(e,r.node,r.offset)?n:0))}}function GV(t,e,n){for(;;){if(!e||n-1;let{impreciseHead:i,impreciseAnchor:l}=e.docView;if(e.state.readOnly&&n>-1)this.newSel=null;else if(n>-1&&(this.bounds=e.docView.domBoundsAround(n,r,0))){let c=i||l?[]:ZV(e),d=new WV(c,e.state);d.readRange(this.bounds.startDOM,this.bounds.endDOM),this.text=d.text,this.newSel=JV(c,this.bounds.from)}else{let c=e.observer.selectionRange,d=i&&i.node==c.focusNode&&i.offset==c.focusOffset||!_2(e.contentDOM,c.focusNode)?e.state.selection.main.head:e.docView.posFromDOM(c.focusNode,c.focusOffset),h=l&&l.node==c.anchorNode&&l.offset==c.anchorOffset||!_2(e.contentDOM,c.anchorNode)?e.state.selection.main.anchor:e.docView.posFromDOM(c.anchorNode,c.anchorOffset),m=e.viewport;if((Fe.ios||Fe.chrome)&&e.state.selection.main.empty&&d!=h&&(m.from>0||m.to-1&&e.state.selection.ranges.length>1?this.newSel=e.state.selection.replaceRange(Ce.range(h,d)):this.newSel=Ce.single(h,d)}}}function wA(t,e){let n,{newSel:r}=e,s=t.state.selection.main,i=t.inputState.lastKeyTime>Date.now()-100?t.inputState.lastKeyCode:-1;if(e.bounds){let{from:l,to:c}=e.bounds,d=s.from,h=null;(i===8||Fe.android&&e.text.length=s.from&&n.to<=s.to&&(n.from!=s.from||n.to!=s.to)&&s.to-s.from-(n.to-n.from)<=4?n={from:s.from,to:s.to,insert:t.state.doc.slice(s.from,n.from).append(n.insert).append(t.state.doc.slice(n.to,s.to))}:t.state.doc.lineAt(s.from).toDate.now()-50?n={from:s.from,to:s.to,insert:t.state.toText(t.inputState.insertingText)}:Fe.chrome&&n&&n.from==n.to&&n.from==s.head&&n.insert.toString()==` - `&&t.lineWrapping&&(r&&(r=Ce.single(r.main.anchor-1,r.main.head-1)),n={from:s.from,to:s.to,insert:Wt.of([" "])}),n)return Mw(t,n,r,i);if(r&&!r.main.eq(s)){let l=!1,c="select";return t.inputState.lastSelectionTime>Date.now()-50&&(t.inputState.lastSelectionOrigin=="select"&&(l=!0),c=t.inputState.lastSelectionOrigin,c=="select.pointer"&&(r=bA(t.state.facet(l0).map(d=>d(t)),r))),t.dispatch({selection:r,scrollIntoView:l,userEvent:c}),!0}else return!1}function Mw(t,e,n,r=-1){if(Fe.ios&&t.inputState.flushIOSKey(e))return!0;let s=t.state.selection.main;if(Fe.android&&(e.to==s.to&&(e.from==s.from||e.from==s.from-1&&t.state.sliceDoc(e.from,s.from)==" ")&&e.insert.length==1&&e.insert.lines==2&&Gu(t.contentDOM,"Enter",13)||(e.from==s.from-1&&e.to==s.to&&e.insert.length==0||r==8&&e.insert.lengths.head)&&Gu(t.contentDOM,"Backspace",8)||e.from==s.from&&e.to==s.to+1&&e.insert.length==0&&Gu(t.contentDOM,"Delete",46)))return!0;let i=e.insert.toString();t.inputState.composing>=0&&t.inputState.composing++;let l,c=()=>l||(l=KV(t,e,n));return t.state.facet(lA).some(d=>d(t,e.from,e.to,i,c))||t.dispatch(c()),!0}function KV(t,e,n){let r,s=t.state,i=s.selection.main,l=-1;if(e.from==e.to&&e.fromi.to){let d=e.fromp(t)),h,d);e.from==m&&(l=m)}if(l>-1)r={changes:e,selection:Ce.cursor(e.from+e.insert.length,-1)};else if(e.from>=i.from&&e.to<=i.to&&e.to-e.from>=(i.to-i.from)/3&&(!n||n.main.empty&&n.main.from==e.from+e.insert.length)&&t.inputState.composing<0){let d=i.frome.to?s.sliceDoc(e.to,i.to):"";r=s.replaceSelection(t.state.toText(d+e.insert.sliceString(0,void 0,t.state.lineBreak)+h))}else{let d=s.changes(e),h=n&&n.main.to<=d.newLength?n.main:void 0;if(s.selection.ranges.length>1&&(t.inputState.composing>=0||t.inputState.compositionPendingChange)&&e.to<=i.to+10&&e.to>=i.to-10){let m=t.state.sliceDoc(e.from,e.to),p,x=n&&xA(t,n.main.head);if(x){let b=e.insert.length-(e.to-e.from);p={from:x.from,to:x.to-b}}else p=t.state.doc.lineAt(i.head);let v=i.to-e.to;r=s.changeByRange(b=>{if(b.from==i.from&&b.to==i.to)return{changes:d,range:h||b.map(d)};let k=b.to-v,O=k-m.length;if(t.state.sliceDoc(O,k)!=m||k>=p.from&&O<=p.to)return{range:b};let j=s.changes({from:O,to:k,insert:e.insert}),T=b.to-i.to;return{changes:j,range:h?Ce.range(Math.max(0,h.anchor+T),Math.max(0,h.head+T)):b.map(j)}})}else r={changes:d,selection:h&&s.selection.replaceRange(h)}}let c="input.type";return(t.composing||t.inputState.compositionPendingChange&&t.inputState.compositionEndedAt>Date.now()-50)&&(t.inputState.compositionPendingChange=!1,c+=".compose",t.inputState.compositionFirstChange&&(c+=".start",t.inputState.compositionFirstChange=!1)),s.update(r,{userEvent:c,scrollIntoView:!0})}function SA(t,e,n,r){let s=Math.min(t.length,e.length),i=0;for(;i0&&c>0&&t.charCodeAt(l-1)==e.charCodeAt(c-1);)l--,c--;if(r=="end"){let d=Math.max(0,i-Math.min(l,c));n-=l+d-i}if(l=l?i-n:0;i-=d,c=i+(c-l),l=i}else if(c=c?i-n:0;i-=d,l=i+(l-c),c=i}return{from:i,toA:l,toB:c}}function ZV(t){let e=[];if(t.root.activeElement!=t.contentDOM)return e;let{anchorNode:n,anchorOffset:r,focusNode:s,focusOffset:i}=t.observer.selectionRange;return n&&(e.push(new bj(n,r)),(s!=n||i!=r)&&e.push(new bj(s,i))),e}function JV(t,e){if(t.length==0)return null;let n=t[0].pos,r=t.length==2?t[1].pos:n;return n>-1&&r>-1?Ce.single(n+e,r+e):null}class eW{setSelectionOrigin(e){this.lastSelectionOrigin=e,this.lastSelectionTime=Date.now()}constructor(e){this.view=e,this.lastKeyCode=0,this.lastKeyTime=0,this.lastTouchTime=0,this.lastFocusTime=0,this.lastScrollTop=0,this.lastScrollLeft=0,this.pendingIOSKey=void 0,this.tabFocusMode=-1,this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastContextMenu=0,this.scrollHandlers=[],this.handlers=Object.create(null),this.composing=-1,this.compositionFirstChange=null,this.compositionEndedAt=0,this.compositionPendingKey=!1,this.compositionPendingChange=!1,this.insertingText="",this.insertingTextAt=0,this.mouseSelection=null,this.draggedContent=null,this.handleEvent=this.handleEvent.bind(this),this.notifiedFocused=e.hasFocus,Fe.safari&&e.contentDOM.addEventListener("input",()=>null),Fe.gecko&&gW(e.contentDOM.ownerDocument)}handleEvent(e){!oW(this.view,e)||this.ignoreDuringComposition(e)||e.type=="keydown"&&this.keydown(e)||(this.view.updateState!=0?Promise.resolve().then(()=>this.runHandlers(e.type,e)):this.runHandlers(e.type,e))}runHandlers(e,n){let r=this.handlers[e];if(r){for(let s of r.observers)s(this.view,n);for(let s of r.handlers){if(n.defaultPrevented)break;if(s(this.view,n)){n.preventDefault();break}}}}ensureHandlers(e){let n=tW(e),r=this.handlers,s=this.view.contentDOM;for(let i in n)if(i!="scroll"){let l=!n[i].handlers.length,c=r[i];c&&l!=!c.handlers.length&&(s.removeEventListener(i,this.handleEvent),c=null),c||s.addEventListener(i,this.handleEvent,{passive:l})}for(let i in r)i!="scroll"&&!n[i]&&s.removeEventListener(i,this.handleEvent);this.handlers=n}keydown(e){if(this.lastKeyCode=e.keyCode,this.lastKeyTime=Date.now(),e.keyCode==9&&this.tabFocusMode>-1&&(!this.tabFocusMode||Date.now()<=this.tabFocusMode))return!0;if(this.tabFocusMode>0&&e.keyCode!=27&&OA.indexOf(e.keyCode)<0&&(this.tabFocusMode=-1),Fe.android&&Fe.chrome&&!e.synthetic&&(e.keyCode==13||e.keyCode==8))return this.view.observer.delayAndroidKey(e.key,e.keyCode),!0;let n;return Fe.ios&&!e.synthetic&&!e.altKey&&!e.metaKey&&((n=kA.find(r=>r.keyCode==e.keyCode))&&!e.ctrlKey||nW.indexOf(e.key)>-1&&e.ctrlKey&&!e.shiftKey)?(this.pendingIOSKey=n||e,setTimeout(()=>this.flushIOSKey(),250),!0):(e.keyCode!=229&&this.view.observer.forceFlush(),!1)}flushIOSKey(e){let n=this.pendingIOSKey;return!n||n.key=="Enter"&&e&&e.from0?!0:Fe.safari&&!Fe.ios&&this.compositionPendingKey&&Date.now()-this.compositionEndedAt<100?(this.compositionPendingKey=!1,!0):!1}startMouseSelection(e){this.mouseSelection&&this.mouseSelection.destroy(),this.mouseSelection=e}update(e){this.view.observer.update(e),this.mouseSelection&&this.mouseSelection.update(e),this.draggedContent&&e.docChanged&&(this.draggedContent=this.draggedContent.map(e.changes)),e.transactions.length&&(this.lastKeyCode=this.lastSelectionTime=0)}destroy(){this.mouseSelection&&this.mouseSelection.destroy()}}function wj(t,e){return(n,r)=>{try{return e.call(t,r,n)}catch(s){Es(n.state,s)}}}function tW(t){let e=Object.create(null);function n(r){return e[r]||(e[r]={observers:[],handlers:[]})}for(let r of t){let s=r.spec,i=s&&s.plugin.domEventHandlers,l=s&&s.plugin.domEventObservers;if(i)for(let c in i){let d=i[c];d&&n(c).handlers.push(wj(r.value,d))}if(l)for(let c in l){let d=l[c];d&&n(c).observers.push(wj(r.value,d))}}for(let r in $i)n(r).handlers.push($i[r]);for(let r in Ci)n(r).observers.push(Ci[r]);return e}const kA=[{key:"Backspace",keyCode:8,inputType:"deleteContentBackward"},{key:"Enter",keyCode:13,inputType:"insertParagraph"},{key:"Enter",keyCode:13,inputType:"insertLineBreak"},{key:"Delete",keyCode:46,inputType:"deleteContentForward"}],nW="dthko",OA=[16,17,18,20,91,92,224,225],rp=6;function sp(t){return Math.max(0,t)*.7+8}function rW(t,e){return Math.max(Math.abs(t.clientX-e.clientX),Math.abs(t.clientY-e.clientY))}class sW{constructor(e,n,r,s){this.view=e,this.startEvent=n,this.style=r,this.mustSelect=s,this.scrollSpeed={x:0,y:0},this.scrolling=-1,this.lastEvent=n,this.scrollParents=hV(e.contentDOM),this.atoms=e.state.facet(l0).map(l=>l(e));let i=e.contentDOM.ownerDocument;i.addEventListener("mousemove",this.move=this.move.bind(this)),i.addEventListener("mouseup",this.up=this.up.bind(this)),this.extend=n.shiftKey,this.multiple=e.state.facet(Vt.allowMultipleSelections)&&iW(e,n),this.dragging=lW(e,n)&&CA(n)==1?null:!1}start(e){this.dragging===!1&&this.select(e)}move(e){if(e.buttons==0)return this.destroy();if(this.dragging||this.dragging==null&&rW(this.startEvent,e)<10)return;this.select(this.lastEvent=e);let n=0,r=0,s=0,i=0,l=this.view.win.innerWidth,c=this.view.win.innerHeight;this.scrollParents.x&&({left:s,right:l}=this.scrollParents.x.getBoundingClientRect()),this.scrollParents.y&&({top:i,bottom:c}=this.scrollParents.y.getBoundingClientRect());let d=Tw(this.view);e.clientX-d.left<=s+rp?n=-sp(s-e.clientX):e.clientX+d.right>=l-rp&&(n=sp(e.clientX-l)),e.clientY-d.top<=i+rp?r=-sp(i-e.clientY):e.clientY+d.bottom>=c-rp&&(r=sp(e.clientY-c)),this.setScrollSpeed(n,r)}up(e){this.dragging==null&&this.select(this.lastEvent),this.dragging||e.preventDefault(),this.destroy()}destroy(){this.setScrollSpeed(0,0);let e=this.view.contentDOM.ownerDocument;e.removeEventListener("mousemove",this.move),e.removeEventListener("mouseup",this.up),this.view.inputState.mouseSelection=this.view.inputState.draggedContent=null}setScrollSpeed(e,n){this.scrollSpeed={x:e,y:n},e||n?this.scrolling<0&&(this.scrolling=setInterval(()=>this.scroll(),50)):this.scrolling>-1&&(clearInterval(this.scrolling),this.scrolling=-1)}scroll(){let{x:e,y:n}=this.scrollSpeed;e&&this.scrollParents.x&&(this.scrollParents.x.scrollLeft+=e,e=0),n&&this.scrollParents.y&&(this.scrollParents.y.scrollTop+=n,n=0),(e||n)&&this.view.win.scrollBy(e,n),this.dragging===!1&&this.select(this.lastEvent)}select(e){let{view:n}=this,r=bA(this.atoms,this.style.get(e,this.extend,this.multiple));(this.mustSelect||!r.eq(n.state.selection,this.dragging===!1))&&this.view.dispatch({selection:r,userEvent:"select.pointer"}),this.mustSelect=!1}update(e){e.transactions.some(n=>n.isUserEvent("input.type"))?this.destroy():this.style.update(e)&&setTimeout(()=>this.select(this.lastEvent),20)}}function iW(t,e){let n=t.state.facet(rA);return n.length?n[0](e):Fe.mac?e.metaKey:e.ctrlKey}function aW(t,e){let n=t.state.facet(sA);return n.length?n[0](e):Fe.mac?!e.altKey:!e.ctrlKey}function lW(t,e){let{main:n}=t.state.selection;if(n.empty)return!1;let r=vf(t.root);if(!r||r.rangeCount==0)return!0;let s=r.getRangeAt(0).getClientRects();for(let i=0;i=e.clientX&&l.top<=e.clientY&&l.bottom>=e.clientY)return!0}return!1}function oW(t,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let n=e.target,r;n!=t.contentDOM;n=n.parentNode)if(!n||n.nodeType==11||(r=jn.get(n))&&r.ignoreEvent(e))return!1;return!0}const $i=Object.create(null),Ci=Object.create(null),jA=Fe.ie&&Fe.ie_version<15||Fe.ios&&Fe.webkit_version<604;function cW(t){let e=t.dom.parentNode;if(!e)return;let n=e.appendChild(document.createElement("textarea"));n.style.cssText="position: fixed; left: -10000px; top: 10px",n.focus(),setTimeout(()=>{t.focus(),n.remove(),NA(t,n.value)},50)}function kx(t,e,n){for(let r of t.facet(e))n=r(n,t);return n}function NA(t,e){e=kx(t.state,jw,e);let{state:n}=t,r,s=1,i=n.toText(e),l=i.lines==n.selection.ranges.length;if(Q2!=null&&n.selection.ranges.every(d=>d.empty)&&Q2==i.toString()){let d=-1;r=n.changeByRange(h=>{let m=n.doc.lineAt(h.from);if(m.from==d)return{range:h};d=m.from;let p=n.toText((l?i.line(s++).text:e)+n.lineBreak);return{changes:{from:m.from,insert:p},range:Ce.cursor(h.from+p.length)}})}else l?r=n.changeByRange(d=>{let h=i.line(s++);return{changes:{from:d.from,to:d.to,insert:h.text},range:Ce.cursor(d.from+h.length)}}):r=n.replaceSelection(i);t.dispatch(r,{userEvent:"input.paste",scrollIntoView:!0})}Ci.scroll=t=>{t.inputState.lastScrollTop=t.scrollDOM.scrollTop,t.inputState.lastScrollLeft=t.scrollDOM.scrollLeft};$i.keydown=(t,e)=>(t.inputState.setSelectionOrigin("select"),e.keyCode==27&&t.inputState.tabFocusMode!=0&&(t.inputState.tabFocusMode=Date.now()+2e3),!1);Ci.touchstart=(t,e)=>{t.inputState.lastTouchTime=Date.now(),t.inputState.setSelectionOrigin("select.pointer")};Ci.touchmove=t=>{t.inputState.setSelectionOrigin("select.pointer")};$i.mousedown=(t,e)=>{if(t.observer.flush(),t.inputState.lastTouchTime>Date.now()-2e3)return!1;let n=null;for(let r of t.state.facet(iA))if(n=r(t,e),n)break;if(!n&&e.button==0&&(n=hW(t,e)),n){let r=!t.hasFocus;t.inputState.startMouseSelection(new sW(t,e,n,r)),r&&t.observer.ignore(()=>{qM(t.contentDOM);let i=t.root.activeElement;i&&!i.contains(t.contentDOM)&&i.blur()});let s=t.inputState.mouseSelection;if(s)return s.start(e),s.dragging===!1}else t.inputState.setSelectionOrigin("select.pointer");return!1};function Sj(t,e,n,r){if(r==1)return Ce.cursor(e,n);if(r==2)return IV(t.state,e,n);{let s=pr.find(t.docView,e),i=t.state.doc.lineAt(s?s.posAtEnd:e),l=s?s.posAtStart:i.from,c=s?s.posAtEnd:i.to;return ce>=n.top&&e<=n.bottom&&t>=n.left&&t<=n.right;function uW(t,e,n,r){let s=pr.find(t.docView,e);if(!s)return 1;let i=e-s.posAtStart;if(i==0)return 1;if(i==s.length)return-1;let l=s.coordsAt(i,-1);if(l&&kj(n,r,l))return-1;let c=s.coordsAt(i,1);return c&&kj(n,r,c)?1:l&&l.bottom>=r?-1:1}function Oj(t,e){let n=t.posAtCoords({x:e.clientX,y:e.clientY},!1);return{pos:n,bias:uW(t,n,e.clientX,e.clientY)}}const dW=Fe.ie&&Fe.ie_version<=11;let jj=null,Nj=0,Cj=0;function CA(t){if(!dW)return t.detail;let e=jj,n=Cj;return jj=t,Cj=Date.now(),Nj=!e||n>Date.now()-400&&Math.abs(e.clientX-t.clientX)<2&&Math.abs(e.clientY-t.clientY)<2?(Nj+1)%3:1}function hW(t,e){let n=Oj(t,e),r=CA(e),s=t.state.selection;return{update(i){i.docChanged&&(n.pos=i.changes.mapPos(n.pos),s=s.map(i.changes))},get(i,l,c){let d=Oj(t,i),h,m=Sj(t,d.pos,d.bias,r);if(n.pos!=d.pos&&!l){let p=Sj(t,n.pos,n.bias,r),x=Math.min(p.from,m.from),v=Math.max(p.to,m.to);m=x1&&(h=fW(s,d.pos))?h:c?s.addRange(m):Ce.create([m])}}}function fW(t,e){for(let n=0;n=e)return Ce.create(t.ranges.slice(0,n).concat(t.ranges.slice(n+1)),t.mainIndex==n?0:t.mainIndex-(t.mainIndex>n?1:0))}return null}$i.dragstart=(t,e)=>{let{selection:{main:n}}=t.state;if(e.target.draggable){let s=t.docView.nearest(e.target);if(s&&s.isWidget){let i=s.posAtStart,l=i+s.length;(i>=n.to||l<=n.from)&&(n=Ce.range(i,l))}}let{inputState:r}=t;return r.mouseSelection&&(r.mouseSelection.dragging=!0),r.draggedContent=n,e.dataTransfer&&(e.dataTransfer.setData("Text",kx(t.state,Nw,t.state.sliceDoc(n.from,n.to))),e.dataTransfer.effectAllowed="copyMove"),!1};$i.dragend=t=>(t.inputState.draggedContent=null,!1);function Tj(t,e,n,r){if(n=kx(t.state,jw,n),!n)return;let s=t.posAtCoords({x:e.clientX,y:e.clientY},!1),{draggedContent:i}=t.inputState,l=r&&i&&aW(t,e)?{from:i.from,to:i.to}:null,c={from:s,insert:n},d=t.state.changes(l?[l,c]:c);t.focus(),t.dispatch({changes:d,selection:{anchor:d.mapPos(s,-1),head:d.mapPos(s,1)},userEvent:l?"move.drop":"input.drop"}),t.inputState.draggedContent=null}$i.drop=(t,e)=>{if(!e.dataTransfer)return!1;if(t.state.readOnly)return!0;let n=e.dataTransfer.files;if(n&&n.length){let r=Array(n.length),s=0,i=()=>{++s==n.length&&Tj(t,e,r.filter(l=>l!=null).join(t.state.lineBreak),!1)};for(let l=0;l{/[\x00-\x08\x0e-\x1f]{2}/.test(c.result)||(r[l]=c.result),i()},c.readAsText(n[l])}return!0}else{let r=e.dataTransfer.getData("Text");if(r)return Tj(t,e,r,!0),!0}return!1};$i.paste=(t,e)=>{if(t.state.readOnly)return!0;t.observer.flush();let n=jA?null:e.clipboardData;return n?(NA(t,n.getData("text/plain")||n.getData("text/uri-list")),!0):(cW(t),!1)};function mW(t,e){let n=t.dom.parentNode;if(!n)return;let r=n.appendChild(document.createElement("textarea"));r.style.cssText="position: fixed; left: -10000px; top: 10px",r.value=e,r.focus(),r.selectionEnd=e.length,r.selectionStart=0,setTimeout(()=>{r.remove(),t.focus()},50)}function pW(t){let e=[],n=[],r=!1;for(let s of t.selection.ranges)s.empty||(e.push(t.sliceDoc(s.from,s.to)),n.push(s));if(!e.length){let s=-1;for(let{from:i}of t.selection.ranges){let l=t.doc.lineAt(i);l.number>s&&(e.push(l.text),n.push({from:l.from,to:Math.min(t.doc.length,l.to+1)})),s=l.number}r=!0}return{text:kx(t,Nw,e.join(t.lineBreak)),ranges:n,linewise:r}}let Q2=null;$i.copy=$i.cut=(t,e)=>{let{text:n,ranges:r,linewise:s}=pW(t.state);if(!n&&!s)return!1;Q2=s?n:null,e.type=="cut"&&!t.state.readOnly&&t.dispatch({changes:r,scrollIntoView:!0,userEvent:"delete.cut"});let i=jA?null:e.clipboardData;return i?(i.clearData(),i.setData("text/plain",n),!0):(mW(t,n),!1)};const TA=Sa.define();function MA(t,e){let n=[];for(let r of t.facet(oA)){let s=r(t,e);s&&n.push(s)}return n.length?t.update({effects:n,annotations:TA.of(!0)}):null}function AA(t){setTimeout(()=>{let e=t.hasFocus;if(e!=t.inputState.notifiedFocused){let n=MA(t.state,e);n?t.dispatch(n):t.update([])}},10)}Ci.focus=t=>{t.inputState.lastFocusTime=Date.now(),!t.scrollDOM.scrollTop&&(t.inputState.lastScrollTop||t.inputState.lastScrollLeft)&&(t.scrollDOM.scrollTop=t.inputState.lastScrollTop,t.scrollDOM.scrollLeft=t.inputState.lastScrollLeft),AA(t)};Ci.blur=t=>{t.observer.clearSelectionRange(),AA(t)};Ci.compositionstart=Ci.compositionupdate=t=>{t.observer.editContext||(t.inputState.compositionFirstChange==null&&(t.inputState.compositionFirstChange=!0),t.inputState.composing<0&&(t.inputState.composing=0))};Ci.compositionend=t=>{t.observer.editContext||(t.inputState.composing=-1,t.inputState.compositionEndedAt=Date.now(),t.inputState.compositionPendingKey=!0,t.inputState.compositionPendingChange=t.observer.pendingRecords().length>0,t.inputState.compositionFirstChange=null,Fe.chrome&&Fe.android?t.observer.flushSoon():t.inputState.compositionPendingChange?Promise.resolve().then(()=>t.observer.flush()):setTimeout(()=>{t.inputState.composing<0&&t.docView.hasComposition&&t.update([])},50))};Ci.contextmenu=t=>{t.inputState.lastContextMenu=Date.now()};$i.beforeinput=(t,e)=>{var n,r;if((e.inputType=="insertText"||e.inputType=="insertCompositionText")&&(t.inputState.insertingText=e.data,t.inputState.insertingTextAt=Date.now()),e.inputType=="insertReplacementText"&&t.observer.editContext){let i=(n=e.dataTransfer)===null||n===void 0?void 0:n.getData("text/plain"),l=e.getTargetRanges();if(i&&l.length){let c=l[0],d=t.posAtDOM(c.startContainer,c.startOffset),h=t.posAtDOM(c.endContainer,c.endOffset);return Mw(t,{from:d,to:h,insert:t.state.toText(i)},null),!0}}let s;if(Fe.chrome&&Fe.android&&(s=kA.find(i=>i.inputType==e.inputType))&&(t.observer.delayAndroidKey(s.key,s.keyCode),s.key=="Backspace"||s.key=="Delete")){let i=((r=window.visualViewport)===null||r===void 0?void 0:r.height)||0;setTimeout(()=>{var l;(((l=window.visualViewport)===null||l===void 0?void 0:l.height)||0)>i+10&&t.hasFocus&&(t.contentDOM.blur(),t.focus())},100)}return Fe.ios&&e.inputType=="deleteContentForward"&&t.observer.flushSoon(),Fe.safari&&e.inputType=="insertText"&&t.inputState.composing>=0&&setTimeout(()=>Ci.compositionend(t,e),20),!1};const Mj=new Set;function gW(t){Mj.has(t)||(Mj.add(t),t.addEventListener("copy",()=>{}),t.addEventListener("cut",()=>{}))}const Aj=["pre-wrap","normal","pre-line","break-spaces"];let fd=!1;function Ej(){fd=!1}class xW{constructor(e){this.lineWrapping=e,this.doc=Wt.empty,this.heightSamples={},this.lineHeight=14,this.charWidth=7,this.textHeight=14,this.lineLength=30}heightForGap(e,n){let r=this.doc.lineAt(n).number-this.doc.lineAt(e).number+1;return this.lineWrapping&&(r+=Math.max(0,Math.ceil((n-e-r*this.lineLength*.5)/this.lineLength))),this.lineHeight*r}heightForLine(e){return this.lineWrapping?(1+Math.max(0,Math.ceil((e-this.lineLength)/Math.max(1,this.lineLength-5))))*this.lineHeight:this.lineHeight}setDoc(e){return this.doc=e,this}mustRefreshForWrapping(e){return Aj.indexOf(e)>-1!=this.lineWrapping}mustRefreshForHeights(e){let n=!1;for(let r=0;r-1,d=Math.round(n)!=Math.round(this.lineHeight)||this.lineWrapping!=c;if(this.lineWrapping=c,this.lineHeight=n,this.charWidth=r,this.textHeight=s,this.lineLength=i,d){this.heightSamples={};for(let h=0;h0}set outdated(e){this.flags=(e?2:0)|this.flags&-3}setHeight(e){this.height!=e&&(Math.abs(this.height-e)>Jp&&(fd=!0),this.height=e)}replace(e,n,r){return ms.of(r)}decomposeLeft(e,n){n.push(this)}decomposeRight(e,n){n.push(this)}applyChanges(e,n,r,s){let i=this,l=r.doc;for(let c=s.length-1;c>=0;c--){let{fromA:d,toA:h,fromB:m,toB:p}=s[c],x=i.lineAt(d,Qn.ByPosNoHeight,r.setDoc(n),0,0),v=x.to>=h?x:i.lineAt(h,Qn.ByPosNoHeight,r,0,0);for(p+=v.to-h,h=v.to;c>0&&x.from<=s[c-1].toA;)d=s[c-1].fromA,m=s[c-1].fromB,c--,di*2){let c=e[n-1];c.break?e.splice(--n,1,c.left,null,c.right):e.splice(--n,1,c.left,c.right),r+=1+c.break,s-=c.size}else if(i>s*2){let c=e[r];c.break?e.splice(r,1,c.left,null,c.right):e.splice(r,1,c.left,c.right),r+=2+c.break,i-=c.size}else break;else if(s=i&&l(this.blockAt(0,r,s,i))}updateHeight(e,n=0,r=!1,s){return s&&s.from<=n&&s.more&&this.setHeight(s.heights[s.index++]),this.outdated=!1,this}toString(){return`block(${this.length})`}}class Js extends EA{constructor(e,n){super(e,n,null),this.collapsed=0,this.widgetHeight=0,this.breaks=0}blockAt(e,n,r,s){return new la(s,this.length,r,this.height,this.breaks)}replace(e,n,r){let s=r[0];return r.length==1&&(s instanceof Js||s instanceof $r&&s.flags&4)&&Math.abs(this.length-s.length)<10?(s instanceof $r?s=new Js(s.length,this.height):s.height=this.height,this.outdated||(s.outdated=!1),s):ms.of(r)}updateHeight(e,n=0,r=!1,s){return s&&s.from<=n&&s.more?this.setHeight(s.heights[s.index++]):(r||this.outdated)&&this.setHeight(Math.max(this.widgetHeight,e.heightForLine(this.length-this.collapsed))+this.breaks*e.lineHeight),this.outdated=!1,this}toString(){return`line(${this.length}${this.collapsed?-this.collapsed:""}${this.widgetHeight?":"+this.widgetHeight:""})`}}class $r extends ms{constructor(e){super(e,0)}heightMetrics(e,n){let r=e.doc.lineAt(n).number,s=e.doc.lineAt(n+this.length).number,i=s-r+1,l,c=0;if(e.lineWrapping){let d=Math.min(this.height,e.lineHeight*i);l=d/i,this.length>i+1&&(c=(this.height-d)/(this.length-i-1))}else l=this.height/i;return{firstLine:r,lastLine:s,perLine:l,perChar:c}}blockAt(e,n,r,s){let{firstLine:i,lastLine:l,perLine:c,perChar:d}=this.heightMetrics(n,s);if(n.lineWrapping){let h=s+(e0){let i=r[r.length-1];i instanceof $r?r[r.length-1]=new $r(i.length+s):r.push(null,new $r(s-1))}if(e>0){let i=r[0];i instanceof $r?r[0]=new $r(e+i.length):r.unshift(new $r(e-1),null)}return ms.of(r)}decomposeLeft(e,n){n.push(new $r(e-1),null)}decomposeRight(e,n){n.push(null,new $r(this.length-e-1))}updateHeight(e,n=0,r=!1,s){let i=n+this.length;if(s&&s.from<=n+this.length&&s.more){let l=[],c=Math.max(n,s.from),d=-1;for(s.from>n&&l.push(new $r(s.from-n-1).updateHeight(e,n));c<=i&&s.more;){let m=e.doc.lineAt(c).length;l.length&&l.push(null);let p=s.heights[s.index++];d==-1?d=p:Math.abs(p-d)>=Jp&&(d=-2);let x=new Js(m,p);x.outdated=!1,l.push(x),c+=m+1}c<=i&&l.push(null,new $r(i-c).updateHeight(e,c));let h=ms.of(l);return(d<0||Math.abs(h.height-this.height)>=Jp||Math.abs(d-this.heightMetrics(e,n).perLine)>=Jp)&&(fd=!0),Cg(this,h)}else(r||this.outdated)&&(this.setHeight(e.heightForGap(n,n+this.length)),this.outdated=!1);return this}toString(){return`gap(${this.length})`}}class yW extends ms{constructor(e,n,r){super(e.length+n+r.length,e.height+r.height,n|(e.outdated||r.outdated?2:0)),this.left=e,this.right=r,this.size=e.size+r.size}get break(){return this.flags&1}blockAt(e,n,r,s){let i=r+this.left.height;return ec))return h;let m=n==Qn.ByPosNoHeight?Qn.ByPosNoHeight:Qn.ByPos;return d?h.join(this.right.lineAt(c,m,r,l,c)):this.left.lineAt(c,m,r,s,i).join(h)}forEachLine(e,n,r,s,i,l){let c=s+this.left.height,d=i+this.left.length+this.break;if(this.break)e=d&&this.right.forEachLine(e,n,r,c,d,l);else{let h=this.lineAt(d,Qn.ByPos,r,s,i);e=e&&h.from<=n&&l(h),n>h.to&&this.right.forEachLine(h.to+1,n,r,c,d,l)}}replace(e,n,r){let s=this.left.length+this.break;if(nthis.left.length)return this.balanced(this.left,this.right.replace(e-s,n-s,r));let i=[];e>0&&this.decomposeLeft(e,i);let l=i.length;for(let c of r)i.push(c);if(e>0&&_j(i,l-1),n=r&&n.push(null)),e>r&&this.right.decomposeLeft(e-r,n)}decomposeRight(e,n){let r=this.left.length,s=r+this.break;if(e>=s)return this.right.decomposeRight(e-s,n);e2*n.size||n.size>2*e.size?ms.of(this.break?[e,null,n]:[e,n]):(this.left=Cg(this.left,e),this.right=Cg(this.right,n),this.setHeight(e.height+n.height),this.outdated=e.outdated||n.outdated,this.size=e.size+n.size,this.length=e.length+this.break+n.length,this)}updateHeight(e,n=0,r=!1,s){let{left:i,right:l}=this,c=n+i.length+this.break,d=null;return s&&s.from<=n+i.length&&s.more?d=i=i.updateHeight(e,n,r,s):i.updateHeight(e,n,r),s&&s.from<=c+l.length&&s.more?d=l=l.updateHeight(e,c,r,s):l.updateHeight(e,c,r),d?this.balanced(i,l):(this.height=this.left.height+this.right.height,this.outdated=!1,this)}toString(){return this.left+(this.break?" ":"-")+this.right}}function _j(t,e){let n,r;t[e]==null&&(n=t[e-1])instanceof $r&&(r=t[e+1])instanceof $r&&t.splice(e-1,3,new $r(n.length+1+r.length))}const bW=5;class Aw{constructor(e,n){this.pos=e,this.oracle=n,this.nodes=[],this.lineStart=-1,this.lineEnd=-1,this.covering=null,this.writtenTo=e}get isCovered(){return this.covering&&this.nodes[this.nodes.length-1]==this.covering}span(e,n){if(this.lineStart>-1){let r=Math.min(n,this.lineEnd),s=this.nodes[this.nodes.length-1];s instanceof Js?s.length+=r-this.pos:(r>this.pos||!this.isCovered)&&this.nodes.push(new Js(r-this.pos,-1)),this.writtenTo=r,n>r&&(this.nodes.push(null),this.writtenTo++,this.lineStart=-1)}this.pos=n}point(e,n,r){if(e=bW)&&this.addLineDeco(s,i,l)}else n>e&&this.span(e,n);this.lineEnd>-1&&this.lineEnd-1)return;let{from:e,to:n}=this.oracle.doc.lineAt(this.pos);this.lineStart=e,this.lineEnd=n,this.writtenToe&&this.nodes.push(new Js(this.pos-e,-1)),this.writtenTo=this.pos}blankContent(e,n){let r=new $r(n-e);return this.oracle.doc.lineAt(e).to==n&&(r.flags|=4),r}ensureLine(){this.enterLine();let e=this.nodes.length?this.nodes[this.nodes.length-1]:null;if(e instanceof Js)return e;let n=new Js(0,-1);return this.nodes.push(n),n}addBlock(e){this.enterLine();let n=e.deco;n&&n.startSide>0&&!this.isCovered&&this.ensureLine(),this.nodes.push(e),this.writtenTo=this.pos=this.pos+e.length,n&&n.endSide>0&&(this.covering=e)}addLineDeco(e,n,r){let s=this.ensureLine();s.length+=r,s.collapsed+=r,s.widgetHeight=Math.max(s.widgetHeight,e),s.breaks+=n,this.writtenTo=this.pos=this.pos+r}finish(e){let n=this.nodes.length==0?null:this.nodes[this.nodes.length-1];this.lineStart>-1&&!(n instanceof Js)&&!this.isCovered?this.nodes.push(new Js(0,-1)):(this.writtenTom.clientHeight||m.scrollWidth>m.clientWidth)&&p.overflow!="visible"){let x=m.getBoundingClientRect();i=Math.max(i,x.left),l=Math.min(l,x.right),c=Math.max(c,x.top),d=Math.min(h==t.parentNode?s.innerHeight:d,x.bottom)}h=p.position=="absolute"||p.position=="fixed"?m.offsetParent:m.parentNode}else if(h.nodeType==11)h=h.host;else break;return{left:i-n.left,right:Math.max(i,l)-n.left,top:c-(n.top+e),bottom:Math.max(c,d)-(n.top+e)}}function OW(t){let e=t.getBoundingClientRect(),n=t.ownerDocument.defaultView||window;return e.left0&&e.top0}function jW(t,e){let n=t.getBoundingClientRect();return{left:0,right:n.right-n.left,top:e,bottom:n.bottom-(n.top+e)}}class Ry{constructor(e,n,r,s){this.from=e,this.to=n,this.size=r,this.displaySize=s}static same(e,n){if(e.length!=n.length)return!1;for(let r=0;rtypeof r!="function"&&r.class=="cm-lineWrapping");this.heightOracle=new xW(n),this.stateDeco=e.facet(yf).filter(r=>typeof r!="function"),this.heightMap=ms.empty().applyChanges(this.stateDeco,Wt.empty,this.heightOracle.setDoc(e.doc),[new ji(0,0,0,e.doc.length)]);for(let r=0;r<2&&(this.viewport=this.getViewport(0,null),!!this.updateForViewport());r++);this.updateViewportLines(),this.lineGaps=this.ensureLineGaps([]),this.lineGapDeco=Je.set(this.lineGaps.map(r=>r.draw(this,!1))),this.computeVisibleRanges()}updateForViewport(){let e=[this.viewport],{main:n}=this.state.selection;for(let r=0;r<=1;r++){let s=r?n.head:n.anchor;if(!e.some(({from:i,to:l})=>s>=i&&s<=l)){let{from:i,to:l}=this.lineBlockAt(s);e.push(new ip(i,l))}}return this.viewports=e.sort((r,s)=>r.from-s.from),this.updateScaler()}updateScaler(){let e=this.scaler;return this.scaler=this.heightMap.height<=7e6?Rj:new Ew(this.heightOracle,this.heightMap,this.viewports),e.eq(this.scaler)?0:2}updateViewportLines(){this.viewportLines=[],this.heightMap.forEachLine(this.viewport.from,this.viewport.to,this.heightOracle.setDoc(this.state.doc),0,0,e=>{this.viewportLines.push(Hh(e,this.scaler))})}update(e,n=null){this.state=e.state;let r=this.stateDeco;this.stateDeco=this.state.facet(yf).filter(m=>typeof m!="function");let s=e.changedRanges,i=ji.extendWithRanges(s,wW(r,this.stateDeco,e?e.changes:kr.empty(this.state.doc.length))),l=this.heightMap.height,c=this.scrolledToBottom?null:this.scrollAnchorAt(this.scrollTop);Ej(),this.heightMap=this.heightMap.applyChanges(this.stateDeco,e.startState.doc,this.heightOracle.setDoc(this.state.doc),i),(this.heightMap.height!=l||fd)&&(e.flags|=2),c?(this.scrollAnchorPos=e.changes.mapPos(c.from,-1),this.scrollAnchorHeight=c.top):(this.scrollAnchorPos=-1,this.scrollAnchorHeight=l);let d=i.length?this.mapViewport(this.viewport,e.changes):this.viewport;(n&&(n.range.headd.to)||!this.viewportIsAppropriate(d))&&(d=this.getViewport(0,n));let h=d.from!=this.viewport.from||d.to!=this.viewport.to;this.viewport=d,e.flags|=this.updateForViewport(),(h||!e.changes.empty||e.flags&2)&&this.updateViewportLines(),(this.lineGaps.length||this.viewport.to-this.viewport.from>4e3)&&this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps,e.changes))),e.flags|=this.computeVisibleRanges(e.changes),n&&(this.scrollTarget=n),!this.mustEnforceCursorAssoc&&e.selectionSet&&e.view.lineWrapping&&e.state.selection.main.empty&&e.state.selection.main.assoc&&!e.state.facet(uA)&&(this.mustEnforceCursorAssoc=!0)}measure(e){let n=e.contentDOM,r=window.getComputedStyle(n),s=this.heightOracle,i=r.whiteSpace;this.defaultTextDirection=r.direction=="rtl"?Hn.RTL:Hn.LTR;let l=this.heightOracle.mustRefreshForWrapping(i),c=n.getBoundingClientRect(),d=l||this.mustMeasureContent||this.contentDOMHeight!=c.height;this.contentDOMHeight=c.height,this.mustMeasureContent=!1;let h=0,m=0;if(c.width&&c.height){let{scaleX:_,scaleY:D}=IM(n,c);(_>.005&&Math.abs(this.scaleX-_)>.005||D>.005&&Math.abs(this.scaleY-D)>.005)&&(this.scaleX=_,this.scaleY=D,h|=16,l=d=!0)}let p=(parseInt(r.paddingTop)||0)*this.scaleY,x=(parseInt(r.paddingBottom)||0)*this.scaleY;(this.paddingTop!=p||this.paddingBottom!=x)&&(this.paddingTop=p,this.paddingBottom=x,h|=18),this.editorWidth!=e.scrollDOM.clientWidth&&(s.lineWrapping&&(d=!0),this.editorWidth=e.scrollDOM.clientWidth,h|=16);let v=e.scrollDOM.scrollTop*this.scaleY;this.scrollTop!=v&&(this.scrollAnchorHeight=-1,this.scrollTop=v),this.scrolledToBottom=QM(e.scrollDOM);let b=(this.printing?jW:kW)(n,this.paddingTop),k=b.top-this.pixelViewport.top,O=b.bottom-this.pixelViewport.bottom;this.pixelViewport=b;let j=this.pixelViewport.bottom>this.pixelViewport.top&&this.pixelViewport.right>this.pixelViewport.left;if(j!=this.inView&&(this.inView=j,j&&(d=!0)),!this.inView&&!this.scrollTarget&&!OW(e.dom))return 0;let T=c.width;if((this.contentDOMWidth!=T||this.editorHeight!=e.scrollDOM.clientHeight)&&(this.contentDOMWidth=c.width,this.editorHeight=e.scrollDOM.clientHeight,h|=16),d){let _=e.docView.measureVisibleLineHeights(this.viewport);if(s.mustRefreshForHeights(_)&&(l=!0),l||s.lineWrapping&&Math.abs(T-this.contentDOMWidth)>s.charWidth){let{lineHeight:D,charWidth:E,textHeight:z}=e.docView.measureTextSize();l=D>0&&s.refresh(i,D,E,z,Math.max(5,T/E),_),l&&(e.docView.minWidth=0,h|=16)}k>0&&O>0?m=Math.max(k,O):k<0&&O<0&&(m=Math.min(k,O)),Ej();for(let D of this.viewports){let E=D.from==this.viewport.from?_:e.docView.measureVisibleLineHeights(D);this.heightMap=(l?ms.empty().applyChanges(this.stateDeco,Wt.empty,this.heightOracle,[new ji(0,0,0,e.state.doc.length)]):this.heightMap).updateHeight(s,0,l,new vW(D.from,E))}fd&&(h|=2)}let M=!this.viewportIsAppropriate(this.viewport,m)||this.scrollTarget&&(this.scrollTarget.range.headthis.viewport.to);return M&&(h&2&&(h|=this.updateScaler()),this.viewport=this.getViewport(m,this.scrollTarget),h|=this.updateForViewport()),(h&2||M)&&this.updateViewportLines(),(this.lineGaps.length||this.viewport.to-this.viewport.from>4e3)&&this.updateLineGaps(this.ensureLineGaps(l?[]:this.lineGaps,e)),h|=this.computeVisibleRanges(),this.mustEnforceCursorAssoc&&(this.mustEnforceCursorAssoc=!1,e.docView.enforceCursorAssoc()),h}get visibleTop(){return this.scaler.fromDOM(this.pixelViewport.top)}get visibleBottom(){return this.scaler.fromDOM(this.pixelViewport.bottom)}getViewport(e,n){let r=.5-Math.max(-.5,Math.min(.5,e/1e3/2)),s=this.heightMap,i=this.heightOracle,{visibleTop:l,visibleBottom:c}=this,d=new ip(s.lineAt(l-r*1e3,Qn.ByHeight,i,0,0).from,s.lineAt(c+(1-r)*1e3,Qn.ByHeight,i,0,0).to);if(n){let{head:h}=n.range;if(hd.to){let m=Math.min(this.editorHeight,this.pixelViewport.bottom-this.pixelViewport.top),p=s.lineAt(h,Qn.ByPos,i,0,0),x;n.y=="center"?x=(p.top+p.bottom)/2-m/2:n.y=="start"||n.y=="nearest"&&h=c+Math.max(10,Math.min(r,250)))&&s>l-2*1e3&&i>1,l=s<<1;if(this.defaultTextDirection!=Hn.LTR&&!r)return[];let c=[],d=(m,p,x,v)=>{if(p-mm&&jj.from>=x.from&&j.to<=x.to&&Math.abs(j.from-m)j.fromT));if(!O){if(pM.from<=p&&M.to>=p)){let M=n.moveToLineBoundary(Ce.cursor(p),!1,!0).head;M>m&&(p=M)}let j=this.gapSize(x,m,p,v),T=r||j<2e6?j:2e6;O=new Ry(m,p,j,T)}c.push(O)},h=m=>{if(m.length2e6)for(let E of e)E.from>=m.from&&E.fromm.from&&d(m.from,v,m,p),bn.draw(this,this.heightOracle.lineWrapping))))}computeVisibleRanges(e){let n=this.stateDeco;this.lineGaps.length&&(n=n.concat(this.lineGapDeco));let r=[];Gt.spans(n,this.viewport.from,this.viewport.to,{span(i,l){r.push({from:i,to:l})},point(){}},20);let s=0;if(r.length!=this.visibleRanges.length)s=12;else for(let i=0;i=this.viewport.from&&e<=this.viewport.to&&this.viewportLines.find(n=>n.from<=e&&n.to>=e)||Hh(this.heightMap.lineAt(e,Qn.ByPos,this.heightOracle,0,0),this.scaler)}lineBlockAtHeight(e){return e>=this.viewportLines[0].top&&e<=this.viewportLines[this.viewportLines.length-1].bottom&&this.viewportLines.find(n=>n.top<=e&&n.bottom>=e)||Hh(this.heightMap.lineAt(this.scaler.fromDOM(e),Qn.ByHeight,this.heightOracle,0,0),this.scaler)}scrollAnchorAt(e){let n=this.lineBlockAtHeight(e+8);return n.from>=this.viewport.from||this.viewportLines[0].top-e>200?n:this.viewportLines[0]}elementAtHeight(e){return Hh(this.heightMap.blockAt(this.scaler.fromDOM(e),this.heightOracle,0,0),this.scaler)}get docHeight(){return this.scaler.toDOM(this.heightMap.height)}get contentHeight(){return this.docHeight+this.paddingTop+this.paddingBottom}}let ip=class{constructor(e,n){this.from=e,this.to=n}};function CW(t,e,n){let r=[],s=t,i=0;return Gt.spans(n,t,e,{span(){},point(l,c){l>s&&(r.push({from:s,to:l}),i+=l-s),s=c}},20),s=1)return e[e.length-1].to;let r=Math.floor(t*n);for(let s=0;;s++){let{from:i,to:l}=e[s],c=l-i;if(r<=c)return i+r;r-=c}}function lp(t,e){let n=0;for(let{from:r,to:s}of t.ranges){if(e<=s){n+=e-r;break}n+=s-r}return n/t.total}function TW(t,e){for(let n of t)if(e(n))return n}const Rj={toDOM(t){return t},fromDOM(t){return t},scale:1,eq(t){return t==this}};class Ew{constructor(e,n,r){let s=0,i=0,l=0;this.viewports=r.map(({from:c,to:d})=>{let h=n.lineAt(c,Qn.ByPos,e,0,0).top,m=n.lineAt(d,Qn.ByPos,e,0,0).bottom;return s+=m-h,{from:c,to:d,top:h,bottom:m,domTop:0,domBottom:0}}),this.scale=(7e6-s)/(n.height-s);for(let c of this.viewports)c.domTop=l+(c.top-i)*this.scale,l=c.domBottom=c.domTop+(c.bottom-c.top),i=c.bottom}toDOM(e){for(let n=0,r=0,s=0;;n++){let i=nn.from==e.viewports[r].from&&n.to==e.viewports[r].to):!1}}function Hh(t,e){if(e.scale==1)return t;let n=e.toDOM(t.top),r=e.toDOM(t.bottom);return new la(t.from,t.length,n,r-n,Array.isArray(t._content)?t._content.map(s=>Hh(s,e)):t._content)}const op=He.define({combine:t=>t.join(" ")}),$2=He.define({combine:t=>t.indexOf(!0)>-1}),H2=ho.newName(),_A=ho.newName(),DA=ho.newName(),RA={"&light":"."+_A,"&dark":"."+DA};function U2(t,e,n){return new ho(e,{finish(r){return/&/.test(r)?r.replace(/&\w*/,s=>{if(s=="&")return t;if(!n||!n[s])throw new RangeError(`Unsupported selector: ${s}`);return n[s]}):t+" "+r}})}const MW=U2("."+H2,{"&":{position:"relative !important",boxSizing:"border-box","&.cm-focused":{outline:"1px dotted #212121"},display:"flex !important",flexDirection:"column"},".cm-scroller":{display:"flex !important",alignItems:"flex-start !important",fontFamily:"monospace",lineHeight:1.4,height:"100%",overflowX:"auto",position:"relative",zIndex:0,overflowAnchor:"none"},".cm-content":{margin:0,flexGrow:2,flexShrink:0,display:"block",whiteSpace:"pre",wordWrap:"normal",boxSizing:"border-box",minHeight:"100%",padding:"4px 0",outline:"none","&[contenteditable=true]":{WebkitUserModify:"read-write-plaintext-only"}},".cm-lineWrapping":{whiteSpace_fallback:"pre-wrap",whiteSpace:"break-spaces",wordBreak:"break-word",overflowWrap:"anywhere",flexShrink:1},"&light .cm-content":{caretColor:"black"},"&dark .cm-content":{caretColor:"white"},".cm-line":{display:"block",padding:"0 2px 0 6px"},".cm-layer":{position:"absolute",left:0,top:0,contain:"size style","& > *":{position:"absolute"}},"&light .cm-selectionBackground":{background:"#d9d9d9"},"&dark .cm-selectionBackground":{background:"#222"},"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground":{background:"#d7d4f0"},"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground":{background:"#233"},".cm-cursorLayer":{pointerEvents:"none"},"&.cm-focused > .cm-scroller > .cm-cursorLayer":{animation:"steps(1) cm-blink 1.2s infinite"},"@keyframes cm-blink":{"0%":{},"50%":{opacity:0},"100%":{}},"@keyframes cm-blink2":{"0%":{},"50%":{opacity:0},"100%":{}},".cm-cursor, .cm-dropCursor":{borderLeft:"1.2px solid black",marginLeft:"-0.6px",pointerEvents:"none"},".cm-cursor":{display:"none"},"&dark .cm-cursor":{borderLeftColor:"#ddd"},".cm-dropCursor":{position:"absolute"},"&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor":{display:"block"},".cm-iso":{unicodeBidi:"isolate"},".cm-announced":{position:"fixed",top:"-10000px"},"@media print":{".cm-announced":{display:"none"}},"&light .cm-activeLine":{backgroundColor:"#cceeff44"},"&dark .cm-activeLine":{backgroundColor:"#99eeff33"},"&light .cm-specialChar":{color:"red"},"&dark .cm-specialChar":{color:"#f78"},".cm-gutters":{flexShrink:0,display:"flex",height:"100%",boxSizing:"border-box",zIndex:200},".cm-gutters-before":{insetInlineStart:0},".cm-gutters-after":{insetInlineEnd:0},"&light .cm-gutters":{backgroundColor:"#f5f5f5",color:"#6c6c6c",border:"0px solid #ddd","&.cm-gutters-before":{borderRightWidth:"1px"},"&.cm-gutters-after":{borderLeftWidth:"1px"}},"&dark .cm-gutters":{backgroundColor:"#333338",color:"#ccc"},".cm-gutter":{display:"flex !important",flexDirection:"column",flexShrink:0,boxSizing:"border-box",minHeight:"100%",overflow:"hidden"},".cm-gutterElement":{boxSizing:"border-box"},".cm-lineNumbers .cm-gutterElement":{padding:"0 3px 0 5px",minWidth:"20px",textAlign:"right",whiteSpace:"nowrap"},"&light .cm-activeLineGutter":{backgroundColor:"#e2f2ff"},"&dark .cm-activeLineGutter":{backgroundColor:"#222227"},".cm-panels":{boxSizing:"border-box",position:"sticky",left:0,right:0,zIndex:300},"&light .cm-panels":{backgroundColor:"#f5f5f5",color:"black"},"&light .cm-panels-top":{borderBottom:"1px solid #ddd"},"&light .cm-panels-bottom":{borderTop:"1px solid #ddd"},"&dark .cm-panels":{backgroundColor:"#333338",color:"white"},".cm-dialog":{padding:"2px 19px 4px 6px",position:"relative","& label":{fontSize:"80%"}},".cm-dialog-close":{position:"absolute",top:"3px",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",fontSize:"14px",padding:"0"},".cm-tab":{display:"inline-block",overflow:"hidden",verticalAlign:"bottom"},".cm-widgetBuffer":{verticalAlign:"text-top",height:"1em",width:0,display:"inline"},".cm-placeholder":{color:"#888",display:"inline-block",verticalAlign:"top",userSelect:"none"},".cm-highlightSpace":{backgroundImage:"radial-gradient(circle at 50% 55%, #aaa 20%, transparent 5%)",backgroundPosition:"center"},".cm-highlightTab":{backgroundImage:`url('data:image/svg+xml,')`,backgroundSize:"auto 100%",backgroundPosition:"right 90%",backgroundRepeat:"no-repeat"},".cm-trailingSpace":{backgroundColor:"#ff332255"},".cm-button":{verticalAlign:"middle",color:"inherit",fontSize:"70%",padding:".2em 1em",borderRadius:"1px"},"&light .cm-button":{backgroundImage:"linear-gradient(#eff1f5, #d9d9df)",border:"1px solid #888","&:active":{backgroundImage:"linear-gradient(#b4b4b4, #d0d3d6)"}},"&dark .cm-button":{backgroundImage:"linear-gradient(#393939, #111)",border:"1px solid #888","&:active":{backgroundImage:"linear-gradient(#111, #333)"}},".cm-textfield":{verticalAlign:"middle",color:"inherit",fontSize:"70%",border:"1px solid silver",padding:".2em .5em"},"&light .cm-textfield":{backgroundColor:"white"},"&dark .cm-textfield":{border:"1px solid #555",backgroundColor:"inherit"}},RA),AW={childList:!0,characterData:!0,subtree:!0,attributes:!0,characterDataOldValue:!0},zy=Fe.ie&&Fe.ie_version<=11;class EW{constructor(e){this.view=e,this.active=!1,this.editContext=null,this.selectionRange=new fV,this.selectionChanged=!1,this.delayedFlush=-1,this.resizeTimeout=-1,this.queue=[],this.delayedAndroidKey=null,this.flushingAndroidKey=-1,this.lastChange=0,this.scrollTargets=[],this.intersection=null,this.resizeScroll=null,this.intersecting=!1,this.gapIntersection=null,this.gaps=[],this.printQuery=null,this.parentCheck=-1,this.dom=e.contentDOM,this.observer=new MutationObserver(n=>{for(let r of n)this.queue.push(r);(Fe.ie&&Fe.ie_version<=11||Fe.ios&&e.composing)&&n.some(r=>r.type=="childList"&&r.removedNodes.length||r.type=="characterData"&&r.oldValue.length>r.target.nodeValue.length)?this.flushSoon():this.flush()}),window.EditContext&&Fe.android&&e.constructor.EDIT_CONTEXT!==!1&&!(Fe.chrome&&Fe.chrome_version<126)&&(this.editContext=new DW(e),e.state.facet(sl)&&(e.contentDOM.editContext=this.editContext.editContext)),zy&&(this.onCharData=n=>{this.queue.push({target:n.target,type:"characterData",oldValue:n.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this),this.onResize=this.onResize.bind(this),this.onPrint=this.onPrint.bind(this),this.onScroll=this.onScroll.bind(this),window.matchMedia&&(this.printQuery=window.matchMedia("print")),typeof ResizeObserver=="function"&&(this.resizeScroll=new ResizeObserver(()=>{var n;((n=this.view.docView)===null||n===void 0?void 0:n.lastUpdate){this.parentCheck<0&&(this.parentCheck=setTimeout(this.listenForScroll.bind(this),1e3)),n.length>0&&n[n.length-1].intersectionRatio>0!=this.intersecting&&(this.intersecting=!this.intersecting,this.intersecting!=this.view.inView&&this.onScrollChanged(document.createEvent("Event")))},{threshold:[0,.001]}),this.intersection.observe(this.dom),this.gapIntersection=new IntersectionObserver(n=>{n.length>0&&n[n.length-1].intersectionRatio>0&&this.onScrollChanged(document.createEvent("Event"))},{})),this.listenForScroll(),this.readSelectionRange()}onScrollChanged(e){this.view.inputState.runHandlers("scroll",e),this.intersecting&&this.view.measure()}onScroll(e){this.intersecting&&this.flush(!1),this.editContext&&this.view.requestMeasure(this.editContext.measureReq),this.onScrollChanged(e)}onResize(){this.resizeTimeout<0&&(this.resizeTimeout=setTimeout(()=>{this.resizeTimeout=-1,this.view.requestMeasure()},50))}onPrint(e){(e.type=="change"||!e.type)&&!e.matches||(this.view.viewState.printing=!0,this.view.measure(),setTimeout(()=>{this.view.viewState.printing=!1,this.view.requestMeasure()},500))}updateGaps(e){if(this.gapIntersection&&(e.length!=this.gaps.length||this.gaps.some((n,r)=>n!=e[r]))){this.gapIntersection.disconnect();for(let n of e)this.gapIntersection.observe(n);this.gaps=e}}onSelectionChange(e){let n=this.selectionChanged;if(!this.readSelectionRange()||this.delayedAndroidKey)return;let{view:r}=this,s=this.selectionRange;if(r.state.facet(sl)?r.root.activeElement!=this.dom:!Kp(this.dom,s))return;let i=s.anchorNode&&r.docView.nearest(s.anchorNode);if(i&&i.ignoreEvent(e)){n||(this.selectionChanged=!1);return}(Fe.ie&&Fe.ie_version<=11||Fe.android&&Fe.chrome)&&!r.state.selection.main.empty&&s.focusNode&&ef(s.focusNode,s.focusOffset,s.anchorNode,s.anchorOffset)?this.flushSoon():this.flush(!1)}readSelectionRange(){let{view:e}=this,n=vf(e.root);if(!n)return!1;let r=Fe.safari&&e.root.nodeType==11&&e.root.activeElement==this.dom&&_W(this.view,n)||n;if(!r||this.selectionRange.eq(r))return!1;let s=Kp(this.dom,r);return s&&!this.selectionChanged&&e.inputState.lastFocusTime>Date.now()-200&&e.inputState.lastTouchTime{let i=this.delayedAndroidKey;i&&(this.clearDelayedAndroidKey(),this.view.inputState.lastKeyCode=i.keyCode,this.view.inputState.lastKeyTime=Date.now(),!this.flush()&&i.force&&Gu(this.dom,i.key,i.keyCode))};this.flushingAndroidKey=this.view.win.requestAnimationFrame(s)}(!this.delayedAndroidKey||e=="Enter")&&(this.delayedAndroidKey={key:e,keyCode:n,force:this.lastChange{this.delayedFlush=-1,this.flush()}))}forceFlush(){this.delayedFlush>=0&&(this.view.win.cancelAnimationFrame(this.delayedFlush),this.delayedFlush=-1),this.flush()}pendingRecords(){for(let e of this.observer.takeRecords())this.queue.push(e);return this.queue}processRecords(){let e=this.pendingRecords();e.length&&(this.queue=[]);let n=-1,r=-1,s=!1;for(let i of e){let l=this.readMutation(i);l&&(l.typeOver&&(s=!0),n==-1?{from:n,to:r}=l:(n=Math.min(l.from,n),r=Math.max(l.to,r)))}return{from:n,to:r,typeOver:s}}readChange(){let{from:e,to:n,typeOver:r}=this.processRecords(),s=this.selectionChanged&&Kp(this.dom,this.selectionRange);if(e<0&&!s)return null;e>-1&&(this.lastChange=Date.now()),this.view.inputState.lastFocusTime=0,this.selectionChanged=!1;let i=new YV(this.view,e,n,r);return this.view.docView.domChanged={newSel:i.newSel?i.newSel.main:null},i}flush(e=!0){if(this.delayedFlush>=0||this.delayedAndroidKey)return!1;e&&this.readSelectionRange();let n=this.readChange();if(!n)return this.view.requestMeasure(),!1;let r=this.view.state,s=wA(this.view,n);return this.view.state==r&&(n.domChanged||n.newSel&&!n.newSel.main.eq(this.view.state.selection.main))&&this.view.update([]),s}readMutation(e){let n=this.view.docView.nearest(e.target);if(!n||n.ignoreMutation(e))return null;if(n.markDirty(e.type=="attributes"),e.type=="attributes"&&(n.flags|=4),e.type=="childList"){let r=zj(n,e.previousSibling||e.target.previousSibling,-1),s=zj(n,e.nextSibling||e.target.nextSibling,1);return{from:r?n.posAfter(r):n.posAtStart,to:s?n.posBefore(s):n.posAtEnd,typeOver:!1}}else return e.type=="characterData"?{from:n.posAtStart,to:n.posAtEnd,typeOver:e.target.nodeValue==e.oldValue}:null}setWindow(e){e!=this.win&&(this.removeWindowListeners(this.win),this.win=e,this.addWindowListeners(this.win))}addWindowListeners(e){e.addEventListener("resize",this.onResize),this.printQuery?this.printQuery.addEventListener?this.printQuery.addEventListener("change",this.onPrint):this.printQuery.addListener(this.onPrint):e.addEventListener("beforeprint",this.onPrint),e.addEventListener("scroll",this.onScroll),e.document.addEventListener("selectionchange",this.onSelectionChange)}removeWindowListeners(e){e.removeEventListener("scroll",this.onScroll),e.removeEventListener("resize",this.onResize),this.printQuery?this.printQuery.removeEventListener?this.printQuery.removeEventListener("change",this.onPrint):this.printQuery.removeListener(this.onPrint):e.removeEventListener("beforeprint",this.onPrint),e.document.removeEventListener("selectionchange",this.onSelectionChange)}update(e){this.editContext&&(this.editContext.update(e),e.startState.facet(sl)!=e.state.facet(sl)&&(e.view.contentDOM.editContext=e.state.facet(sl)?this.editContext.editContext:null))}destroy(){var e,n,r;this.stop(),(e=this.intersection)===null||e===void 0||e.disconnect(),(n=this.gapIntersection)===null||n===void 0||n.disconnect(),(r=this.resizeScroll)===null||r===void 0||r.disconnect();for(let s of this.scrollTargets)s.removeEventListener("scroll",this.onScroll);this.removeWindowListeners(this.win),clearTimeout(this.parentCheck),clearTimeout(this.resizeTimeout),this.win.cancelAnimationFrame(this.delayedFlush),this.win.cancelAnimationFrame(this.flushingAndroidKey),this.editContext&&(this.view.contentDOM.editContext=null,this.editContext.destroy())}}function zj(t,e,n){for(;e;){let r=jn.get(e);if(r&&r.parent==t)return r;let s=e.parentNode;e=s!=t.dom?s:n>0?e.nextSibling:e.previousSibling}return null}function Pj(t,e){let n=e.startContainer,r=e.startOffset,s=e.endContainer,i=e.endOffset,l=t.docView.domAtPos(t.state.selection.main.anchor);return ef(l.node,l.offset,s,i)&&([n,r,s,i]=[s,i,n,r]),{anchorNode:n,anchorOffset:r,focusNode:s,focusOffset:i}}function _W(t,e){if(e.getComposedRanges){let s=e.getComposedRanges(t.root)[0];if(s)return Pj(t,s)}let n=null;function r(s){s.preventDefault(),s.stopImmediatePropagation(),n=s.getTargetRanges()[0]}return t.contentDOM.addEventListener("beforeinput",r,!0),t.dom.ownerDocument.execCommand("indent"),t.contentDOM.removeEventListener("beforeinput",r,!0),n?Pj(t,n):null}class DW{constructor(e){this.from=0,this.to=0,this.pendingContextChange=null,this.handlers=Object.create(null),this.composing=null,this.resetRange(e.state);let n=this.editContext=new window.EditContext({text:e.state.doc.sliceString(this.from,this.to),selectionStart:this.toContextPos(Math.max(this.from,Math.min(this.to,e.state.selection.main.anchor))),selectionEnd:this.toContextPos(e.state.selection.main.head)});this.handlers.textupdate=r=>{let s=e.state.selection.main,{anchor:i,head:l}=s,c=this.toEditorPos(r.updateRangeStart),d=this.toEditorPos(r.updateRangeEnd);e.inputState.composing>=0&&!this.composing&&(this.composing={contextBase:r.updateRangeStart,editorBase:c,drifted:!1});let h=d-c>r.text.length;c==this.from&&ithis.to&&(d=i);let m=SA(e.state.sliceDoc(c,d),r.text,(h?s.from:s.to)-c,h?"end":null);if(!m){let x=Ce.single(this.toEditorPos(r.selectionStart),this.toEditorPos(r.selectionEnd));x.main.eq(s)||e.dispatch({selection:x,userEvent:"select"});return}let p={from:m.from+c,to:m.toA+c,insert:Wt.of(r.text.slice(m.from,m.toB).split(` -`))};if((Fe.mac||Fe.android)&&p.from==l-1&&/^\. ?$/.test(r.text)&&e.contentDOM.getAttribute("autocorrect")=="off"&&(p={from:c,to:d,insert:Wt.of([r.text.replace("."," ")])}),this.pendingContextChange=p,!e.state.readOnly){let x=this.to-this.from+(p.to-p.from+p.insert.length);Mw(e,p,Ce.single(this.toEditorPos(r.selectionStart,x),this.toEditorPos(r.selectionEnd,x)))}this.pendingContextChange&&(this.revertPending(e.state),this.setSelection(e.state)),p.from=0&&!/[\\p{Alphabetic}\\p{Number}_]/.test(n.text.slice(Math.max(0,r.updateRangeStart-1),Math.min(n.text.length,r.updateRangeStart+1)))&&this.handlers.compositionend(r)},this.handlers.characterboundsupdate=r=>{let s=[],i=null;for(let l=this.toEditorPos(r.rangeStart),c=this.toEditorPos(r.rangeEnd);l{let s=[];for(let i of r.getTextFormats()){let l=i.underlineStyle,c=i.underlineThickness;if(!/none/i.test(l)&&!/none/i.test(c)){let d=this.toEditorPos(i.rangeStart),h=this.toEditorPos(i.rangeEnd);if(d{e.inputState.composing<0&&(e.inputState.composing=0,e.inputState.compositionFirstChange=!0)},this.handlers.compositionend=()=>{if(e.inputState.composing=-1,e.inputState.compositionFirstChange=null,this.composing){let{drifted:r}=this.composing;this.composing=null,r&&this.reset(e.state)}};for(let r in this.handlers)n.addEventListener(r,this.handlers[r]);this.measureReq={read:r=>{this.editContext.updateControlBounds(r.contentDOM.getBoundingClientRect());let s=vf(r.root);s&&s.rangeCount&&this.editContext.updateSelectionBounds(s.getRangeAt(0).getBoundingClientRect())}}}applyEdits(e){let n=0,r=!1,s=this.pendingContextChange;return e.changes.iterChanges((i,l,c,d,h)=>{if(r)return;let m=h.length-(l-i);if(s&&l>=s.to)if(s.from==i&&s.to==l&&s.insert.eq(h)){s=this.pendingContextChange=null,n+=m,this.to+=m;return}else s=null,this.revertPending(e.state);if(i+=n,l+=n,l<=this.from)this.from+=m,this.to+=m;else if(ithis.to||this.to-this.from+h.length>3e4){r=!0;return}this.editContext.updateText(this.toContextPos(i),this.toContextPos(l),h.toString()),this.to+=m}n+=m}),s&&!r&&this.revertPending(e.state),!r}update(e){let n=this.pendingContextChange,r=e.startState.selection.main;this.composing&&(this.composing.drifted||!e.changes.touchesRange(r.from,r.to)&&e.transactions.some(s=>!s.isUserEvent("input.type")&&s.changes.touchesRange(this.from,this.to)))?(this.composing.drifted=!0,this.composing.editorBase=e.changes.mapPos(this.composing.editorBase)):!this.applyEdits(e)||!this.rangeIsValid(e.state)?(this.pendingContextChange=null,this.reset(e.state)):(e.docChanged||e.selectionSet||n)&&this.setSelection(e.state),(e.geometryChanged||e.docChanged||e.selectionSet)&&e.view.requestMeasure(this.measureReq)}resetRange(e){let{head:n}=e.selection.main;this.from=Math.max(0,n-1e4),this.to=Math.min(e.doc.length,n+1e4)}reset(e){this.resetRange(e),this.editContext.updateText(0,this.editContext.text.length,e.doc.sliceString(this.from,this.to)),this.setSelection(e)}revertPending(e){let n=this.pendingContextChange;this.pendingContextChange=null,this.editContext.updateText(this.toContextPos(n.from),this.toContextPos(n.from+n.insert.length),e.doc.sliceString(n.from,n.to))}setSelection(e){let{main:n}=e.selection,r=this.toContextPos(Math.max(this.from,Math.min(this.to,n.anchor))),s=this.toContextPos(n.head);(this.editContext.selectionStart!=r||this.editContext.selectionEnd!=s)&&this.editContext.updateSelection(r,s)}rangeIsValid(e){let{head:n}=e.selection.main;return!(this.from>0&&n-this.from<500||this.to1e4*3)}toEditorPos(e,n=this.to-this.from){e=Math.min(e,n);let r=this.composing;return r&&r.drifted?r.editorBase+(e-r.contextBase):e+this.from}toContextPos(e){let n=this.composing;return n&&n.drifted?n.contextBase+(e-n.editorBase):e-this.from}destroy(){for(let e in this.handlers)this.editContext.removeEventListener(e,this.handlers[e])}}class qe{get state(){return this.viewState.state}get viewport(){return this.viewState.viewport}get visibleRanges(){return this.viewState.visibleRanges}get inView(){return this.viewState.inView}get composing(){return!!this.inputState&&this.inputState.composing>0}get compositionStarted(){return!!this.inputState&&this.inputState.composing>=0}get root(){return this._root}get win(){return this.dom.ownerDocument.defaultView||window}constructor(e={}){var n;this.plugins=[],this.pluginMap=new Map,this.editorAttrs={},this.contentAttrs={},this.bidiCache=[],this.destroyed=!1,this.updateState=2,this.measureScheduled=-1,this.measureRequests=[],this.contentDOM=document.createElement("div"),this.scrollDOM=document.createElement("div"),this.scrollDOM.tabIndex=-1,this.scrollDOM.className="cm-scroller",this.scrollDOM.appendChild(this.contentDOM),this.announceDOM=document.createElement("div"),this.announceDOM.className="cm-announced",this.announceDOM.setAttribute("aria-live","polite"),this.dom=document.createElement("div"),this.dom.appendChild(this.announceDOM),this.dom.appendChild(this.scrollDOM),e.parent&&e.parent.appendChild(this.dom);let{dispatch:r}=e;this.dispatchTransactions=e.dispatchTransactions||r&&(s=>s.forEach(i=>r(i,this)))||(s=>this.update(s)),this.dispatch=this.dispatch.bind(this),this._root=e.root||mV(e.parent)||document,this.viewState=new Dj(e.state||Vt.create(e)),e.scrollTo&&e.scrollTo.is(np)&&(this.viewState.scrollTarget=e.scrollTo.value.clip(this.viewState.state)),this.plugins=this.state.facet(Fu).map(s=>new Ey(s));for(let s of this.plugins)s.update(this);this.observer=new EW(this),this.inputState=new eW(this),this.inputState.ensureHandlers(this.plugins),this.docView=new mj(this),this.mountStyles(),this.updateAttrs(),this.updateState=0,this.requestMeasure(),!((n=document.fonts)===null||n===void 0)&&n.ready&&document.fonts.ready.then(()=>this.requestMeasure())}dispatch(...e){let n=e.length==1&&e[0]instanceof gr?e:e.length==1&&Array.isArray(e[0])?e[0]:[this.state.update(...e)];this.dispatchTransactions(n,this)}update(e){if(this.updateState!=0)throw new Error("Calls to EditorView.update are not allowed while an update is in progress");let n=!1,r=!1,s,i=this.state;for(let x of e){if(x.startState!=i)throw new RangeError("Trying to update state with a transaction that doesn't start from the previous state.");i=x.state}if(this.destroyed){this.viewState.state=i;return}let l=this.hasFocus,c=0,d=null;e.some(x=>x.annotation(TA))?(this.inputState.notifiedFocused=l,c=1):l!=this.inputState.notifiedFocused&&(this.inputState.notifiedFocused=l,d=MA(i,l),d||(c=1));let h=this.observer.delayedAndroidKey,m=null;if(h?(this.observer.clearDelayedAndroidKey(),m=this.observer.readChange(),(m&&!this.state.doc.eq(i.doc)||!this.state.selection.eq(i.selection))&&(m=null)):this.observer.clear(),i.facet(Vt.phrases)!=this.state.facet(Vt.phrases))return this.setState(i);s=Ng.create(this,i,e),s.flags|=c;let p=this.viewState.scrollTarget;try{this.updateState=2;for(let x of e){if(p&&(p=p.map(x.changes)),x.scrollIntoView){let{main:v}=x.state.selection;p=new Xu(v.empty?v:Ce.cursor(v.head,v.head>v.anchor?-1:1))}for(let v of x.effects)v.is(np)&&(p=v.value.clip(this.state))}this.viewState.update(s,p),this.bidiCache=Tg.update(this.bidiCache,s.changes),s.empty||(this.updatePlugins(s),this.inputState.update(s)),n=this.docView.update(s),this.state.facet(Qh)!=this.styleModules&&this.mountStyles(),r=this.updateAttrs(),this.showAnnouncements(e),this.docView.updateSelection(n,e.some(x=>x.isUserEvent("select.pointer")))}finally{this.updateState=0}if(s.startState.facet(op)!=s.state.facet(op)&&(this.viewState.mustMeasureContent=!0),(n||r||p||this.viewState.mustEnforceCursorAssoc||this.viewState.mustMeasureContent)&&this.requestMeasure(),n&&this.docViewUpdate(),!s.empty)for(let x of this.state.facet(I2))try{x(s)}catch(v){Es(this.state,v,"update listener")}(d||m)&&Promise.resolve().then(()=>{d&&this.state==d.startState&&this.dispatch(d),m&&!wA(this,m)&&h.force&&Gu(this.contentDOM,h.key,h.keyCode)})}setState(e){if(this.updateState!=0)throw new Error("Calls to EditorView.setState are not allowed while an update is in progress");if(this.destroyed){this.viewState.state=e;return}this.updateState=2;let n=this.hasFocus;try{for(let r of this.plugins)r.destroy(this);this.viewState=new Dj(e),this.plugins=e.facet(Fu).map(r=>new Ey(r)),this.pluginMap.clear();for(let r of this.plugins)r.update(this);this.docView.destroy(),this.docView=new mj(this),this.inputState.ensureHandlers(this.plugins),this.mountStyles(),this.updateAttrs(),this.bidiCache=[]}finally{this.updateState=0}n&&this.focus(),this.requestMeasure()}updatePlugins(e){let n=e.startState.facet(Fu),r=e.state.facet(Fu);if(n!=r){let s=[];for(let i of r){let l=n.indexOf(i);if(l<0)s.push(new Ey(i));else{let c=this.plugins[l];c.mustUpdate=e,s.push(c)}}for(let i of this.plugins)i.mustUpdate!=e&&i.destroy(this);this.plugins=s,this.pluginMap.clear()}else for(let s of this.plugins)s.mustUpdate=e;for(let s=0;s-1&&this.win.cancelAnimationFrame(this.measureScheduled),this.observer.delayedAndroidKey){this.measureScheduled=-1,this.requestMeasure();return}this.measureScheduled=0,e&&this.observer.forceFlush();let n=null,r=this.scrollDOM,s=r.scrollTop*this.scaleY,{scrollAnchorPos:i,scrollAnchorHeight:l}=this.viewState;Math.abs(s-this.viewState.scrollTop)>1&&(l=-1),this.viewState.scrollAnchorHeight=-1;try{for(let c=0;;c++){if(l<0)if(QM(r))i=-1,l=this.viewState.heightMap.height;else{let v=this.viewState.scrollAnchorAt(s);i=v.from,l=v.top}this.updateState=1;let d=this.viewState.measure(this);if(!d&&!this.measureRequests.length&&this.viewState.scrollTarget==null)break;if(c>5){console.warn(this.measureRequests.length?"Measure loop restarted more than 5 times":"Viewport failed to stabilize");break}let h=[];d&4||([this.measureRequests,h]=[h,this.measureRequests]);let m=h.map(v=>{try{return v.read(this)}catch(b){return Es(this.state,b),Lj}}),p=Ng.create(this,this.state,[]),x=!1;p.flags|=d,n?n.flags|=d:n=p,this.updateState=2,p.empty||(this.updatePlugins(p),this.inputState.update(p),this.updateAttrs(),x=this.docView.update(p),x&&this.docViewUpdate());for(let v=0;v1||b<-1){s=s+b,r.scrollTop=s/this.scaleY,l=-1;continue}}break}}}finally{this.updateState=0,this.measureScheduled=-1}if(n&&!n.empty)for(let c of this.state.facet(I2))c(n)}get themeClasses(){return H2+" "+(this.state.facet($2)?DA:_A)+" "+this.state.facet(op)}updateAttrs(){let e=Bj(this,fA,{class:"cm-editor"+(this.hasFocus?" cm-focused ":" ")+this.themeClasses}),n={spellcheck:"false",autocorrect:"off",autocapitalize:"off",writingsuggestions:"false",translate:"no",contenteditable:this.state.facet(sl)?"true":"false",class:"cm-content",style:`${Fe.tabSize}: ${this.state.tabSize}`,role:"textbox","aria-multiline":"true"};this.state.readOnly&&(n["aria-readonly"]="true"),Bj(this,Cw,n);let r=this.observer.ignore(()=>{let s=R2(this.contentDOM,this.contentAttrs,n),i=R2(this.dom,this.editorAttrs,e);return s||i});return this.editorAttrs=e,this.contentAttrs=n,r}showAnnouncements(e){let n=!0;for(let r of e)for(let s of r.effects)if(s.is(qe.announce)){n&&(this.announceDOM.textContent=""),n=!1;let i=this.announceDOM.appendChild(document.createElement("div"));i.textContent=s.value}}mountStyles(){this.styleModules=this.state.facet(Qh);let e=this.state.facet(qe.cspNonce);ho.mount(this.root,this.styleModules.concat(MW).reverse(),e?{nonce:e}:void 0)}readMeasured(){if(this.updateState==2)throw new Error("Reading the editor layout isn't allowed during an update");this.updateState==0&&this.measureScheduled>-1&&this.measure(!1)}requestMeasure(e){if(this.measureScheduled<0&&(this.measureScheduled=this.win.requestAnimationFrame(()=>this.measure())),e){if(this.measureRequests.indexOf(e)>-1)return;if(e.key!=null){for(let n=0;nr.plugin==e)||null),n&&n.update(this).value}get documentTop(){return this.contentDOM.getBoundingClientRect().top+this.viewState.paddingTop}get documentPadding(){return{top:this.viewState.paddingTop,bottom:this.viewState.paddingBottom}}get scaleX(){return this.viewState.scaleX}get scaleY(){return this.viewState.scaleY}elementAtHeight(e){return this.readMeasured(),this.viewState.elementAtHeight(e)}lineBlockAtHeight(e){return this.readMeasured(),this.viewState.lineBlockAtHeight(e)}get viewportLineBlocks(){return this.viewState.viewportLines}lineBlockAt(e){return this.viewState.lineBlockAt(e)}get contentHeight(){return this.viewState.contentHeight}moveByChar(e,n,r){return Dy(this,e,yj(this,e,n,r))}moveByGroup(e,n){return Dy(this,e,yj(this,e,n,r=>UV(this,e.head,r)))}visualLineSide(e,n){let r=this.bidiSpans(e),s=this.textDirectionAt(e.from),i=r[n?r.length-1:0];return Ce.cursor(i.side(n,s)+e.from,i.forward(!n,s)?1:-1)}moveToLineBoundary(e,n,r=!0){return HV(this,e,n,r)}moveVertically(e,n,r){return Dy(this,e,VV(this,e,n,r))}domAtPos(e){return this.docView.domAtPos(e)}posAtDOM(e,n=0){return this.docView.posFromDOM(e,n)}posAtCoords(e,n=!0){return this.readMeasured(),vA(this,e,n)}coordsAtPos(e,n=1){this.readMeasured();let r=this.docView.coordsAt(e,n);if(!r||r.left==r.right)return r;let s=this.state.doc.lineAt(e),i=this.bidiSpans(s),l=i[ro.find(i,e-s.from,-1,n)];return s0(r,l.dir==Hn.LTR==n>0)}coordsForChar(e){return this.readMeasured(),this.docView.coordsForChar(e)}get defaultCharacterWidth(){return this.viewState.heightOracle.charWidth}get defaultLineHeight(){return this.viewState.heightOracle.lineHeight}get textDirection(){return this.viewState.defaultTextDirection}textDirectionAt(e){return!this.state.facet(cA)||ethis.viewport.to?this.textDirection:(this.readMeasured(),this.docView.textDirectionAt(e))}get lineWrapping(){return this.viewState.heightOracle.lineWrapping}bidiSpans(e){if(e.length>RW)return tA(e.length);let n=this.textDirectionAt(e.from),r;for(let i of this.bidiCache)if(i.from==e.from&&i.dir==n&&(i.fresh||eA(i.isolates,r=fj(this,e))))return i.order;r||(r=fj(this,e));let s=TV(e.text,n,r);return this.bidiCache.push(new Tg(e.from,e.to,n,r,!0,s)),s}get hasFocus(){var e;return(this.dom.ownerDocument.hasFocus()||Fe.safari&&((e=this.inputState)===null||e===void 0?void 0:e.lastContextMenu)>Date.now()-3e4)&&this.root.activeElement==this.contentDOM}focus(){this.observer.ignore(()=>{qM(this.contentDOM),this.docView.updateSelection()})}setRoot(e){this._root!=e&&(this._root=e,this.observer.setWindow((e.nodeType==9?e:e.ownerDocument).defaultView||window),this.mountStyles())}destroy(){this.root.activeElement==this.contentDOM&&this.contentDOM.blur();for(let e of this.plugins)e.destroy(this);this.plugins=[],this.inputState.destroy(),this.docView.destroy(),this.dom.remove(),this.observer.destroy(),this.measureScheduled>-1&&this.win.cancelAnimationFrame(this.measureScheduled),this.destroyed=!0}static scrollIntoView(e,n={}){return np.of(new Xu(typeof e=="number"?Ce.cursor(e):e,n.y,n.x,n.yMargin,n.xMargin))}scrollSnapshot(){let{scrollTop:e,scrollLeft:n}=this.scrollDOM,r=this.viewState.scrollAnchorAt(e);return np.of(new Xu(Ce.cursor(r.from),"start","start",r.top-e,n,!0))}setTabFocusMode(e){e==null?this.inputState.tabFocusMode=this.inputState.tabFocusMode<0?0:-1:typeof e=="boolean"?this.inputState.tabFocusMode=e?0:-1:this.inputState.tabFocusMode!=0&&(this.inputState.tabFocusMode=Date.now()+e)}static domEventHandlers(e){return lr.define(()=>({}),{eventHandlers:e})}static domEventObservers(e){return lr.define(()=>({}),{eventObservers:e})}static theme(e,n){let r=ho.newName(),s=[op.of(r),Qh.of(U2(`.${r}`,e))];return n&&n.dark&&s.push($2.of(!0)),s}static baseTheme(e){return jo.lowest(Qh.of(U2("."+H2,e,RA)))}static findFromDOM(e){var n;let r=e.querySelector(".cm-content"),s=r&&jn.get(r)||jn.get(e);return((n=s?.rootView)===null||n===void 0?void 0:n.view)||null}}qe.styleModule=Qh;qe.inputHandler=lA;qe.clipboardInputFilter=jw;qe.clipboardOutputFilter=Nw;qe.scrollHandler=dA;qe.focusChangeEffect=oA;qe.perLineTextDirection=cA;qe.exceptionSink=aA;qe.updateListener=I2;qe.editable=sl;qe.mouseSelectionStyle=iA;qe.dragMovesSelection=sA;qe.clickAddsSelectionRange=rA;qe.decorations=yf;qe.outerDecorations=mA;qe.atomicRanges=l0;qe.bidiIsolatedRanges=pA;qe.scrollMargins=gA;qe.darkTheme=$2;qe.cspNonce=He.define({combine:t=>t.length?t[0]:""});qe.contentAttributes=Cw;qe.editorAttributes=fA;qe.lineWrapping=qe.contentAttributes.of({class:"cm-lineWrapping"});qe.announce=xt.define();const RW=4096,Lj={};class Tg{constructor(e,n,r,s,i,l){this.from=e,this.to=n,this.dir=r,this.isolates=s,this.fresh=i,this.order=l}static update(e,n){if(n.empty&&!e.some(i=>i.fresh))return e;let r=[],s=e.length?e[e.length-1].dir:Hn.LTR;for(let i=Math.max(0,e.length-10);i=0;s--){let i=r[s],l=typeof i=="function"?i(t):i;l&&D2(l,n)}return n}const zW=Fe.mac?"mac":Fe.windows?"win":Fe.linux?"linux":"key";function PW(t,e){const n=t.split(/-(?!$)/);let r=n[n.length-1];r=="Space"&&(r=" ");let s,i,l,c;for(let d=0;dr.concat(s),[]))),n}function BW(t,e,n){return PA(zA(t.state),e,t,n)}let to=null;const IW=4e3;function qW(t,e=zW){let n=Object.create(null),r=Object.create(null),s=(l,c)=>{let d=r[l];if(d==null)r[l]=c;else if(d!=c)throw new Error("Key binding "+l+" is used both as a regular binding and as a multi-stroke prefix")},i=(l,c,d,h,m)=>{var p,x;let v=n[l]||(n[l]=Object.create(null)),b=c.split(/ (?!$)/).map(j=>PW(j,e));for(let j=1;j{let _=to={view:M,prefix:T,scope:l};return setTimeout(()=>{to==_&&(to=null)},IW),!0}]})}let k=b.join(" ");s(k,!1);let O=v[k]||(v[k]={preventDefault:!1,stopPropagation:!1,run:((x=(p=v._any)===null||p===void 0?void 0:p.run)===null||x===void 0?void 0:x.slice())||[]});d&&O.run.push(d),h&&(O.preventDefault=!0),m&&(O.stopPropagation=!0)};for(let l of t){let c=l.scope?l.scope.split(" "):["editor"];if(l.any)for(let h of c){let m=n[h]||(n[h]=Object.create(null));m._any||(m._any={preventDefault:!1,stopPropagation:!1,run:[]});let{any:p}=l;for(let x in m)m[x].run.push(v=>p(v,V2))}let d=l[e]||l.key;if(d)for(let h of c)i(h,d,l.run,l.preventDefault,l.stopPropagation),l.shift&&i(h,"Shift-"+d,l.shift,l.preventDefault,l.stopPropagation)}return n}let V2=null;function PA(t,e,n,r){V2=e;let s=oV(e),i=Ms(s,0),l=aa(i)==s.length&&s!=" ",c="",d=!1,h=!1,m=!1;to&&to.view==n&&to.scope==r&&(c=to.prefix+" ",OA.indexOf(e.keyCode)<0&&(h=!0,to=null));let p=new Set,x=O=>{if(O){for(let j of O.run)if(!p.has(j)&&(p.add(j),j(n)))return O.stopPropagation&&(m=!0),!0;O.preventDefault&&(O.stopPropagation&&(m=!0),h=!0)}return!1},v=t[r],b,k;return v&&(x(v[c+cp(s,e,!l)])?d=!0:l&&(e.altKey||e.metaKey||e.ctrlKey)&&!(Fe.windows&&e.ctrlKey&&e.altKey)&&!(Fe.mac&&e.altKey&&!(e.ctrlKey||e.metaKey))&&(b=fo[e.keyCode])&&b!=s?(x(v[c+cp(b,e,!0)])||e.shiftKey&&(k=xf[e.keyCode])!=s&&k!=b&&x(v[c+cp(k,e,!1)]))&&(d=!0):l&&e.shiftKey&&x(v[c+cp(s,e,!0)])&&(d=!0),!d&&x(v._any)&&(d=!0)),h&&(d=!0),d&&m&&e.stopPropagation(),V2=null,d}class c0{constructor(e,n,r,s,i){this.className=e,this.left=n,this.top=r,this.width=s,this.height=i}draw(){let e=document.createElement("div");return e.className=this.className,this.adjust(e),e}update(e,n){return n.className!=this.className?!1:(this.adjust(e),!0)}adjust(e){e.style.left=this.left+"px",e.style.top=this.top+"px",this.width!=null&&(e.style.width=this.width+"px"),e.style.height=this.height+"px"}eq(e){return this.left==e.left&&this.top==e.top&&this.width==e.width&&this.height==e.height&&this.className==e.className}static forRange(e,n,r){if(r.empty){let s=e.coordsAtPos(r.head,r.assoc||1);if(!s)return[];let i=LA(e);return[new c0(n,s.left-i.left,s.top-i.top,null,s.bottom-s.top)]}else return FW(e,n,r)}}function LA(t){let e=t.scrollDOM.getBoundingClientRect();return{left:(t.textDirection==Hn.LTR?e.left:e.right-t.scrollDOM.clientWidth*t.scaleX)-t.scrollDOM.scrollLeft*t.scaleX,top:e.top-t.scrollDOM.scrollTop*t.scaleY}}function qj(t,e,n,r){let s=t.coordsAtPos(e,n*2);if(!s)return r;let i=t.dom.getBoundingClientRect(),l=(s.top+s.bottom)/2,c=t.posAtCoords({x:i.left+1,y:l}),d=t.posAtCoords({x:i.right-1,y:l});return c==null||d==null?r:{from:Math.max(r.from,Math.min(c,d)),to:Math.min(r.to,Math.max(c,d))}}function FW(t,e,n){if(n.to<=t.viewport.from||n.from>=t.viewport.to)return[];let r=Math.max(n.from,t.viewport.from),s=Math.min(n.to,t.viewport.to),i=t.textDirection==Hn.LTR,l=t.contentDOM,c=l.getBoundingClientRect(),d=LA(t),h=l.querySelector(".cm-line"),m=h&&window.getComputedStyle(h),p=c.left+(m?parseInt(m.paddingLeft)+Math.min(0,parseInt(m.textIndent)):0),x=c.right-(m?parseInt(m.paddingRight):0),v=F2(t,r,1),b=F2(t,s,-1),k=v.type==fs.Text?v:null,O=b.type==fs.Text?b:null;if(k&&(t.lineWrapping||v.widgetLineBreaks)&&(k=qj(t,r,1,k)),O&&(t.lineWrapping||b.widgetLineBreaks)&&(O=qj(t,s,-1,O)),k&&O&&k.from==O.from&&k.to==O.to)return T(M(n.from,n.to,k));{let D=k?M(n.from,null,k):_(v,!1),E=O?M(null,n.to,O):_(b,!0),z=[];return(k||v).to<(O||b).from-(k&&O?1:0)||v.widgetLineBreaks>1&&D.bottom+t.defaultLineHeight/2V&&W.from=H)break;R>J&&U(Math.max(ue,J),D==null&&ue<=V,Math.min(R,H),E==null&&R>=ce,ne.dir)}if(J=ae.to+1,J>=H)break}return B.length==0&&U(V,D==null,ce,E==null,t.textDirection),{top:Q,bottom:F,horizontal:B}}function _(D,E){let z=c.top+(E?D.top:D.bottom);return{top:z,bottom:z,horizontal:[]}}}function QW(t,e){return t.constructor==e.constructor&&t.eq(e)}class $W{constructor(e,n){this.view=e,this.layer=n,this.drawn=[],this.scaleX=1,this.scaleY=1,this.measureReq={read:this.measure.bind(this),write:this.draw.bind(this)},this.dom=e.scrollDOM.appendChild(document.createElement("div")),this.dom.classList.add("cm-layer"),n.above&&this.dom.classList.add("cm-layer-above"),n.class&&this.dom.classList.add(n.class),this.scale(),this.dom.setAttribute("aria-hidden","true"),this.setOrder(e.state),e.requestMeasure(this.measureReq),n.mount&&n.mount(this.dom,e)}update(e){e.startState.facet(eg)!=e.state.facet(eg)&&this.setOrder(e.state),(this.layer.update(e,this.dom)||e.geometryChanged)&&(this.scale(),e.view.requestMeasure(this.measureReq))}docViewUpdate(e){this.layer.updateOnDocViewUpdate!==!1&&e.requestMeasure(this.measureReq)}setOrder(e){let n=0,r=e.facet(eg);for(;n!QW(n,this.drawn[r]))){let n=this.dom.firstChild,r=0;for(let s of e)s.update&&n&&s.constructor&&this.drawn[r].constructor&&s.update(n,this.drawn[r])?(n=n.nextSibling,r++):this.dom.insertBefore(s.draw(),n);for(;n;){let s=n.nextSibling;n.remove(),n=s}this.drawn=e,Fe.safari&&Fe.safari_version>=26&&(this.dom.style.display=this.dom.firstChild?"":"none")}}destroy(){this.layer.destroy&&this.layer.destroy(this.dom,this.view),this.dom.remove()}}const eg=He.define();function BA(t){return[lr.define(e=>new $W(e,t)),eg.of(t)]}const bf=He.define({combine(t){return ka(t,{cursorBlinkRate:1200,drawRangeCursor:!0},{cursorBlinkRate:(e,n)=>Math.min(e,n),drawRangeCursor:(e,n)=>e||n})}});function HW(t={}){return[bf.of(t),UW,VW,WW,uA.of(!0)]}function IA(t){return t.startState.facet(bf)!=t.state.facet(bf)}const UW=BA({above:!0,markers(t){let{state:e}=t,n=e.facet(bf),r=[];for(let s of e.selection.ranges){let i=s==e.selection.main;if(s.empty||n.drawRangeCursor){let l=i?"cm-cursor cm-cursor-primary":"cm-cursor cm-cursor-secondary",c=s.empty?s:Ce.cursor(s.head,s.head>s.anchor?-1:1);for(let d of c0.forRange(t,l,c))r.push(d)}}return r},update(t,e){t.transactions.some(r=>r.selection)&&(e.style.animationName=e.style.animationName=="cm-blink"?"cm-blink2":"cm-blink");let n=IA(t);return n&&Fj(t.state,e),t.docChanged||t.selectionSet||n},mount(t,e){Fj(e.state,t)},class:"cm-cursorLayer"});function Fj(t,e){e.style.animationDuration=t.facet(bf).cursorBlinkRate+"ms"}const VW=BA({above:!1,markers(t){return t.state.selection.ranges.map(e=>e.empty?[]:c0.forRange(t,"cm-selectionBackground",e)).reduce((e,n)=>e.concat(n))},update(t,e){return t.docChanged||t.selectionSet||t.viewportChanged||IA(t)},class:"cm-selectionLayer"}),WW=jo.highest(qe.theme({".cm-line":{"& ::selection, &::selection":{backgroundColor:"transparent !important"},caretColor:"transparent !important"},".cm-content":{caretColor:"transparent !important","& :focus":{caretColor:"initial !important","&::selection, & ::selection":{backgroundColor:"Highlight !important"}}}})),qA=xt.define({map(t,e){return t==null?null:e.mapPos(t)}}),Uh=Lr.define({create(){return null},update(t,e){return t!=null&&(t=e.changes.mapPos(t)),e.effects.reduce((n,r)=>r.is(qA)?r.value:n,t)}}),GW=lr.fromClass(class{constructor(t){this.view=t,this.cursor=null,this.measureReq={read:this.readPos.bind(this),write:this.drawCursor.bind(this)}}update(t){var e;let n=t.state.field(Uh);n==null?this.cursor!=null&&((e=this.cursor)===null||e===void 0||e.remove(),this.cursor=null):(this.cursor||(this.cursor=this.view.scrollDOM.appendChild(document.createElement("div")),this.cursor.className="cm-dropCursor"),(t.startState.field(Uh)!=n||t.docChanged||t.geometryChanged)&&this.view.requestMeasure(this.measureReq))}readPos(){let{view:t}=this,e=t.state.field(Uh),n=e!=null&&t.coordsAtPos(e);if(!n)return null;let r=t.scrollDOM.getBoundingClientRect();return{left:n.left-r.left+t.scrollDOM.scrollLeft*t.scaleX,top:n.top-r.top+t.scrollDOM.scrollTop*t.scaleY,height:n.bottom-n.top}}drawCursor(t){if(this.cursor){let{scaleX:e,scaleY:n}=this.view;t?(this.cursor.style.left=t.left/e+"px",this.cursor.style.top=t.top/n+"px",this.cursor.style.height=t.height/n+"px"):this.cursor.style.left="-100000px"}}destroy(){this.cursor&&this.cursor.remove()}setDropPos(t){this.view.state.field(Uh)!=t&&this.view.dispatch({effects:qA.of(t)})}},{eventObservers:{dragover(t){this.setDropPos(this.view.posAtCoords({x:t.clientX,y:t.clientY}))},dragleave(t){(t.target==this.view.contentDOM||!this.view.contentDOM.contains(t.relatedTarget))&&this.setDropPos(null)},dragend(){this.setDropPos(null)},drop(){this.setDropPos(null)}}});function XW(){return[Uh,GW]}function Qj(t,e,n,r,s){e.lastIndex=0;for(let i=t.iterRange(n,r),l=n,c;!i.next().done;l+=i.value.length)if(!i.lineBreak)for(;c=e.exec(i.value);)s(l+c.index,c)}function YW(t,e){let n=t.visibleRanges;if(n.length==1&&n[0].from==t.viewport.from&&n[0].to==t.viewport.to)return n;let r=[];for(let{from:s,to:i}of n)s=Math.max(t.state.doc.lineAt(s).from,s-e),i=Math.min(t.state.doc.lineAt(i).to,i+e),r.length&&r[r.length-1].to>=s?r[r.length-1].to=i:r.push({from:s,to:i});return r}class KW{constructor(e){const{regexp:n,decoration:r,decorate:s,boundary:i,maxLength:l=1e3}=e;if(!n.global)throw new RangeError("The regular expression given to MatchDecorator should have its 'g' flag set");if(this.regexp=n,s)this.addMatch=(c,d,h,m)=>s(m,h,h+c[0].length,c,d);else if(typeof r=="function")this.addMatch=(c,d,h,m)=>{let p=r(c,d,h);p&&m(h,h+c[0].length,p)};else if(r)this.addMatch=(c,d,h,m)=>m(h,h+c[0].length,r);else throw new RangeError("Either 'decorate' or 'decoration' should be provided to MatchDecorator");this.boundary=i,this.maxLength=l}createDeco(e){let n=new fl,r=n.add.bind(n);for(let{from:s,to:i}of YW(e,this.maxLength))Qj(e.state.doc,this.regexp,s,i,(l,c)=>this.addMatch(c,e,l,r));return n.finish()}updateDeco(e,n){let r=1e9,s=-1;return e.docChanged&&e.changes.iterChanges((i,l,c,d)=>{d>=e.view.viewport.from&&c<=e.view.viewport.to&&(r=Math.min(c,r),s=Math.max(d,s))}),e.viewportMoved||s-r>1e3?this.createDeco(e.view):s>-1?this.updateRange(e.view,n.map(e.changes),r,s):n}updateRange(e,n,r,s){for(let i of e.visibleRanges){let l=Math.max(i.from,r),c=Math.min(i.to,s);if(c>=l){let d=e.state.doc.lineAt(l),h=d.tod.from;l--)if(this.boundary.test(d.text[l-1-d.from])){m=l;break}for(;cx.push(j.range(k,O));if(d==h)for(this.regexp.lastIndex=m-d.from;(v=this.regexp.exec(d.text))&&v.indexthis.addMatch(O,e,k,b));n=n.update({filterFrom:m,filterTo:p,filter:(k,O)=>kp,add:x})}}return n}}const W2=/x/.unicode!=null?"gu":"g",ZW=new RegExp(`[\0-\b ---Ÿ­؜​‎‏\u2028\u2029‭‮⁦⁧⁩\uFEFF-]`,W2),JW={0:"null",7:"bell",8:"backspace",10:"newline",11:"vertical tab",13:"carriage return",27:"escape",8203:"zero width space",8204:"zero width non-joiner",8205:"zero width joiner",8206:"left-to-right mark",8207:"right-to-left mark",8232:"line separator",8237:"left-to-right override",8238:"right-to-left override",8294:"left-to-right isolate",8295:"right-to-left isolate",8297:"pop directional isolate",8233:"paragraph separator",65279:"zero width no-break space",65532:"object replacement"};let Py=null;function eG(){var t;if(Py==null&&typeof document<"u"&&document.body){let e=document.body.style;Py=((t=e.tabSize)!==null&&t!==void 0?t:e.MozTabSize)!=null}return Py||!1}const tg=He.define({combine(t){let e=ka(t,{render:null,specialChars:ZW,addSpecialChars:null});return(e.replaceTabs=!eG())&&(e.specialChars=new RegExp(" |"+e.specialChars.source,W2)),e.addSpecialChars&&(e.specialChars=new RegExp(e.specialChars.source+"|"+e.addSpecialChars.source,W2)),e}});function tG(t={}){return[tg.of(t),nG()]}let $j=null;function nG(){return $j||($j=lr.fromClass(class{constructor(t){this.view=t,this.decorations=Je.none,this.decorationCache=Object.create(null),this.decorator=this.makeDecorator(t.state.facet(tg)),this.decorations=this.decorator.createDeco(t)}makeDecorator(t){return new KW({regexp:t.specialChars,decoration:(e,n,r)=>{let{doc:s}=n.state,i=Ms(e[0],0);if(i==9){let l=s.lineAt(r),c=n.state.tabSize,d=Td(l.text,c,r-l.from);return Je.replace({widget:new aG((c-d%c)*this.view.defaultCharacterWidth/this.view.scaleX)})}return this.decorationCache[i]||(this.decorationCache[i]=Je.replace({widget:new iG(t,i)}))},boundary:t.replaceTabs?void 0:/[^]/})}update(t){let e=t.state.facet(tg);t.startState.facet(tg)!=e?(this.decorator=this.makeDecorator(e),this.decorations=this.decorator.createDeco(t.view)):this.decorations=this.decorator.updateDeco(t,this.decorations)}},{decorations:t=>t.decorations}))}const rG="•";function sG(t){return t>=32?rG:t==10?"␤":String.fromCharCode(9216+t)}class iG extends Oa{constructor(e,n){super(),this.options=e,this.code=n}eq(e){return e.code==this.code}toDOM(e){let n=sG(this.code),r=e.state.phrase("Control character")+" "+(JW[this.code]||"0x"+this.code.toString(16)),s=this.options.render&&this.options.render(this.code,r,n);if(s)return s;let i=document.createElement("span");return i.textContent=n,i.title=r,i.setAttribute("aria-label",r),i.className="cm-specialChar",i}ignoreEvent(){return!1}}class aG extends Oa{constructor(e){super(),this.width=e}eq(e){return e.width==this.width}toDOM(){let e=document.createElement("span");return e.textContent=" ",e.className="cm-tab",e.style.width=this.width+"px",e}ignoreEvent(){return!1}}function lG(){return cG}const oG=Je.line({class:"cm-activeLine"}),cG=lr.fromClass(class{constructor(t){this.decorations=this.getDeco(t)}update(t){(t.docChanged||t.selectionSet)&&(this.decorations=this.getDeco(t.view))}getDeco(t){let e=-1,n=[];for(let r of t.state.selection.ranges){let s=t.lineBlockAt(r.head);s.from>e&&(n.push(oG.range(s.from)),e=s.from)}return Je.set(n)}},{decorations:t=>t.decorations});class uG extends Oa{constructor(e){super(),this.content=e}toDOM(e){let n=document.createElement("span");return n.className="cm-placeholder",n.style.pointerEvents="none",n.appendChild(typeof this.content=="string"?document.createTextNode(this.content):typeof this.content=="function"?this.content(e):this.content.cloneNode(!0)),n.setAttribute("aria-hidden","true"),n}coordsAt(e){let n=e.firstChild?ud(e.firstChild):[];if(!n.length)return null;let r=window.getComputedStyle(e.parentNode),s=s0(n[0],r.direction!="rtl"),i=parseInt(r.lineHeight);return s.bottom-s.top>i*1.5?{left:s.left,right:s.right,top:s.top,bottom:s.top+i}:s}ignoreEvent(){return!1}}function dG(t){let e=lr.fromClass(class{constructor(n){this.view=n,this.placeholder=t?Je.set([Je.widget({widget:new uG(t),side:1}).range(0)]):Je.none}get decorations(){return this.view.state.doc.length?Je.none:this.placeholder}},{decorations:n=>n.decorations});return typeof t=="string"?[e,qe.contentAttributes.of({"aria-placeholder":t})]:e}const G2=2e3;function hG(t,e,n){let r=Math.min(e.line,n.line),s=Math.max(e.line,n.line),i=[];if(e.off>G2||n.off>G2||e.col<0||n.col<0){let l=Math.min(e.off,n.off),c=Math.max(e.off,n.off);for(let d=r;d<=s;d++){let h=t.doc.line(d);h.length<=c&&i.push(Ce.range(h.from+l,h.to+c))}}else{let l=Math.min(e.col,n.col),c=Math.max(e.col,n.col);for(let d=r;d<=s;d++){let h=t.doc.line(d),m=j2(h.text,l,t.tabSize,!0);if(m<0)i.push(Ce.cursor(h.to));else{let p=j2(h.text,c,t.tabSize);i.push(Ce.range(h.from+m,h.from+p))}}}return i}function fG(t,e){let n=t.coordsAtPos(t.viewport.from);return n?Math.round(Math.abs((n.left-e)/t.defaultCharacterWidth)):-1}function Hj(t,e){let n=t.posAtCoords({x:e.clientX,y:e.clientY},!1),r=t.state.doc.lineAt(n),s=n-r.from,i=s>G2?-1:s==r.length?fG(t,e.clientX):Td(r.text,t.state.tabSize,n-r.from);return{line:r.number,col:i,off:s}}function mG(t,e){let n=Hj(t,e),r=t.state.selection;return n?{update(s){if(s.docChanged){let i=s.changes.mapPos(s.startState.doc.line(n.line).from),l=s.state.doc.lineAt(i);n={line:l.number,col:n.col,off:Math.min(n.off,l.length)},r=r.map(s.changes)}},get(s,i,l){let c=Hj(t,s);if(!c)return r;let d=hG(t.state,n,c);return d.length?l?Ce.create(d.concat(r.ranges)):Ce.create(d):r}}:null}function pG(t){let e=(n=>n.altKey&&n.button==0);return qe.mouseSelectionStyle.of((n,r)=>e(r)?mG(n,r):null)}const gG={Alt:[18,t=>!!t.altKey],Control:[17,t=>!!t.ctrlKey],Shift:[16,t=>!!t.shiftKey],Meta:[91,t=>!!t.metaKey]},xG={style:"cursor: crosshair"};function vG(t={}){let[e,n]=gG[t.key||"Alt"],r=lr.fromClass(class{constructor(s){this.view=s,this.isDown=!1}set(s){this.isDown!=s&&(this.isDown=s,this.view.update([]))}},{eventObservers:{keydown(s){this.set(s.keyCode==e||n(s))},keyup(s){(s.keyCode==e||!n(s))&&this.set(!1)},mousemove(s){this.set(n(s))}}});return[r,qe.contentAttributes.of(s=>{var i;return!((i=s.plugin(r))===null||i===void 0)&&i.isDown?xG:null})]}const up="-10000px";class FA{constructor(e,n,r,s){this.facet=n,this.createTooltipView=r,this.removeTooltipView=s,this.input=e.state.facet(n),this.tooltips=this.input.filter(l=>l);let i=null;this.tooltipViews=this.tooltips.map(l=>i=r(l,i))}update(e,n){var r;let s=e.state.facet(this.facet),i=s.filter(d=>d);if(s===this.input){for(let d of this.tooltipViews)d.update&&d.update(e);return!1}let l=[],c=n?[]:null;for(let d=0;dn[h]=d),n.length=c.length),this.input=s,this.tooltips=i,this.tooltipViews=l,!0}}function yG(t){let e=t.dom.ownerDocument.documentElement;return{top:0,left:0,bottom:e.clientHeight,right:e.clientWidth}}const Ly=He.define({combine:t=>{var e,n,r;return{position:Fe.ios?"absolute":((e=t.find(s=>s.position))===null||e===void 0?void 0:e.position)||"fixed",parent:((n=t.find(s=>s.parent))===null||n===void 0?void 0:n.parent)||null,tooltipSpace:((r=t.find(s=>s.tooltipSpace))===null||r===void 0?void 0:r.tooltipSpace)||yG}}}),Uj=new WeakMap,_w=lr.fromClass(class{constructor(t){this.view=t,this.above=[],this.inView=!0,this.madeAbsolute=!1,this.lastTransaction=0,this.measureTimeout=-1;let e=t.state.facet(Ly);this.position=e.position,this.parent=e.parent,this.classes=t.themeClasses,this.createContainer(),this.measureReq={read:this.readMeasure.bind(this),write:this.writeMeasure.bind(this),key:this},this.resizeObserver=typeof ResizeObserver=="function"?new ResizeObserver(()=>this.measureSoon()):null,this.manager=new FA(t,Dw,(n,r)=>this.createTooltip(n,r),n=>{this.resizeObserver&&this.resizeObserver.unobserve(n.dom),n.dom.remove()}),this.above=this.manager.tooltips.map(n=>!!n.above),this.intersectionObserver=typeof IntersectionObserver=="function"?new IntersectionObserver(n=>{Date.now()>this.lastTransaction-50&&n.length>0&&n[n.length-1].intersectionRatio<1&&this.measureSoon()},{threshold:[1]}):null,this.observeIntersection(),t.win.addEventListener("resize",this.measureSoon=this.measureSoon.bind(this)),this.maybeMeasure()}createContainer(){this.parent?(this.container=document.createElement("div"),this.container.style.position="relative",this.container.className=this.view.themeClasses,this.parent.appendChild(this.container)):this.container=this.view.dom}observeIntersection(){if(this.intersectionObserver){this.intersectionObserver.disconnect();for(let t of this.manager.tooltipViews)this.intersectionObserver.observe(t.dom)}}measureSoon(){this.measureTimeout<0&&(this.measureTimeout=setTimeout(()=>{this.measureTimeout=-1,this.maybeMeasure()},50))}update(t){t.transactions.length&&(this.lastTransaction=Date.now());let e=this.manager.update(t,this.above);e&&this.observeIntersection();let n=e||t.geometryChanged,r=t.state.facet(Ly);if(r.position!=this.position&&!this.madeAbsolute){this.position=r.position;for(let s of this.manager.tooltipViews)s.dom.style.position=this.position;n=!0}if(r.parent!=this.parent){this.parent&&this.container.remove(),this.parent=r.parent,this.createContainer();for(let s of this.manager.tooltipViews)this.container.appendChild(s.dom);n=!0}else this.parent&&this.view.themeClasses!=this.classes&&(this.classes=this.container.className=this.view.themeClasses);n&&this.maybeMeasure()}createTooltip(t,e){let n=t.create(this.view),r=e?e.dom:null;if(n.dom.classList.add("cm-tooltip"),t.arrow&&!n.dom.querySelector(".cm-tooltip > .cm-tooltip-arrow")){let s=document.createElement("div");s.className="cm-tooltip-arrow",n.dom.appendChild(s)}return n.dom.style.position=this.position,n.dom.style.top=up,n.dom.style.left="0px",this.container.insertBefore(n.dom,r),n.mount&&n.mount(this.view),this.resizeObserver&&this.resizeObserver.observe(n.dom),n}destroy(){var t,e,n;this.view.win.removeEventListener("resize",this.measureSoon);for(let r of this.manager.tooltipViews)r.dom.remove(),(t=r.destroy)===null||t===void 0||t.call(r);this.parent&&this.container.remove(),(e=this.resizeObserver)===null||e===void 0||e.disconnect(),(n=this.intersectionObserver)===null||n===void 0||n.disconnect(),clearTimeout(this.measureTimeout)}readMeasure(){let t=1,e=1,n=!1;if(this.position=="fixed"&&this.manager.tooltipViews.length){let{dom:i}=this.manager.tooltipViews[0];if(Fe.safari){let l=i.getBoundingClientRect();n=Math.abs(l.top+1e4)>1||Math.abs(l.left)>1}else n=!!i.offsetParent&&i.offsetParent!=this.container.ownerDocument.body}if(n||this.position=="absolute")if(this.parent){let i=this.parent.getBoundingClientRect();i.width&&i.height&&(t=i.width/this.parent.offsetWidth,e=i.height/this.parent.offsetHeight)}else({scaleX:t,scaleY:e}=this.view.viewState);let r=this.view.scrollDOM.getBoundingClientRect(),s=Tw(this.view);return{visible:{left:r.left+s.left,top:r.top+s.top,right:r.right-s.right,bottom:r.bottom-s.bottom},parent:this.parent?this.container.getBoundingClientRect():this.view.dom.getBoundingClientRect(),pos:this.manager.tooltips.map((i,l)=>{let c=this.manager.tooltipViews[l];return c.getCoords?c.getCoords(i.pos):this.view.coordsAtPos(i.pos)}),size:this.manager.tooltipViews.map(({dom:i})=>i.getBoundingClientRect()),space:this.view.state.facet(Ly).tooltipSpace(this.view),scaleX:t,scaleY:e,makeAbsolute:n}}writeMeasure(t){var e;if(t.makeAbsolute){this.madeAbsolute=!0,this.position="absolute";for(let c of this.manager.tooltipViews)c.dom.style.position="absolute"}let{visible:n,space:r,scaleX:s,scaleY:i}=t,l=[];for(let c=0;c=Math.min(n.bottom,r.bottom)||p.rightMath.min(n.right,r.right)+.1)){m.style.top=up;continue}let v=d.arrow?h.dom.querySelector(".cm-tooltip-arrow"):null,b=v?7:0,k=x.right-x.left,O=(e=Uj.get(h))!==null&&e!==void 0?e:x.bottom-x.top,j=h.offset||wG,T=this.view.textDirection==Hn.LTR,M=x.width>r.right-r.left?T?r.left:r.right-x.width:T?Math.max(r.left,Math.min(p.left-(v?14:0)+j.x,r.right-k)):Math.min(Math.max(r.left,p.left-k+(v?14:0)-j.x),r.right-k),_=this.above[c];!d.strictSide&&(_?p.top-O-b-j.yr.bottom)&&_==r.bottom-p.bottom>p.top-r.top&&(_=this.above[c]=!_);let D=(_?p.top-r.top:r.bottom-p.bottom)-b;if(DM&&Q.topE&&(E=_?Q.top-O-2-b:Q.bottom+b+2);if(this.position=="absolute"?(m.style.top=(E-t.parent.top)/i+"px",Vj(m,(M-t.parent.left)/s)):(m.style.top=E/i+"px",Vj(m,M/s)),v){let Q=p.left+(T?j.x:-j.x)-(M+14-7);v.style.left=Q/s+"px"}h.overlap!==!0&&l.push({left:M,top:E,right:z,bottom:E+O}),m.classList.toggle("cm-tooltip-above",_),m.classList.toggle("cm-tooltip-below",!_),h.positioned&&h.positioned(t.space)}}maybeMeasure(){if(this.manager.tooltips.length&&(this.view.inView&&this.view.requestMeasure(this.measureReq),this.inView!=this.view.inView&&(this.inView=this.view.inView,!this.inView)))for(let t of this.manager.tooltipViews)t.dom.style.top=up}},{eventObservers:{scroll(){this.maybeMeasure()}}});function Vj(t,e){let n=parseInt(t.style.left,10);(isNaN(n)||Math.abs(e-n)>1)&&(t.style.left=e+"px")}const bG=qe.baseTheme({".cm-tooltip":{zIndex:500,boxSizing:"border-box"},"&light .cm-tooltip":{border:"1px solid #bbb",backgroundColor:"#f5f5f5"},"&light .cm-tooltip-section:not(:first-child)":{borderTop:"1px solid #bbb"},"&dark .cm-tooltip":{backgroundColor:"#333338",color:"white"},".cm-tooltip-arrow":{height:"7px",width:"14px",position:"absolute",zIndex:-1,overflow:"hidden","&:before, &:after":{content:"''",position:"absolute",width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent"},".cm-tooltip-above &":{bottom:"-7px","&:before":{borderTop:"7px solid #bbb"},"&:after":{borderTop:"7px solid #f5f5f5",bottom:"1px"}},".cm-tooltip-below &":{top:"-7px","&:before":{borderBottom:"7px solid #bbb"},"&:after":{borderBottom:"7px solid #f5f5f5",top:"1px"}}},"&dark .cm-tooltip .cm-tooltip-arrow":{"&:before":{borderTopColor:"#333338",borderBottomColor:"#333338"},"&:after":{borderTopColor:"transparent",borderBottomColor:"transparent"}}}),wG={x:0,y:0},Dw=He.define({enables:[_w,bG]}),Mg=He.define({combine:t=>t.reduce((e,n)=>e.concat(n),[])});class Ox{static create(e){return new Ox(e)}constructor(e){this.view=e,this.mounted=!1,this.dom=document.createElement("div"),this.dom.classList.add("cm-tooltip-hover"),this.manager=new FA(e,Mg,(n,r)=>this.createHostedView(n,r),n=>n.dom.remove())}createHostedView(e,n){let r=e.create(this.view);return r.dom.classList.add("cm-tooltip-section"),this.dom.insertBefore(r.dom,n?n.dom.nextSibling:this.dom.firstChild),this.mounted&&r.mount&&r.mount(this.view),r}mount(e){for(let n of this.manager.tooltipViews)n.mount&&n.mount(e);this.mounted=!0}positioned(e){for(let n of this.manager.tooltipViews)n.positioned&&n.positioned(e)}update(e){this.manager.update(e)}destroy(){var e;for(let n of this.manager.tooltipViews)(e=n.destroy)===null||e===void 0||e.call(n)}passProp(e){let n;for(let r of this.manager.tooltipViews){let s=r[e];if(s!==void 0){if(n===void 0)n=s;else if(n!==s)return}}return n}get offset(){return this.passProp("offset")}get getCoords(){return this.passProp("getCoords")}get overlap(){return this.passProp("overlap")}get resize(){return this.passProp("resize")}}const SG=Dw.compute([Mg],t=>{let e=t.facet(Mg);return e.length===0?null:{pos:Math.min(...e.map(n=>n.pos)),end:Math.max(...e.map(n=>{var r;return(r=n.end)!==null&&r!==void 0?r:n.pos})),create:Ox.create,above:e[0].above,arrow:e.some(n=>n.arrow)}});class kG{constructor(e,n,r,s,i){this.view=e,this.source=n,this.field=r,this.setHover=s,this.hoverTime=i,this.hoverTimeout=-1,this.restartTimeout=-1,this.pending=null,this.lastMove={x:0,y:0,target:e.dom,time:0},this.checkHover=this.checkHover.bind(this),e.dom.addEventListener("mouseleave",this.mouseleave=this.mouseleave.bind(this)),e.dom.addEventListener("mousemove",this.mousemove=this.mousemove.bind(this))}update(){this.pending&&(this.pending=null,clearTimeout(this.restartTimeout),this.restartTimeout=setTimeout(()=>this.startHover(),20))}get active(){return this.view.state.field(this.field)}checkHover(){if(this.hoverTimeout=-1,this.active.length)return;let e=Date.now()-this.lastMove.time;ec.bottom||n.xc.right+e.defaultCharacterWidth)return;let d=e.bidiSpans(e.state.doc.lineAt(s)).find(m=>m.from<=s&&m.to>=s),h=d&&d.dir==Hn.RTL?-1:1;i=n.x{this.pending==c&&(this.pending=null,d&&!(Array.isArray(d)&&!d.length)&&e.dispatch({effects:this.setHover.of(Array.isArray(d)?d:[d])}))},d=>Es(e.state,d,"hover tooltip"))}else l&&!(Array.isArray(l)&&!l.length)&&e.dispatch({effects:this.setHover.of(Array.isArray(l)?l:[l])})}get tooltip(){let e=this.view.plugin(_w),n=e?e.manager.tooltips.findIndex(r=>r.create==Ox.create):-1;return n>-1?e.manager.tooltipViews[n]:null}mousemove(e){var n,r;this.lastMove={x:e.clientX,y:e.clientY,target:e.target,time:Date.now()},this.hoverTimeout<0&&(this.hoverTimeout=setTimeout(this.checkHover,this.hoverTime));let{active:s,tooltip:i}=this;if(s.length&&i&&!OG(i.dom,e)||this.pending){let{pos:l}=s[0]||this.pending,c=(r=(n=s[0])===null||n===void 0?void 0:n.end)!==null&&r!==void 0?r:l;(l==c?this.view.posAtCoords(this.lastMove)!=l:!jG(this.view,l,c,e.clientX,e.clientY))&&(this.view.dispatch({effects:this.setHover.of([])}),this.pending=null)}}mouseleave(e){clearTimeout(this.hoverTimeout),this.hoverTimeout=-1;let{active:n}=this;if(n.length){let{tooltip:r}=this;r&&r.dom.contains(e.relatedTarget)?this.watchTooltipLeave(r.dom):this.view.dispatch({effects:this.setHover.of([])})}}watchTooltipLeave(e){let n=r=>{e.removeEventListener("mouseleave",n),this.active.length&&!this.view.dom.contains(r.relatedTarget)&&this.view.dispatch({effects:this.setHover.of([])})};e.addEventListener("mouseleave",n)}destroy(){clearTimeout(this.hoverTimeout),this.view.dom.removeEventListener("mouseleave",this.mouseleave),this.view.dom.removeEventListener("mousemove",this.mousemove)}}const dp=4;function OG(t,e){let{left:n,right:r,top:s,bottom:i}=t.getBoundingClientRect(),l;if(l=t.querySelector(".cm-tooltip-arrow")){let c=l.getBoundingClientRect();s=Math.min(c.top,s),i=Math.max(c.bottom,i)}return e.clientX>=n-dp&&e.clientX<=r+dp&&e.clientY>=s-dp&&e.clientY<=i+dp}function jG(t,e,n,r,s,i){let l=t.scrollDOM.getBoundingClientRect(),c=t.documentTop+t.documentPadding.top+t.contentHeight;if(l.left>r||l.rights||Math.min(l.bottom,c)=e&&d<=n}function NG(t,e={}){let n=xt.define(),r=Lr.define({create(){return[]},update(s,i){if(s.length&&(e.hideOnChange&&(i.docChanged||i.selection)?s=[]:e.hideOn&&(s=s.filter(l=>!e.hideOn(i,l))),i.docChanged)){let l=[];for(let c of s){let d=i.changes.mapPos(c.pos,-1,Ur.TrackDel);if(d!=null){let h=Object.assign(Object.create(null),c);h.pos=d,h.end!=null&&(h.end=i.changes.mapPos(h.end)),l.push(h)}}s=l}for(let l of i.effects)l.is(n)&&(s=l.value),l.is(CG)&&(s=[]);return s},provide:s=>Mg.from(s)});return{active:r,extension:[r,lr.define(s=>new kG(s,t,r,n,e.hoverTime||300)),SG]}}function QA(t,e){let n=t.plugin(_w);if(!n)return null;let r=n.manager.tooltips.indexOf(e);return r<0?null:n.manager.tooltipViews[r]}const CG=xt.define(),Wj=He.define({combine(t){let e,n;for(let r of t)e=e||r.topContainer,n=n||r.bottomContainer;return{topContainer:e,bottomContainer:n}}});function wf(t,e){let n=t.plugin($A),r=n?n.specs.indexOf(e):-1;return r>-1?n.panels[r]:null}const $A=lr.fromClass(class{constructor(t){this.input=t.state.facet(Sf),this.specs=this.input.filter(n=>n),this.panels=this.specs.map(n=>n(t));let e=t.state.facet(Wj);this.top=new hp(t,!0,e.topContainer),this.bottom=new hp(t,!1,e.bottomContainer),this.top.sync(this.panels.filter(n=>n.top)),this.bottom.sync(this.panels.filter(n=>!n.top));for(let n of this.panels)n.dom.classList.add("cm-panel"),n.mount&&n.mount()}update(t){let e=t.state.facet(Wj);this.top.container!=e.topContainer&&(this.top.sync([]),this.top=new hp(t.view,!0,e.topContainer)),this.bottom.container!=e.bottomContainer&&(this.bottom.sync([]),this.bottom=new hp(t.view,!1,e.bottomContainer)),this.top.syncClasses(),this.bottom.syncClasses();let n=t.state.facet(Sf);if(n!=this.input){let r=n.filter(d=>d),s=[],i=[],l=[],c=[];for(let d of r){let h=this.specs.indexOf(d),m;h<0?(m=d(t.view),c.push(m)):(m=this.panels[h],m.update&&m.update(t)),s.push(m),(m.top?i:l).push(m)}this.specs=r,this.panels=s,this.top.sync(i),this.bottom.sync(l);for(let d of c)d.dom.classList.add("cm-panel"),d.mount&&d.mount()}else for(let r of this.panels)r.update&&r.update(t)}destroy(){this.top.sync([]),this.bottom.sync([])}},{provide:t=>qe.scrollMargins.of(e=>{let n=e.plugin(t);return n&&{top:n.top.scrollMargin(),bottom:n.bottom.scrollMargin()}})});class hp{constructor(e,n,r){this.view=e,this.top=n,this.container=r,this.dom=void 0,this.classes="",this.panels=[],this.syncClasses()}sync(e){for(let n of this.panels)n.destroy&&e.indexOf(n)<0&&n.destroy();this.panels=e,this.syncDOM()}syncDOM(){if(this.panels.length==0){this.dom&&(this.dom.remove(),this.dom=void 0);return}if(!this.dom){this.dom=document.createElement("div"),this.dom.className=this.top?"cm-panels cm-panels-top":"cm-panels cm-panels-bottom",this.dom.style[this.top?"top":"bottom"]="0";let n=this.container||this.view.dom;n.insertBefore(this.dom,this.top?n.firstChild:null)}let e=this.dom.firstChild;for(let n of this.panels)if(n.dom.parentNode==this.dom){for(;e!=n.dom;)e=Gj(e);e=e.nextSibling}else this.dom.insertBefore(n.dom,e);for(;e;)e=Gj(e)}scrollMargin(){return!this.dom||this.container?0:Math.max(0,this.top?this.dom.getBoundingClientRect().bottom-Math.max(0,this.view.scrollDOM.getBoundingClientRect().top):Math.min(innerHeight,this.view.scrollDOM.getBoundingClientRect().bottom)-this.dom.getBoundingClientRect().top)}syncClasses(){if(!(!this.container||this.classes==this.view.themeClasses)){for(let e of this.classes.split(" "))e&&this.container.classList.remove(e);for(let e of(this.classes=this.view.themeClasses).split(" "))e&&this.container.classList.add(e)}}}function Gj(t){let e=t.nextSibling;return t.remove(),e}const Sf=He.define({enables:$A});class pl extends yc{compare(e){return this==e||this.constructor==e.constructor&&this.eq(e)}eq(e){return!1}destroy(e){}}pl.prototype.elementClass="";pl.prototype.toDOM=void 0;pl.prototype.mapMode=Ur.TrackBefore;pl.prototype.startSide=pl.prototype.endSide=-1;pl.prototype.point=!0;const ng=He.define(),TG=He.define(),MG={class:"",renderEmptyElements:!1,elementStyle:"",markers:()=>Gt.empty,lineMarker:()=>null,widgetMarker:()=>null,lineMarkerChange:null,initialSpacer:null,updateSpacer:null,domEventHandlers:{},side:"before"},rf=He.define();function AG(t){return[HA(),rf.of({...MG,...t})]}const Xj=He.define({combine:t=>t.some(e=>e)});function HA(t){return[EG]}const EG=lr.fromClass(class{constructor(t){this.view=t,this.domAfter=null,this.prevViewport=t.viewport,this.dom=document.createElement("div"),this.dom.className="cm-gutters cm-gutters-before",this.dom.setAttribute("aria-hidden","true"),this.dom.style.minHeight=this.view.contentHeight/this.view.scaleY+"px",this.gutters=t.state.facet(rf).map(e=>new Kj(t,e)),this.fixed=!t.state.facet(Xj);for(let e of this.gutters)e.config.side=="after"?this.getDOMAfter().appendChild(e.dom):this.dom.appendChild(e.dom);this.fixed&&(this.dom.style.position="sticky"),this.syncGutters(!1),t.scrollDOM.insertBefore(this.dom,t.contentDOM)}getDOMAfter(){return this.domAfter||(this.domAfter=document.createElement("div"),this.domAfter.className="cm-gutters cm-gutters-after",this.domAfter.setAttribute("aria-hidden","true"),this.domAfter.style.minHeight=this.view.contentHeight/this.view.scaleY+"px",this.domAfter.style.position=this.fixed?"sticky":"",this.view.scrollDOM.appendChild(this.domAfter)),this.domAfter}update(t){if(this.updateGutters(t)){let e=this.prevViewport,n=t.view.viewport,r=Math.min(e.to,n.to)-Math.max(e.from,n.from);this.syncGutters(r<(n.to-n.from)*.8)}if(t.geometryChanged){let e=this.view.contentHeight/this.view.scaleY+"px";this.dom.style.minHeight=e,this.domAfter&&(this.domAfter.style.minHeight=e)}this.view.state.facet(Xj)!=!this.fixed&&(this.fixed=!this.fixed,this.dom.style.position=this.fixed?"sticky":"",this.domAfter&&(this.domAfter.style.position=this.fixed?"sticky":"")),this.prevViewport=t.view.viewport}syncGutters(t){let e=this.dom.nextSibling;t&&(this.dom.remove(),this.domAfter&&this.domAfter.remove());let n=Gt.iter(this.view.state.facet(ng),this.view.viewport.from),r=[],s=this.gutters.map(i=>new _G(i,this.view.viewport,-this.view.documentPadding.top));for(let i of this.view.viewportLineBlocks)if(r.length&&(r=[]),Array.isArray(i.type)){let l=!0;for(let c of i.type)if(c.type==fs.Text&&l){X2(n,r,c.from);for(let d of s)d.line(this.view,c,r);l=!1}else if(c.widget)for(let d of s)d.widget(this.view,c)}else if(i.type==fs.Text){X2(n,r,i.from);for(let l of s)l.line(this.view,i,r)}else if(i.widget)for(let l of s)l.widget(this.view,i);for(let i of s)i.finish();t&&(this.view.scrollDOM.insertBefore(this.dom,e),this.domAfter&&this.view.scrollDOM.appendChild(this.domAfter))}updateGutters(t){let e=t.startState.facet(rf),n=t.state.facet(rf),r=t.docChanged||t.heightChanged||t.viewportChanged||!Gt.eq(t.startState.facet(ng),t.state.facet(ng),t.view.viewport.from,t.view.viewport.to);if(e==n)for(let s of this.gutters)s.update(t)&&(r=!0);else{r=!0;let s=[];for(let i of n){let l=e.indexOf(i);l<0?s.push(new Kj(this.view,i)):(this.gutters[l].update(t),s.push(this.gutters[l]))}for(let i of this.gutters)i.dom.remove(),s.indexOf(i)<0&&i.destroy();for(let i of s)i.config.side=="after"?this.getDOMAfter().appendChild(i.dom):this.dom.appendChild(i.dom);this.gutters=s}return r}destroy(){for(let t of this.gutters)t.destroy();this.dom.remove(),this.domAfter&&this.domAfter.remove()}},{provide:t=>qe.scrollMargins.of(e=>{let n=e.plugin(t);if(!n||n.gutters.length==0||!n.fixed)return null;let r=n.dom.offsetWidth*e.scaleX,s=n.domAfter?n.domAfter.offsetWidth*e.scaleX:0;return e.textDirection==Hn.LTR?{left:r,right:s}:{right:r,left:s}})});function Yj(t){return Array.isArray(t)?t:[t]}function X2(t,e,n){for(;t.value&&t.from<=n;)t.from==n&&e.push(t.value),t.next()}class _G{constructor(e,n,r){this.gutter=e,this.height=r,this.i=0,this.cursor=Gt.iter(e.markers,n.from)}addElement(e,n,r){let{gutter:s}=this,i=(n.top-this.height)/e.scaleY,l=n.height/e.scaleY;if(this.i==s.elements.length){let c=new UA(e,l,i,r);s.elements.push(c),s.dom.appendChild(c.dom)}else s.elements[this.i].update(e,l,i,r);this.height=n.bottom,this.i++}line(e,n,r){let s=[];X2(this.cursor,s,n.from),r.length&&(s=s.concat(r));let i=this.gutter.config.lineMarker(e,n,s);i&&s.unshift(i);let l=this.gutter;s.length==0&&!l.config.renderEmptyElements||this.addElement(e,n,s)}widget(e,n){let r=this.gutter.config.widgetMarker(e,n.widget,n),s=r?[r]:null;for(let i of e.state.facet(TG)){let l=i(e,n.widget,n);l&&(s||(s=[])).push(l)}s&&this.addElement(e,n,s)}finish(){let e=this.gutter;for(;e.elements.length>this.i;){let n=e.elements.pop();e.dom.removeChild(n.dom),n.destroy()}}}class Kj{constructor(e,n){this.view=e,this.config=n,this.elements=[],this.spacer=null,this.dom=document.createElement("div"),this.dom.className="cm-gutter"+(this.config.class?" "+this.config.class:"");for(let r in n.domEventHandlers)this.dom.addEventListener(r,s=>{let i=s.target,l;if(i!=this.dom&&this.dom.contains(i)){for(;i.parentNode!=this.dom;)i=i.parentNode;let d=i.getBoundingClientRect();l=(d.top+d.bottom)/2}else l=s.clientY;let c=e.lineBlockAtHeight(l-e.documentTop);n.domEventHandlers[r](e,c,s)&&s.preventDefault()});this.markers=Yj(n.markers(e)),n.initialSpacer&&(this.spacer=new UA(e,0,0,[n.initialSpacer(e)]),this.dom.appendChild(this.spacer.dom),this.spacer.dom.style.cssText+="visibility: hidden; pointer-events: none")}update(e){let n=this.markers;if(this.markers=Yj(this.config.markers(e.view)),this.spacer&&this.config.updateSpacer){let s=this.config.updateSpacer(this.spacer.markers[0],e);s!=this.spacer.markers[0]&&this.spacer.update(e.view,0,0,[s])}let r=e.view.viewport;return!Gt.eq(this.markers,n,r.from,r.to)||(this.config.lineMarkerChange?this.config.lineMarkerChange(e):!1)}destroy(){for(let e of this.elements)e.destroy()}}class UA{constructor(e,n,r,s){this.height=-1,this.above=0,this.markers=[],this.dom=document.createElement("div"),this.dom.className="cm-gutterElement",this.update(e,n,r,s)}update(e,n,r,s){this.height!=n&&(this.height=n,this.dom.style.height=n+"px"),this.above!=r&&(this.dom.style.marginTop=(this.above=r)?r+"px":""),DG(this.markers,s)||this.setMarkers(e,s)}setMarkers(e,n){let r="cm-gutterElement",s=this.dom.firstChild;for(let i=0,l=0;;){let c=l,d=ii(c,d,h)||l(c,d,h):l}return r}})}});class By extends pl{constructor(e){super(),this.number=e}eq(e){return this.number==e.number}toDOM(){return document.createTextNode(this.number)}}function Iy(t,e){return t.state.facet(Qu).formatNumber(e,t.state)}const PG=rf.compute([Qu],t=>({class:"cm-lineNumbers",renderEmptyElements:!1,markers(e){return e.state.facet(RG)},lineMarker(e,n,r){return r.some(s=>s.toDOM)?null:new By(Iy(e,e.state.doc.lineAt(n.from).number))},widgetMarker:(e,n,r)=>{for(let s of e.state.facet(zG)){let i=s(e,n,r);if(i)return i}return null},lineMarkerChange:e=>e.startState.facet(Qu)!=e.state.facet(Qu),initialSpacer(e){return new By(Iy(e,Zj(e.state.doc.lines)))},updateSpacer(e,n){let r=Iy(n.view,Zj(n.view.state.doc.lines));return r==e.number?e:new By(r)},domEventHandlers:t.facet(Qu).domEventHandlers,side:"before"}));function LG(t={}){return[Qu.of(t),HA(),PG]}function Zj(t){let e=9;for(;e{let e=[],n=-1;for(let r of t.selection.ranges){let s=t.doc.lineAt(r.head).from;s>n&&(n=s,e.push(BG.range(s)))}return Gt.of(e)});function qG(){return IG}const VA=1024;let FG=0;class qy{constructor(e,n){this.from=e,this.to=n}}class Et{constructor(e={}){this.id=FG++,this.perNode=!!e.perNode,this.deserialize=e.deserialize||(()=>{throw new Error("This node type doesn't define a deserialize function")}),this.combine=e.combine||null}add(e){if(this.perNode)throw new RangeError("Can't add per-node props to node types");return typeof e!="function"&&(e=gs.match(e)),n=>{let r=e(n);return r===void 0?null:[this,r]}}}Et.closedBy=new Et({deserialize:t=>t.split(" ")});Et.openedBy=new Et({deserialize:t=>t.split(" ")});Et.group=new Et({deserialize:t=>t.split(" ")});Et.isolate=new Et({deserialize:t=>{if(t&&t!="rtl"&&t!="ltr"&&t!="auto")throw new RangeError("Invalid value for isolate: "+t);return t||"auto"}});Et.contextHash=new Et({perNode:!0});Et.lookAhead=new Et({perNode:!0});Et.mounted=new Et({perNode:!0});class Ag{constructor(e,n,r){this.tree=e,this.overlay=n,this.parser=r}static get(e){return e&&e.props&&e.props[Et.mounted.id]}}const QG=Object.create(null);class gs{constructor(e,n,r,s=0){this.name=e,this.props=n,this.id=r,this.flags=s}static define(e){let n=e.props&&e.props.length?Object.create(null):QG,r=(e.top?1:0)|(e.skipped?2:0)|(e.error?4:0)|(e.name==null?8:0),s=new gs(e.name||"",n,e.id,r);if(e.props){for(let i of e.props)if(Array.isArray(i)||(i=i(s)),i){if(i[0].perNode)throw new RangeError("Can't store a per-node prop on a node type");n[i[0].id]=i[1]}}return s}prop(e){return this.props[e.id]}get isTop(){return(this.flags&1)>0}get isSkipped(){return(this.flags&2)>0}get isError(){return(this.flags&4)>0}get isAnonymous(){return(this.flags&8)>0}is(e){if(typeof e=="string"){if(this.name==e)return!0;let n=this.prop(Et.group);return n?n.indexOf(e)>-1:!1}return this.id==e}static match(e){let n=Object.create(null);for(let r in e)for(let s of r.split(" "))n[s]=e[r];return r=>{for(let s=r.prop(Et.group),i=-1;i<(s?s.length:0);i++){let l=n[i<0?r.name:s[i]];if(l)return l}}}}gs.none=new gs("",Object.create(null),0,8);class jx{constructor(e){this.types=e;for(let n=0;n0;for(let d=this.cursor(l|Or.IncludeAnonymous);;){let h=!1;if(d.from<=i&&d.to>=s&&(!c&&d.type.isAnonymous||n(d)!==!1)){if(d.firstChild())continue;h=!0}for(;h&&r&&(c||!d.type.isAnonymous)&&r(d),!d.nextSibling();){if(!d.parent())return;h=!0}}}prop(e){return e.perNode?this.props?this.props[e.id]:void 0:this.type.prop(e)}get propValues(){let e=[];if(this.props)for(let n in this.props)e.push([+n,this.props[n]]);return e}balance(e={}){return this.children.length<=8?this:Pw(gs.none,this.children,this.positions,0,this.children.length,0,this.length,(n,r,s)=>new _n(this.type,n,r,s,this.propValues),e.makeTree||((n,r,s)=>new _n(gs.none,n,r,s)))}static build(e){return VG(e)}}_n.empty=new _n(gs.none,[],[],0);class Rw{constructor(e,n){this.buffer=e,this.index=n}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}get pos(){return this.index}next(){this.index-=4}fork(){return new Rw(this.buffer,this.index)}}class po{constructor(e,n,r){this.buffer=e,this.length=n,this.set=r}get type(){return gs.none}toString(){let e=[];for(let n=0;n0));d=l[d+3]);return c}slice(e,n,r){let s=this.buffer,i=new Uint16Array(n-e),l=0;for(let c=e,d=0;c=e&&ne;case 1:return n<=e&&r>e;case 2:return r>e;case 4:return!0}}function kf(t,e,n,r){for(var s;t.from==t.to||(n<1?t.from>=e:t.from>e)||(n>-1?t.to<=e:t.to0?c.length:-1;e!=h;e+=n){let m=c[e],p=d[e]+l.from;if(WA(s,r,p,p+m.length)){if(m instanceof po){if(i&Or.ExcludeBuffers)continue;let x=m.findChild(0,m.buffer.length,n,r-p,s);if(x>-1)return new da(new $G(l,m,e,p),null,x)}else if(i&Or.IncludeAnonymous||!m.type.isAnonymous||zw(m)){let x;if(!(i&Or.IgnoreMounts)&&(x=Ag.get(m))&&!x.overlay)return new zs(x.tree,p,e,l);let v=new zs(m,p,e,l);return i&Or.IncludeAnonymous||!v.type.isAnonymous?v:v.nextChild(n<0?m.children.length-1:0,n,r,s)}}}if(i&Or.IncludeAnonymous||!l.type.isAnonymous||(l.index>=0?e=l.index+n:e=n<0?-1:l._parent._tree.children.length,l=l._parent,!l))return null}}get firstChild(){return this.nextChild(0,1,0,4)}get lastChild(){return this.nextChild(this._tree.children.length-1,-1,0,4)}childAfter(e){return this.nextChild(0,1,e,2)}childBefore(e){return this.nextChild(this._tree.children.length-1,-1,e,-2)}enter(e,n,r=0){let s;if(!(r&Or.IgnoreOverlays)&&(s=Ag.get(this._tree))&&s.overlay){let i=e-this.from;for(let{from:l,to:c}of s.overlay)if((n>0?l<=i:l=i:c>i))return new zs(s.tree,s.overlay[0].from+this.from,-1,this)}return this.nextChild(0,1,e,n,r)}nextSignificantParent(){let e=this;for(;e.type.isAnonymous&&e._parent;)e=e._parent;return e}get parent(){return this._parent?this._parent.nextSignificantParent():null}get nextSibling(){return this._parent&&this.index>=0?this._parent.nextChild(this.index+1,1,0,4):null}get prevSibling(){return this._parent&&this.index>=0?this._parent.nextChild(this.index-1,-1,0,4):null}get tree(){return this._tree}toTree(){return this._tree}toString(){return this._tree.toString()}}function e7(t,e,n,r){let s=t.cursor(),i=[];if(!s.firstChild())return i;if(n!=null){for(let l=!1;!l;)if(l=s.type.is(n),!s.nextSibling())return i}for(;;){if(r!=null&&s.type.is(r))return i;if(s.type.is(e)&&i.push(s.node),!s.nextSibling())return r==null?i:[]}}function Y2(t,e,n=e.length-1){for(let r=t;n>=0;r=r.parent){if(!r)return!1;if(!r.type.isAnonymous){if(e[n]&&e[n]!=r.name)return!1;n--}}return!0}class $G{constructor(e,n,r,s){this.parent=e,this.buffer=n,this.index=r,this.start=s}}class da extends GA{get name(){return this.type.name}get from(){return this.context.start+this.context.buffer.buffer[this.index+1]}get to(){return this.context.start+this.context.buffer.buffer[this.index+2]}constructor(e,n,r){super(),this.context=e,this._parent=n,this.index=r,this.type=e.buffer.set.types[e.buffer.buffer[r]]}child(e,n,r){let{buffer:s}=this.context,i=s.findChild(this.index+4,s.buffer[this.index+3],e,n-this.context.start,r);return i<0?null:new da(this.context,this,i)}get firstChild(){return this.child(1,0,4)}get lastChild(){return this.child(-1,0,4)}childAfter(e){return this.child(1,e,2)}childBefore(e){return this.child(-1,e,-2)}enter(e,n,r=0){if(r&Or.ExcludeBuffers)return null;let{buffer:s}=this.context,i=s.findChild(this.index+4,s.buffer[this.index+3],n>0?1:-1,e-this.context.start,n);return i<0?null:new da(this.context,this,i)}get parent(){return this._parent||this.context.parent.nextSignificantParent()}externalSibling(e){return this._parent?null:this.context.parent.nextChild(this.context.index+e,e,0,4)}get nextSibling(){let{buffer:e}=this.context,n=e.buffer[this.index+3];return n<(this._parent?e.buffer[this._parent.index+3]:e.buffer.length)?new da(this.context,this._parent,n):this.externalSibling(1)}get prevSibling(){let{buffer:e}=this.context,n=this._parent?this._parent.index+4:0;return this.index==n?this.externalSibling(-1):new da(this.context,this._parent,e.findChild(n,this.index,-1,0,4))}get tree(){return null}toTree(){let e=[],n=[],{buffer:r}=this.context,s=this.index+4,i=r.buffer[this.index+3];if(i>s){let l=r.buffer[this.index+1];e.push(r.slice(s,i,l)),n.push(0)}return new _n(this.type,e,n,this.to-this.from)}toString(){return this.context.buffer.childString(this.index)}}function XA(t){if(!t.length)return null;let e=0,n=t[0];for(let i=1;in.from||l.to=e){let c=new zs(l.tree,l.overlay[0].from+i.from,-1,i);(s||(s=[r])).push(kf(c,e,n,!1))}}return s?XA(s):r}class K2{get name(){return this.type.name}constructor(e,n=0){if(this.mode=n,this.buffer=null,this.stack=[],this.index=0,this.bufferNode=null,e instanceof zs)this.yieldNode(e);else{this._tree=e.context.parent,this.buffer=e.context;for(let r=e._parent;r;r=r._parent)this.stack.unshift(r.index);this.bufferNode=e,this.yieldBuf(e.index)}}yieldNode(e){return e?(this._tree=e,this.type=e.type,this.from=e.from,this.to=e.to,!0):!1}yieldBuf(e,n){this.index=e;let{start:r,buffer:s}=this.buffer;return this.type=n||s.set.types[s.buffer[e]],this.from=r+s.buffer[e+1],this.to=r+s.buffer[e+2],!0}yield(e){return e?e instanceof zs?(this.buffer=null,this.yieldNode(e)):(this.buffer=e.context,this.yieldBuf(e.index,e.type)):!1}toString(){return this.buffer?this.buffer.buffer.childString(this.index):this._tree.toString()}enterChild(e,n,r){if(!this.buffer)return this.yield(this._tree.nextChild(e<0?this._tree._tree.children.length-1:0,e,n,r,this.mode));let{buffer:s}=this.buffer,i=s.findChild(this.index+4,s.buffer[this.index+3],e,n-this.buffer.start,r);return i<0?!1:(this.stack.push(this.index),this.yieldBuf(i))}firstChild(){return this.enterChild(1,0,4)}lastChild(){return this.enterChild(-1,0,4)}childAfter(e){return this.enterChild(1,e,2)}childBefore(e){return this.enterChild(-1,e,-2)}enter(e,n,r=this.mode){return this.buffer?r&Or.ExcludeBuffers?!1:this.enterChild(1,e,n):this.yield(this._tree.enter(e,n,r))}parent(){if(!this.buffer)return this.yieldNode(this.mode&Or.IncludeAnonymous?this._tree._parent:this._tree.parent);if(this.stack.length)return this.yieldBuf(this.stack.pop());let e=this.mode&Or.IncludeAnonymous?this.buffer.parent:this.buffer.parent.nextSignificantParent();return this.buffer=null,this.yieldNode(e)}sibling(e){if(!this.buffer)return this._tree._parent?this.yield(this._tree.index<0?null:this._tree._parent.nextChild(this._tree.index+e,e,0,4,this.mode)):!1;let{buffer:n}=this.buffer,r=this.stack.length-1;if(e<0){let s=r<0?0:this.stack[r]+4;if(this.index!=s)return this.yieldBuf(n.findChild(s,this.index,-1,0,4))}else{let s=n.buffer[this.index+3];if(s<(r<0?n.buffer.length:n.buffer[this.stack[r]+3]))return this.yieldBuf(s)}return r<0?this.yield(this.buffer.parent.nextChild(this.buffer.index+e,e,0,4,this.mode)):!1}nextSibling(){return this.sibling(1)}prevSibling(){return this.sibling(-1)}atLastNode(e){let n,r,{buffer:s}=this;if(s){if(e>0){if(this.index-1)for(let i=n+e,l=e<0?-1:r._tree.children.length;i!=l;i+=e){let c=r._tree.children[i];if(this.mode&Or.IncludeAnonymous||c instanceof po||!c.type.isAnonymous||zw(c))return!1}return!0}move(e,n){if(n&&this.enterChild(e,0,4))return!0;for(;;){if(this.sibling(e))return!0;if(this.atLastNode(e)||!this.parent())return!1}}next(e=!0){return this.move(1,e)}prev(e=!0){return this.move(-1,e)}moveTo(e,n=0){for(;(this.from==this.to||(n<1?this.from>=e:this.from>e)||(n>-1?this.to<=e:this.to=0;){for(let l=e;l;l=l._parent)if(l.index==s){if(s==this.index)return l;n=l,r=i+1;break e}s=this.stack[--i]}for(let s=r;s=0;i--){if(i<0)return Y2(this._tree,e,s);let l=r[n.buffer[this.stack[i]]];if(!l.isAnonymous){if(e[s]&&e[s]!=l.name)return!1;s--}}return!0}}function zw(t){return t.children.some(e=>e instanceof po||!e.type.isAnonymous||zw(e))}function VG(t){var e;let{buffer:n,nodeSet:r,maxBufferLength:s=VA,reused:i=[],minRepeatType:l=r.types.length}=t,c=Array.isArray(n)?new Rw(n,n.length):n,d=r.types,h=0,m=0;function p(D,E,z,Q,F,B){let{id:U,start:V,end:ce,size:W}=c,J=m,H=h;if(W<0)if(c.next(),W==-1){let me=i[U];z.push(me),Q.push(V-D);return}else if(W==-3){h=U;return}else if(W==-4){m=U;return}else throw new RangeError(`Unrecognized record size: ${W}`);let ae=d[U],ne,ue,R=V-D;if(ce-V<=s&&(ue=O(c.pos-E,F))){let me=new Uint16Array(ue.size-ue.skip),Y=c.pos-ue.size,P=me.length;for(;c.pos>Y;)P=j(ue.start,me,P);ne=new po(me,ce-ue.start,r),R=ue.start-D}else{let me=c.pos-W;c.next();let Y=[],P=[],K=U>=l?U:-1,$=0,fe=ce;for(;c.pos>me;)K>=0&&c.id==K&&c.size>=0?(c.end<=fe-s&&(b(Y,P,V,$,c.end,fe,K,J,H),$=Y.length,fe=c.end),c.next()):B>2500?x(V,me,Y,P):p(V,me,Y,P,K,B+1);if(K>=0&&$>0&&$-1&&$>0){let ve=v(ae,H);ne=Pw(ae,Y,P,0,Y.length,0,ce-V,ve,ve)}else ne=k(ae,Y,P,ce-V,J-ce,H)}z.push(ne),Q.push(R)}function x(D,E,z,Q){let F=[],B=0,U=-1;for(;c.pos>E;){let{id:V,start:ce,end:W,size:J}=c;if(J>4)c.next();else{if(U>-1&&ce=0;W-=3)V[J++]=F[W],V[J++]=F[W+1]-ce,V[J++]=F[W+2]-ce,V[J++]=J;z.push(new po(V,F[2]-ce,r)),Q.push(ce-D)}}function v(D,E){return(z,Q,F)=>{let B=0,U=z.length-1,V,ce;if(U>=0&&(V=z[U])instanceof _n){if(!U&&V.type==D&&V.length==F)return V;(ce=V.prop(Et.lookAhead))&&(B=Q[U]+V.length+ce)}return k(D,z,Q,F,B,E)}}function b(D,E,z,Q,F,B,U,V,ce){let W=[],J=[];for(;D.length>Q;)W.push(D.pop()),J.push(E.pop()+z-F);D.push(k(r.types[U],W,J,B-F,V-B,ce)),E.push(F-z)}function k(D,E,z,Q,F,B,U){if(B){let V=[Et.contextHash,B];U=U?[V].concat(U):[V]}if(F>25){let V=[Et.lookAhead,F];U=U?[V].concat(U):[V]}return new _n(D,E,z,Q,U)}function O(D,E){let z=c.fork(),Q=0,F=0,B=0,U=z.end-s,V={size:0,start:0,skip:0};e:for(let ce=z.pos-D;z.pos>ce;){let W=z.size;if(z.id==E&&W>=0){V.size=Q,V.start=F,V.skip=B,B+=4,Q+=4,z.next();continue}let J=z.pos-W;if(W<0||J=l?4:0,ae=z.start;for(z.next();z.pos>J;){if(z.size<0)if(z.size==-3)H+=4;else break e;else z.id>=l&&(H+=4);z.next()}F=ae,Q+=W,B+=H}return(E<0||Q==D)&&(V.size=Q,V.start=F,V.skip=B),V.size>4?V:void 0}function j(D,E,z){let{id:Q,start:F,end:B,size:U}=c;if(c.next(),U>=0&&Q4){let ce=c.pos-(U-4);for(;c.pos>ce;)z=j(D,E,z)}E[--z]=V,E[--z]=B-D,E[--z]=F-D,E[--z]=Q}else U==-3?h=Q:U==-4&&(m=Q);return z}let T=[],M=[];for(;c.pos>0;)p(t.start||0,t.bufferStart||0,T,M,-1,0);let _=(e=t.length)!==null&&e!==void 0?e:T.length?M[0]+T[0].length:0;return new _n(d[t.topID],T.reverse(),M.reverse(),_)}const t7=new WeakMap;function rg(t,e){if(!t.isAnonymous||e instanceof po||e.type!=t)return 1;let n=t7.get(e);if(n==null){n=1;for(let r of e.children){if(r.type!=t||!(r instanceof _n)){n=1;break}n+=rg(t,r)}t7.set(e,n)}return n}function Pw(t,e,n,r,s,i,l,c,d){let h=0;for(let b=r;b=m)break;E+=z}if(M==_+1){if(E>m){let z=b[_];v(z.children,z.positions,0,z.children.length,k[_]+T);continue}p.push(b[_])}else{let z=k[M-1]+b[M-1].length-D;p.push(Pw(t,b,k,_,M,D,z,null,d))}x.push(D+T-i)}}return v(e,n,r,s,0),(c||d)(p,x,l)}class WG{constructor(){this.map=new WeakMap}setBuffer(e,n,r){let s=this.map.get(e);s||this.map.set(e,s=new Map),s.set(n,r)}getBuffer(e,n){let r=this.map.get(e);return r&&r.get(n)}set(e,n){e instanceof da?this.setBuffer(e.context.buffer,e.index,n):e instanceof zs&&this.map.set(e.tree,n)}get(e){return e instanceof da?this.getBuffer(e.context.buffer,e.index):e instanceof zs?this.map.get(e.tree):void 0}cursorSet(e,n){e.buffer?this.setBuffer(e.buffer.buffer,e.index,n):this.map.set(e.tree,n)}cursorGet(e){return e.buffer?this.getBuffer(e.buffer.buffer,e.index):this.map.get(e.tree)}}class pc{constructor(e,n,r,s,i=!1,l=!1){this.from=e,this.to=n,this.tree=r,this.offset=s,this.open=(i?1:0)|(l?2:0)}get openStart(){return(this.open&1)>0}get openEnd(){return(this.open&2)>0}static addTree(e,n=[],r=!1){let s=[new pc(0,e.length,e,0,!1,r)];for(let i of n)i.to>e.length&&s.push(i);return s}static applyChanges(e,n,r=128){if(!n.length)return e;let s=[],i=1,l=e.length?e[0]:null;for(let c=0,d=0,h=0;;c++){let m=c=r)for(;l&&l.from=x.from||p<=x.to||h){let v=Math.max(x.from,d)-h,b=Math.min(x.to,p)-h;x=v>=b?null:new pc(v,b,x.tree,x.offset+h,c>0,!!m)}if(x&&s.push(x),l.to>p)break;l=inew qy(s.from,s.to)):[new qy(0,0)]:[new qy(0,e.length)],this.createParse(e,n||[],r)}parse(e,n,r){let s=this.startParse(e,n,r);for(;;){let i=s.advance();if(i)return i}}};class GG{constructor(e){this.string=e}get length(){return this.string.length}chunk(e){return this.string.slice(e)}get lineChunks(){return!1}read(e,n){return this.string.slice(e,n)}}new Et({perNode:!0});let XG=0;class vi{constructor(e,n,r,s){this.name=e,this.set=n,this.base=r,this.modified=s,this.id=XG++}toString(){let{name:e}=this;for(let n of this.modified)n.name&&(e=`${n.name}(${e})`);return e}static define(e,n){let r=typeof e=="string"?e:"?";if(e instanceof vi&&(n=e),n?.base)throw new Error("Can not derive from a modified tag");let s=new vi(r,[],null,[]);if(s.set.push(s),n)for(let i of n.set)s.set.push(i);return s}static defineModifier(e){let n=new Eg(e);return r=>r.modified.indexOf(n)>-1?r:Eg.get(r.base||r,r.modified.concat(n).sort((s,i)=>s.id-i.id))}}let YG=0;class Eg{constructor(e){this.name=e,this.instances=[],this.id=YG++}static get(e,n){if(!n.length)return e;let r=n[0].instances.find(c=>c.base==e&&KG(n,c.modified));if(r)return r;let s=[],i=new vi(e.name,s,e,n);for(let c of n)c.instances.push(i);let l=ZG(n);for(let c of e.set)if(!c.modified.length)for(let d of l)s.push(Eg.get(c,d));return i}}function KG(t,e){return t.length==e.length&&t.every((n,r)=>n==e[r])}function ZG(t){let e=[[]];for(let n=0;nr.length-n.length)}function Bw(t){let e=Object.create(null);for(let n in t){let r=t[n];Array.isArray(r)||(r=[r]);for(let s of n.split(" "))if(s){let i=[],l=2,c=s;for(let p=0;;){if(c=="..."&&p>0&&p+3==s.length){l=1;break}let x=/^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(c);if(!x)throw new RangeError("Invalid path: "+s);if(i.push(x[0]=="*"?"":x[0][0]=='"'?JSON.parse(x[0]):x[0]),p+=x[0].length,p==s.length)break;let v=s[p++];if(p==s.length&&v=="!"){l=0;break}if(v!="/")throw new RangeError("Invalid path: "+s);c=s.slice(p)}let d=i.length-1,h=i[d];if(!h)throw new RangeError("Invalid path: "+s);let m=new Of(r,l,d>0?i.slice(0,d):null);e[h]=m.sort(e[h])}}return YA.add(e)}const YA=new Et({combine(t,e){let n,r,s;for(;t||e;){if(!t||e&&t.depth>=e.depth?(s=e,e=e.next):(s=t,t=t.next),n&&n.mode==s.mode&&!s.context&&!n.context)continue;let i=new Of(s.tags,s.mode,s.context);n?n.next=i:r=i,n=i}return r}});class Of{constructor(e,n,r,s){this.tags=e,this.mode=n,this.context=r,this.next=s}get opaque(){return this.mode==0}get inherit(){return this.mode==1}sort(e){return!e||e.depth{let l=s;for(let c of i)for(let d of c.set){let h=n[d.id];if(h){l=l?l+" "+h:h;break}}return l},scope:r}}function JG(t,e){let n=null;for(let r of t){let s=r.style(e);s&&(n=n?n+" "+s:s)}return n}function eX(t,e,n,r=0,s=t.length){let i=new tX(r,Array.isArray(e)?e:[e],n);i.highlightRange(t.cursor(),r,s,"",i.highlighters),i.flush(s)}class tX{constructor(e,n,r){this.at=e,this.highlighters=n,this.span=r,this.class=""}startSpan(e,n){n!=this.class&&(this.flush(e),e>this.at&&(this.at=e),this.class=n)}flush(e){e>this.at&&this.class&&this.span(this.at,e,this.class)}highlightRange(e,n,r,s,i){let{type:l,from:c,to:d}=e;if(c>=r||d<=n)return;l.isTop&&(i=this.highlighters.filter(v=>!v.scope||v.scope(l)));let h=s,m=nX(e)||Of.empty,p=JG(i,m.tags);if(p&&(h&&(h+=" "),h+=p,m.mode==1&&(s+=(s?" ":"")+p)),this.startSpan(Math.max(n,c),h),m.opaque)return;let x=e.tree&&e.tree.prop(Et.mounted);if(x&&x.overlay){let v=e.node.enter(x.overlay[0].from+c,1),b=this.highlighters.filter(O=>!O.scope||O.scope(x.tree.type)),k=e.firstChild();for(let O=0,j=c;;O++){let T=O=M||!e.nextSibling())););if(!T||M>r)break;j=T.to+c,j>n&&(this.highlightRange(v.cursor(),Math.max(n,T.from+c),Math.min(r,j),"",b),this.startSpan(Math.min(r,j),h))}k&&e.parent()}else if(e.firstChild()){x&&(s="");do if(!(e.to<=n)){if(e.from>=r)break;this.highlightRange(e,n,r,s,i),this.startSpan(Math.min(r,e.to),h)}while(e.nextSibling());e.parent()}}}function nX(t){let e=t.type.prop(YA);for(;e&&e.context&&!t.matchContext(e.context);)e=e.next;return e||null}const Ie=vi.define,mp=Ie(),Jl=Ie(),n7=Ie(Jl),r7=Ie(Jl),eo=Ie(),pp=Ie(eo),Fy=Ie(eo),na=Ie(),Ko=Ie(na),ea=Ie(),ta=Ie(),Z2=Ie(),Rh=Ie(Z2),gp=Ie(),he={comment:mp,lineComment:Ie(mp),blockComment:Ie(mp),docComment:Ie(mp),name:Jl,variableName:Ie(Jl),typeName:n7,tagName:Ie(n7),propertyName:r7,attributeName:Ie(r7),className:Ie(Jl),labelName:Ie(Jl),namespace:Ie(Jl),macroName:Ie(Jl),literal:eo,string:pp,docString:Ie(pp),character:Ie(pp),attributeValue:Ie(pp),number:Fy,integer:Ie(Fy),float:Ie(Fy),bool:Ie(eo),regexp:Ie(eo),escape:Ie(eo),color:Ie(eo),url:Ie(eo),keyword:ea,self:Ie(ea),null:Ie(ea),atom:Ie(ea),unit:Ie(ea),modifier:Ie(ea),operatorKeyword:Ie(ea),controlKeyword:Ie(ea),definitionKeyword:Ie(ea),moduleKeyword:Ie(ea),operator:ta,derefOperator:Ie(ta),arithmeticOperator:Ie(ta),logicOperator:Ie(ta),bitwiseOperator:Ie(ta),compareOperator:Ie(ta),updateOperator:Ie(ta),definitionOperator:Ie(ta),typeOperator:Ie(ta),controlOperator:Ie(ta),punctuation:Z2,separator:Ie(Z2),bracket:Rh,angleBracket:Ie(Rh),squareBracket:Ie(Rh),paren:Ie(Rh),brace:Ie(Rh),content:na,heading:Ko,heading1:Ie(Ko),heading2:Ie(Ko),heading3:Ie(Ko),heading4:Ie(Ko),heading5:Ie(Ko),heading6:Ie(Ko),contentSeparator:Ie(na),list:Ie(na),quote:Ie(na),emphasis:Ie(na),strong:Ie(na),link:Ie(na),monospace:Ie(na),strikethrough:Ie(na),inserted:Ie(),deleted:Ie(),changed:Ie(),invalid:Ie(),meta:gp,documentMeta:Ie(gp),annotation:Ie(gp),processingInstruction:Ie(gp),definition:vi.defineModifier("definition"),constant:vi.defineModifier("constant"),function:vi.defineModifier("function"),standard:vi.defineModifier("standard"),local:vi.defineModifier("local"),special:vi.defineModifier("special")};for(let t in he){let e=he[t];e instanceof vi&&(e.name=t)}KA([{tag:he.link,class:"tok-link"},{tag:he.heading,class:"tok-heading"},{tag:he.emphasis,class:"tok-emphasis"},{tag:he.strong,class:"tok-strong"},{tag:he.keyword,class:"tok-keyword"},{tag:he.atom,class:"tok-atom"},{tag:he.bool,class:"tok-bool"},{tag:he.url,class:"tok-url"},{tag:he.labelName,class:"tok-labelName"},{tag:he.inserted,class:"tok-inserted"},{tag:he.deleted,class:"tok-deleted"},{tag:he.literal,class:"tok-literal"},{tag:he.string,class:"tok-string"},{tag:he.number,class:"tok-number"},{tag:[he.regexp,he.escape,he.special(he.string)],class:"tok-string2"},{tag:he.variableName,class:"tok-variableName"},{tag:he.local(he.variableName),class:"tok-variableName tok-local"},{tag:he.definition(he.variableName),class:"tok-variableName tok-definition"},{tag:he.special(he.variableName),class:"tok-variableName2"},{tag:he.definition(he.propertyName),class:"tok-propertyName tok-definition"},{tag:he.typeName,class:"tok-typeName"},{tag:he.namespace,class:"tok-namespace"},{tag:he.className,class:"tok-className"},{tag:he.macroName,class:"tok-macroName"},{tag:he.propertyName,class:"tok-propertyName"},{tag:he.operator,class:"tok-operator"},{tag:he.comment,class:"tok-comment"},{tag:he.meta,class:"tok-meta"},{tag:he.invalid,class:"tok-invalid"},{tag:he.punctuation,class:"tok-punctuation"}]);var Qy;const lc=new Et;function ZA(t){return He.define({combine:t?e=>e.concat(t):void 0})}const rX=new Et;class bi{constructor(e,n,r=[],s=""){this.data=e,this.name=s,Vt.prototype.hasOwnProperty("tree")||Object.defineProperty(Vt.prototype,"tree",{get(){return zr(this)}}),this.parser=n,this.extension=[go.of(this),Vt.languageData.of((i,l,c)=>{let d=s7(i,l,c),h=d.type.prop(lc);if(!h)return[];let m=i.facet(h),p=d.type.prop(rX);if(p){let x=d.resolve(l-d.from,c);for(let v of p)if(v.test(x,i)){let b=i.facet(v.facet);return v.type=="replace"?b:b.concat(m)}}return m})].concat(r)}isActiveAt(e,n,r=-1){return s7(e,n,r).type.prop(lc)==this.data}findRegions(e){let n=e.facet(go);if(n?.data==this.data)return[{from:0,to:e.doc.length}];if(!n||!n.allowsNesting)return[];let r=[],s=(i,l)=>{if(i.prop(lc)==this.data){r.push({from:l,to:l+i.length});return}let c=i.prop(Et.mounted);if(c){if(c.tree.prop(lc)==this.data){if(c.overlay)for(let d of c.overlay)r.push({from:d.from+l,to:d.to+l});else r.push({from:l,to:l+i.length});return}else if(c.overlay){let d=r.length;if(s(c.tree,c.overlay[0].from+l),r.length>d)return}}for(let d=0;dr.isTop?n:void 0)]}),e.name)}configure(e,n){return new jf(this.data,this.parser.configure(e),n||this.name)}get allowsNesting(){return this.parser.hasWrappers()}}function zr(t){let e=t.field(bi.state,!1);return e?e.tree:_n.empty}class sX{constructor(e){this.doc=e,this.cursorPos=0,this.string="",this.cursor=e.iter()}get length(){return this.doc.length}syncTo(e){return this.string=this.cursor.next(e-this.cursorPos).value,this.cursorPos=e+this.string.length,this.cursorPos-this.string.length}chunk(e){return this.syncTo(e),this.string}get lineChunks(){return!0}read(e,n){let r=this.cursorPos-this.string.length;return e=this.cursorPos?this.doc.sliceString(e,n):this.string.slice(e-r,n-r)}}let zh=null;class md{constructor(e,n,r=[],s,i,l,c,d){this.parser=e,this.state=n,this.fragments=r,this.tree=s,this.treeLen=i,this.viewport=l,this.skipped=c,this.scheduleOn=d,this.parse=null,this.tempSkipped=[]}static create(e,n,r){return new md(e,n,[],_n.empty,0,r,[],null)}startParse(){return this.parser.startParse(new sX(this.state.doc),this.fragments)}work(e,n){return n!=null&&n>=this.state.doc.length&&(n=void 0),this.tree!=_n.empty&&this.isDone(n??this.state.doc.length)?(this.takeTree(),!0):this.withContext(()=>{var r;if(typeof e=="number"){let s=Date.now()+e;e=()=>Date.now()>s}for(this.parse||(this.parse=this.startParse()),n!=null&&(this.parse.stoppedAt==null||this.parse.stoppedAt>n)&&n=this.treeLen&&((this.parse.stoppedAt==null||this.parse.stoppedAt>e)&&this.parse.stopAt(e),this.withContext(()=>{for(;!(n=this.parse.advance()););}),this.treeLen=e,this.tree=n,this.fragments=this.withoutTempSkipped(pc.addTree(this.tree,this.fragments,!0)),this.parse=null)}withContext(e){let n=zh;zh=this;try{return e()}finally{zh=n}}withoutTempSkipped(e){for(let n;n=this.tempSkipped.pop();)e=i7(e,n.from,n.to);return e}changes(e,n){let{fragments:r,tree:s,treeLen:i,viewport:l,skipped:c}=this;if(this.takeTree(),!e.empty){let d=[];if(e.iterChangedRanges((h,m,p,x)=>d.push({fromA:h,toA:m,fromB:p,toB:x})),r=pc.applyChanges(r,d),s=_n.empty,i=0,l={from:e.mapPos(l.from,-1),to:e.mapPos(l.to,1)},this.skipped.length){c=[];for(let h of this.skipped){let m=e.mapPos(h.from,1),p=e.mapPos(h.to,-1);me.from&&(this.fragments=i7(this.fragments,s,i),this.skipped.splice(r--,1))}return this.skipped.length>=n?!1:(this.reset(),!0)}reset(){this.parse&&(this.takeTree(),this.parse=null)}skipUntilInView(e,n){this.skipped.push({from:e,to:n})}static getSkippingParser(e){return new class extends Lw{createParse(n,r,s){let i=s[0].from,l=s[s.length-1].to;return{parsedPos:i,advance(){let d=zh;if(d){for(let h of s)d.tempSkipped.push(h);e&&(d.scheduleOn=d.scheduleOn?Promise.all([d.scheduleOn,e]):e)}return this.parsedPos=l,new _n(gs.none,[],[],l-i)},stoppedAt:null,stopAt(){}}}}}isDone(e){e=Math.min(e,this.state.doc.length);let n=this.fragments;return this.treeLen>=e&&n.length&&n[0].from==0&&n[0].to>=e}static get(){return zh}}function i7(t,e,n){return pc.applyChanges(t,[{fromA:e,toA:n,fromB:e,toB:n}])}class pd{constructor(e){this.context=e,this.tree=e.tree}apply(e){if(!e.docChanged&&this.tree==this.context.tree)return this;let n=this.context.changes(e.changes,e.state),r=this.context.treeLen==e.startState.doc.length?void 0:Math.max(e.changes.mapPos(this.context.treeLen),n.viewport.to);return n.work(20,r)||n.takeTree(),new pd(n)}static init(e){let n=Math.min(3e3,e.doc.length),r=md.create(e.facet(go).parser,e,{from:0,to:n});return r.work(20,n)||r.takeTree(),new pd(r)}}bi.state=Lr.define({create:pd.init,update(t,e){for(let n of e.effects)if(n.is(bi.setState))return n.value;return e.startState.facet(go)!=e.state.facet(go)?pd.init(e.state):t.apply(e)}});let JA=t=>{let e=setTimeout(()=>t(),500);return()=>clearTimeout(e)};typeof requestIdleCallback<"u"&&(JA=t=>{let e=-1,n=setTimeout(()=>{e=requestIdleCallback(t,{timeout:400})},100);return()=>e<0?clearTimeout(n):cancelIdleCallback(e)});const $y=typeof navigator<"u"&&(!((Qy=navigator.scheduling)===null||Qy===void 0)&&Qy.isInputPending)?()=>navigator.scheduling.isInputPending():null,iX=lr.fromClass(class{constructor(e){this.view=e,this.working=null,this.workScheduled=0,this.chunkEnd=-1,this.chunkBudget=-1,this.work=this.work.bind(this),this.scheduleWork()}update(e){let n=this.view.state.field(bi.state).context;(n.updateViewport(e.view.viewport)||this.view.viewport.to>n.treeLen)&&this.scheduleWork(),(e.docChanged||e.selectionSet)&&(this.view.hasFocus&&(this.chunkBudget+=50),this.scheduleWork()),this.checkAsyncSchedule(n)}scheduleWork(){if(this.working)return;let{state:e}=this.view,n=e.field(bi.state);(n.tree!=n.context.tree||!n.context.isDone(e.doc.length))&&(this.working=JA(this.work))}work(e){this.working=null;let n=Date.now();if(this.chunkEnds+1e3,d=i.context.work(()=>$y&&$y()||Date.now()>l,s+(c?0:1e5));this.chunkBudget-=Date.now()-n,(d||this.chunkBudget<=0)&&(i.context.takeTree(),this.view.dispatch({effects:bi.setState.of(new pd(i.context))})),this.chunkBudget>0&&!(d&&!c)&&this.scheduleWork(),this.checkAsyncSchedule(i.context)}checkAsyncSchedule(e){e.scheduleOn&&(this.workScheduled++,e.scheduleOn.then(()=>this.scheduleWork()).catch(n=>Es(this.view.state,n)).then(()=>this.workScheduled--),e.scheduleOn=null)}destroy(){this.working&&this.working()}isWorking(){return!!(this.working||this.workScheduled>0)}},{eventHandlers:{focus(){this.scheduleWork()}}}),go=He.define({combine(t){return t.length?t[0]:null},enables:t=>[bi.state,iX,qe.contentAttributes.compute([t],e=>{let n=e.facet(t);return n&&n.name?{"data-language":n.name}:{}})]});class eE{constructor(e,n=[]){this.language=e,this.support=n,this.extension=[e,n]}}const aX=He.define(),u0=He.define({combine:t=>{if(!t.length)return" ";let e=t[0];if(!e||/\S/.test(e)||Array.from(e).some(n=>n!=e[0]))throw new Error("Invalid indent unit: "+JSON.stringify(t[0]));return e}});function kc(t){let e=t.facet(u0);return e.charCodeAt(0)==9?t.tabSize*e.length:e.length}function Nf(t,e){let n="",r=t.tabSize,s=t.facet(u0)[0];if(s==" "){for(;e>=r;)n+=" ",e-=r;s=" "}for(let i=0;i=e?lX(t,n,e):null}class Nx{constructor(e,n={}){this.state=e,this.options=n,this.unit=kc(e)}lineAt(e,n=1){let r=this.state.doc.lineAt(e),{simulateBreak:s,simulateDoubleBreak:i}=this.options;return s!=null&&s>=r.from&&s<=r.to?i&&s==e?{text:"",from:e}:(n<0?s-1&&(i+=l-this.countColumn(r,r.search(/\S|$/))),i}countColumn(e,n=e.length){return Td(e,this.state.tabSize,n)}lineIndent(e,n=1){let{text:r,from:s}=this.lineAt(e,n),i=this.options.overrideIndentation;if(i){let l=i(s);if(l>-1)return l}return this.countColumn(r,r.search(/\S|$/))}get simulatedBreak(){return this.options.simulateBreak||null}}const Cx=new Et;function lX(t,e,n){let r=e.resolveStack(n),s=e.resolveInner(n,-1).resolve(n,0).enterUnfinishedNodesBefore(n);if(s!=r.node){let i=[];for(let l=s;l&&!(l.fromr.node.to||l.from==r.node.from&&l.type==r.node.type);l=l.parent)i.push(l);for(let l=i.length-1;l>=0;l--)r={node:i[l],next:r}}return tE(r,t,n)}function tE(t,e,n){for(let r=t;r;r=r.next){let s=cX(r.node);if(s)return s(qw.create(e,n,r))}return 0}function oX(t){return t.pos==t.options.simulateBreak&&t.options.simulateDoubleBreak}function cX(t){let e=t.type.prop(Cx);if(e)return e;let n=t.firstChild,r;if(n&&(r=n.type.prop(Et.closedBy))){let s=t.lastChild,i=s&&r.indexOf(s.name)>-1;return l=>nE(l,!0,1,void 0,i&&!oX(l)?s.from:void 0)}return t.parent==null?uX:null}function uX(){return 0}class qw extends Nx{constructor(e,n,r){super(e.state,e.options),this.base=e,this.pos=n,this.context=r}get node(){return this.context.node}static create(e,n,r){return new qw(e,n,r)}get textAfter(){return this.textAfterPos(this.pos)}get baseIndent(){return this.baseIndentFor(this.node)}baseIndentFor(e){let n=this.state.doc.lineAt(e.from);for(;;){let r=e.resolve(n.from);for(;r.parent&&r.parent.from==r.from;)r=r.parent;if(dX(r,e))break;n=this.state.doc.lineAt(r.from)}return this.lineIndent(n.from)}continue(){return tE(this.context.next,this.base,this.pos)}}function dX(t,e){for(let n=e;n;n=n.parent)if(t==n)return!0;return!1}function hX(t){let e=t.node,n=e.childAfter(e.from),r=e.lastChild;if(!n)return null;let s=t.options.simulateBreak,i=t.state.doc.lineAt(n.from),l=s==null||s<=i.from?i.to:Math.min(i.to,s);for(let c=n.to;;){let d=e.childAfter(c);if(!d||d==r)return null;if(!d.type.isSkipped){if(d.from>=l)return null;let h=/^ */.exec(i.text.slice(n.to-i.from))[0].length;return{from:n.from,to:n.to+h}}c=d.to}}function Hy({closing:t,align:e=!0,units:n=1}){return r=>nE(r,e,n,t)}function nE(t,e,n,r,s){let i=t.textAfter,l=i.match(/^\s*/)[0].length,c=r&&i.slice(l,l+r.length)==r||s==t.pos+l,d=e?hX(t):null;return d?c?t.column(d.from):t.column(d.to):t.baseIndent+(c?0:t.unit*n)}function a7({except:t,units:e=1}={}){return n=>{let r=t&&t.test(n.textAfter);return n.baseIndent+(r?0:e*n.unit)}}const fX=200;function mX(){return Vt.transactionFilter.of(t=>{if(!t.docChanged||!t.isUserEvent("input.type")&&!t.isUserEvent("input.complete"))return t;let e=t.startState.languageDataAt("indentOnInput",t.startState.selection.main.head);if(!e.length)return t;let n=t.newDoc,{head:r}=t.newSelection.main,s=n.lineAt(r);if(r>s.from+fX)return t;let i=n.sliceString(s.from,r);if(!e.some(h=>h.test(i)))return t;let{state:l}=t,c=-1,d=[];for(let{head:h}of l.selection.ranges){let m=l.doc.lineAt(h);if(m.from==c)continue;c=m.from;let p=Iw(l,m.from);if(p==null)continue;let x=/^\s*/.exec(m.text)[0],v=Nf(l,p);x!=v&&d.push({from:m.from,to:m.from+x.length,insert:v})}return d.length?[t,{changes:d,sequential:!0}]:t})}const pX=He.define(),Fw=new Et;function rE(t){let e=t.firstChild,n=t.lastChild;return e&&e.ton)continue;if(i&&c.from=e&&h.to>n&&(i=h)}}return i}function xX(t){let e=t.lastChild;return e&&e.to==t.to&&e.type.isError}function _g(t,e,n){for(let r of t.facet(pX)){let s=r(t,e,n);if(s)return s}return gX(t,e,n)}function sE(t,e){let n=e.mapPos(t.from,1),r=e.mapPos(t.to,-1);return n>=r?void 0:{from:n,to:r}}const Tx=xt.define({map:sE}),d0=xt.define({map:sE});function iE(t){let e=[];for(let{head:n}of t.state.selection.ranges)e.some(r=>r.from<=n&&r.to>=n)||e.push(t.lineBlockAt(n));return e}const Oc=Lr.define({create(){return Je.none},update(t,e){e.isUserEvent("delete")&&e.changes.iterChangedRanges((n,r)=>t=l7(t,n,r)),t=t.map(e.changes);for(let n of e.effects)if(n.is(Tx)&&!vX(t,n.value.from,n.value.to)){let{preparePlaceholder:r}=e.state.facet(oE),s=r?Je.replace({widget:new jX(r(e.state,n.value))}):o7;t=t.update({add:[s.range(n.value.from,n.value.to)]})}else n.is(d0)&&(t=t.update({filter:(r,s)=>n.value.from!=r||n.value.to!=s,filterFrom:n.value.from,filterTo:n.value.to}));return e.selection&&(t=l7(t,e.selection.main.head)),t},provide:t=>qe.decorations.from(t),toJSON(t,e){let n=[];return t.between(0,e.doc.length,(r,s)=>{n.push(r,s)}),n},fromJSON(t){if(!Array.isArray(t)||t.length%2)throw new RangeError("Invalid JSON for fold state");let e=[];for(let n=0;n{se&&(r=!0)}),r?t.update({filterFrom:e,filterTo:n,filter:(s,i)=>s>=n||i<=e}):t}function Dg(t,e,n){var r;let s=null;return(r=t.field(Oc,!1))===null||r===void 0||r.between(e,n,(i,l)=>{(!s||s.from>i)&&(s={from:i,to:l})}),s}function vX(t,e,n){let r=!1;return t.between(e,e,(s,i)=>{s==e&&i==n&&(r=!0)}),r}function aE(t,e){return t.field(Oc,!1)?e:e.concat(xt.appendConfig.of(cE()))}const yX=t=>{for(let e of iE(t)){let n=_g(t.state,e.from,e.to);if(n)return t.dispatch({effects:aE(t.state,[Tx.of(n),lE(t,n)])}),!0}return!1},bX=t=>{if(!t.state.field(Oc,!1))return!1;let e=[];for(let n of iE(t)){let r=Dg(t.state,n.from,n.to);r&&e.push(d0.of(r),lE(t,r,!1))}return e.length&&t.dispatch({effects:e}),e.length>0};function lE(t,e,n=!0){let r=t.state.doc.lineAt(e.from).number,s=t.state.doc.lineAt(e.to).number;return qe.announce.of(`${t.state.phrase(n?"Folded lines":"Unfolded lines")} ${r} ${t.state.phrase("to")} ${s}.`)}const wX=t=>{let{state:e}=t,n=[];for(let r=0;r{let e=t.state.field(Oc,!1);if(!e||!e.size)return!1;let n=[];return e.between(0,t.state.doc.length,(r,s)=>{n.push(d0.of({from:r,to:s}))}),t.dispatch({effects:n}),!0},kX=[{key:"Ctrl-Shift-[",mac:"Cmd-Alt-[",run:yX},{key:"Ctrl-Shift-]",mac:"Cmd-Alt-]",run:bX},{key:"Ctrl-Alt-[",run:wX},{key:"Ctrl-Alt-]",run:SX}],OX={placeholderDOM:null,preparePlaceholder:null,placeholderText:"…"},oE=He.define({combine(t){return ka(t,OX)}});function cE(t){return[Oc,TX]}function uE(t,e){let{state:n}=t,r=n.facet(oE),s=l=>{let c=t.lineBlockAt(t.posAtDOM(l.target)),d=Dg(t.state,c.from,c.to);d&&t.dispatch({effects:d0.of(d)}),l.preventDefault()};if(r.placeholderDOM)return r.placeholderDOM(t,s,e);let i=document.createElement("span");return i.textContent=r.placeholderText,i.setAttribute("aria-label",n.phrase("folded code")),i.title=n.phrase("unfold"),i.className="cm-foldPlaceholder",i.onclick=s,i}const o7=Je.replace({widget:new class extends Oa{toDOM(t){return uE(t,null)}}});class jX extends Oa{constructor(e){super(),this.value=e}eq(e){return this.value==e.value}toDOM(e){return uE(e,this.value)}}const NX={openText:"⌄",closedText:"›",markerDOM:null,domEventHandlers:{},foldingChanged:()=>!1};class Uy extends pl{constructor(e,n){super(),this.config=e,this.open=n}eq(e){return this.config==e.config&&this.open==e.open}toDOM(e){if(this.config.markerDOM)return this.config.markerDOM(this.open);let n=document.createElement("span");return n.textContent=this.open?this.config.openText:this.config.closedText,n.title=e.state.phrase(this.open?"Fold line":"Unfold line"),n}}function CX(t={}){let e={...NX,...t},n=new Uy(e,!0),r=new Uy(e,!1),s=lr.fromClass(class{constructor(l){this.from=l.viewport.from,this.markers=this.buildMarkers(l)}update(l){(l.docChanged||l.viewportChanged||l.startState.facet(go)!=l.state.facet(go)||l.startState.field(Oc,!1)!=l.state.field(Oc,!1)||zr(l.startState)!=zr(l.state)||e.foldingChanged(l))&&(this.markers=this.buildMarkers(l.view))}buildMarkers(l){let c=new fl;for(let d of l.viewportLineBlocks){let h=Dg(l.state,d.from,d.to)?r:_g(l.state,d.from,d.to)?n:null;h&&c.add(d.from,d.from,h)}return c.finish()}}),{domEventHandlers:i}=e;return[s,AG({class:"cm-foldGutter",markers(l){var c;return((c=l.plugin(s))===null||c===void 0?void 0:c.markers)||Gt.empty},initialSpacer(){return new Uy(e,!1)},domEventHandlers:{...i,click:(l,c,d)=>{if(i.click&&i.click(l,c,d))return!0;let h=Dg(l.state,c.from,c.to);if(h)return l.dispatch({effects:d0.of(h)}),!0;let m=_g(l.state,c.from,c.to);return m?(l.dispatch({effects:Tx.of(m)}),!0):!1}}}),cE()]}const TX=qe.baseTheme({".cm-foldPlaceholder":{backgroundColor:"#eee",border:"1px solid #ddd",color:"#888",borderRadius:".2em",margin:"0 1px",padding:"0 1px",cursor:"pointer"},".cm-foldGutter span":{padding:"0 1px",cursor:"pointer"}});class h0{constructor(e,n){this.specs=e;let r;function s(c){let d=ho.newName();return(r||(r=Object.create(null)))["."+d]=c,d}const i=typeof n.all=="string"?n.all:n.all?s(n.all):void 0,l=n.scope;this.scope=l instanceof bi?c=>c.prop(lc)==l.data:l?c=>c==l:void 0,this.style=KA(e.map(c=>({tag:c.tag,class:c.class||s(Object.assign({},c,{tag:null}))})),{all:i}).style,this.module=r?new ho(r):null,this.themeType=n.themeType}static define(e,n){return new h0(e,n||{})}}const J2=He.define(),dE=He.define({combine(t){return t.length?[t[0]]:null}});function Vy(t){let e=t.facet(J2);return e.length?e:t.facet(dE)}function hE(t,e){let n=[AX],r;return t instanceof h0&&(t.module&&n.push(qe.styleModule.of(t.module)),r=t.themeType),e?.fallback?n.push(dE.of(t)):r?n.push(J2.computeN([qe.darkTheme],s=>s.facet(qe.darkTheme)==(r=="dark")?[t]:[])):n.push(J2.of(t)),n}class MX{constructor(e){this.markCache=Object.create(null),this.tree=zr(e.state),this.decorations=this.buildDeco(e,Vy(e.state)),this.decoratedTo=e.viewport.to}update(e){let n=zr(e.state),r=Vy(e.state),s=r!=Vy(e.startState),{viewport:i}=e.view,l=e.changes.mapPos(this.decoratedTo,1);n.length=i.to?(this.decorations=this.decorations.map(e.changes),this.decoratedTo=l):(n!=this.tree||e.viewportChanged||s)&&(this.tree=n,this.decorations=this.buildDeco(e.view,r),this.decoratedTo=i.to)}buildDeco(e,n){if(!n||!this.tree.length)return Je.none;let r=new fl;for(let{from:s,to:i}of e.visibleRanges)eX(this.tree,n,(l,c,d)=>{r.add(l,c,this.markCache[d]||(this.markCache[d]=Je.mark({class:d})))},s,i);return r.finish()}}const AX=jo.high(lr.fromClass(MX,{decorations:t=>t.decorations})),EX=h0.define([{tag:he.meta,color:"#404740"},{tag:he.link,textDecoration:"underline"},{tag:he.heading,textDecoration:"underline",fontWeight:"bold"},{tag:he.emphasis,fontStyle:"italic"},{tag:he.strong,fontWeight:"bold"},{tag:he.strikethrough,textDecoration:"line-through"},{tag:he.keyword,color:"#708"},{tag:[he.atom,he.bool,he.url,he.contentSeparator,he.labelName],color:"#219"},{tag:[he.literal,he.inserted],color:"#164"},{tag:[he.string,he.deleted],color:"#a11"},{tag:[he.regexp,he.escape,he.special(he.string)],color:"#e40"},{tag:he.definition(he.variableName),color:"#00f"},{tag:he.local(he.variableName),color:"#30a"},{tag:[he.typeName,he.namespace],color:"#085"},{tag:he.className,color:"#167"},{tag:[he.special(he.variableName),he.macroName],color:"#256"},{tag:he.definition(he.propertyName),color:"#00c"},{tag:he.comment,color:"#940"},{tag:he.invalid,color:"#f00"}]),_X=qe.baseTheme({"&.cm-focused .cm-matchingBracket":{backgroundColor:"#328c8252"},"&.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bb555544"}}),fE=1e4,mE="()[]{}",pE=He.define({combine(t){return ka(t,{afterCursor:!0,brackets:mE,maxScanDistance:fE,renderMatch:zX})}}),DX=Je.mark({class:"cm-matchingBracket"}),RX=Je.mark({class:"cm-nonmatchingBracket"});function zX(t){let e=[],n=t.matched?DX:RX;return e.push(n.range(t.start.from,t.start.to)),t.end&&e.push(n.range(t.end.from,t.end.to)),e}const PX=Lr.define({create(){return Je.none},update(t,e){if(!e.docChanged&&!e.selection)return t;let n=[],r=e.state.facet(pE);for(let s of e.state.selection.ranges){if(!s.empty)continue;let i=ha(e.state,s.head,-1,r)||s.head>0&&ha(e.state,s.head-1,1,r)||r.afterCursor&&(ha(e.state,s.head,1,r)||s.headqe.decorations.from(t)}),LX=[PX,_X];function BX(t={}){return[pE.of(t),LX]}const IX=new Et;function e4(t,e,n){let r=t.prop(e<0?Et.openedBy:Et.closedBy);if(r)return r;if(t.name.length==1){let s=n.indexOf(t.name);if(s>-1&&s%2==(e<0?1:0))return[n[s+e]]}return null}function t4(t){let e=t.type.prop(IX);return e?e(t.node):t}function ha(t,e,n,r={}){let s=r.maxScanDistance||fE,i=r.brackets||mE,l=zr(t),c=l.resolveInner(e,n);for(let d=c;d;d=d.parent){let h=e4(d.type,n,i);if(h&&d.from0?e>=m.from&&em.from&&e<=m.to))return qX(t,e,n,d,m,h,i)}}return FX(t,e,n,l,c.type,s,i)}function qX(t,e,n,r,s,i,l){let c=r.parent,d={from:s.from,to:s.to},h=0,m=c?.cursor();if(m&&(n<0?m.childBefore(r.from):m.childAfter(r.to)))do if(n<0?m.to<=r.from:m.from>=r.to){if(h==0&&i.indexOf(m.type.name)>-1&&m.from0)return null;let h={from:n<0?e-1:e,to:n>0?e+1:e},m=t.doc.iterRange(e,n>0?t.doc.length:0),p=0;for(let x=0;!m.next().done&&x<=i;){let v=m.value;n<0&&(x+=v.length);let b=e+x*n;for(let k=n>0?0:v.length-1,O=n>0?v.length:-1;k!=O;k+=n){let j=l.indexOf(v[k]);if(!(j<0||r.resolveInner(b+k,1).type!=s))if(j%2==0==n>0)p++;else{if(p==1)return{start:h,end:{from:b+k,to:b+k+1},matched:j>>1==d>>1};p--}}n>0&&(x+=v.length)}return m.done?{start:h,matched:!1}:null}function c7(t,e,n,r=0,s=0){e==null&&(e=t.search(/[^\s\u00a0]/),e==-1&&(e=t.length));let i=s;for(let l=r;l=this.string.length}sol(){return this.pos==0}peek(){return this.string.charAt(this.pos)||void 0}next(){if(this.posn}eatSpace(){let e=this.pos;for(;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e}skipToEnd(){this.pos=this.string.length}skipTo(e){let n=this.string.indexOf(e,this.pos);if(n>-1)return this.pos=n,!0}backUp(e){this.pos-=e}column(){return this.lastColumnPosr?l.toLowerCase():l,i=this.string.substr(this.pos,e.length);return s(i)==s(e)?(n!==!1&&(this.pos+=e.length),!0):null}else{let s=this.string.slice(this.pos).match(e);return s&&s.index>0?null:(s&&n!==!1&&(this.pos+=s[0].length),s)}}current(){return this.string.slice(this.start,this.pos)}}function QX(t){return{name:t.name||"",token:t.token,blankLine:t.blankLine||(()=>{}),startState:t.startState||(()=>!0),copyState:t.copyState||$X,indent:t.indent||(()=>null),languageData:t.languageData||{},tokenTable:t.tokenTable||Hw,mergeTokens:t.mergeTokens!==!1}}function $X(t){if(typeof t!="object")return t;let e={};for(let n in t){let r=t[n];e[n]=r instanceof Array?r.slice():r}return e}const u7=new WeakMap;class Qw extends bi{constructor(e){let n=ZA(e.languageData),r=QX(e),s,i=new class extends Lw{createParse(l,c,d){return new UX(s,l,c,d)}};super(n,i,[],e.name),this.topNode=GX(n,this),s=this,this.streamParser=r,this.stateAfter=new Et({perNode:!0}),this.tokenTable=e.tokenTable?new bE(r.tokenTable):WX}static define(e){return new Qw(e)}getIndent(e){let n,{overrideIndentation:r}=e.options;r&&(n=u7.get(e.state),n!=null&&n1e4)return null;for(;i=r&&n+e.length<=s&&e.prop(t.stateAfter);if(i)return{state:t.streamParser.copyState(i),pos:n+e.length};for(let l=e.children.length-1;l>=0;l--){let c=e.children[l],d=n+e.positions[l],h=c instanceof _n&&d=e.length)return e;!s&&n==0&&e.type==t.topNode&&(s=!0);for(let i=e.children.length-1;i>=0;i--){let l=e.positions[i],c=e.children[i],d;if(ln&&$w(t,i.tree,0-i.offset,n,c),h;if(d&&d.pos<=r&&(h=xE(t,i.tree,n+i.offset,d.pos+i.offset,!1)))return{state:d.state,tree:h}}return{state:t.streamParser.startState(s?kc(s):4),tree:_n.empty}}let UX=class{constructor(e,n,r,s){this.lang=e,this.input=n,this.fragments=r,this.ranges=s,this.stoppedAt=null,this.chunks=[],this.chunkPos=[],this.chunk=[],this.chunkReused=void 0,this.rangeIndex=0,this.to=s[s.length-1].to;let i=md.get(),l=s[0].from,{state:c,tree:d}=HX(e,r,l,this.to,i?.state);this.state=c,this.parsedPos=this.chunkStart=l+d.length;for(let h=0;hh.from<=i.viewport.from&&h.to>=i.viewport.from)&&(this.state=this.lang.streamParser.startState(kc(i.state)),i.skipUntilInView(this.parsedPos,i.viewport.from),this.parsedPos=i.viewport.from),this.moveRangeIndex()}advance(){let e=md.get(),n=this.stoppedAt==null?this.to:Math.min(this.to,this.stoppedAt),r=Math.min(n,this.chunkStart+512);for(e&&(r=Math.min(r,e.viewport.to));this.parsedPos=n?this.finish():e&&this.parsedPos>=e.viewport.to?(e.skipUntilInView(this.parsedPos,n),this.finish()):null}stopAt(e){this.stoppedAt=e}lineAfter(e){let n=this.input.chunk(e);if(this.input.lineChunks)n==` -`&&(n="");else{let r=n.indexOf(` -`);r>-1&&(n=n.slice(0,r))}return e+n.length<=this.to?n:n.slice(0,this.to-e)}nextLine(){let e=this.parsedPos,n=this.lineAfter(e),r=e+n.length;for(let s=this.rangeIndex;;){let i=this.ranges[s].to;if(i>=r||(n=n.slice(0,i-(r-n.length)),s++,s==this.ranges.length))break;let l=this.ranges[s].from,c=this.lineAfter(l);n+=c,r=l+c.length}return{line:n,end:r}}skipGapsTo(e,n,r){for(;;){let s=this.ranges[this.rangeIndex].to,i=e+n;if(r>0?s>i:s>=i)break;let l=this.ranges[++this.rangeIndex].from;n+=l-s}return n}moveRangeIndex(){for(;this.ranges[this.rangeIndex].to1){s=this.skipGapsTo(n,s,1),n+=s;let c=this.chunk.length;s=this.skipGapsTo(r,s,-1),r+=s,i+=this.chunk.length-c}let l=this.chunk.length-4;return this.lang.streamParser.mergeTokens&&i==4&&l>=0&&this.chunk[l]==e&&this.chunk[l+2]==n?this.chunk[l+2]=r:this.chunk.push(e,n,r,i),s}parseLine(e){let{line:n,end:r}=this.nextLine(),s=0,{streamParser:i}=this.lang,l=new gE(n,e?e.state.tabSize:4,e?kc(e.state):2);if(l.eol())i.blankLine(this.state,l.indentUnit);else for(;!l.eol();){let c=vE(i.token,l,this.state);if(c&&(s=this.emitToken(this.lang.tokenTable.resolve(c),this.parsedPos+l.start,this.parsedPos+l.pos,s)),l.start>1e4)break}this.parsedPos=r,this.moveRangeIndex(),this.parsedPose.start)return s}throw new Error("Stream parser failed to advance stream.")}const Hw=Object.create(null),Cf=[gs.none],VX=new jx(Cf),d7=[],h7=Object.create(null),yE=Object.create(null);for(let[t,e]of[["variable","variableName"],["variable-2","variableName.special"],["string-2","string.special"],["def","variableName.definition"],["tag","tagName"],["attribute","attributeName"],["type","typeName"],["builtin","variableName.standard"],["qualifier","modifier"],["error","invalid"],["header","heading"],["property","propertyName"]])yE[t]=wE(Hw,e);class bE{constructor(e){this.extra=e,this.table=Object.assign(Object.create(null),yE)}resolve(e){return e?this.table[e]||(this.table[e]=wE(this.extra,e)):0}}const WX=new bE(Hw);function Wy(t,e){d7.indexOf(t)>-1||(d7.push(t),console.warn(e))}function wE(t,e){let n=[];for(let c of e.split(" ")){let d=[];for(let h of c.split(".")){let m=t[h]||he[h];m?typeof m=="function"?d.length?d=d.map(m):Wy(h,`Modifier ${h} used at start of tag`):d.length?Wy(h,`Tag ${h} used as modifier`):d=Array.isArray(m)?m:[m]:Wy(h,`Unknown highlighting tag ${h}`)}for(let h of d)n.push(h)}if(!n.length)return 0;let r=e.replace(/ /g,"_"),s=r+" "+n.map(c=>c.id),i=h7[s];if(i)return i.id;let l=h7[s]=gs.define({id:Cf.length,name:r,props:[Bw({[r]:n})]});return Cf.push(l),l.id}function GX(t,e){let n=gs.define({id:Cf.length,name:"Document",props:[lc.add(()=>t),Cx.add(()=>r=>e.getIndent(r))],top:!0});return Cf.push(n),n}Hn.RTL,Hn.LTR;const XX=t=>{let{state:e}=t,n=e.doc.lineAt(e.selection.main.from),r=Vw(t.state,n.from);return r.line?YX(t):r.block?ZX(t):!1};function Uw(t,e){return({state:n,dispatch:r})=>{if(n.readOnly)return!1;let s=t(e,n);return s?(r(n.update(s)),!0):!1}}const YX=Uw(tY,0),KX=Uw(SE,0),ZX=Uw((t,e)=>SE(t,e,eY(e)),0);function Vw(t,e){let n=t.languageDataAt("commentTokens",e,1);return n.length?n[0]:{}}const Ph=50;function JX(t,{open:e,close:n},r,s){let i=t.sliceDoc(r-Ph,r),l=t.sliceDoc(s,s+Ph),c=/\s*$/.exec(i)[0].length,d=/^\s*/.exec(l)[0].length,h=i.length-c;if(i.slice(h-e.length,h)==e&&l.slice(d,d+n.length)==n)return{open:{pos:r-c,margin:c&&1},close:{pos:s+d,margin:d&&1}};let m,p;s-r<=2*Ph?m=p=t.sliceDoc(r,s):(m=t.sliceDoc(r,r+Ph),p=t.sliceDoc(s-Ph,s));let x=/^\s*/.exec(m)[0].length,v=/\s*$/.exec(p)[0].length,b=p.length-v-n.length;return m.slice(x,x+e.length)==e&&p.slice(b,b+n.length)==n?{open:{pos:r+x+e.length,margin:/\s/.test(m.charAt(x+e.length))?1:0},close:{pos:s-v-n.length,margin:/\s/.test(p.charAt(b-1))?1:0}}:null}function eY(t){let e=[];for(let n of t.selection.ranges){let r=t.doc.lineAt(n.from),s=n.to<=r.to?r:t.doc.lineAt(n.to);s.from>r.from&&s.from==n.to&&(s=n.to==r.to+1?r:t.doc.lineAt(n.to-1));let i=e.length-1;i>=0&&e[i].to>r.from?e[i].to=s.to:e.push({from:r.from+/^\s*/.exec(r.text)[0].length,to:s.to})}return e}function SE(t,e,n=e.selection.ranges){let r=n.map(i=>Vw(e,i.from).block);if(!r.every(i=>i))return null;let s=n.map((i,l)=>JX(e,r[l],i.from,i.to));if(t!=2&&!s.every(i=>i))return{changes:e.changes(n.map((i,l)=>s[l]?[]:[{from:i.from,insert:r[l].open+" "},{from:i.to,insert:" "+r[l].close}]))};if(t!=1&&s.some(i=>i)){let i=[];for(let l=0,c;ls&&(i==l||l>p.from)){s=p.from;let x=/^\s*/.exec(p.text)[0].length,v=x==p.length,b=p.text.slice(x,x+h.length)==h?x:-1;xi.comment<0&&(!i.empty||i.single))){let i=[];for(let{line:c,token:d,indent:h,empty:m,single:p}of r)(p||!m)&&i.push({from:c.from+h,insert:d+" "});let l=e.changes(i);return{changes:l,selection:e.selection.map(l,1)}}else if(t!=1&&r.some(i=>i.comment>=0)){let i=[];for(let{line:l,comment:c,token:d}of r)if(c>=0){let h=l.from+c,m=h+d.length;l.text[m-l.from]==" "&&m++,i.push({from:h,to:m})}return{changes:i}}return null}const n4=Sa.define(),nY=Sa.define(),rY=He.define(),kE=He.define({combine(t){return ka(t,{minDepth:100,newGroupDelay:500,joinToEvent:(e,n)=>n},{minDepth:Math.max,newGroupDelay:Math.min,joinToEvent:(e,n)=>(r,s)=>e(r,s)||n(r,s)})}}),OE=Lr.define({create(){return fa.empty},update(t,e){let n=e.state.facet(kE),r=e.annotation(n4);if(r){let d=_s.fromTransaction(e,r.selection),h=r.side,m=h==0?t.undone:t.done;return d?m=Rg(m,m.length,n.minDepth,d):m=CE(m,e.startState.selection),new fa(h==0?r.rest:m,h==0?m:r.rest)}let s=e.annotation(nY);if((s=="full"||s=="before")&&(t=t.isolate()),e.annotation(gr.addToHistory)===!1)return e.changes.empty?t:t.addMapping(e.changes.desc);let i=_s.fromTransaction(e),l=e.annotation(gr.time),c=e.annotation(gr.userEvent);return i?t=t.addChanges(i,l,c,n,e):e.selection&&(t=t.addSelection(e.startState.selection,l,c,n.newGroupDelay)),(s=="full"||s=="after")&&(t=t.isolate()),t},toJSON(t){return{done:t.done.map(e=>e.toJSON()),undone:t.undone.map(e=>e.toJSON())}},fromJSON(t){return new fa(t.done.map(_s.fromJSON),t.undone.map(_s.fromJSON))}});function sY(t={}){return[OE,kE.of(t),qe.domEventHandlers({beforeinput(e,n){let r=e.inputType=="historyUndo"?jE:e.inputType=="historyRedo"?r4:null;return r?(e.preventDefault(),r(n)):!1}})]}function Mx(t,e){return function({state:n,dispatch:r}){if(!e&&n.readOnly)return!1;let s=n.field(OE,!1);if(!s)return!1;let i=s.pop(t,n,e);return i?(r(i),!0):!1}}const jE=Mx(0,!1),r4=Mx(1,!1),iY=Mx(0,!0),aY=Mx(1,!0);class _s{constructor(e,n,r,s,i){this.changes=e,this.effects=n,this.mapped=r,this.startSelection=s,this.selectionsAfter=i}setSelAfter(e){return new _s(this.changes,this.effects,this.mapped,this.startSelection,e)}toJSON(){var e,n,r;return{changes:(e=this.changes)===null||e===void 0?void 0:e.toJSON(),mapped:(n=this.mapped)===null||n===void 0?void 0:n.toJSON(),startSelection:(r=this.startSelection)===null||r===void 0?void 0:r.toJSON(),selectionsAfter:this.selectionsAfter.map(s=>s.toJSON())}}static fromJSON(e){return new _s(e.changes&&kr.fromJSON(e.changes),[],e.mapped&&xa.fromJSON(e.mapped),e.startSelection&&Ce.fromJSON(e.startSelection),e.selectionsAfter.map(Ce.fromJSON))}static fromTransaction(e,n){let r=wi;for(let s of e.startState.facet(rY)){let i=s(e);i.length&&(r=r.concat(i))}return!r.length&&e.changes.empty?null:new _s(e.changes.invert(e.startState.doc),r,void 0,n||e.startState.selection,wi)}static selection(e){return new _s(void 0,wi,void 0,void 0,e)}}function Rg(t,e,n,r){let s=e+1>n+20?e-n-1:0,i=t.slice(s,e);return i.push(r),i}function lY(t,e){let n=[],r=!1;return t.iterChangedRanges((s,i)=>n.push(s,i)),e.iterChangedRanges((s,i,l,c)=>{for(let d=0;d=h&&l<=m&&(r=!0)}}),r}function oY(t,e){return t.ranges.length==e.ranges.length&&t.ranges.filter((n,r)=>n.empty!=e.ranges[r].empty).length===0}function NE(t,e){return t.length?e.length?t.concat(e):t:e}const wi=[],cY=200;function CE(t,e){if(t.length){let n=t[t.length-1],r=n.selectionsAfter.slice(Math.max(0,n.selectionsAfter.length-cY));return r.length&&r[r.length-1].eq(e)?t:(r.push(e),Rg(t,t.length-1,1e9,n.setSelAfter(r)))}else return[_s.selection([e])]}function uY(t){let e=t[t.length-1],n=t.slice();return n[t.length-1]=e.setSelAfter(e.selectionsAfter.slice(0,e.selectionsAfter.length-1)),n}function Gy(t,e){if(!t.length)return t;let n=t.length,r=wi;for(;n;){let s=dY(t[n-1],e,r);if(s.changes&&!s.changes.empty||s.effects.length){let i=t.slice(0,n);return i[n-1]=s,i}else e=s.mapped,n--,r=s.selectionsAfter}return r.length?[_s.selection(r)]:wi}function dY(t,e,n){let r=NE(t.selectionsAfter.length?t.selectionsAfter.map(c=>c.map(e)):wi,n);if(!t.changes)return _s.selection(r);let s=t.changes.map(e),i=e.mapDesc(t.changes,!0),l=t.mapped?t.mapped.composeDesc(i):i;return new _s(s,xt.mapEffects(t.effects,e),l,t.startSelection.map(i),r)}const hY=/^(input\.type|delete)($|\.)/;class fa{constructor(e,n,r=0,s=void 0){this.done=e,this.undone=n,this.prevTime=r,this.prevUserEvent=s}isolate(){return this.prevTime?new fa(this.done,this.undone):this}addChanges(e,n,r,s,i){let l=this.done,c=l[l.length-1];return c&&c.changes&&!c.changes.empty&&e.changes&&(!r||hY.test(r))&&(!c.selectionsAfter.length&&n-this.prevTime0&&n-this.prevTimen.empty?t.moveByChar(n,e):Ax(n,e))}function is(t){return t.textDirectionAt(t.state.selection.main.head)==Hn.LTR}const ME=t=>TE(t,!is(t)),AE=t=>TE(t,is(t));function EE(t,e){return Wi(t,n=>n.empty?t.moveByGroup(n,e):Ax(n,e))}const mY=t=>EE(t,!is(t)),pY=t=>EE(t,is(t));function gY(t,e,n){if(e.type.prop(n))return!0;let r=e.to-e.from;return r&&(r>2||/[^\s,.;:]/.test(t.sliceDoc(e.from,e.to)))||e.firstChild}function Ex(t,e,n){let r=zr(t).resolveInner(e.head),s=n?Et.closedBy:Et.openedBy;for(let d=e.head;;){let h=n?r.childAfter(d):r.childBefore(d);if(!h)break;gY(t,h,s)?r=h:d=n?h.to:h.from}let i=r.type.prop(s),l,c;return i&&(l=n?ha(t,r.from,1):ha(t,r.to,-1))&&l.matched?c=n?l.end.to:l.end.from:c=n?r.to:r.from,Ce.cursor(c,n?-1:1)}const xY=t=>Wi(t,e=>Ex(t.state,e,!is(t))),vY=t=>Wi(t,e=>Ex(t.state,e,is(t)));function _E(t,e){return Wi(t,n=>{if(!n.empty)return Ax(n,e);let r=t.moveVertically(n,e);return r.head!=n.head?r:t.moveToLineBoundary(n,e)})}const DE=t=>_E(t,!1),RE=t=>_E(t,!0);function zE(t){let e=t.scrollDOM.clientHeightl.empty?t.moveVertically(l,e,n.height):Ax(l,e));if(s.eq(r.selection))return!1;let i;if(n.selfScroll){let l=t.coordsAtPos(r.selection.main.head),c=t.scrollDOM.getBoundingClientRect(),d=c.top+n.marginTop,h=c.bottom-n.marginBottom;l&&l.top>d&&l.bottomPE(t,!1),s4=t=>PE(t,!0);function No(t,e,n){let r=t.lineBlockAt(e.head),s=t.moveToLineBoundary(e,n);if(s.head==e.head&&s.head!=(n?r.to:r.from)&&(s=t.moveToLineBoundary(e,n,!1)),!n&&s.head==r.from&&r.length){let i=/^\s*/.exec(t.state.sliceDoc(r.from,Math.min(r.from+100,r.to)))[0].length;i&&e.head!=r.from+i&&(s=Ce.cursor(r.from+i))}return s}const yY=t=>Wi(t,e=>No(t,e,!0)),bY=t=>Wi(t,e=>No(t,e,!1)),wY=t=>Wi(t,e=>No(t,e,!is(t))),SY=t=>Wi(t,e=>No(t,e,is(t))),kY=t=>Wi(t,e=>Ce.cursor(t.lineBlockAt(e.head).from,1)),OY=t=>Wi(t,e=>Ce.cursor(t.lineBlockAt(e.head).to,-1));function jY(t,e,n){let r=!1,s=Md(t.selection,i=>{let l=ha(t,i.head,-1)||ha(t,i.head,1)||i.head>0&&ha(t,i.head-1,1)||i.headjY(t,e);function Ei(t,e){let n=Md(t.state.selection,r=>{let s=e(r);return Ce.range(r.anchor,s.head,s.goalColumn,s.bidiLevel||void 0)});return n.eq(t.state.selection)?!1:(t.dispatch(Vi(t.state,n)),!0)}function LE(t,e){return Ei(t,n=>t.moveByChar(n,e))}const BE=t=>LE(t,!is(t)),IE=t=>LE(t,is(t));function qE(t,e){return Ei(t,n=>t.moveByGroup(n,e))}const CY=t=>qE(t,!is(t)),TY=t=>qE(t,is(t)),MY=t=>Ei(t,e=>Ex(t.state,e,!is(t))),AY=t=>Ei(t,e=>Ex(t.state,e,is(t)));function FE(t,e){return Ei(t,n=>t.moveVertically(n,e))}const QE=t=>FE(t,!1),$E=t=>FE(t,!0);function HE(t,e){return Ei(t,n=>t.moveVertically(n,e,zE(t).height))}const m7=t=>HE(t,!1),p7=t=>HE(t,!0),EY=t=>Ei(t,e=>No(t,e,!0)),_Y=t=>Ei(t,e=>No(t,e,!1)),DY=t=>Ei(t,e=>No(t,e,!is(t))),RY=t=>Ei(t,e=>No(t,e,is(t))),zY=t=>Ei(t,e=>Ce.cursor(t.lineBlockAt(e.head).from)),PY=t=>Ei(t,e=>Ce.cursor(t.lineBlockAt(e.head).to)),g7=({state:t,dispatch:e})=>(e(Vi(t,{anchor:0})),!0),x7=({state:t,dispatch:e})=>(e(Vi(t,{anchor:t.doc.length})),!0),v7=({state:t,dispatch:e})=>(e(Vi(t,{anchor:t.selection.main.anchor,head:0})),!0),y7=({state:t,dispatch:e})=>(e(Vi(t,{anchor:t.selection.main.anchor,head:t.doc.length})),!0),LY=({state:t,dispatch:e})=>(e(t.update({selection:{anchor:0,head:t.doc.length},userEvent:"select"})),!0),BY=({state:t,dispatch:e})=>{let n=_x(t).map(({from:r,to:s})=>Ce.range(r,Math.min(s+1,t.doc.length)));return e(t.update({selection:Ce.create(n),userEvent:"select"})),!0},IY=({state:t,dispatch:e})=>{let n=Md(t.selection,r=>{let s=zr(t),i=s.resolveStack(r.from,1);if(r.empty){let l=s.resolveStack(r.from,-1);l.node.from>=i.node.from&&l.node.to<=i.node.to&&(i=l)}for(let l=i;l;l=l.next){let{node:c}=l;if((c.from=r.to||c.to>r.to&&c.from<=r.from)&&l.next)return Ce.range(c.to,c.from)}return r});return n.eq(t.selection)?!1:(e(Vi(t,n)),!0)};function UE(t,e){let{state:n}=t,r=n.selection,s=n.selection.ranges.slice();for(let i of n.selection.ranges){let l=n.doc.lineAt(i.head);if(e?l.to0)for(let c=i;;){let d=t.moveVertically(c,e);if(d.headl.to){s.some(h=>h.head==d.head)||s.push(d);break}else{if(d.head==c.head)break;c=d}}}return s.length==r.ranges.length?!1:(t.dispatch(Vi(n,Ce.create(s,s.length-1))),!0)}const qY=t=>UE(t,!1),FY=t=>UE(t,!0),QY=({state:t,dispatch:e})=>{let n=t.selection,r=null;return n.ranges.length>1?r=Ce.create([n.main]):n.main.empty||(r=Ce.create([Ce.cursor(n.main.head)])),r?(e(Vi(t,r)),!0):!1};function f0(t,e){if(t.state.readOnly)return!1;let n="delete.selection",{state:r}=t,s=r.changeByRange(i=>{let{from:l,to:c}=i;if(l==c){let d=e(i);dl&&(n="delete.forward",d=xp(t,d,!0)),l=Math.min(l,d),c=Math.max(c,d)}else l=xp(t,l,!1),c=xp(t,c,!0);return l==c?{range:i}:{changes:{from:l,to:c},range:Ce.cursor(l,ls(t)))r.between(e,e,(s,i)=>{se&&(e=n?i:s)});return e}const VE=(t,e,n)=>f0(t,r=>{let s=r.from,{state:i}=t,l=i.doc.lineAt(s),c,d;if(n&&!e&&s>l.from&&sVE(t,!1,!0),WE=t=>VE(t,!0,!1),GE=(t,e)=>f0(t,n=>{let r=n.head,{state:s}=t,i=s.doc.lineAt(r),l=s.charCategorizer(r);for(let c=null;;){if(r==(e?i.to:i.from)){r==n.head&&i.number!=(e?s.doc.lines:1)&&(r+=e?1:-1);break}let d=Vr(i.text,r-i.from,e)+i.from,h=i.text.slice(Math.min(r,d)-i.from,Math.max(r,d)-i.from),m=l(h);if(c!=null&&m!=c)break;(h!=" "||r!=n.head)&&(c=m),r=d}return r}),XE=t=>GE(t,!1),$Y=t=>GE(t,!0),HY=t=>f0(t,e=>{let n=t.lineBlockAt(e.head).to;return e.headf0(t,e=>{let n=t.moveToLineBoundary(e,!1).head;return e.head>n?n:Math.max(0,e.head-1)}),VY=t=>f0(t,e=>{let n=t.moveToLineBoundary(e,!0).head;return e.head{if(t.readOnly)return!1;let n=t.changeByRange(r=>({changes:{from:r.from,to:r.to,insert:Wt.of(["",""])},range:Ce.cursor(r.from)}));return e(t.update(n,{scrollIntoView:!0,userEvent:"input"})),!0},GY=({state:t,dispatch:e})=>{if(t.readOnly)return!1;let n=t.changeByRange(r=>{if(!r.empty||r.from==0||r.from==t.doc.length)return{range:r};let s=r.from,i=t.doc.lineAt(s),l=s==i.from?s-1:Vr(i.text,s-i.from,!1)+i.from,c=s==i.to?s+1:Vr(i.text,s-i.from,!0)+i.from;return{changes:{from:l,to:c,insert:t.doc.slice(s,c).append(t.doc.slice(l,s))},range:Ce.cursor(c)}});return n.changes.empty?!1:(e(t.update(n,{scrollIntoView:!0,userEvent:"move.character"})),!0)};function _x(t){let e=[],n=-1;for(let r of t.selection.ranges){let s=t.doc.lineAt(r.from),i=t.doc.lineAt(r.to);if(!r.empty&&r.to==i.from&&(i=t.doc.lineAt(r.to-1)),n>=s.number){let l=e[e.length-1];l.to=i.to,l.ranges.push(r)}else e.push({from:s.from,to:i.to,ranges:[r]});n=i.number+1}return e}function YE(t,e,n){if(t.readOnly)return!1;let r=[],s=[];for(let i of _x(t)){if(n?i.to==t.doc.length:i.from==0)continue;let l=t.doc.lineAt(n?i.to+1:i.from-1),c=l.length+1;if(n){r.push({from:i.to,to:l.to},{from:i.from,insert:l.text+t.lineBreak});for(let d of i.ranges)s.push(Ce.range(Math.min(t.doc.length,d.anchor+c),Math.min(t.doc.length,d.head+c)))}else{r.push({from:l.from,to:i.from},{from:i.to,insert:t.lineBreak+l.text});for(let d of i.ranges)s.push(Ce.range(d.anchor-c,d.head-c))}}return r.length?(e(t.update({changes:r,scrollIntoView:!0,selection:Ce.create(s,t.selection.mainIndex),userEvent:"move.line"})),!0):!1}const XY=({state:t,dispatch:e})=>YE(t,e,!1),YY=({state:t,dispatch:e})=>YE(t,e,!0);function KE(t,e,n){if(t.readOnly)return!1;let r=[];for(let s of _x(t))n?r.push({from:s.from,insert:t.doc.slice(s.from,s.to)+t.lineBreak}):r.push({from:s.to,insert:t.lineBreak+t.doc.slice(s.from,s.to)});return e(t.update({changes:r,scrollIntoView:!0,userEvent:"input.copyline"})),!0}const KY=({state:t,dispatch:e})=>KE(t,e,!1),ZY=({state:t,dispatch:e})=>KE(t,e,!0),JY=t=>{if(t.state.readOnly)return!1;let{state:e}=t,n=e.changes(_x(e).map(({from:s,to:i})=>(s>0?s--:i{let i;if(t.lineWrapping){let l=t.lineBlockAt(s.head),c=t.coordsAtPos(s.head,s.assoc||1);c&&(i=l.bottom+t.documentTop-c.bottom+t.defaultLineHeight/2)}return t.moveVertically(s,!0,i)}).map(n);return t.dispatch({changes:n,selection:r,scrollIntoView:!0,userEvent:"delete.line"}),!0};function eK(t,e){if(/\(\)|\[\]|\{\}/.test(t.sliceDoc(e-1,e+1)))return{from:e,to:e};let n=zr(t).resolveInner(e),r=n.childBefore(e),s=n.childAfter(e),i;return r&&s&&r.to<=e&&s.from>=e&&(i=r.type.prop(Et.closedBy))&&i.indexOf(s.name)>-1&&t.doc.lineAt(r.to).from==t.doc.lineAt(s.from).from&&!/\S/.test(t.sliceDoc(r.to,s.from))?{from:r.to,to:s.from}:null}const b7=ZE(!1),tK=ZE(!0);function ZE(t){return({state:e,dispatch:n})=>{if(e.readOnly)return!1;let r=e.changeByRange(s=>{let{from:i,to:l}=s,c=e.doc.lineAt(i),d=!t&&i==l&&eK(e,i);t&&(i=l=(l<=c.to?c:e.doc.lineAt(l)).to);let h=new Nx(e,{simulateBreak:i,simulateDoubleBreak:!!d}),m=Iw(h,i);for(m==null&&(m=Td(/^\s*/.exec(e.doc.lineAt(i).text)[0],e.tabSize));lc.from&&i{let s=[];for(let l=r.from;l<=r.to;){let c=t.doc.lineAt(l);c.number>n&&(r.empty||r.to>c.from)&&(e(c,s,r),n=c.number),l=c.to+1}let i=t.changes(s);return{changes:s,range:Ce.range(i.mapPos(r.anchor,1),i.mapPos(r.head,1))}})}const nK=({state:t,dispatch:e})=>{if(t.readOnly)return!1;let n=Object.create(null),r=new Nx(t,{overrideIndentation:i=>{let l=n[i];return l??-1}}),s=Ww(t,(i,l,c)=>{let d=Iw(r,i.from);if(d==null)return;/\S/.test(i.text)||(d=0);let h=/^\s*/.exec(i.text)[0],m=Nf(t,d);(h!=m||c.fromt.readOnly?!1:(e(t.update(Ww(t,(n,r)=>{r.push({from:n.from,insert:t.facet(u0)})}),{userEvent:"input.indent"})),!0),e_=({state:t,dispatch:e})=>t.readOnly?!1:(e(t.update(Ww(t,(n,r)=>{let s=/^\s*/.exec(n.text)[0];if(!s)return;let i=Td(s,t.tabSize),l=0,c=Nf(t,Math.max(0,i-kc(t)));for(;l(t.setTabFocusMode(),!0),sK=[{key:"Ctrl-b",run:ME,shift:BE,preventDefault:!0},{key:"Ctrl-f",run:AE,shift:IE},{key:"Ctrl-p",run:DE,shift:QE},{key:"Ctrl-n",run:RE,shift:$E},{key:"Ctrl-a",run:kY,shift:zY},{key:"Ctrl-e",run:OY,shift:PY},{key:"Ctrl-d",run:WE},{key:"Ctrl-h",run:i4},{key:"Ctrl-k",run:HY},{key:"Ctrl-Alt-h",run:XE},{key:"Ctrl-o",run:WY},{key:"Ctrl-t",run:GY},{key:"Ctrl-v",run:s4}],iK=[{key:"ArrowLeft",run:ME,shift:BE,preventDefault:!0},{key:"Mod-ArrowLeft",mac:"Alt-ArrowLeft",run:mY,shift:CY,preventDefault:!0},{mac:"Cmd-ArrowLeft",run:wY,shift:DY,preventDefault:!0},{key:"ArrowRight",run:AE,shift:IE,preventDefault:!0},{key:"Mod-ArrowRight",mac:"Alt-ArrowRight",run:pY,shift:TY,preventDefault:!0},{mac:"Cmd-ArrowRight",run:SY,shift:RY,preventDefault:!0},{key:"ArrowUp",run:DE,shift:QE,preventDefault:!0},{mac:"Cmd-ArrowUp",run:g7,shift:v7},{mac:"Ctrl-ArrowUp",run:f7,shift:m7},{key:"ArrowDown",run:RE,shift:$E,preventDefault:!0},{mac:"Cmd-ArrowDown",run:x7,shift:y7},{mac:"Ctrl-ArrowDown",run:s4,shift:p7},{key:"PageUp",run:f7,shift:m7},{key:"PageDown",run:s4,shift:p7},{key:"Home",run:bY,shift:_Y,preventDefault:!0},{key:"Mod-Home",run:g7,shift:v7},{key:"End",run:yY,shift:EY,preventDefault:!0},{key:"Mod-End",run:x7,shift:y7},{key:"Enter",run:b7,shift:b7},{key:"Mod-a",run:LY},{key:"Backspace",run:i4,shift:i4,preventDefault:!0},{key:"Delete",run:WE,preventDefault:!0},{key:"Mod-Backspace",mac:"Alt-Backspace",run:XE,preventDefault:!0},{key:"Mod-Delete",mac:"Alt-Delete",run:$Y,preventDefault:!0},{mac:"Mod-Backspace",run:UY,preventDefault:!0},{mac:"Mod-Delete",run:VY,preventDefault:!0}].concat(sK.map(t=>({mac:t.key,run:t.run,shift:t.shift}))),aK=[{key:"Alt-ArrowLeft",mac:"Ctrl-ArrowLeft",run:xY,shift:MY},{key:"Alt-ArrowRight",mac:"Ctrl-ArrowRight",run:vY,shift:AY},{key:"Alt-ArrowUp",run:XY},{key:"Shift-Alt-ArrowUp",run:KY},{key:"Alt-ArrowDown",run:YY},{key:"Shift-Alt-ArrowDown",run:ZY},{key:"Mod-Alt-ArrowUp",run:qY},{key:"Mod-Alt-ArrowDown",run:FY},{key:"Escape",run:QY},{key:"Mod-Enter",run:tK},{key:"Alt-l",mac:"Ctrl-l",run:BY},{key:"Mod-i",run:IY,preventDefault:!0},{key:"Mod-[",run:e_},{key:"Mod-]",run:JE},{key:"Mod-Alt-\\",run:nK},{key:"Shift-Mod-k",run:JY},{key:"Shift-Mod-\\",run:NY},{key:"Mod-/",run:XX},{key:"Alt-A",run:KX},{key:"Ctrl-m",mac:"Shift-Alt-m",run:rK}].concat(iK),lK={key:"Tab",run:JE,shift:e_},w7=typeof String.prototype.normalize=="function"?t=>t.normalize("NFKD"):t=>t;class gd{constructor(e,n,r=0,s=e.length,i,l){this.test=l,this.value={from:0,to:0},this.done=!1,this.matches=[],this.buffer="",this.bufferPos=0,this.iter=e.iterRange(r,s),this.bufferStart=r,this.normalize=i?c=>i(w7(c)):w7,this.query=this.normalize(n)}peek(){if(this.bufferPos==this.buffer.length){if(this.bufferStart+=this.buffer.length,this.iter.next(),this.iter.done)return-1;this.bufferPos=0,this.buffer=this.iter.value}return Ms(this.buffer,this.bufferPos)}next(){for(;this.matches.length;)this.matches.pop();return this.nextOverlapping()}nextOverlapping(){for(;;){let e=this.peek();if(e<0)return this.done=!0,this;let n=yw(e),r=this.bufferStart+this.bufferPos;this.bufferPos+=aa(e);let s=this.normalize(n);if(s.length)for(let i=0,l=r;;i++){let c=s.charCodeAt(i),d=this.match(c,l,this.bufferPos+this.bufferStart);if(i==s.length-1){if(d)return this.value=d,this;break}l==r&&ithis.to&&(this.curLine=this.curLine.slice(0,this.to-this.curLineStart)),this.iter.next())}nextLine(){this.curLineStart=this.curLineStart+this.curLine.length+1,this.curLineStart>this.to?this.curLine="":this.getLine(0)}next(){for(let e=this.matchPos-this.curLineStart;;){this.re.lastIndex=e;let n=this.matchPos<=this.to&&this.re.exec(this.curLine);if(n){let r=this.curLineStart+n.index,s=r+n[0].length;if(this.matchPos=zg(this.text,s+(r==s?1:0)),r==this.curLineStart+this.curLine.length&&this.nextLine(),(rthis.value.to)&&(!this.test||this.test(r,s,n)))return this.value={from:r,to:s,match:n},this;e=this.matchPos-this.curLineStart}else if(this.curLineStart+this.curLine.length=r||s.to<=n){let c=new Yu(n,e.sliceString(n,r));return Xy.set(e,c),c}if(s.from==n&&s.to==r)return s;let{text:i,from:l}=s;return l>n&&(i=e.sliceString(n,l)+i,l=n),s.to=this.to?this.to:this.text.lineAt(e).to}next(){for(;;){let e=this.re.lastIndex=this.matchPos-this.flat.from,n=this.re.exec(this.flat.text);if(n&&!n[0]&&n.index==e&&(this.re.lastIndex=e+1,n=this.re.exec(this.flat.text)),n){let r=this.flat.from+n.index,s=r+n[0].length;if((this.flat.to>=this.to||n.index+n[0].length<=this.flat.text.length-10)&&(!this.test||this.test(r,s,n)))return this.value={from:r,to:s,match:n},this.matchPos=zg(this.text,s+(r==s?1:0)),this}if(this.flat.to==this.to)return this.done=!0,this;this.flat=Yu.get(this.text,this.flat.from,this.chunkEnd(this.flat.from+this.flat.text.length*2))}}}typeof Symbol<"u"&&(n_.prototype[Symbol.iterator]=r_.prototype[Symbol.iterator]=function(){return this});function oK(t){try{return new RegExp(t,Gw),!0}catch{return!1}}function zg(t,e){if(e>=t.length)return e;let n=t.lineAt(e),r;for(;e=56320&&r<57344;)e++;return e}function a4(t){let e=String(t.state.doc.lineAt(t.state.selection.main.head).number),n=An("input",{class:"cm-textfield",name:"line",value:e}),r=An("form",{class:"cm-gotoLine",onkeydown:i=>{i.keyCode==27?(i.preventDefault(),t.dispatch({effects:sf.of(!1)}),t.focus()):i.keyCode==13&&(i.preventDefault(),s())},onsubmit:i=>{i.preventDefault(),s()}},An("label",t.state.phrase("Go to line"),": ",n)," ",An("button",{class:"cm-button",type:"submit"},t.state.phrase("go")),An("button",{name:"close",onclick:()=>{t.dispatch({effects:sf.of(!1)}),t.focus()},"aria-label":t.state.phrase("close"),type:"button"},["×"]));function s(){let i=/^([+-])?(\d+)?(:\d+)?(%)?$/.exec(n.value);if(!i)return;let{state:l}=t,c=l.doc.lineAt(l.selection.main.head),[,d,h,m,p]=i,x=m?+m.slice(1):0,v=h?+h:c.number;if(h&&p){let O=v/100;d&&(O=O*(d=="-"?-1:1)+c.number/l.doc.lines),v=Math.round(l.doc.lines*O)}else h&&d&&(v=v*(d=="-"?-1:1)+c.number);let b=l.doc.line(Math.max(1,Math.min(l.doc.lines,v))),k=Ce.cursor(b.from+Math.max(0,Math.min(x,b.length)));t.dispatch({effects:[sf.of(!1),qe.scrollIntoView(k.from,{y:"center"})],selection:k}),t.focus()}return{dom:r}}const sf=xt.define(),S7=Lr.define({create(){return!0},update(t,e){for(let n of e.effects)n.is(sf)&&(t=n.value);return t},provide:t=>Sf.from(t,e=>e?a4:null)}),cK=t=>{let e=wf(t,a4);if(!e){let n=[sf.of(!0)];t.state.field(S7,!1)==null&&n.push(xt.appendConfig.of([S7,uK])),t.dispatch({effects:n}),e=wf(t,a4)}return e&&e.dom.querySelector("input").select(),!0},uK=qe.baseTheme({".cm-panel.cm-gotoLine":{padding:"2px 6px 4px",position:"relative","& label":{fontSize:"80%"},"& [name=close]":{position:"absolute",top:"0",bottom:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:"0"}}}),dK={highlightWordAroundCursor:!1,minSelectionLength:1,maxMatches:100,wholeWords:!1},hK=He.define({combine(t){return ka(t,dK,{highlightWordAroundCursor:(e,n)=>e||n,minSelectionLength:Math.min,maxMatches:Math.min})}});function fK(t){return[vK,xK]}const mK=Je.mark({class:"cm-selectionMatch"}),pK=Je.mark({class:"cm-selectionMatch cm-selectionMatch-main"});function k7(t,e,n,r){return(n==0||t(e.sliceDoc(n-1,n))!=Vn.Word)&&(r==e.doc.length||t(e.sliceDoc(r,r+1))!=Vn.Word)}function gK(t,e,n,r){return t(e.sliceDoc(n,n+1))==Vn.Word&&t(e.sliceDoc(r-1,r))==Vn.Word}const xK=lr.fromClass(class{constructor(t){this.decorations=this.getDeco(t)}update(t){(t.selectionSet||t.docChanged||t.viewportChanged)&&(this.decorations=this.getDeco(t.view))}getDeco(t){let e=t.state.facet(hK),{state:n}=t,r=n.selection;if(r.ranges.length>1)return Je.none;let s=r.main,i,l=null;if(s.empty){if(!e.highlightWordAroundCursor)return Je.none;let d=n.wordAt(s.head);if(!d)return Je.none;l=n.charCategorizer(s.head),i=n.sliceDoc(d.from,d.to)}else{let d=s.to-s.from;if(d200)return Je.none;if(e.wholeWords){if(i=n.sliceDoc(s.from,s.to),l=n.charCategorizer(s.head),!(k7(l,n,s.from,s.to)&&gK(l,n,s.from,s.to)))return Je.none}else if(i=n.sliceDoc(s.from,s.to),!i)return Je.none}let c=[];for(let d of t.visibleRanges){let h=new gd(n.doc,i,d.from,d.to);for(;!h.next().done;){let{from:m,to:p}=h.value;if((!l||k7(l,n,m,p))&&(s.empty&&m<=s.from&&p>=s.to?c.push(pK.range(m,p)):(m>=s.to||p<=s.from)&&c.push(mK.range(m,p)),c.length>e.maxMatches))return Je.none}}return Je.set(c)}},{decorations:t=>t.decorations}),vK=qe.baseTheme({".cm-selectionMatch":{backgroundColor:"#99ff7780"},".cm-searchMatch .cm-selectionMatch":{backgroundColor:"transparent"}}),yK=({state:t,dispatch:e})=>{let{selection:n}=t,r=Ce.create(n.ranges.map(s=>t.wordAt(s.head)||Ce.cursor(s.head)),n.mainIndex);return r.eq(n)?!1:(e(t.update({selection:r})),!0)};function bK(t,e){let{main:n,ranges:r}=t.selection,s=t.wordAt(n.head),i=s&&s.from==n.from&&s.to==n.to;for(let l=!1,c=new gd(t.doc,e,r[r.length-1].to);;)if(c.next(),c.done){if(l)return null;c=new gd(t.doc,e,0,Math.max(0,r[r.length-1].from-1)),l=!0}else{if(l&&r.some(d=>d.from==c.value.from))continue;if(i){let d=t.wordAt(c.value.from);if(!d||d.from!=c.value.from||d.to!=c.value.to)continue}return c.value}}const wK=({state:t,dispatch:e})=>{let{ranges:n}=t.selection;if(n.some(i=>i.from===i.to))return yK({state:t,dispatch:e});let r=t.sliceDoc(n[0].from,n[0].to);if(t.selection.ranges.some(i=>t.sliceDoc(i.from,i.to)!=r))return!1;let s=bK(t,r);return s?(e(t.update({selection:t.selection.addRange(Ce.range(s.from,s.to),!1),effects:qe.scrollIntoView(s.to)})),!0):!1},Ad=He.define({combine(t){return ka(t,{top:!1,caseSensitive:!1,literal:!1,regexp:!1,wholeWord:!1,createPanel:e=>new DK(e),scrollToMatch:e=>qe.scrollIntoView(e)})}});class s_{constructor(e){this.search=e.search,this.caseSensitive=!!e.caseSensitive,this.literal=!!e.literal,this.regexp=!!e.regexp,this.replace=e.replace||"",this.valid=!!this.search&&(!this.regexp||oK(this.search)),this.unquoted=this.unquote(this.search),this.wholeWord=!!e.wholeWord}unquote(e){return this.literal?e:e.replace(/\\([nrt\\])/g,(n,r)=>r=="n"?` -`:r=="r"?"\r":r=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord}create(){return this.regexp?new jK(this):new kK(this)}getCursor(e,n=0,r){let s=e.doc?e:Vt.create({doc:e});return r==null&&(r=s.doc.length),this.regexp?zu(this,s,n,r):Ru(this,s,n,r)}}class i_{constructor(e){this.spec=e}}function Ru(t,e,n,r){return new gd(e.doc,t.unquoted,n,r,t.caseSensitive?void 0:s=>s.toLowerCase(),t.wholeWord?SK(e.doc,e.charCategorizer(e.selection.main.head)):void 0)}function SK(t,e){return(n,r,s,i)=>((i>n||i+s.length=n)return null;s.push(r.value)}return s}highlight(e,n,r,s){let i=Ru(this.spec,e,Math.max(0,n-this.spec.unquoted.length),Math.min(r+this.spec.unquoted.length,e.doc.length));for(;!i.next().done;)s(i.value.from,i.value.to)}}function zu(t,e,n,r){return new n_(e.doc,t.search,{ignoreCase:!t.caseSensitive,test:t.wholeWord?OK(e.charCategorizer(e.selection.main.head)):void 0},n,r)}function Pg(t,e){return t.slice(Vr(t,e,!1),e)}function Lg(t,e){return t.slice(e,Vr(t,e))}function OK(t){return(e,n,r)=>!r[0].length||(t(Pg(r.input,r.index))!=Vn.Word||t(Lg(r.input,r.index))!=Vn.Word)&&(t(Lg(r.input,r.index+r[0].length))!=Vn.Word||t(Pg(r.input,r.index+r[0].length))!=Vn.Word)}class jK extends i_{nextMatch(e,n,r){let s=zu(this.spec,e,r,e.doc.length).next();return s.done&&(s=zu(this.spec,e,0,n).next()),s.done?null:s.value}prevMatchInRange(e,n,r){for(let s=1;;s++){let i=Math.max(n,r-s*1e4),l=zu(this.spec,e,i,r),c=null;for(;!l.next().done;)c=l.value;if(c&&(i==n||c.from>i+10))return c;if(i==n)return null}}prevMatch(e,n,r){return this.prevMatchInRange(e,0,n)||this.prevMatchInRange(e,r,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(n,r)=>{if(r=="&")return e.match[0];if(r=="$")return"$";for(let s=r.length;s>0;s--){let i=+r.slice(0,s);if(i>0&&i=n)return null;s.push(r.value)}return s}highlight(e,n,r,s){let i=zu(this.spec,e,Math.max(0,n-250),Math.min(r+250,e.doc.length));for(;!i.next().done;)s(i.value.from,i.value.to)}}const Tf=xt.define(),Xw=xt.define(),ao=Lr.define({create(t){return new Yy(l4(t).create(),null)},update(t,e){for(let n of e.effects)n.is(Tf)?t=new Yy(n.value.create(),t.panel):n.is(Xw)&&(t=new Yy(t.query,n.value?Yw:null));return t},provide:t=>Sf.from(t,e=>e.panel)});class Yy{constructor(e,n){this.query=e,this.panel=n}}const NK=Je.mark({class:"cm-searchMatch"}),CK=Je.mark({class:"cm-searchMatch cm-searchMatch-selected"}),TK=lr.fromClass(class{constructor(t){this.view=t,this.decorations=this.highlight(t.state.field(ao))}update(t){let e=t.state.field(ao);(e!=t.startState.field(ao)||t.docChanged||t.selectionSet||t.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:t,panel:e}){if(!e||!t.spec.valid)return Je.none;let{view:n}=this,r=new fl;for(let s=0,i=n.visibleRanges,l=i.length;si[s+1].from-500;)d=i[++s].to;t.highlight(n.state,c,d,(h,m)=>{let p=n.state.selection.ranges.some(x=>x.from==h&&x.to==m);r.add(h,m,p?CK:NK)})}return r.finish()}},{decorations:t=>t.decorations});function m0(t){return e=>{let n=e.state.field(ao,!1);return n&&n.query.spec.valid?t(e,n):o_(e)}}const Bg=m0((t,{query:e})=>{let{to:n}=t.state.selection.main,r=e.nextMatch(t.state,n,n);if(!r)return!1;let s=Ce.single(r.from,r.to),i=t.state.facet(Ad);return t.dispatch({selection:s,effects:[Kw(t,r),i.scrollToMatch(s.main,t)],userEvent:"select.search"}),l_(t),!0}),Ig=m0((t,{query:e})=>{let{state:n}=t,{from:r}=n.selection.main,s=e.prevMatch(n,r,r);if(!s)return!1;let i=Ce.single(s.from,s.to),l=t.state.facet(Ad);return t.dispatch({selection:i,effects:[Kw(t,s),l.scrollToMatch(i.main,t)],userEvent:"select.search"}),l_(t),!0}),MK=m0((t,{query:e})=>{let n=e.matchAll(t.state,1e3);return!n||!n.length?!1:(t.dispatch({selection:Ce.create(n.map(r=>Ce.range(r.from,r.to))),userEvent:"select.search.matches"}),!0)}),AK=({state:t,dispatch:e})=>{let n=t.selection;if(n.ranges.length>1||n.main.empty)return!1;let{from:r,to:s}=n.main,i=[],l=0;for(let c=new gd(t.doc,t.sliceDoc(r,s));!c.next().done;){if(i.length>1e3)return!1;c.value.from==r&&(l=i.length),i.push(Ce.range(c.value.from,c.value.to))}return e(t.update({selection:Ce.create(i,l),userEvent:"select.search.matches"})),!0},O7=m0((t,{query:e})=>{let{state:n}=t,{from:r,to:s}=n.selection.main;if(n.readOnly)return!1;let i=e.nextMatch(n,r,r);if(!i)return!1;let l=i,c=[],d,h,m=[];l.from==r&&l.to==s&&(h=n.toText(e.getReplacement(l)),c.push({from:l.from,to:l.to,insert:h}),l=e.nextMatch(n,l.from,l.to),m.push(qe.announce.of(n.phrase("replaced match on line $",n.doc.lineAt(r).number)+".")));let p=t.state.changes(c);return l&&(d=Ce.single(l.from,l.to).map(p),m.push(Kw(t,l)),m.push(n.facet(Ad).scrollToMatch(d.main,t))),t.dispatch({changes:p,selection:d,effects:m,userEvent:"input.replace"}),!0}),EK=m0((t,{query:e})=>{if(t.state.readOnly)return!1;let n=e.matchAll(t.state,1e9).map(s=>{let{from:i,to:l}=s;return{from:i,to:l,insert:e.getReplacement(s)}});if(!n.length)return!1;let r=t.state.phrase("replaced $ matches",n.length)+".";return t.dispatch({changes:n,effects:qe.announce.of(r),userEvent:"input.replace.all"}),!0});function Yw(t){return t.state.facet(Ad).createPanel(t)}function l4(t,e){var n,r,s,i,l;let c=t.selection.main,d=c.empty||c.to>c.from+100?"":t.sliceDoc(c.from,c.to);if(e&&!d)return e;let h=t.facet(Ad);return new s_({search:((n=e?.literal)!==null&&n!==void 0?n:h.literal)?d:d.replace(/\n/g,"\\n"),caseSensitive:(r=e?.caseSensitive)!==null&&r!==void 0?r:h.caseSensitive,literal:(s=e?.literal)!==null&&s!==void 0?s:h.literal,regexp:(i=e?.regexp)!==null&&i!==void 0?i:h.regexp,wholeWord:(l=e?.wholeWord)!==null&&l!==void 0?l:h.wholeWord})}function a_(t){let e=wf(t,Yw);return e&&e.dom.querySelector("[main-field]")}function l_(t){let e=a_(t);e&&e==t.root.activeElement&&e.select()}const o_=t=>{let e=t.state.field(ao,!1);if(e&&e.panel){let n=a_(t);if(n&&n!=t.root.activeElement){let r=l4(t.state,e.query.spec);r.valid&&t.dispatch({effects:Tf.of(r)}),n.focus(),n.select()}}else t.dispatch({effects:[Xw.of(!0),e?Tf.of(l4(t.state,e.query.spec)):xt.appendConfig.of(zK)]});return!0},c_=t=>{let e=t.state.field(ao,!1);if(!e||!e.panel)return!1;let n=wf(t,Yw);return n&&n.dom.contains(t.root.activeElement)&&t.focus(),t.dispatch({effects:Xw.of(!1)}),!0},_K=[{key:"Mod-f",run:o_,scope:"editor search-panel"},{key:"F3",run:Bg,shift:Ig,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:Bg,shift:Ig,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:c_,scope:"editor search-panel"},{key:"Mod-Shift-l",run:AK},{key:"Mod-Alt-g",run:cK},{key:"Mod-d",run:wK,preventDefault:!0}];class DK{constructor(e){this.view=e;let n=this.query=e.state.field(ao).query.spec;this.commit=this.commit.bind(this),this.searchField=An("input",{value:n.search,placeholder:Xs(e,"Find"),"aria-label":Xs(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=An("input",{value:n.replace,placeholder:Xs(e,"Replace"),"aria-label":Xs(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=An("input",{type:"checkbox",name:"case",form:"",checked:n.caseSensitive,onchange:this.commit}),this.reField=An("input",{type:"checkbox",name:"re",form:"",checked:n.regexp,onchange:this.commit}),this.wordField=An("input",{type:"checkbox",name:"word",form:"",checked:n.wholeWord,onchange:this.commit});function r(s,i,l){return An("button",{class:"cm-button",name:s,onclick:i,type:"button"},l)}this.dom=An("div",{onkeydown:s=>this.keydown(s),class:"cm-search"},[this.searchField,r("next",()=>Bg(e),[Xs(e,"next")]),r("prev",()=>Ig(e),[Xs(e,"previous")]),r("select",()=>MK(e),[Xs(e,"all")]),An("label",null,[this.caseField,Xs(e,"match case")]),An("label",null,[this.reField,Xs(e,"regexp")]),An("label",null,[this.wordField,Xs(e,"by word")]),...e.state.readOnly?[]:[An("br"),this.replaceField,r("replace",()=>O7(e),[Xs(e,"replace")]),r("replaceAll",()=>EK(e),[Xs(e,"replace all")])],An("button",{name:"close",onclick:()=>c_(e),"aria-label":Xs(e,"close"),type:"button"},["×"])])}commit(){let e=new s_({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:Tf.of(e)}))}keydown(e){BW(this.view,e,"search-panel")?e.preventDefault():e.keyCode==13&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?Ig:Bg)(this.view)):e.keyCode==13&&e.target==this.replaceField&&(e.preventDefault(),O7(this.view))}update(e){for(let n of e.transactions)for(let r of n.effects)r.is(Tf)&&!r.value.eq(this.query)&&this.setQuery(r.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(Ad).top}}function Xs(t,e){return t.state.phrase(e)}const vp=30,yp=/[\s\.,:;?!]/;function Kw(t,{from:e,to:n}){let r=t.state.doc.lineAt(e),s=t.state.doc.lineAt(n).to,i=Math.max(r.from,e-vp),l=Math.min(s,n+vp),c=t.state.sliceDoc(i,l);if(i!=r.from){for(let d=0;dc.length-vp;d--)if(!yp.test(c[d-1])&&yp.test(c[d])){c=c.slice(0,d);break}}return qe.announce.of(`${t.state.phrase("current match")}. ${c} ${t.state.phrase("on line")} ${r.number}.`)}const RK=qe.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),zK=[ao,jo.low(TK),RK];class u_{constructor(e,n,r,s){this.state=e,this.pos=n,this.explicit=r,this.view=s,this.abortListeners=[],this.abortOnDocChange=!1}tokenBefore(e){let n=zr(this.state).resolveInner(this.pos,-1);for(;n&&e.indexOf(n.name)<0;)n=n.parent;return n?{from:n.from,to:this.pos,text:this.state.sliceDoc(n.from,this.pos),type:n.type}:null}matchBefore(e){let n=this.state.doc.lineAt(this.pos),r=Math.max(n.from,this.pos-250),s=n.text.slice(r-n.from,this.pos-n.from),i=s.search(h_(e,!1));return i<0?null:{from:r+i,to:this.pos,text:s.slice(i)}}get aborted(){return this.abortListeners==null}addEventListener(e,n,r){e=="abort"&&this.abortListeners&&(this.abortListeners.push(n),r&&r.onDocChange&&(this.abortOnDocChange=!0))}}function j7(t){let e=Object.keys(t).join(""),n=/\w/.test(e);return n&&(e=e.replace(/\w/g,"")),`[${n?"\\w":""}${e.replace(/[^\w\s]/g,"\\$&")}]`}function PK(t){let e=Object.create(null),n=Object.create(null);for(let{label:s}of t){e[s[0]]=!0;for(let i=1;itypeof s=="string"?{label:s}:s),[n,r]=e.every(s=>/^\w+$/.test(s.label))?[/\w*$/,/\w+$/]:PK(e);return s=>{let i=s.matchBefore(r);return i||s.explicit?{from:i?i.from:s.pos,options:e,validFor:n}:null}}function LK(t,e){return n=>{for(let r=zr(n.state).resolveInner(n.pos,-1);r;r=r.parent){if(t.indexOf(r.name)>-1)return null;if(r.type.isTop)break}return e(n)}}let N7=class{constructor(e,n,r,s){this.completion=e,this.source=n,this.match=r,this.score=s}};function gc(t){return t.selection.main.from}function h_(t,e){var n;let{source:r}=t,s=e&&r[0]!="^",i=r[r.length-1]!="$";return!s&&!i?t:new RegExp(`${s?"^":""}(?:${r})${i?"$":""}`,(n=t.flags)!==null&&n!==void 0?n:t.ignoreCase?"i":"")}const Zw=Sa.define();function BK(t,e,n,r){let{main:s}=t.selection,i=n-s.from,l=r-s.from;return{...t.changeByRange(c=>{if(c!=s&&n!=r&&t.sliceDoc(c.from+i,c.from+l)!=t.sliceDoc(n,r))return{range:c};let d=t.toText(e);return{changes:{from:c.from+i,to:r==s.from?c.to:c.from+l,insert:d},range:Ce.cursor(c.from+i+d.length)}}),scrollIntoView:!0,userEvent:"input.complete"}}const C7=new WeakMap;function IK(t){if(!Array.isArray(t))return t;let e=C7.get(t);return e||C7.set(t,e=d_(t)),e}const qg=xt.define(),Mf=xt.define();class qK{constructor(e){this.pattern=e,this.chars=[],this.folded=[],this.any=[],this.precise=[],this.byWord=[],this.score=0,this.matched=[];for(let n=0;n=48&&D<=57||D>=97&&D<=122?2:D>=65&&D<=90?1:0:(E=yw(D))!=E.toLowerCase()?1:E!=E.toUpperCase()?2:0;(!T||z==1&&O||_==0&&z!=0)&&(n[p]==D||r[p]==D&&(x=!0)?l[p++]=T:l.length&&(j=!1)),_=z,T+=aa(D)}return p==d&&l[0]==0&&j?this.result(-100+(x?-200:0),l,e):v==d&&b==0?this.ret(-200-e.length+(k==e.length?0:-100),[0,k]):c>-1?this.ret(-700-e.length,[c,c+this.pattern.length]):v==d?this.ret(-900-e.length,[b,k]):p==d?this.result(-100+(x?-200:0)+-700+(j?0:-1100),l,e):n.length==2?null:this.result((s[0]?-700:0)+-200+-1100,s,e)}result(e,n,r){let s=[],i=0;for(let l of n){let c=l+(this.astral?aa(Ms(r,l)):1);i&&s[i-1]==l?s[i-1]=c:(s[i++]=l,s[i++]=c)}return this.ret(e-r.length,s)}}class FK{constructor(e){this.pattern=e,this.matched=[],this.score=0,this.folded=e.toLowerCase()}match(e){if(e.length!1,activateOnTypingDelay:100,selectOnOpen:!0,override:null,closeOnBlur:!0,maxRenderedOptions:100,defaultKeymap:!0,tooltipClass:()=>"",optionClass:()=>"",aboveCursor:!1,icons:!0,addToOptions:[],positionInfo:QK,filterStrict:!1,compareCompletions:(e,n)=>e.label.localeCompare(n.label),interactionDelay:75,updateSyncTime:100},{defaultKeymap:(e,n)=>e&&n,closeOnBlur:(e,n)=>e&&n,icons:(e,n)=>e&&n,tooltipClass:(e,n)=>r=>T7(e(r),n(r)),optionClass:(e,n)=>r=>T7(e(r),n(r)),addToOptions:(e,n)=>e.concat(n),filterStrict:(e,n)=>e||n})}});function T7(t,e){return t?e?t+" "+e:t:e}function QK(t,e,n,r,s,i){let l=t.textDirection==Hn.RTL,c=l,d=!1,h="top",m,p,x=e.left-s.left,v=s.right-e.right,b=r.right-r.left,k=r.bottom-r.top;if(c&&x=k||T>e.top?m=n.bottom-e.top:(h="bottom",m=e.bottom-n.top)}let O=(e.bottom-e.top)/i.offsetHeight,j=(e.right-e.left)/i.offsetWidth;return{style:`${h}: ${m/O}px; max-width: ${p/j}px`,class:"cm-completionInfo-"+(d?l?"left-narrow":"right-narrow":c?"left":"right")}}function $K(t){let e=t.addToOptions.slice();return t.icons&&e.push({render(n){let r=document.createElement("div");return r.classList.add("cm-completionIcon"),n.type&&r.classList.add(...n.type.split(/\s+/g).map(s=>"cm-completionIcon-"+s)),r.setAttribute("aria-hidden","true"),r},position:20}),e.push({render(n,r,s,i){let l=document.createElement("span");l.className="cm-completionLabel";let c=n.displayLabel||n.label,d=0;for(let h=0;hd&&l.appendChild(document.createTextNode(c.slice(d,m)));let x=l.appendChild(document.createElement("span"));x.appendChild(document.createTextNode(c.slice(m,p))),x.className="cm-completionMatchedText",d=p}return dn.position-r.position).map(n=>n.render)}function Ky(t,e,n){if(t<=n)return{from:0,to:t};if(e<0&&(e=0),e<=t>>1){let s=Math.floor(e/n);return{from:s*n,to:(s+1)*n}}let r=Math.floor((t-e)/n);return{from:t-(r+1)*n,to:t-r*n}}class HK{constructor(e,n,r){this.view=e,this.stateField=n,this.applyCompletion=r,this.info=null,this.infoDestroy=null,this.placeInfoReq={read:()=>this.measureInfo(),write:d=>this.placeInfo(d),key:this},this.space=null,this.currentClass="";let s=e.state.field(n),{options:i,selected:l}=s.open,c=e.state.facet(Dr);this.optionContent=$K(c),this.optionClass=c.optionClass,this.tooltipClass=c.tooltipClass,this.range=Ky(i.length,l,c.maxRenderedOptions),this.dom=document.createElement("div"),this.dom.className="cm-tooltip-autocomplete",this.updateTooltipClass(e.state),this.dom.addEventListener("mousedown",d=>{let{options:h}=e.state.field(n).open;for(let m=d.target,p;m&&m!=this.dom;m=m.parentNode)if(m.nodeName=="LI"&&(p=/-(\d+)$/.exec(m.id))&&+p[1]{let h=e.state.field(this.stateField,!1);h&&h.tooltip&&e.state.facet(Dr).closeOnBlur&&d.relatedTarget!=e.contentDOM&&e.dispatch({effects:Mf.of(null)})}),this.showOptions(i,s.id)}mount(){this.updateSel()}showOptions(e,n){this.list&&this.list.remove(),this.list=this.dom.appendChild(this.createListBox(e,n,this.range)),this.list.addEventListener("scroll",()=>{this.info&&this.view.requestMeasure(this.placeInfoReq)})}update(e){var n;let r=e.state.field(this.stateField),s=e.startState.field(this.stateField);if(this.updateTooltipClass(e.state),r!=s){let{options:i,selected:l,disabled:c}=r.open;(!s.open||s.open.options!=i)&&(this.range=Ky(i.length,l,e.state.facet(Dr).maxRenderedOptions),this.showOptions(i,r.id)),this.updateSel(),c!=((n=s.open)===null||n===void 0?void 0:n.disabled)&&this.dom.classList.toggle("cm-tooltip-autocomplete-disabled",!!c)}}updateTooltipClass(e){let n=this.tooltipClass(e);if(n!=this.currentClass){for(let r of this.currentClass.split(" "))r&&this.dom.classList.remove(r);for(let r of n.split(" "))r&&this.dom.classList.add(r);this.currentClass=n}}positioned(e){this.space=e,this.info&&this.view.requestMeasure(this.placeInfoReq)}updateSel(){let e=this.view.state.field(this.stateField),n=e.open;(n.selected>-1&&n.selected=this.range.to)&&(this.range=Ky(n.options.length,n.selected,this.view.state.facet(Dr).maxRenderedOptions),this.showOptions(n.options,e.id));let r=this.updateSelectedOption(n.selected);if(r){this.destroyInfo();let{completion:s}=n.options[n.selected],{info:i}=s;if(!i)return;let l=typeof i=="string"?document.createTextNode(i):i(s);if(!l)return;"then"in l?l.then(c=>{c&&this.view.state.field(this.stateField,!1)==e&&this.addInfoPane(c,s)}).catch(c=>Es(this.view.state,c,"completion info")):(this.addInfoPane(l,s),r.setAttribute("aria-describedby",this.info.id))}}addInfoPane(e,n){this.destroyInfo();let r=this.info=document.createElement("div");if(r.className="cm-tooltip cm-completionInfo",r.id="cm-completionInfo-"+Math.floor(Math.random()*65535).toString(16),e.nodeType!=null)r.appendChild(e),this.infoDestroy=null;else{let{dom:s,destroy:i}=e;r.appendChild(s),this.infoDestroy=i||null}this.dom.appendChild(r),this.view.requestMeasure(this.placeInfoReq)}updateSelectedOption(e){let n=null;for(let r=this.list.firstChild,s=this.range.from;r;r=r.nextSibling,s++)r.nodeName!="LI"||!r.id?s--:s==e?r.hasAttribute("aria-selected")||(r.setAttribute("aria-selected","true"),n=r):r.hasAttribute("aria-selected")&&(r.removeAttribute("aria-selected"),r.removeAttribute("aria-describedby"));return n&&VK(this.list,n),n}measureInfo(){let e=this.dom.querySelector("[aria-selected]");if(!e||!this.info)return null;let n=this.dom.getBoundingClientRect(),r=this.info.getBoundingClientRect(),s=e.getBoundingClientRect(),i=this.space;if(!i){let l=this.dom.ownerDocument.documentElement;i={left:0,top:0,right:l.clientWidth,bottom:l.clientHeight}}return s.top>Math.min(i.bottom,n.bottom)-10||s.bottom{l.target==s&&l.preventDefault()});let i=null;for(let l=r.from;lr.from||r.from==0))if(i=x,typeof h!="string"&&h.header)s.appendChild(h.header(h));else{let v=s.appendChild(document.createElement("completion-section"));v.textContent=x}}const m=s.appendChild(document.createElement("li"));m.id=n+"-"+l,m.setAttribute("role","option");let p=this.optionClass(c);p&&(m.className=p);for(let x of this.optionContent){let v=x(c,this.view.state,this.view,d);v&&m.appendChild(v)}}return r.from&&s.classList.add("cm-completionListIncompleteTop"),r.tonew HK(n,t,e)}function VK(t,e){let n=t.getBoundingClientRect(),r=e.getBoundingClientRect(),s=n.height/t.offsetHeight;r.topn.bottom&&(t.scrollTop+=(r.bottom-n.bottom)/s)}function M7(t){return(t.boost||0)*100+(t.apply?10:0)+(t.info?5:0)+(t.type?1:0)}function WK(t,e){let n=[],r=null,s=null,i=m=>{n.push(m);let{section:p}=m.completion;if(p){r||(r=[]);let x=typeof p=="string"?p:p.name;r.some(v=>v.name==x)||r.push(typeof p=="string"?{name:x}:p)}},l=e.facet(Dr);for(let m of t)if(m.hasResult()){let p=m.result.getMatch;if(m.result.filter===!1)for(let x of m.result.options)i(new N7(x,m.source,p?p(x):[],1e9-n.length));else{let x=e.sliceDoc(m.from,m.to),v,b=l.filterStrict?new FK(x):new qK(x);for(let k of m.result.options)if(v=b.match(k.label)){let O=k.displayLabel?p?p(k,v.matched):[]:v.matched,j=v.score+(k.boost||0);if(i(new N7(k,m.source,O,j)),typeof k.section=="object"&&k.section.rank==="dynamic"){let{name:T}=k.section;s||(s=Object.create(null)),s[T]=Math.max(j,s[T]||-1e9)}}}}if(r){let m=Object.create(null),p=0,x=(v,b)=>(v.rank==="dynamic"&&b.rank==="dynamic"?s[b.name]-s[v.name]:0)||(typeof v.rank=="number"?v.rank:1e9)-(typeof b.rank=="number"?b.rank:1e9)||(v.namex.score-p.score||h(p.completion,x.completion))){let p=m.completion;!d||d.label!=p.label||d.detail!=p.detail||d.type!=null&&p.type!=null&&d.type!=p.type||d.apply!=p.apply||d.boost!=p.boost?c.push(m):M7(m.completion)>M7(d)&&(c[c.length-1]=m),d=m.completion}return c}class $u{constructor(e,n,r,s,i,l){this.options=e,this.attrs=n,this.tooltip=r,this.timestamp=s,this.selected=i,this.disabled=l}setSelected(e,n){return e==this.selected||e>=this.options.length?this:new $u(this.options,A7(n,e),this.tooltip,this.timestamp,e,this.disabled)}static build(e,n,r,s,i,l){if(s&&!l&&e.some(h=>h.isPending))return s.setDisabled();let c=WK(e,n);if(!c.length)return s&&e.some(h=>h.isPending)?s.setDisabled():null;let d=n.facet(Dr).selectOnOpen?0:-1;if(s&&s.selected!=d&&s.selected!=-1){let h=s.options[s.selected].completion;for(let m=0;mm.hasResult()?Math.min(h,m.from):h,1e8),create:JK,above:i.aboveCursor},s?s.timestamp:Date.now(),d,!1)}map(e){return new $u(this.options,this.attrs,{...this.tooltip,pos:e.mapPos(this.tooltip.pos)},this.timestamp,this.selected,this.disabled)}setDisabled(){return new $u(this.options,this.attrs,this.tooltip,this.timestamp,this.selected,!0)}}class Fg{constructor(e,n,r){this.active=e,this.id=n,this.open=r}static start(){return new Fg(KK,"cm-ac-"+Math.floor(Math.random()*2e6).toString(36),null)}update(e){let{state:n}=e,r=n.facet(Dr),i=(r.override||n.languageDataAt("autocomplete",gc(n)).map(IK)).map(d=>(this.active.find(m=>m.source==d)||new Si(d,this.active.some(m=>m.state!=0)?1:0)).update(e,r));i.length==this.active.length&&i.every((d,h)=>d==this.active[h])&&(i=this.active);let l=this.open,c=e.effects.some(d=>d.is(Jw));l&&e.docChanged&&(l=l.map(e.changes)),e.selection||i.some(d=>d.hasResult()&&e.changes.touchesRange(d.from,d.to))||!GK(i,this.active)||c?l=$u.build(i,n,this.id,l,r,c):l&&l.disabled&&!i.some(d=>d.isPending)&&(l=null),!l&&i.every(d=>!d.isPending)&&i.some(d=>d.hasResult())&&(i=i.map(d=>d.hasResult()?new Si(d.source,0):d));for(let d of e.effects)d.is(m_)&&(l=l&&l.setSelected(d.value,this.id));return i==this.active&&l==this.open?this:new Fg(i,this.id,l)}get tooltip(){return this.open?this.open.tooltip:null}get attrs(){return this.open?this.open.attrs:this.active.length?XK:YK}}function GK(t,e){if(t==e)return!0;for(let n=0,r=0;;){for(;n-1&&(n["aria-activedescendant"]=t+"-"+e),n}const KK=[];function f_(t,e){if(t.isUserEvent("input.complete")){let r=t.annotation(Zw);if(r&&e.activateOnCompletion(r))return 12}let n=t.isUserEvent("input.type");return n&&e.activateOnTyping?5:n?1:t.isUserEvent("delete.backward")?2:t.selection?8:t.docChanged?16:0}class Si{constructor(e,n,r=!1){this.source=e,this.state=n,this.explicit=r}hasResult(){return!1}get isPending(){return this.state==1}update(e,n){let r=f_(e,n),s=this;(r&8||r&16&&this.touches(e))&&(s=new Si(s.source,0)),r&4&&s.state==0&&(s=new Si(this.source,1)),s=s.updateFor(e,r);for(let i of e.effects)if(i.is(qg))s=new Si(s.source,1,i.value);else if(i.is(Mf))s=new Si(s.source,0);else if(i.is(Jw))for(let l of i.value)l.source==s.source&&(s=l);return s}updateFor(e,n){return this.map(e.changes)}map(e){return this}touches(e){return e.changes.touchesRange(gc(e.state))}}class Ku extends Si{constructor(e,n,r,s,i,l){super(e,3,n),this.limit=r,this.result=s,this.from=i,this.to=l}hasResult(){return!0}updateFor(e,n){var r;if(!(n&3))return this.map(e.changes);let s=this.result;s.map&&!e.changes.empty&&(s=s.map(s,e.changes));let i=e.changes.mapPos(this.from),l=e.changes.mapPos(this.to,1),c=gc(e.state);if(c>l||!s||n&2&&(gc(e.startState)==this.from||cn.map(e))}}),m_=xt.define(),As=Lr.define({create(){return Fg.start()},update(t,e){return t.update(e)},provide:t=>[Dw.from(t,e=>e.tooltip),qe.contentAttributes.from(t,e=>e.attrs)]});function e5(t,e){const n=e.completion.apply||e.completion.label;let r=t.state.field(As).active.find(s=>s.source==e.source);return r instanceof Ku?(typeof n=="string"?t.dispatch({...BK(t.state,n,r.from,r.to),annotations:Zw.of(e.completion)}):n(t,e.completion,r.from,r.to),!0):!1}const JK=UK(As,e5);function bp(t,e="option"){return n=>{let r=n.state.field(As,!1);if(!r||!r.open||r.open.disabled||Date.now()-r.open.timestamp-1?r.open.selected+s*(t?1:-1):t?0:l-1;return c<0?c=e=="page"?0:l-1:c>=l&&(c=e=="page"?l-1:0),n.dispatch({effects:m_.of(c)}),!0}}const eZ=t=>{let e=t.state.field(As,!1);return t.state.readOnly||!e||!e.open||e.open.selected<0||e.open.disabled||Date.now()-e.open.timestampt.state.field(As,!1)?(t.dispatch({effects:qg.of(!0)}),!0):!1,tZ=t=>{let e=t.state.field(As,!1);return!e||!e.active.some(n=>n.state!=0)?!1:(t.dispatch({effects:Mf.of(null)}),!0)};class nZ{constructor(e,n){this.active=e,this.context=n,this.time=Date.now(),this.updates=[],this.done=void 0}}const rZ=50,sZ=1e3,iZ=lr.fromClass(class{constructor(t){this.view=t,this.debounceUpdate=-1,this.running=[],this.debounceAccept=-1,this.pendingStart=!1,this.composing=0;for(let e of t.state.field(As).active)e.isPending&&this.startQuery(e)}update(t){let e=t.state.field(As),n=t.state.facet(Dr);if(!t.selectionSet&&!t.docChanged&&t.startState.field(As)==e)return;let r=t.transactions.some(i=>{let l=f_(i,n);return l&8||(i.selection||i.docChanged)&&!(l&3)});for(let i=0;irZ&&Date.now()-l.time>sZ){for(let c of l.context.abortListeners)try{c()}catch(d){Es(this.view.state,d)}l.context.abortListeners=null,this.running.splice(i--,1)}else l.updates.push(...t.transactions)}this.debounceUpdate>-1&&clearTimeout(this.debounceUpdate),t.transactions.some(i=>i.effects.some(l=>l.is(qg)))&&(this.pendingStart=!0);let s=this.pendingStart?50:n.activateOnTypingDelay;if(this.debounceUpdate=e.active.some(i=>i.isPending&&!this.running.some(l=>l.active.source==i.source))?setTimeout(()=>this.startUpdate(),s):-1,this.composing!=0)for(let i of t.transactions)i.isUserEvent("input.type")?this.composing=2:this.composing==2&&i.selection&&(this.composing=3)}startUpdate(){this.debounceUpdate=-1,this.pendingStart=!1;let{state:t}=this.view,e=t.field(As);for(let n of e.active)n.isPending&&!this.running.some(r=>r.active.source==n.source)&&this.startQuery(n);this.running.length&&e.open&&e.open.disabled&&(this.debounceAccept=setTimeout(()=>this.accept(),this.view.state.facet(Dr).updateSyncTime))}startQuery(t){let{state:e}=this.view,n=gc(e),r=new u_(e,n,t.explicit,this.view),s=new nZ(t,r);this.running.push(s),Promise.resolve(t.source(r)).then(i=>{s.context.aborted||(s.done=i||null,this.scheduleAccept())},i=>{this.view.dispatch({effects:Mf.of(null)}),Es(this.view.state,i)})}scheduleAccept(){this.running.every(t=>t.done!==void 0)?this.accept():this.debounceAccept<0&&(this.debounceAccept=setTimeout(()=>this.accept(),this.view.state.facet(Dr).updateSyncTime))}accept(){var t;this.debounceAccept>-1&&clearTimeout(this.debounceAccept),this.debounceAccept=-1;let e=[],n=this.view.state.facet(Dr),r=this.view.state.field(As);for(let s=0;sc.source==i.active.source);if(l&&l.isPending)if(i.done==null){let c=new Si(i.active.source,0);for(let d of i.updates)c=c.update(d,n);c.isPending||e.push(c)}else this.startQuery(l)}(e.length||r.open&&r.open.disabled)&&this.view.dispatch({effects:Jw.of(e)})}},{eventHandlers:{blur(t){let e=this.view.state.field(As,!1);if(e&&e.tooltip&&this.view.state.facet(Dr).closeOnBlur){let n=e.open&&QA(this.view,e.open.tooltip);(!n||!n.dom.contains(t.relatedTarget))&&setTimeout(()=>this.view.dispatch({effects:Mf.of(null)}),10)}},compositionstart(){this.composing=1},compositionend(){this.composing==3&&setTimeout(()=>this.view.dispatch({effects:qg.of(!1)}),20),this.composing=0}}}),aZ=typeof navigator=="object"&&/Win/.test(navigator.platform),lZ=jo.highest(qe.domEventHandlers({keydown(t,e){let n=e.state.field(As,!1);if(!n||!n.open||n.open.disabled||n.open.selected<0||t.key.length>1||t.ctrlKey&&!(aZ&&t.altKey)||t.metaKey)return!1;let r=n.open.options[n.open.selected],s=n.active.find(l=>l.source==r.source),i=r.completion.commitCharacters||s.result.commitCharacters;return i&&i.indexOf(t.key)>-1&&e5(e,r),!1}})),p_=qe.baseTheme({".cm-tooltip.cm-tooltip-autocomplete":{"& > ul":{fontFamily:"monospace",whiteSpace:"nowrap",overflow:"hidden auto",maxWidth_fallback:"700px",maxWidth:"min(700px, 95vw)",minWidth:"250px",maxHeight:"10em",height:"100%",listStyle:"none",margin:0,padding:0,"& > li, & > completion-section":{padding:"1px 3px",lineHeight:1.2},"& > li":{overflowX:"hidden",textOverflow:"ellipsis",cursor:"pointer"},"& > completion-section":{display:"list-item",borderBottom:"1px solid silver",paddingLeft:"0.5em",opacity:.7}}},"&light .cm-tooltip-autocomplete ul li[aria-selected]":{background:"#17c",color:"white"},"&light .cm-tooltip-autocomplete-disabled ul li[aria-selected]":{background:"#777"},"&dark .cm-tooltip-autocomplete ul li[aria-selected]":{background:"#347",color:"white"},"&dark .cm-tooltip-autocomplete-disabled ul li[aria-selected]":{background:"#444"},".cm-completionListIncompleteTop:before, .cm-completionListIncompleteBottom:after":{content:'"···"',opacity:.5,display:"block",textAlign:"center"},".cm-tooltip.cm-completionInfo":{position:"absolute",padding:"3px 9px",width:"max-content",maxWidth:"400px",boxSizing:"border-box",whiteSpace:"pre-line"},".cm-completionInfo.cm-completionInfo-left":{right:"100%"},".cm-completionInfo.cm-completionInfo-right":{left:"100%"},".cm-completionInfo.cm-completionInfo-left-narrow":{right:"30px"},".cm-completionInfo.cm-completionInfo-right-narrow":{left:"30px"},"&light .cm-snippetField":{backgroundColor:"#00000022"},"&dark .cm-snippetField":{backgroundColor:"#ffffff22"},".cm-snippetFieldPosition":{verticalAlign:"text-top",width:0,height:"1.15em",display:"inline-block",margin:"0 -0.7px -.7em",borderLeft:"1.4px dotted #888"},".cm-completionMatchedText":{textDecoration:"underline"},".cm-completionDetail":{marginLeft:"0.5em",fontStyle:"italic"},".cm-completionIcon":{fontSize:"90%",width:".8em",display:"inline-block",textAlign:"center",paddingRight:".6em",opacity:"0.6",boxSizing:"content-box"},".cm-completionIcon-function, .cm-completionIcon-method":{"&:after":{content:"'ƒ'"}},".cm-completionIcon-class":{"&:after":{content:"'○'"}},".cm-completionIcon-interface":{"&:after":{content:"'◌'"}},".cm-completionIcon-variable":{"&:after":{content:"'𝑥'"}},".cm-completionIcon-constant":{"&:after":{content:"'𝐶'"}},".cm-completionIcon-type":{"&:after":{content:"'𝑡'"}},".cm-completionIcon-enum":{"&:after":{content:"'∪'"}},".cm-completionIcon-property":{"&:after":{content:"'□'"}},".cm-completionIcon-keyword":{"&:after":{content:"'🔑︎'"}},".cm-completionIcon-namespace":{"&:after":{content:"'▢'"}},".cm-completionIcon-text":{"&:after":{content:"'abc'",fontSize:"50%",verticalAlign:"middle"}}});class oZ{constructor(e,n,r,s){this.field=e,this.line=n,this.from=r,this.to=s}}class t5{constructor(e,n,r){this.field=e,this.from=n,this.to=r}map(e){let n=e.mapPos(this.from,-1,Ur.TrackDel),r=e.mapPos(this.to,1,Ur.TrackDel);return n==null||r==null?null:new t5(this.field,n,r)}}class n5{constructor(e,n){this.lines=e,this.fieldPositions=n}instantiate(e,n){let r=[],s=[n],i=e.doc.lineAt(n),l=/^\s*/.exec(i.text)[0];for(let d of this.lines){if(r.length){let h=l,m=/^\t*/.exec(d)[0].length;for(let p=0;pnew t5(d.field,s[d.line]+d.from,s[d.line]+d.to));return{text:r,ranges:c}}static parse(e){let n=[],r=[],s=[],i;for(let l of e.split(/\r\n?|\n/)){for(;i=/[#$]\{(?:(\d+)(?::([^{}]*))?|((?:\\[{}]|[^{}])*))\}/.exec(l);){let c=i[1]?+i[1]:null,d=i[2]||i[3]||"",h=-1,m=d.replace(/\\[{}]/g,p=>p[1]);for(let p=0;p=h&&x.field++}for(let p of s)if(p.line==r.length&&p.from>i.index){let x=i[2]?3+(i[1]||"").length:2;p.from-=x,p.to-=x}s.push(new oZ(h,r.length,i.index,i.index+m.length)),l=l.slice(0,i.index)+d+l.slice(i.index+i[0].length)}l=l.replace(/\\([{}])/g,(c,d,h)=>{for(let m of s)m.line==r.length&&m.from>h&&(m.from--,m.to--);return d}),r.push(l)}return new n5(r,s)}}let cZ=Je.widget({widget:new class extends Oa{toDOM(){let t=document.createElement("span");return t.className="cm-snippetFieldPosition",t}ignoreEvent(){return!1}}}),uZ=Je.mark({class:"cm-snippetField"});class Ed{constructor(e,n){this.ranges=e,this.active=n,this.deco=Je.set(e.map(r=>(r.from==r.to?cZ:uZ).range(r.from,r.to)),!0)}map(e){let n=[];for(let r of this.ranges){let s=r.map(e);if(!s)return null;n.push(s)}return new Ed(n,this.active)}selectionInsideField(e){return e.ranges.every(n=>this.ranges.some(r=>r.field==this.active&&r.from<=n.from&&r.to>=n.to))}}const p0=xt.define({map(t,e){return t&&t.map(e)}}),dZ=xt.define(),Af=Lr.define({create(){return null},update(t,e){for(let n of e.effects){if(n.is(p0))return n.value;if(n.is(dZ)&&t)return new Ed(t.ranges,n.value)}return t&&e.docChanged&&(t=t.map(e.changes)),t&&e.selection&&!t.selectionInsideField(e.selection)&&(t=null),t},provide:t=>qe.decorations.from(t,e=>e?e.deco:Je.none)});function r5(t,e){return Ce.create(t.filter(n=>n.field==e).map(n=>Ce.range(n.from,n.to)))}function hZ(t){let e=n5.parse(t);return(n,r,s,i)=>{let{text:l,ranges:c}=e.instantiate(n.state,s),{main:d}=n.state.selection,h={changes:{from:s,to:i==d.from?d.to:i,insert:Wt.of(l)},scrollIntoView:!0,annotations:r?[Zw.of(r),gr.userEvent.of("input.complete")]:void 0};if(c.length&&(h.selection=r5(c,0)),c.some(m=>m.field>0)){let m=new Ed(c,0),p=h.effects=[p0.of(m)];n.state.field(Af,!1)===void 0&&p.push(xt.appendConfig.of([Af,xZ,vZ,p_]))}n.dispatch(n.state.update(h))}}function g_(t){return({state:e,dispatch:n})=>{let r=e.field(Af,!1);if(!r||t<0&&r.active==0)return!1;let s=r.active+t,i=t>0&&!r.ranges.some(l=>l.field==s+t);return n(e.update({selection:r5(r.ranges,s),effects:p0.of(i?null:new Ed(r.ranges,s)),scrollIntoView:!0})),!0}}const fZ=({state:t,dispatch:e})=>t.field(Af,!1)?(e(t.update({effects:p0.of(null)})),!0):!1,mZ=g_(1),pZ=g_(-1),gZ=[{key:"Tab",run:mZ,shift:pZ},{key:"Escape",run:fZ}],E7=He.define({combine(t){return t.length?t[0]:gZ}}),xZ=jo.highest(o0.compute([E7],t=>t.facet(E7)));function Xa(t,e){return{...e,apply:hZ(t)}}const vZ=qe.domEventHandlers({mousedown(t,e){let n=e.state.field(Af,!1),r;if(!n||(r=e.posAtCoords({x:t.clientX,y:t.clientY}))==null)return!1;let s=n.ranges.find(i=>i.from<=r&&i.to>=r);return!s||s.field==n.active?!1:(e.dispatch({selection:r5(n.ranges,s.field),effects:p0.of(n.ranges.some(i=>i.field>s.field)?new Ed(n.ranges,s.field):null),scrollIntoView:!0}),!0)}}),Ef={brackets:["(","[","{","'",'"'],before:")]}:;>",stringPrefixes:[]},oc=xt.define({map(t,e){let n=e.mapPos(t,-1,Ur.TrackAfter);return n??void 0}}),s5=new class extends yc{};s5.startSide=1;s5.endSide=-1;const x_=Lr.define({create(){return Gt.empty},update(t,e){if(t=t.map(e.changes),e.selection){let n=e.state.doc.lineAt(e.selection.main.head);t=t.update({filter:r=>r>=n.from&&r<=n.to})}for(let n of e.effects)n.is(oc)&&(t=t.update({add:[s5.range(n.value,n.value+1)]}));return t}});function yZ(){return[wZ,x_]}const Jy="()[]{}<>«»»«[]{}";function v_(t){for(let e=0;e{if((bZ?t.composing:t.compositionStarted)||t.state.readOnly)return!1;let s=t.state.selection.main;if(r.length>2||r.length==2&&aa(Ms(r,0))==1||e!=s.from||n!=s.to)return!1;let i=OZ(t.state,r);return i?(t.dispatch(i),!0):!1}),SZ=({state:t,dispatch:e})=>{if(t.readOnly)return!1;let r=y_(t,t.selection.main.head).brackets||Ef.brackets,s=null,i=t.changeByRange(l=>{if(l.empty){let c=jZ(t.doc,l.head);for(let d of r)if(d==c&&Dx(t.doc,l.head)==v_(Ms(d,0)))return{changes:{from:l.head-d.length,to:l.head+d.length},range:Ce.cursor(l.head-d.length)}}return{range:s=l}});return s||e(t.update(i,{scrollIntoView:!0,userEvent:"delete.backward"})),!s},kZ=[{key:"Backspace",run:SZ}];function OZ(t,e){let n=y_(t,t.selection.main.head),r=n.brackets||Ef.brackets;for(let s of r){let i=v_(Ms(s,0));if(e==s)return i==s?TZ(t,s,r.indexOf(s+s+s)>-1,n):NZ(t,s,i,n.before||Ef.before);if(e==i&&b_(t,t.selection.main.from))return CZ(t,s,i)}return null}function b_(t,e){let n=!1;return t.field(x_).between(0,t.doc.length,r=>{r==e&&(n=!0)}),n}function Dx(t,e){let n=t.sliceString(e,e+2);return n.slice(0,aa(Ms(n,0)))}function jZ(t,e){let n=t.sliceString(e-2,e);return aa(Ms(n,0))==n.length?n:n.slice(1)}function NZ(t,e,n,r){let s=null,i=t.changeByRange(l=>{if(!l.empty)return{changes:[{insert:e,from:l.from},{insert:n,from:l.to}],effects:oc.of(l.to+e.length),range:Ce.range(l.anchor+e.length,l.head+e.length)};let c=Dx(t.doc,l.head);return!c||/\s/.test(c)||r.indexOf(c)>-1?{changes:{insert:e+n,from:l.head},effects:oc.of(l.head+e.length),range:Ce.cursor(l.head+e.length)}:{range:s=l}});return s?null:t.update(i,{scrollIntoView:!0,userEvent:"input.type"})}function CZ(t,e,n){let r=null,s=t.changeByRange(i=>i.empty&&Dx(t.doc,i.head)==n?{changes:{from:i.head,to:i.head+n.length,insert:n},range:Ce.cursor(i.head+n.length)}:r={range:i});return r?null:t.update(s,{scrollIntoView:!0,userEvent:"input.type"})}function TZ(t,e,n,r){let s=r.stringPrefixes||Ef.stringPrefixes,i=null,l=t.changeByRange(c=>{if(!c.empty)return{changes:[{insert:e,from:c.from},{insert:e,from:c.to}],effects:oc.of(c.to+e.length),range:Ce.range(c.anchor+e.length,c.head+e.length)};let d=c.head,h=Dx(t.doc,d),m;if(h==e){if(_7(t,d))return{changes:{insert:e+e,from:d},effects:oc.of(d+e.length),range:Ce.cursor(d+e.length)};if(b_(t,d)){let x=n&&t.sliceDoc(d,d+e.length*3)==e+e+e?e+e+e:e;return{changes:{from:d,to:d+x.length,insert:x},range:Ce.cursor(d+x.length)}}}else{if(n&&t.sliceDoc(d-2*e.length,d)==e+e&&(m=D7(t,d-2*e.length,s))>-1&&_7(t,m))return{changes:{insert:e+e+e+e,from:d},effects:oc.of(d+e.length),range:Ce.cursor(d+e.length)};if(t.charCategorizer(d)(h)!=Vn.Word&&D7(t,d,s)>-1&&!MZ(t,d,e,s))return{changes:{insert:e+e,from:d},effects:oc.of(d+e.length),range:Ce.cursor(d+e.length)}}return{range:i=c}});return i?null:t.update(l,{scrollIntoView:!0,userEvent:"input.type"})}function _7(t,e){let n=zr(t).resolveInner(e+1);return n.parent&&n.from==e}function MZ(t,e,n,r){let s=zr(t).resolveInner(e,-1),i=r.reduce((l,c)=>Math.max(l,c.length),0);for(let l=0;l<5;l++){let c=t.sliceDoc(s.from,Math.min(s.to,s.from+n.length+i)),d=c.indexOf(n);if(!d||d>-1&&r.indexOf(c.slice(0,d))>-1){let m=s.firstChild;for(;m&&m.from==s.from&&m.to-m.from>n.length+d;){if(t.sliceDoc(m.to-n.length,m.to)==n)return!1;m=m.firstChild}return!0}let h=s.to==e&&s.parent;if(!h)break;s=h}return!1}function D7(t,e,n){let r=t.charCategorizer(e);if(r(t.sliceDoc(e-1,e))!=Vn.Word)return e;for(let s of n){let i=e-s.length;if(t.sliceDoc(i,e)==s&&r(t.sliceDoc(i-1,i))!=Vn.Word)return i}return-1}function AZ(t={}){return[lZ,As,Dr.of(t),iZ,EZ,p_]}const w_=[{key:"Ctrl-Space",run:Zy},{mac:"Alt-`",run:Zy},{mac:"Alt-i",run:Zy},{key:"Escape",run:tZ},{key:"ArrowDown",run:bp(!0)},{key:"ArrowUp",run:bp(!1)},{key:"PageDown",run:bp(!0,"page")},{key:"PageUp",run:bp(!1,"page")},{key:"Enter",run:eZ}],EZ=jo.highest(o0.computeN([Dr],t=>t.facet(Dr).defaultKeymap?[w_]:[]));class R7{constructor(e,n,r){this.from=e,this.to=n,this.diagnostic=r}}class sc{constructor(e,n,r){this.diagnostics=e,this.panel=n,this.selected=r}static init(e,n,r){let s=r.facet(_f).markerFilter;s&&(e=s(e,r));let i=e.slice().sort((v,b)=>v.from-b.from||v.to-b.to),l=new fl,c=[],d=0,h=r.doc.iter(),m=0,p=r.doc.length;for(let v=0;;){let b=v==i.length?null:i[v];if(!b&&!c.length)break;let k,O;if(c.length)k=d,O=c.reduce((M,_)=>Math.min(M,_.to),b&&b.from>k?b.from:1e8);else{if(k=b.from,k>p)break;O=b.to,c.push(b),v++}for(;vM.from||M.to==k))c.push(M),v++,O=Math.min(M.to,O);else{O=Math.min(M.from,O);break}}O=Math.min(O,p);let j=!1;if(c.some(M=>M.from==k&&(M.to==O||O==p))&&(j=k==O,!j&&O-k<10)){let M=k-(m+h.value.length);M>0&&(h.next(M),m=k);for(let _=k;;){if(_>=O){j=!0;break}if(!h.lineBreak&&m+h.value.length>_)break;_=m+h.value.length,m+=h.value.length,h.next()}}let T=HZ(c);if(j)l.add(k,k,Je.widget({widget:new qZ(T),diagnostics:c.slice()}));else{let M=c.reduce((_,D)=>D.markClass?_+" "+D.markClass:_,"");l.add(k,O,Je.mark({class:"cm-lintRange cm-lintRange-"+T+M,diagnostics:c.slice(),inclusiveEnd:c.some(_=>_.to>O)}))}if(d=O,d==p)break;for(let M=0;M{if(!(e&&l.diagnostics.indexOf(e)<0))if(!r)r=new R7(s,i,e||l.diagnostics[0]);else{if(l.diagnostics.indexOf(r.diagnostic)<0)return!1;r=new R7(r.from,i,r.diagnostic)}}),r}function _Z(t,e){let n=e.pos,r=e.end||n,s=t.state.facet(_f).hideOn(t,n,r);if(s!=null)return s;let i=t.startState.doc.lineAt(e.pos);return!!(t.effects.some(l=>l.is(S_))||t.changes.touchesRange(i.from,Math.max(i.to,r)))}function DZ(t,e){return t.field(ni,!1)?e:e.concat(xt.appendConfig.of(UZ))}const S_=xt.define(),i5=xt.define(),k_=xt.define(),ni=Lr.define({create(){return new sc(Je.none,null,null)},update(t,e){if(e.docChanged&&t.diagnostics.size){let n=t.diagnostics.map(e.changes),r=null,s=t.panel;if(t.selected){let i=e.changes.mapPos(t.selected.from,1);r=xd(n,t.selected.diagnostic,i)||xd(n,null,i)}!n.size&&s&&e.state.facet(_f).autoPanel&&(s=null),t=new sc(n,s,r)}for(let n of e.effects)if(n.is(S_)){let r=e.state.facet(_f).autoPanel?n.value.length?Df.open:null:t.panel;t=sc.init(n.value,r,e.state)}else n.is(i5)?t=new sc(t.diagnostics,n.value?Df.open:null,t.selected):n.is(k_)&&(t=new sc(t.diagnostics,t.panel,n.value));return t},provide:t=>[Sf.from(t,e=>e.panel),qe.decorations.from(t,e=>e.diagnostics)]}),RZ=Je.mark({class:"cm-lintRange cm-lintRange-active"});function zZ(t,e,n){let{diagnostics:r}=t.state.field(ni),s,i=-1,l=-1;r.between(e-(n<0?1:0),e+(n>0?1:0),(d,h,{spec:m})=>{if(e>=d&&e<=h&&(d==h||(e>d||n>0)&&(ej_(t,n,!1)))}const LZ=t=>{let e=t.state.field(ni,!1);(!e||!e.panel)&&t.dispatch({effects:DZ(t.state,[i5.of(!0)])});let n=wf(t,Df.open);return n&&n.dom.querySelector(".cm-panel-lint ul").focus(),!0},z7=t=>{let e=t.state.field(ni,!1);return!e||!e.panel?!1:(t.dispatch({effects:i5.of(!1)}),!0)},BZ=t=>{let e=t.state.field(ni,!1);if(!e)return!1;let n=t.state.selection.main,r=e.diagnostics.iter(n.to+1);return!r.value&&(r=e.diagnostics.iter(0),!r.value||r.from==n.from&&r.to==n.to)?!1:(t.dispatch({selection:{anchor:r.from,head:r.to},scrollIntoView:!0}),!0)},IZ=[{key:"Mod-Shift-m",run:LZ,preventDefault:!0},{key:"F8",run:BZ}],_f=He.define({combine(t){return{sources:t.map(e=>e.source).filter(e=>e!=null),...ka(t.map(e=>e.config),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null,hideOn:()=>null},{delay:Math.max,markerFilter:P7,tooltipFilter:P7,needsRefresh:(e,n)=>e?n?r=>e(r)||n(r):e:n,hideOn:(e,n)=>e?n?(r,s,i)=>e(r,s,i)||n(r,s,i):e:n,autoPanel:(e,n)=>e||n})}}});function P7(t,e){return t?e?(n,r)=>e(t(n,r),r):t:e}function O_(t){let e=[];if(t)e:for(let{name:n}of t){for(let r=0;ri.toLowerCase()==s.toLowerCase())){e.push(s);continue e}}e.push("")}return e}function j_(t,e,n){var r;let s=n?O_(e.actions):[];return An("li",{class:"cm-diagnostic cm-diagnostic-"+e.severity},An("span",{class:"cm-diagnosticText"},e.renderMessage?e.renderMessage(t):e.message),(r=e.actions)===null||r===void 0?void 0:r.map((i,l)=>{let c=!1,d=v=>{if(v.preventDefault(),c)return;c=!0;let b=xd(t.state.field(ni).diagnostics,e);b&&i.apply(t,b.from,b.to)},{name:h}=i,m=s[l]?h.indexOf(s[l]):-1,p=m<0?h:[h.slice(0,m),An("u",h.slice(m,m+1)),h.slice(m+1)],x=i.markClass?" "+i.markClass:"";return An("button",{type:"button",class:"cm-diagnosticAction"+x,onclick:d,onmousedown:d,"aria-label":` Action: ${h}${m<0?"":` (access key "${s[l]})"`}.`},p)}),e.source&&An("div",{class:"cm-diagnosticSource"},e.source))}class qZ extends Oa{constructor(e){super(),this.sev=e}eq(e){return e.sev==this.sev}toDOM(){return An("span",{class:"cm-lintPoint cm-lintPoint-"+this.sev})}}class L7{constructor(e,n){this.diagnostic=n,this.id="item_"+Math.floor(Math.random()*4294967295).toString(16),this.dom=j_(e,n,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class Df{constructor(e){this.view=e,this.items=[];let n=s=>{if(s.keyCode==27)z7(this.view),this.view.focus();else if(s.keyCode==38||s.keyCode==33)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(s.keyCode==40||s.keyCode==34)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(s.keyCode==36)this.moveSelection(0);else if(s.keyCode==35)this.moveSelection(this.items.length-1);else if(s.keyCode==13)this.view.focus();else if(s.keyCode>=65&&s.keyCode<=90&&this.selectedIndex>=0){let{diagnostic:i}=this.items[this.selectedIndex],l=O_(i.actions);for(let c=0;c{for(let i=0;iz7(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(ni).selected;if(!e)return-1;for(let n=0;n{for(let m of h.diagnostics){if(l.has(m))continue;l.add(m);let p=-1,x;for(let v=r;vr&&(this.items.splice(r,p-r),s=!0)),n&&x.diagnostic==n.diagnostic?x.dom.hasAttribute("aria-selected")||(x.dom.setAttribute("aria-selected","true"),i=x):x.dom.hasAttribute("aria-selected")&&x.dom.removeAttribute("aria-selected"),r++}});r({sel:i.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:c,panel:d})=>{let h=d.height/this.list.offsetHeight;c.topd.bottom&&(this.list.scrollTop+=(c.bottom-d.bottom)/h)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),s&&this.sync()}sync(){let e=this.list.firstChild;function n(){let r=e;e=r.nextSibling,r.remove()}for(let r of this.items)if(r.dom.parentNode==this.list){for(;e!=r.dom;)n();e=r.dom.nextSibling}else this.list.insertBefore(r.dom,e);for(;e;)n()}moveSelection(e){if(this.selectedIndex<0)return;let n=this.view.state.field(ni),r=xd(n.diagnostics,this.items[e].diagnostic);r&&this.view.dispatch({selection:{anchor:r.from,head:r.to},scrollIntoView:!0,effects:k_.of(r)})}static open(e){return new Df(e)}}function FZ(t,e='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(t)}')`}function wp(t){return FZ(``,'width="6" height="3"')}const QZ=qe.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:wp("#d11")},".cm-lintRange-warning":{backgroundImage:wp("orange")},".cm-lintRange-info":{backgroundImage:wp("#999")},".cm-lintRange-hint":{backgroundImage:wp("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}}});function $Z(t){return t=="error"?4:t=="warning"?3:t=="info"?2:1}function HZ(t){let e="hint",n=1;for(let r of t){let s=$Z(r.severity);s>n&&(n=s,e=r.severity)}return e}const UZ=[ni,qe.decorations.compute([ni],t=>{let{selected:e,panel:n}=t.field(ni);return!e||!n||e.from==e.to?Je.none:Je.set([RZ.range(e.from,e.to)])}),NG(zZ,{hideOn:_Z}),QZ];var B7=function(e){e===void 0&&(e={});var{crosshairCursor:n=!1}=e,r=[];e.closeBracketsKeymap!==!1&&(r=r.concat(kZ)),e.defaultKeymap!==!1&&(r=r.concat(aK)),e.searchKeymap!==!1&&(r=r.concat(_K)),e.historyKeymap!==!1&&(r=r.concat(fY)),e.foldKeymap!==!1&&(r=r.concat(kX)),e.completionKeymap!==!1&&(r=r.concat(w_)),e.lintKeymap!==!1&&(r=r.concat(IZ));var s=[];return e.lineNumbers!==!1&&s.push(LG()),e.highlightActiveLineGutter!==!1&&s.push(qG()),e.highlightSpecialChars!==!1&&s.push(tG()),e.history!==!1&&s.push(sY()),e.foldGutter!==!1&&s.push(CX()),e.drawSelection!==!1&&s.push(HW()),e.dropCursor!==!1&&s.push(XW()),e.allowMultipleSelections!==!1&&s.push(Vt.allowMultipleSelections.of(!0)),e.indentOnInput!==!1&&s.push(mX()),e.syntaxHighlighting!==!1&&s.push(hE(EX,{fallback:!0})),e.bracketMatching!==!1&&s.push(BX()),e.closeBrackets!==!1&&s.push(yZ()),e.autocompletion!==!1&&s.push(AZ()),e.rectangularSelection!==!1&&s.push(pG()),n!==!1&&s.push(vG()),e.highlightActiveLine!==!1&&s.push(lG()),e.highlightSelectionMatches!==!1&&s.push(fK()),e.tabSize&&typeof e.tabSize=="number"&&s.push(u0.of(" ".repeat(e.tabSize))),s.concat([o0.of(r.flat())]).filter(Boolean)};const VZ="#e5c07b",I7="#e06c75",WZ="#56b6c2",GZ="#ffffff",sg="#abb2bf",o4="#7d8799",XZ="#61afef",YZ="#98c379",q7="#d19a66",KZ="#c678dd",ZZ="#21252b",F7="#2c313a",Q7="#282c34",eb="#353a42",JZ="#3E4451",$7="#528bff",eJ=qe.theme({"&":{color:sg,backgroundColor:Q7},".cm-content":{caretColor:$7},".cm-cursor, .cm-dropCursor":{borderLeftColor:$7},"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:JZ},".cm-panels":{backgroundColor:ZZ,color:sg},".cm-panels.cm-panels-top":{borderBottom:"2px solid black"},".cm-panels.cm-panels-bottom":{borderTop:"2px solid black"},".cm-searchMatch":{backgroundColor:"#72a1ff59",outline:"1px solid #457dff"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:"#6199ff2f"},".cm-activeLine":{backgroundColor:"#6699ff0b"},".cm-selectionMatch":{backgroundColor:"#aafe661a"},"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bad0f847"},".cm-gutters":{backgroundColor:Q7,color:o4,border:"none"},".cm-activeLineGutter":{backgroundColor:F7},".cm-foldPlaceholder":{backgroundColor:"transparent",border:"none",color:"#ddd"},".cm-tooltip":{border:"none",backgroundColor:eb},".cm-tooltip .cm-tooltip-arrow:before":{borderTopColor:"transparent",borderBottomColor:"transparent"},".cm-tooltip .cm-tooltip-arrow:after":{borderTopColor:eb,borderBottomColor:eb},".cm-tooltip-autocomplete":{"& > ul > li[aria-selected]":{backgroundColor:F7,color:sg}}},{dark:!0}),tJ=h0.define([{tag:he.keyword,color:KZ},{tag:[he.name,he.deleted,he.character,he.propertyName,he.macroName],color:I7},{tag:[he.function(he.variableName),he.labelName],color:XZ},{tag:[he.color,he.constant(he.name),he.standard(he.name)],color:q7},{tag:[he.definition(he.name),he.separator],color:sg},{tag:[he.typeName,he.className,he.number,he.changed,he.annotation,he.modifier,he.self,he.namespace],color:VZ},{tag:[he.operator,he.operatorKeyword,he.url,he.escape,he.regexp,he.link,he.special(he.string)],color:WZ},{tag:[he.meta,he.comment],color:o4},{tag:he.strong,fontWeight:"bold"},{tag:he.emphasis,fontStyle:"italic"},{tag:he.strikethrough,textDecoration:"line-through"},{tag:he.link,color:o4,textDecoration:"underline"},{tag:he.heading,fontWeight:"bold",color:I7},{tag:[he.atom,he.bool,he.special(he.variableName)],color:q7},{tag:[he.processingInstruction,he.string,he.inserted],color:YZ},{tag:he.invalid,color:GZ}]),N_=[eJ,hE(tJ)];var nJ=qe.theme({"&":{backgroundColor:"#fff"}},{dark:!1}),rJ=function(e){e===void 0&&(e={});var{indentWithTab:n=!0,editable:r=!0,readOnly:s=!1,theme:i="light",placeholder:l="",basicSetup:c=!0}=e,d=[];switch(n&&d.unshift(o0.of([lK])),c&&(typeof c=="boolean"?d.unshift(B7()):d.unshift(B7(c))),l&&d.unshift(dG(l)),i){case"light":d.push(nJ);break;case"dark":d.push(N_);break;case"none":break;default:d.push(i);break}return r===!1&&d.push(qe.editable.of(!1)),s&&d.push(Vt.readOnly.of(!0)),[...d]},sJ=t=>({line:t.state.doc.lineAt(t.state.selection.main.from),lineCount:t.state.doc.lines,lineBreak:t.state.lineBreak,length:t.state.doc.length,readOnly:t.state.readOnly,tabSize:t.state.tabSize,selection:t.state.selection,selectionAsSingle:t.state.selection.asSingle().main,ranges:t.state.selection.ranges,selectionCode:t.state.sliceDoc(t.state.selection.main.from,t.state.selection.main.to),selections:t.state.selection.ranges.map(e=>t.state.sliceDoc(e.from,e.to)),selectedText:t.state.selection.ranges.some(e=>!e.empty)});class iJ{constructor(e,n){this.timeLeftMS=void 0,this.timeoutMS=void 0,this.isCancelled=!1,this.isTimeExhausted=!1,this.callbacks=[],this.timeLeftMS=n,this.timeoutMS=n,this.callbacks.push(e)}tick(){if(!this.isCancelled&&!this.isTimeExhausted&&(this.timeLeftMS--,this.timeLeftMS<=0)){this.isTimeExhausted=!0;var e=this.callbacks.slice();this.callbacks.length=0,e.forEach(n=>{try{n()}catch(r){console.error("TimeoutLatch callback error:",r)}})}}cancel(){this.isCancelled=!0,this.callbacks.length=0}reset(){this.timeLeftMS=this.timeoutMS,this.isCancelled=!1,this.isTimeExhausted=!1}get isDone(){return this.isCancelled||this.isTimeExhausted}}class H7{constructor(){this.interval=null,this.latches=new Set}add(e){this.latches.add(e),this.start()}remove(e){this.latches.delete(e),this.latches.size===0&&this.stop()}start(){this.interval===null&&(this.interval=setInterval(()=>{this.latches.forEach(e=>{e.tick(),e.isDone&&this.remove(e)})},1))}stop(){this.interval!==null&&(clearInterval(this.interval),this.interval=null)}}var tb=null,aJ=()=>typeof window>"u"?new H7:(tb||(tb=new H7),tb),U7=Sa.define(),lJ=200,oJ=[];function cJ(t){var{value:e,selection:n,onChange:r,onStatistics:s,onCreateEditor:i,onUpdate:l,extensions:c=oJ,autoFocus:d,theme:h="light",height:m=null,minHeight:p=null,maxHeight:x=null,width:v=null,minWidth:b=null,maxWidth:k=null,placeholder:O="",editable:j=!0,readOnly:T=!1,indentWithTab:M=!0,basicSetup:_=!0,root:D,initialState:E}=t,[z,Q]=S.useState(),[F,B]=S.useState(),[U,V]=S.useState(),ce=S.useState(()=>({current:null}))[0],W=S.useState(()=>({current:null}))[0],J=qe.theme({"&":{height:m,minHeight:p,maxHeight:x,width:v,minWidth:b,maxWidth:k},"& .cm-scroller":{height:"100% !important"}}),H=qe.updateListener.of(ue=>{if(ue.docChanged&&typeof r=="function"&&!ue.transactions.some(Y=>Y.annotation(U7))){ce.current?ce.current.reset():(ce.current=new iJ(()=>{if(W.current){var Y=W.current;W.current=null,Y()}ce.current=null},lJ),aJ().add(ce.current));var R=ue.state.doc,me=R.toString();r(me,ue)}s&&s(sJ(ue))}),ae=rJ({theme:h,editable:j,readOnly:T,placeholder:O,indentWithTab:M,basicSetup:_}),ne=[H,J,...ae];return l&&typeof l=="function"&&ne.push(qe.updateListener.of(l)),ne=ne.concat(c),S.useLayoutEffect(()=>{if(z&&!U){var ue={doc:e,selection:n,extensions:ne},R=E?Vt.fromJSON(E.json,ue,E.fields):Vt.create(ue);if(V(R),!F){var me=new qe({state:R,parent:z,root:D});B(me),i&&i(me,R)}}return()=>{F&&(V(void 0),B(void 0))}},[z,U]),S.useEffect(()=>{t.container&&Q(t.container)},[t.container]),S.useEffect(()=>()=>{F&&(F.destroy(),B(void 0)),ce.current&&(ce.current.cancel(),ce.current=null)},[F]),S.useEffect(()=>{d&&F&&F.focus()},[d,F]),S.useEffect(()=>{F&&F.dispatch({effects:xt.reconfigure.of(ne)})},[h,c,m,p,x,v,b,k,O,j,T,M,_,r,l]),S.useEffect(()=>{if(e!==void 0){var ue=F?F.state.doc.toString():"";if(F&&e!==ue){var R=ce.current&&!ce.current.isDone,me=()=>{F&&e!==F.state.doc.toString()&&F.dispatch({changes:{from:0,to:F.state.doc.toString().length,insert:e||""},annotations:[U7.of(!0)]})};R?W.current=me:me()}}},[e,F]),{state:U,setState:V,view:F,setView:B,container:z,setContainer:Q}}var uJ=["className","value","selection","extensions","onChange","onStatistics","onCreateEditor","onUpdate","autoFocus","theme","height","minHeight","maxHeight","width","minWidth","maxWidth","basicSetup","placeholder","indentWithTab","editable","readOnly","root","initialState"],C_=S.forwardRef((t,e)=>{var{className:n,value:r="",selection:s,extensions:i=[],onChange:l,onStatistics:c,onCreateEditor:d,onUpdate:h,autoFocus:m,theme:p="light",height:x,minHeight:v,maxHeight:b,width:k,minWidth:O,maxWidth:j,basicSetup:T,placeholder:M,indentWithTab:_,editable:D,readOnly:E,root:z,initialState:Q}=t,F=VI(t,uJ),B=S.useRef(null),{state:U,view:V,container:ce,setContainer:W}=cJ({root:z,value:r,autoFocus:m,theme:p,height:x,minHeight:v,maxHeight:b,width:k,minWidth:O,maxWidth:j,basicSetup:T,placeholder:M,indentWithTab:_,editable:D,readOnly:E,selection:s,onChange:l,onStatistics:c,onCreateEditor:d,onUpdate:h,extensions:i,initialState:Q});S.useImperativeHandle(e,()=>({editor:B.current,state:U,view:V}),[B,ce,U,V]);var J=S.useCallback(ae=>{B.current=ae,W(ae)},[W]);if(typeof r!="string")throw new Error("value must be typeof string but got "+typeof r);var H=typeof p=="string"?"cm-theme-"+p:"cm-theme";return a.jsx("div",WI({ref:J,className:""+H+(n?" "+n:"")},F))});C_.displayName="CodeMirror";var V7={};class Qg{constructor(e,n,r,s,i,l,c,d,h,m=0,p){this.p=e,this.stack=n,this.state=r,this.reducePos=s,this.pos=i,this.score=l,this.buffer=c,this.bufferBase=d,this.curContext=h,this.lookAhead=m,this.parent=p}toString(){return`[${this.stack.filter((e,n)=>n%3==0).concat(this.state)}]@${this.pos}${this.score?"!"+this.score:""}`}static start(e,n,r=0){let s=e.parser.context;return new Qg(e,[],n,r,r,0,[],0,s?new W7(s,s.start):null,0,null)}get context(){return this.curContext?this.curContext.context:null}pushState(e,n){this.stack.push(this.state,n,this.bufferBase+this.buffer.length),this.state=e}reduce(e){var n;let r=e>>19,s=e&65535,{parser:i}=this.p,l=this.reducePos=2e3&&!(!((n=this.p.parser.nodeSet.types[s])===null||n===void 0)&&n.isAnonymous)&&(h==this.p.lastBigReductionStart?(this.p.bigReductionCount++,this.p.lastBigReductionSize=m):this.p.lastBigReductionSized;)this.stack.pop();this.reduceContext(s,h)}storeNode(e,n,r,s=4,i=!1){if(e==0&&(!this.stack.length||this.stack[this.stack.length-1]0&&l.buffer[c-4]==0&&l.buffer[c-1]>-1){if(n==r)return;if(l.buffer[c-2]>=n){l.buffer[c-2]=r;return}}}if(!i||this.pos==r)this.buffer.push(e,n,r,s);else{let l=this.buffer.length;if(l>0&&(this.buffer[l-4]!=0||this.buffer[l-1]<0)){let c=!1;for(let d=l;d>0&&this.buffer[d-2]>r;d-=4)if(this.buffer[d-1]>=0){c=!0;break}if(c)for(;l>0&&this.buffer[l-2]>r;)this.buffer[l]=this.buffer[l-4],this.buffer[l+1]=this.buffer[l-3],this.buffer[l+2]=this.buffer[l-2],this.buffer[l+3]=this.buffer[l-1],l-=4,s>4&&(s-=4)}this.buffer[l]=e,this.buffer[l+1]=n,this.buffer[l+2]=r,this.buffer[l+3]=s}}shift(e,n,r,s){if(e&131072)this.pushState(e&65535,this.pos);else if((e&262144)==0){let i=e,{parser:l}=this.p;(s>this.pos||n<=l.maxNode)&&(this.pos=s,l.stateFlag(i,1)||(this.reducePos=s)),this.pushState(i,r),this.shiftContext(n,r),n<=l.maxNode&&this.buffer.push(n,r,s,4)}else this.pos=s,this.shiftContext(n,r),n<=this.p.parser.maxNode&&this.buffer.push(n,r,s,4)}apply(e,n,r,s){e&65536?this.reduce(e):this.shift(e,n,r,s)}useNode(e,n){let r=this.p.reused.length-1;(r<0||this.p.reused[r]!=e)&&(this.p.reused.push(e),r++);let s=this.pos;this.reducePos=this.pos=s+e.length,this.pushState(n,s),this.buffer.push(r,s,this.reducePos,-1),this.curContext&&this.updateContext(this.curContext.tracker.reuse(this.curContext.context,e,this,this.p.stream.reset(this.pos-e.length)))}split(){let e=this,n=e.buffer.length;for(;n>0&&e.buffer[n-2]>e.reducePos;)n-=4;let r=e.buffer.slice(n),s=e.bufferBase+n;for(;e&&s==e.bufferBase;)e=e.parent;return new Qg(this.p,this.stack.slice(),this.state,this.reducePos,this.pos,this.score,r,s,this.curContext,this.lookAhead,e)}recoverByDelete(e,n){let r=e<=this.p.parser.maxNode;r&&this.storeNode(e,this.pos,n,4),this.storeNode(0,this.pos,n,r?8:4),this.pos=this.reducePos=n,this.score-=190}canShift(e){for(let n=new dJ(this);;){let r=this.p.parser.stateSlot(n.state,4)||this.p.parser.hasAction(n.state,e);if(r==0)return!1;if((r&65536)==0)return!0;n.reduce(r)}}recoverByInsert(e){if(this.stack.length>=300)return[];let n=this.p.parser.nextStates(this.state);if(n.length>8||this.stack.length>=120){let s=[];for(let i=0,l;id&1&&c==l)||s.push(n[i],l)}n=s}let r=[];for(let s=0;s>19,s=n&65535,i=this.stack.length-r*3;if(i<0||e.getGoto(this.stack[i],s,!1)<0){let l=this.findForcedReduction();if(l==null)return!1;n=l}this.storeNode(0,this.pos,this.pos,4,!0),this.score-=100}return this.reducePos=this.pos,this.reduce(n),!0}findForcedReduction(){let{parser:e}=this.p,n=[],r=(s,i)=>{if(!n.includes(s))return n.push(s),e.allActions(s,l=>{if(!(l&393216))if(l&65536){let c=(l>>19)-i;if(c>1){let d=l&65535,h=this.stack.length-c*3;if(h>=0&&e.getGoto(this.stack[h],d,!1)>=0)return c<<19|65536|d}}else{let c=r(l,i+1);if(c!=null)return c}})};return r(this.state,0)}forceAll(){for(;!this.p.parser.stateFlag(this.state,2);)if(!this.forceReduce()){this.storeNode(0,this.pos,this.pos,4,!0);break}return this}get deadEnd(){if(this.stack.length!=3)return!1;let{parser:e}=this.p;return e.data[e.stateSlot(this.state,1)]==65535&&!e.stateSlot(this.state,4)}restart(){this.storeNode(0,this.pos,this.pos,4,!0),this.state=this.stack[0],this.stack.length=0}sameState(e){if(this.state!=e.state||this.stack.length!=e.stack.length)return!1;for(let n=0;nthis.lookAhead&&(this.emitLookAhead(),this.lookAhead=e)}close(){this.curContext&&this.curContext.tracker.strict&&this.emitContext(),this.lookAhead>0&&this.emitLookAhead()}}class W7{constructor(e,n){this.tracker=e,this.context=n,this.hash=e.strict?e.hash(n):0}}class dJ{constructor(e){this.start=e,this.state=e.state,this.stack=e.stack,this.base=this.stack.length}reduce(e){let n=e&65535,r=e>>19;r==0?(this.stack==this.start.stack&&(this.stack=this.stack.slice()),this.stack.push(this.state,0,0),this.base+=3):this.base-=(r-1)*3;let s=this.start.p.parser.getGoto(this.stack[this.base-3],n,!0);this.state=s}}class $g{constructor(e,n,r){this.stack=e,this.pos=n,this.index=r,this.buffer=e.buffer,this.index==0&&this.maybeNext()}static create(e,n=e.bufferBase+e.buffer.length){return new $g(e,n,n-e.bufferBase)}maybeNext(){let e=this.stack.parent;e!=null&&(this.index=this.stack.bufferBase-e.bufferBase,this.stack=e,this.buffer=e.buffer)}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}next(){this.index-=4,this.pos-=4,this.index==0&&this.maybeNext()}fork(){return new $g(this.stack,this.pos,this.index)}}function Sp(t,e=Uint16Array){if(typeof t!="string")return t;let n=null;for(let r=0,s=0;r=92&&l--,l>=34&&l--;let d=l-32;if(d>=46&&(d-=46,c=!0),i+=d,c)break;i*=46}n?n[s++]=i:n=new e(i)}return n}class ig{constructor(){this.start=-1,this.value=-1,this.end=-1,this.extended=-1,this.lookAhead=0,this.mask=0,this.context=0}}const G7=new ig;class hJ{constructor(e,n){this.input=e,this.ranges=n,this.chunk="",this.chunkOff=0,this.chunk2="",this.chunk2Pos=0,this.next=-1,this.token=G7,this.rangeIndex=0,this.pos=this.chunkPos=n[0].from,this.range=n[0],this.end=n[n.length-1].to,this.readNext()}resolveOffset(e,n){let r=this.range,s=this.rangeIndex,i=this.pos+e;for(;ir.to:i>=r.to;){if(s==this.ranges.length-1)return null;let l=this.ranges[++s];i+=l.from-r.to,r=l}return i}clipPos(e){if(e>=this.range.from&&ee)return Math.max(e,n.from);return this.end}peek(e){let n=this.chunkOff+e,r,s;if(n>=0&&n=this.chunk2Pos&&rc.to&&(this.chunk2=this.chunk2.slice(0,c.to-r)),s=this.chunk2.charCodeAt(0)}}return r>=this.token.lookAhead&&(this.token.lookAhead=r+1),s}acceptToken(e,n=0){let r=n?this.resolveOffset(n,-1):this.pos;if(r==null||r=this.chunk2Pos&&this.posthis.range.to?e.slice(0,this.range.to-this.pos):e,this.chunkPos=this.pos,this.chunkOff=0}}readNext(){return this.chunkOff>=this.chunk.length&&(this.getChunk(),this.chunkOff==this.chunk.length)?this.next=-1:this.next=this.chunk.charCodeAt(this.chunkOff)}advance(e=1){for(this.chunkOff+=e;this.pos+e>=this.range.to;){if(this.rangeIndex==this.ranges.length-1)return this.setDone();e-=this.range.to-this.pos,this.range=this.ranges[++this.rangeIndex],this.pos=this.range.from}return this.pos+=e,this.pos>=this.token.lookAhead&&(this.token.lookAhead=this.pos+1),this.readNext()}setDone(){return this.pos=this.chunkPos=this.end,this.range=this.ranges[this.rangeIndex=this.ranges.length-1],this.chunk="",this.next=-1}reset(e,n){if(n?(this.token=n,n.start=e,n.lookAhead=e+1,n.value=n.extended=-1):this.token=G7,this.pos!=e){if(this.pos=e,e==this.end)return this.setDone(),this;for(;e=this.range.to;)this.range=this.ranges[++this.rangeIndex];e>=this.chunkPos&&e=this.chunkPos&&n<=this.chunkPos+this.chunk.length)return this.chunk.slice(e-this.chunkPos,n-this.chunkPos);if(e>=this.chunk2Pos&&n<=this.chunk2Pos+this.chunk2.length)return this.chunk2.slice(e-this.chunk2Pos,n-this.chunk2Pos);if(e>=this.range.from&&n<=this.range.to)return this.input.read(e,n);let r="";for(let s of this.ranges){if(s.from>=n)break;s.to>e&&(r+=this.input.read(Math.max(s.from,e),Math.min(s.to,n)))}return r}}class Zu{constructor(e,n){this.data=e,this.id=n}token(e,n){let{parser:r}=n.p;fJ(this.data,e,n,this.id,r.data,r.tokenPrecTable)}}Zu.prototype.contextual=Zu.prototype.fallback=Zu.prototype.extend=!1;Zu.prototype.fallback=Zu.prototype.extend=!1;class Rx{constructor(e,n={}){this.token=e,this.contextual=!!n.contextual,this.fallback=!!n.fallback,this.extend=!!n.extend}}function fJ(t,e,n,r,s,i){let l=0,c=1<0){let b=t[v];if(d.allows(b)&&(e.token.value==-1||e.token.value==b||mJ(b,e.token.value,s,i))){e.acceptToken(b);break}}let m=e.next,p=0,x=t[l+2];if(e.next<0&&x>p&&t[h+x*3-3]==65535){l=t[h+x*3-1];continue e}for(;p>1,b=h+v+(v<<1),k=t[b],O=t[b+1]||65536;if(m=O)p=v+1;else{l=t[b+2],e.advance();continue e}}break}}function X7(t,e,n){for(let r=e,s;(s=t[r])!=65535;r++)if(s==n)return r-e;return-1}function mJ(t,e,n,r){let s=X7(n,r,e);return s<0||X7(n,r,t)e)&&!r.type.isError)return n<0?Math.max(0,Math.min(r.to-1,e-25)):Math.min(t.length,Math.max(r.from+1,e+25));if(n<0?r.prevSibling():r.nextSibling())break;if(!r.parent())return n<0?0:t.length}}class pJ{constructor(e,n){this.fragments=e,this.nodeSet=n,this.i=0,this.fragment=null,this.safeFrom=-1,this.safeTo=-1,this.trees=[],this.start=[],this.index=[],this.nextFragment()}nextFragment(){let e=this.fragment=this.i==this.fragments.length?null:this.fragments[this.i++];if(e){for(this.safeFrom=e.openStart?Y7(e.tree,e.from+e.offset,1)-e.offset:e.from,this.safeTo=e.openEnd?Y7(e.tree,e.to+e.offset,-1)-e.offset:e.to;this.trees.length;)this.trees.pop(),this.start.pop(),this.index.pop();this.trees.push(e.tree),this.start.push(-e.offset),this.index.push(0),this.nextStart=this.safeFrom}else this.nextStart=1e9}nodeAt(e){if(ee)return this.nextStart=l,null;if(i instanceof _n){if(l==e){if(l=Math.max(this.safeFrom,e)&&(this.trees.push(i),this.start.push(l),this.index.push(0))}else this.index[n]++,this.nextStart=l+i.length}}}class gJ{constructor(e,n){this.stream=n,this.tokens=[],this.mainToken=null,this.actions=[],this.tokens=e.tokenizers.map(r=>new ig)}getActions(e){let n=0,r=null,{parser:s}=e.p,{tokenizers:i}=s,l=s.stateSlot(e.state,3),c=e.curContext?e.curContext.hash:0,d=0;for(let h=0;hp.end+25&&(d=Math.max(p.lookAhead,d)),p.value!=0)){let x=n;if(p.extended>-1&&(n=this.addActions(e,p.extended,p.end,n)),n=this.addActions(e,p.value,p.end,n),!m.extend&&(r=p,n>x))break}}for(;this.actions.length>n;)this.actions.pop();return d&&e.setLookAhead(d),!r&&e.pos==this.stream.end&&(r=new ig,r.value=e.p.parser.eofTerm,r.start=r.end=e.pos,n=this.addActions(e,r.value,r.end,n)),this.mainToken=r,this.actions}getMainToken(e){if(this.mainToken)return this.mainToken;let n=new ig,{pos:r,p:s}=e;return n.start=r,n.end=Math.min(r+1,s.stream.end),n.value=r==s.stream.end?s.parser.eofTerm:0,n}updateCachedToken(e,n,r){let s=this.stream.clipPos(r.pos);if(n.token(this.stream.reset(s,e),r),e.value>-1){let{parser:i}=r.p;for(let l=0;l=0&&r.p.parser.dialect.allows(c>>1)){(c&1)==0?e.value=c>>1:e.extended=c>>1;break}}}else e.value=0,e.end=this.stream.clipPos(s+1)}putAction(e,n,r,s){for(let i=0;ie.bufferLength*4?new pJ(r,e.nodeSet):null}get parsedPos(){return this.minStackPos}advance(){let e=this.stacks,n=this.minStackPos,r=this.stacks=[],s,i;if(this.bigReductionCount>300&&e.length==1){let[l]=e;for(;l.forceReduce()&&l.stack.length&&l.stack[l.stack.length-2]>=this.lastBigReductionStart;);this.bigReductionCount=this.lastBigReductionSize=0}for(let l=0;ln)r.push(c);else{if(this.advanceStack(c,r,e))continue;{s||(s=[],i=[]),s.push(c);let d=this.tokens.getMainToken(c);i.push(d.value,d.end)}}break}}if(!r.length){let l=s&&bJ(s);if(l)return Ys&&console.log("Finish with "+this.stackID(l)),this.stackToTree(l);if(this.parser.strict)throw Ys&&s&&console.log("Stuck with token "+(this.tokens.mainToken?this.parser.getName(this.tokens.mainToken.value):"none")),new SyntaxError("No parse at "+n);this.recovering||(this.recovering=5)}if(this.recovering&&s){let l=this.stoppedAt!=null&&s[0].pos>this.stoppedAt?s[0]:this.runRecovery(s,i,r);if(l)return Ys&&console.log("Force-finish "+this.stackID(l)),this.stackToTree(l.forceAll())}if(this.recovering){let l=this.recovering==1?1:this.recovering*3;if(r.length>l)for(r.sort((c,d)=>d.score-c.score);r.length>l;)r.pop();r.some(c=>c.reducePos>n)&&this.recovering--}else if(r.length>1){e:for(let l=0;l500&&h.buffer.length>500)if((c.score-h.score||c.buffer.length-h.buffer.length)>0)r.splice(d--,1);else{r.splice(l--,1);continue e}}}r.length>12&&r.splice(12,r.length-12)}this.minStackPos=r[0].pos;for(let l=1;l ":"";if(this.stoppedAt!=null&&s>this.stoppedAt)return e.forceReduce()?e:null;if(this.fragments){let h=e.curContext&&e.curContext.tracker.strict,m=h?e.curContext.hash:0;for(let p=this.fragments.nodeAt(s);p;){let x=this.parser.nodeSet.types[p.type.id]==p.type?i.getGoto(e.state,p.type.id):-1;if(x>-1&&p.length&&(!h||(p.prop(Et.contextHash)||0)==m))return e.useNode(p,x),Ys&&console.log(l+this.stackID(e)+` (via reuse of ${i.getName(p.type.id)})`),!0;if(!(p instanceof _n)||p.children.length==0||p.positions[0]>0)break;let v=p.children[0];if(v instanceof _n&&p.positions[0]==0)p=v;else break}}let c=i.stateSlot(e.state,4);if(c>0)return e.reduce(c),Ys&&console.log(l+this.stackID(e)+` (via always-reduce ${i.getName(c&65535)})`),!0;if(e.stack.length>=8400)for(;e.stack.length>6e3&&e.forceReduce(););let d=this.tokens.getActions(e);for(let h=0;hs?n.push(b):r.push(b)}return!1}advanceFully(e,n){let r=e.pos;for(;;){if(!this.advanceStack(e,null,null))return!1;if(e.pos>r)return K7(e,n),!0}}runRecovery(e,n,r){let s=null,i=!1;for(let l=0;l ":"";if(c.deadEnd&&(i||(i=!0,c.restart(),Ys&&console.log(m+this.stackID(c)+" (restarted)"),this.advanceFully(c,r))))continue;let p=c.split(),x=m;for(let v=0;v<10&&p.forceReduce()&&(Ys&&console.log(x+this.stackID(p)+" (via force-reduce)"),!this.advanceFully(p,r));v++)Ys&&(x=this.stackID(p)+" -> ");for(let v of c.recoverByInsert(d))Ys&&console.log(m+this.stackID(v)+" (via recover-insert)"),this.advanceFully(v,r);this.stream.end>c.pos?(h==c.pos&&(h++,d=0),c.recoverByDelete(d,h),Ys&&console.log(m+this.stackID(c)+` (via recover-delete ${this.parser.getName(d)})`),K7(c,r)):(!s||s.scoret;class yJ{constructor(e){this.start=e.start,this.shift=e.shift||rb,this.reduce=e.reduce||rb,this.reuse=e.reuse||rb,this.hash=e.hash||(()=>0),this.strict=e.strict!==!1}}class Rf extends Lw{constructor(e){if(super(),this.wrappers=[],e.version!=14)throw new RangeError(`Parser version (${e.version}) doesn't match runtime version (14)`);let n=e.nodeNames.split(" ");this.minRepeatTerm=n.length;for(let c=0;ce.topRules[c][1]),s=[];for(let c=0;c=0)i(m,d,c[h++]);else{let p=c[h+-m];for(let x=-m;x>0;x--)i(c[h++],d,p);h++}}}this.nodeSet=new jx(n.map((c,d)=>gs.define({name:d>=this.minRepeatTerm?void 0:c,id:d,props:s[d],top:r.indexOf(d)>-1,error:d==0,skipped:e.skippedNodes&&e.skippedNodes.indexOf(d)>-1}))),e.propSources&&(this.nodeSet=this.nodeSet.extend(...e.propSources)),this.strict=!1,this.bufferLength=VA;let l=Sp(e.tokenData);this.context=e.context,this.specializerSpecs=e.specialized||[],this.specialized=new Uint16Array(this.specializerSpecs.length);for(let c=0;ctypeof c=="number"?new Zu(l,c):c),this.topRules=e.topRules,this.dialects=e.dialects||{},this.dynamicPrecedences=e.dynamicPrecedences||null,this.tokenPrecTable=e.tokenPrec,this.termNames=e.termNames||null,this.maxNode=this.nodeSet.types.length-1,this.dialect=this.parseDialect(),this.top=this.topRules[Object.keys(this.topRules)[0]]}createParse(e,n,r){let s=new xJ(this,e,n,r);for(let i of this.wrappers)s=i(s,e,n,r);return s}getGoto(e,n,r=!1){let s=this.goto;if(n>=s[0])return-1;for(let i=s[n+1];;){let l=s[i++],c=l&1,d=s[i++];if(c&&r)return d;for(let h=i+(l>>1);i0}validAction(e,n){return!!this.allActions(e,r=>r==n?!0:null)}allActions(e,n){let r=this.stateSlot(e,4),s=r?n(r):void 0;for(let i=this.stateSlot(e,1);s==null;i+=3){if(this.data[i]==65535)if(this.data[i+1]==1)i=nl(this.data,i+2);else break;s=n(nl(this.data,i+1))}return s}nextStates(e){let n=[];for(let r=this.stateSlot(e,1);;r+=3){if(this.data[r]==65535)if(this.data[r+1]==1)r=nl(this.data,r+2);else break;if((this.data[r+2]&1)==0){let s=this.data[r+1];n.some((i,l)=>l&1&&i==s)||n.push(this.data[r],s)}}return n}configure(e){let n=Object.assign(Object.create(Rf.prototype),this);if(e.props&&(n.nodeSet=this.nodeSet.extend(...e.props)),e.top){let r=this.topRules[e.top];if(!r)throw new RangeError(`Invalid top rule name ${e.top}`);n.top=r}return e.tokenizers&&(n.tokenizers=this.tokenizers.map(r=>{let s=e.tokenizers.find(i=>i.from==r);return s?s.to:r})),e.specializers&&(n.specializers=this.specializers.slice(),n.specializerSpecs=this.specializerSpecs.map((r,s)=>{let i=e.specializers.find(c=>c.from==r.external);if(!i)return r;let l=Object.assign(Object.assign({},r),{external:i.to});return n.specializers[s]=Z7(l),l})),e.contextTracker&&(n.context=e.contextTracker),e.dialect&&(n.dialect=this.parseDialect(e.dialect)),e.strict!=null&&(n.strict=e.strict),e.wrap&&(n.wrappers=n.wrappers.concat(e.wrap)),e.bufferLength!=null&&(n.bufferLength=e.bufferLength),n}hasWrappers(){return this.wrappers.length>0}getName(e){return this.termNames?this.termNames[e]:String(e<=this.maxNode&&this.nodeSet.types[e].name||e)}get eofTerm(){return this.maxNode+1}get topNode(){return this.nodeSet.types[this.top[1]]}dynamicPrecedence(e){let n=this.dynamicPrecedences;return n==null?0:n[e]||0}parseDialect(e){let n=Object.keys(this.dialects),r=n.map(()=>!1);if(e)for(let i of e.split(" ")){let l=n.indexOf(i);l>=0&&(r[l]=!0)}let s=null;for(let i=0;ir)&&n.p.parser.stateFlag(n.state,2)&&(!e||e.scoret.external(n,r)<<1|e}return t.get}const wJ=1,T_=194,M_=195,SJ=196,J7=197,kJ=198,OJ=199,jJ=200,NJ=2,A_=3,e8=201,CJ=24,TJ=25,MJ=49,AJ=50,EJ=55,_J=56,DJ=57,RJ=59,zJ=60,PJ=61,LJ=62,BJ=63,IJ=65,qJ=238,FJ=71,QJ=241,$J=242,HJ=243,UJ=244,VJ=245,WJ=246,GJ=247,XJ=248,E_=72,YJ=249,KJ=250,ZJ=251,JJ=252,eee=253,tee=254,nee=255,ree=256,see=73,iee=77,aee=263,lee=112,oee=130,cee=151,uee=152,dee=155,jc=10,zf=13,a5=32,zx=9,l5=35,hee=40,fee=46,c4=123,t8=125,__=39,D_=34,n8=92,mee=111,pee=120,gee=78,xee=117,vee=85,yee=new Set([TJ,MJ,AJ,aee,IJ,oee,_J,DJ,qJ,LJ,BJ,E_,see,iee,zJ,PJ,cee,uee,dee,lee]);function sb(t){return t==jc||t==zf}function ib(t){return t>=48&&t<=57||t>=65&&t<=70||t>=97&&t<=102}const bee=new Rx((t,e)=>{let n;if(t.next<0)t.acceptToken(OJ);else if(e.context.flags&ag)sb(t.next)&&t.acceptToken(kJ,1);else if(((n=t.peek(-1))<0||sb(n))&&e.canShift(J7)){let r=0;for(;t.next==a5||t.next==zx;)t.advance(),r++;(t.next==jc||t.next==zf||t.next==l5)&&t.acceptToken(J7,-r)}else sb(t.next)&&t.acceptToken(SJ,1)},{contextual:!0}),wee=new Rx((t,e)=>{let n=e.context;if(n.flags)return;let r=t.peek(-1);if(r==jc||r==zf){let s=0,i=0;for(;;){if(t.next==a5)s++;else if(t.next==zx)s+=8-s%8;else break;t.advance(),i++}s!=n.indent&&t.next!=jc&&t.next!=zf&&t.next!=l5&&(s[t,e|R_])),Oee=new yJ({start:See,reduce(t,e,n,r){return t.flags&ag&&yee.has(e)||(e==FJ||e==E_)&&t.flags&R_?t.parent:t},shift(t,e,n,r){return e==T_?new lg(t,kee(r.read(r.pos,n.pos)),0):e==M_?t.parent:e==CJ||e==EJ||e==RJ||e==A_?new lg(t,0,ag):r8.has(e)?new lg(t,0,r8.get(e)|t.flags&ag):t},hash(t){return t.hash}}),jee=new Rx(t=>{for(let e=0;e<5;e++){if(t.next!="print".charCodeAt(e))return;t.advance()}if(!/\w/.test(String.fromCharCode(t.next)))for(let e=0;;e++){let n=t.peek(e);if(!(n==a5||n==zx)){n!=hee&&n!=fee&&n!=jc&&n!=zf&&n!=l5&&t.acceptToken(wJ);return}}}),Nee=new Rx((t,e)=>{let{flags:n}=e.context,r=n&Za?D_:__,s=(n&Ja)>0,i=!(n&el),l=(n&tl)>0,c=t.pos;for(;!(t.next<0);)if(l&&t.next==c4)if(t.peek(1)==c4)t.advance(2);else{if(t.pos==c){t.acceptToken(A_,1);return}break}else if(i&&t.next==n8){if(t.pos==c){t.advance();let d=t.next;d>=0&&(t.advance(),Cee(t,d)),t.acceptToken(NJ);return}break}else if(t.next==n8&&!i&&t.peek(1)>-1)t.advance(2);else if(t.next==r&&(!s||t.peek(1)==r&&t.peek(2)==r)){if(t.pos==c){t.acceptToken(e8,s?3:1);return}break}else if(t.next==jc){if(s)t.advance();else if(t.pos==c){t.acceptToken(e8);return}break}else t.advance();t.pos>c&&t.acceptToken(jJ)});function Cee(t,e){if(e==mee)for(let n=0;n<2&&t.next>=48&&t.next<=55;n++)t.advance();else if(e==pee)for(let n=0;n<2&&ib(t.next);n++)t.advance();else if(e==xee)for(let n=0;n<4&&ib(t.next);n++)t.advance();else if(e==vee)for(let n=0;n<8&&ib(t.next);n++)t.advance();else if(e==gee&&t.next==c4){for(t.advance();t.next>=0&&t.next!=t8&&t.next!=__&&t.next!=D_&&t.next!=jc;)t.advance();t.next==t8&&t.advance()}}const Tee=Bw({'async "*" "**" FormatConversion FormatSpec':he.modifier,"for while if elif else try except finally return raise break continue with pass assert await yield match case":he.controlKeyword,"in not and or is del":he.operatorKeyword,"from def class global nonlocal lambda":he.definitionKeyword,import:he.moduleKeyword,"with as print":he.keyword,Boolean:he.bool,None:he.null,VariableName:he.variableName,"CallExpression/VariableName":he.function(he.variableName),"FunctionDefinition/VariableName":he.function(he.definition(he.variableName)),"ClassDefinition/VariableName":he.definition(he.className),PropertyName:he.propertyName,"CallExpression/MemberExpression/PropertyName":he.function(he.propertyName),Comment:he.lineComment,Number:he.number,String:he.string,FormatString:he.special(he.string),Escape:he.escape,UpdateOp:he.updateOperator,"ArithOp!":he.arithmeticOperator,BitOp:he.bitwiseOperator,CompareOp:he.compareOperator,AssignOp:he.definitionOperator,Ellipsis:he.punctuation,At:he.meta,"( )":he.paren,"[ ]":he.squareBracket,"{ }":he.brace,".":he.derefOperator,", ;":he.separator}),Mee={__proto__:null,await:44,or:54,and:56,in:60,not:62,is:64,if:70,else:72,lambda:76,yield:94,from:96,async:102,for:104,None:162,True:164,False:164,del:178,pass:182,break:186,continue:190,return:194,raise:202,import:206,as:208,global:212,nonlocal:214,assert:218,type:223,elif:236,while:240,try:246,except:248,finally:250,with:254,def:258,class:268,match:279,case:285},Aee=Rf.deserialize({version:14,states:"##jO`QeOOP$}OSOOO&WQtO'#HUOOQS'#Co'#CoOOQS'#Cp'#CpO'vQdO'#CnO*UQtO'#HTOOQS'#HU'#HUOOQS'#DU'#DUOOQS'#HT'#HTO*rQdO'#D_O+VQdO'#DfO+gQdO'#DjO+zOWO'#DuO,VOWO'#DvO.[QtO'#GuOOQS'#Gu'#GuO'vQdO'#GtO0ZQtO'#GtOOQS'#Eb'#EbO0rQdO'#EcOOQS'#Gs'#GsO0|QdO'#GrOOQV'#Gr'#GrO1XQdO'#FYOOQS'#G^'#G^O1^QdO'#FXOOQV'#IS'#ISOOQV'#Gq'#GqOOQV'#Fq'#FqQ`QeOOO'vQdO'#CqO1lQdO'#C}O1sQdO'#DRO2RQdO'#HYO2cQtO'#EVO'vQdO'#EWOOQS'#EY'#EYOOQS'#E['#E[OOQS'#E^'#E^O2wQdO'#E`O3_QdO'#EdO3rQdO'#EfO3zQtO'#EfO1XQdO'#EiO0rQdO'#ElO1XQdO'#EnO0rQdO'#EtO0rQdO'#EwO4VQdO'#EyO4^QdO'#FOO4iQdO'#EzO0rQdO'#FOO1XQdO'#FQO1XQdO'#FVO4nQdO'#F[P4uOdO'#GpPOOO)CBd)CBdOOQS'#Ce'#CeOOQS'#Cf'#CfOOQS'#Cg'#CgOOQS'#Ch'#ChOOQS'#Ci'#CiOOQS'#Cj'#CjOOQS'#Cl'#ClO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO5TQdO'#DoOOQS,5:Y,5:YO5hQdO'#HdOOQS,5:],5:]O5uQ!fO,5:]O5zQtO,59YO1lQdO,59bO1lQdO,59bO1lQdO,59bO8jQdO,59bO8oQdO,59bO8vQdO,59jO8}QdO'#HTO:TQdO'#HSOOQS'#HS'#HSOOQS'#D['#D[O:lQdO,59aO'vQdO,59aO:zQdO,59aOOQS,59y,59yO;PQdO,5:RO'vQdO,5:ROOQS,5:Q,5:QO;_QdO,5:QO;dQdO,5:XO'vQdO,5:XO'vQdO,5:VOOQS,5:U,5:UO;uQdO,5:UO;zQdO,5:WOOOW'#Fy'#FyOOOOQS'#Ds'#DsOOQS1G/w1G/wOOQS1G.|1G.|O!/[QtO1G.|O!/cQtO1G.|O1lQdO1G.|O!0OQdO1G/UOOQS'#DZ'#DZO0rQdO,59tOOQS1G.{1G.{O!0VQdO1G/eO!0gQdO1G/eO!0oQdO1G/fO'vQdO'#H[O!0tQdO'#H[O!0yQtO1G.{O!1ZQdO,59iO!2aQdO,5=zO!2qQdO,5=zO!2yQdO1G/mO!3OQtO1G/mOOQS1G/l1G/lO!3`QdO,5=uO!4VQdO,5=uO0rQdO1G/qO!4tQdO1G/sO!4yQtO1G/sO!5ZQtO1G/qOOQS1G/p1G/pOOQS1G/r1G/rOOOW-E9w-E9wOOQS1G/{1G/{O!5kQdO'#HxO0rQdO'#HxO!5|QdO,5>cOOOW-E9x-E9xOOQS1G/|1G/|OOQS-E9{-E9{O!6[Q#xO1G2zO!6{QtO1G2zO'vQdO,5kOOQS1G1`1G1`O!8RQdO1G1`OOQS'#DV'#DVO0rQdO,5=qOOQS,5=q,5=qO!8WQdO'#FrO!8cQdO,59oO!8kQdO1G/XO!8uQtO,5=uOOQS1G3`1G3`OOQS,5:m,5:mO!9fQdO'#GtOOQS,5jO!;ZQdO,5>jO1XQdO,5>jO!;lQdO,5>iOOQS-E:R-E:RO!;qQdO1G0lO!;|QdO1G0lO!lO!lO!hO!=VQdO,5>hO!=hQdO'#EpO0rQdO1G0tO!=sQdO1G0tO!=xQgO1G0zO!AvQgO1G0}O!EqQdO,5>oO!E{QdO,5>oO!FTQtO,5>oO0rQdO1G1PO!F_QdO1G1PO4iQdO1G1UO!!vQdO1G1WOOQV,5;a,5;aO!FdQfO,5;aO!FiQgO1G1QO!JjQdO'#GZO4iQdO1G1QO4iQdO1G1QO!JzQdO,5>pO!KXQdO,5>pO1XQdO,5>pOOQV1G1U1G1UO!KaQdO'#FSO!KrQ!fO1G1WO!KzQdO1G1WOOQV1G1]1G1]O4iQdO1G1]O!LPQdO1G1]O!LXQdO'#F^OOQV1G1b1G1bO!#ZQtO1G1bPOOO1G2v1G2vP!L^OSO1G2vOOQS,5=},5=}OOQS'#Dp'#DpO0rQdO,5=}O!LfQdO,5=|O!LyQdO,5=|OOQS1G/u1G/uO!MRQdO,5>PO!McQdO,5>PO!MkQdO,5>PO!NOQdO,5>PO!N`QdO,5>POOQS1G3j1G3jOOQS7+$h7+$hO!8kQdO7+$pO#!RQdO1G.|O#!YQdO1G.|OOQS1G/`1G/`OOQS,5<`,5<`O'vQdO,5<`OOQS7+%P7+%PO#!aQdO7+%POOQS-E9r-E9rOOQS7+%Q7+%QO#!qQdO,5=vO'vQdO,5=vOOQS7+$g7+$gO#!vQdO7+%PO##OQdO7+%QO##TQdO1G3fOOQS7+%X7+%XO##eQdO1G3fO##mQdO7+%XOOQS,5<_,5<_O'vQdO,5<_O##rQdO1G3aOOQS-E9q-E9qO#$iQdO7+%]OOQS7+%_7+%_O#$wQdO1G3aO#%fQdO7+%_O#%kQdO1G3gO#%{QdO1G3gO#&TQdO7+%]O#&YQdO,5>dO#&sQdO,5>dO#&sQdO,5>dOOQS'#Dx'#DxO#'UO&jO'#DzO#'aO`O'#HyOOOW1G3}1G3}O#'fQdO1G3}O#'nQdO1G3}O#'yQ#xO7+(fO#(jQtO1G2UP#)TQdO'#GOOOQS,5nQdO,5sQdO1G4OOOQS-E9y-E9yO#?^QdO1G4OO<[QdO'#H{OOOO'#D{'#D{OOOO'#F|'#F|O#?oO&jO,5:fOOOW,5>e,5>eOOOW7+)i7+)iO#?zQdO7+)iO#@SQdO1G2zO#@mQdO1G2zP'vQdO'#FuO0rQdO<mO#BQQdO,5>mOOQS1G0v1G0vOOQS<rO#KgQdO,5>rO#KrQdO,5>rO#K}QdO,5>qO#L`QdO,5>qOOQS1G1Y1G1YOOQS,5;p,5;pOOQV<VAN>VO$ oQdO<cAN>cO0rQdO1G1|O$!PQtO1G1|P$!ZQdO'#FvOOQS1G2R1G2RP$!hQdO'#F{O$!uQdO7+)jO$#`QdO,5>gOOOO-E9z-E9zOOOW<tO$4{QdO,5>tO1XQdO,5vO$)nQdO,5>vOOQS1G1p1G1pOOQS,5<[,5<[OOQU7+'P7+'PO$+zQdO1G/iO$)nQdO,5wO$8zQdO,5>wOOQS1G1s1G1sOOQS7+'S7+'SP$)nQdO'#GdO$9SQdO1G4bO$9^QdO1G4bO$9fQdO1G4bOOQS7+%T7+%TO$9tQdO1G1tO$:SQtO'#FaO$:ZQdO,5<}OOQS,5<},5<}O$:iQdO1G4cOOQS-E:a-E:aO$)nQdO,5<|O$:pQdO,5<|O$:uQdO7+)|OOQS-E:`-E:`O$;PQdO7+)|O$)nQdO,5S~O%cOS%^OSSOS%]PQ~OPdOVaOfoOhYOopOs!POvqO!PrO!Q{O!T!SO!U!RO!XZO!][O!h`O!r`O!s`O!t`O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO#l!QO#o!TO#s!UO#u!VO#z!WO#}hO$P!XO%oRO%pRO%tSO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O~O%]!YO~OV!aO_!aOa!bOh!iO!X!kO!f!mO%j![O%k!]O%l!^O%m!_O%n!_O%o!`O%p!`O%q!aO%r!aO%s!aO~Ok%xXl%xXm%xXn%xXo%xXp%xXs%xXz%xX{%xX!x%xX#g%xX%[%xX%_%xX%z%xXg%xX!T%xX!U%xX%{%xX!W%xX![%xX!Q%xX#[%xXt%xX!m%xX~P%SOfoOhYO!XZO!][O!h`O!r`O!s`O!t`O%oRO%pRO%tSO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O~Oz%wX{%wX#g%wX%[%wX%_%wX%z%wX~Ok!pOl!qOm!oOn!oOo!rOp!sOs!tO!x%wX~P)pOV!zOg!|Oo0cOv0qO!PrO~P'vOV#OOo0cOv0qO!W#PO~P'vOV#SOa#TOo0cOv0qO![#UO~P'vOQ#XO%`#XO%a#ZO~OQ#^OR#[O%`#^O%a#`O~OV%iX_%iXa%iXh%iXk%iXl%iXm%iXn%iXo%iXp%iXs%iXz%iX!X%iX!f%iX%j%iX%k%iX%l%iX%m%iX%n%iX%o%iX%p%iX%q%iX%r%iX%s%iXg%iX!T%iX!U%iX~O&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O{%iX!x%iX#g%iX%[%iX%_%iX%z%iX%{%iX!W%iX![%iX!Q%iX#[%iXt%iX!m%iX~P,eOz#dO{%hX!x%hX#g%hX%[%hX%_%hX%z%hX~Oo0cOv0qO~P'vO#g#gO%[#iO%_#iO~O%uWO~O!T#nO#u!VO#z!WO#}hO~OopO~P'vOV#sOa#tO%uWO{wP~OV#xOo0cOv0qO!Q#yO~P'vO{#{O!x$QO%z#|O#g!yX%[!yX%_!yX~OV#xOo0cOv0qO#g#SX%[#SX%_#SX~P'vOo0cOv0qO#g#WX%[#WX%_#WX~P'vOh$WO%uWO~O!f$YO!r$YO%uWO~OV$eO~P'vO!U$gO#s$hO#u$iO~O{$jO~OV$qO~P'vOS$sO%[$rO%_$rO%c$tO~OV$}Oa$}Og%POo0cOv0qO~P'vOo0cOv0qO{%SO~P'vO&Y%UO~Oa!bOh!iO!X!kO!f!mOVba_bakbalbambanbaobapbasbazba{ba!xba#gba%[ba%_ba%jba%kba%lba%mba%nba%oba%pba%qba%rba%sba%zbagba!Tba!Uba%{ba!Wba![ba!Qba#[batba!mba~On%ZO~Oo%ZO~P'vOo0cO~P'vOk0eOl0fOm0dOn0dOo0mOp0nOs0rOg%wX!T%wX!U%wX%{%wX!W%wX![%wX!Q%wX#[%wX!m%wX~P)pO%{%]Og%vXz%vX!T%vX!U%vX!W%vX{%vX~Og%_Oz%`O!T%dO!U%cO~Og%_O~Oz%gO!T%dO!U%cO!W&SX~O!W%kO~Oz%lO{%nO!T%dO!U%cO![%}X~O![%rO~O![%sO~OQ#XO%`#XO%a%uO~OV%wOo0cOv0qO!PrO~P'vOQ#^OR#[O%`#^O%a%zO~OV!qa_!qaa!qah!qak!qal!qam!qan!qao!qap!qas!qaz!qa{!qa!X!qa!f!qa!x!qa#g!qa%[!qa%_!qa%j!qa%k!qa%l!qa%m!qa%n!qa%o!qa%p!qa%q!qa%r!qa%s!qa%z!qag!qa!T!qa!U!qa%{!qa!W!qa![!qa!Q!qa#[!qat!qa!m!qa~P#yOz%|O{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~P%SOV&OOopOvqO{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~P'vOz%|O{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~OPdOVaOopOvqO!PrO!Q{O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO#g$zX%[$zX%_$zX~P'vO#g#gO%[&TO%_&TO~O!f&UOh&sX%[&sXz&sX#[&sX#g&sX%_&sX#Z&sXg&sX~Oh!iO%[&WO~Okealeameaneaoeapeaseazea{ea!xea#gea%[ea%_ea%zeagea!Tea!Uea%{ea!Wea![ea!Qea#[eatea!mea~P%SOsqazqa{qa#gqa%[qa%_qa%zqa~Ok!pOl!qOm!oOn!oOo!rOp!sO!xqa~PEcO%z&YOz%yX{%yX~O%uWOz%yX{%yX~Oz&]O{wX~O{&_O~Oz%lO#g%}X%[%}X%_%}Xg%}X{%}X![%}X!m%}X%z%}X~OV0lOo0cOv0qO!PrO~P'vO%z#|O#gUa%[Ua%_Ua~Oz&hO#g&PX%[&PX%_&PXn&PX~P%SOz&kO!Q&jO#g#Wa%[#Wa%_#Wa~Oz&lO#[&nO#g&rX%[&rX%_&rXg&rX~O!f$YO!r$YO#Z&qO%uWO~O#Z&qO~Oz&sO#g&tX%[&tX%_&tX~Oz&uO#g&pX%[&pX%_&pX{&pX~O!X&wO%z&xO~Oz&|On&wX~P%SOn'PO~OPdOVaOopOvqO!PrO!Q{O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO%['UO~P'vOt'YO#p'WO#q'XOP#naV#naf#nah#nao#nas#nav#na!P#na!Q#na!T#na!U#na!X#na!]#na!h#na!r#na!s#na!t#na!{#na!}#na#P#na#R#na#T#na#X#na#Z#na#^#na#_#na#a#na#c#na#l#na#o#na#s#na#u#na#z#na#}#na$P#na%X#na%o#na%p#na%t#na%u#na&Z#na&[#na&]#na&^#na&_#na&`#na&a#na&b#na&c#na&d#na&e#na&f#na&g#na&h#na&i#na&j#na%Z#na%_#na~Oz'ZO#[']O{&xX~Oh'_O!X&wO~Oh!iO{$jO!X&wO~O{'eO~P%SO%['hO%_'hO~OS'iO%['hO%_'hO~OV!aO_!aOa!bOh!iO!X!kO!f!mO%l!^O%m!_O%n!_O%o!`O%p!`O%q!aO%r!aO%s!aOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~O%k!]O~P!#uO%kWi~P!#uOV!aO_!aOa!bOh!iO!X!kO!f!mO%o!`O%p!`O%q!aO%r!aO%s!aOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%kWi%lWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~O%m!_O%n!_O~P!&pO%mWi%nWi~P!&pOa!bOh!iO!X!kO!f!mOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%kWi%lWi%mWi%nWi%oWi%pWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~OV!aO_!aO%q!aO%r!aO%s!aO~P!)nOVWi_Wi%qWi%rWi%sWi~P!)nO!T%dO!U%cOg&VXz&VX~O%z'kO%{'kO~P,eOz'mOg&UX~Og'oO~Oz'pO{'rO!W&XX~Oo0cOv0qOz'pO{'sO!W&XX~P'vO!W'uO~Om!oOn!oOo!rOp!sOkjisjizji{ji!xji#gji%[ji%_ji%zji~Ol!qO~P!.aOlji~P!.aOk0eOl0fOm0dOn0dOo0mOp0nO~Ot'wO~P!/jOV'|Og'}Oo0cOv0qO~P'vOg'}Oz(OO~Og(QO~O!U(SO~Og(TOz(OO!T%dO!U%cO~P%SOk0eOl0fOm0dOn0dOo0mOp0nOgqa!Tqa!Uqa%{qa!Wqa![qa!Qqa#[qatqa!mqa~PEcOV'|Oo0cOv0qO!W&Sa~P'vOz(WO!W&Sa~O!W(XO~Oz(WO!T%dO!U%cO!W&Sa~P%SOV(]Oo0cOv0qO![%}a#g%}a%[%}a%_%}ag%}a{%}a!m%}a%z%}a~P'vOz(^O![%}a#g%}a%[%}a%_%}ag%}a{%}a!m%}a%z%}a~O![(aO~Oz(^O!T%dO!U%cO![%}a~P%SOz(dO!T%dO!U%cO![&Ta~P%SOz(gO{&lX![&lX!m&lX%z&lX~O{(kO![(mO!m(nO%z(jO~OV&OOopOvqO{%hi!x%hi#g%hi%[%hi%_%hi%z%hi~P'vOz(pO{%hi!x%hi#g%hi%[%hi%_%hi%z%hi~O!f&UOh&sa%[&saz&sa#[&sa#g&sa%_&sa#Z&sag&sa~O%[(uO~OV#sOa#tO%uWO~Oz&]O{wa~OopOvqO~P'vOz(^O#g%}a%[%}a%_%}ag%}a{%}a![%}a!m%}a%z%}a~P%SOz(zO#g%hX%[%hX%_%hX%z%hX~O%z#|O#gUi%[Ui%_Ui~O#g&Pa%[&Pa%_&Pan&Pa~P'vOz(}O#g&Pa%[&Pa%_&Pan&Pa~O%uWO#g&ra%[&ra%_&rag&ra~Oz)SO#g&ra%[&ra%_&rag&ra~Og)VO~OV)WOh$WO%uWO~O#Z)XO~O%uWO#g&ta%[&ta%_&ta~Oz)ZO#g&ta%[&ta%_&ta~Oo0cOv0qO#g&pa%[&pa%_&pa{&pa~P'vOz)^O#g&pa%[&pa%_&pa{&pa~OV)`Oa)`O%uWO~O%z)eO~Ot)hO#j)gOP#hiV#hif#hih#hio#his#hiv#hi!P#hi!Q#hi!T#hi!U#hi!X#hi!]#hi!h#hi!r#hi!s#hi!t#hi!{#hi!}#hi#P#hi#R#hi#T#hi#X#hi#Z#hi#^#hi#_#hi#a#hi#c#hi#l#hi#o#hi#s#hi#u#hi#z#hi#}#hi$P#hi%X#hi%o#hi%p#hi%t#hi%u#hi&Z#hi&[#hi&]#hi&^#hi&_#hi&`#hi&a#hi&b#hi&c#hi&d#hi&e#hi&f#hi&g#hi&h#hi&i#hi&j#hi%Z#hi%_#hi~Ot)iOP#kiV#kif#kih#kio#kis#kiv#ki!P#ki!Q#ki!T#ki!U#ki!X#ki!]#ki!h#ki!r#ki!s#ki!t#ki!{#ki!}#ki#P#ki#R#ki#T#ki#X#ki#Z#ki#^#ki#_#ki#a#ki#c#ki#l#ki#o#ki#s#ki#u#ki#z#ki#}#ki$P#ki%X#ki%o#ki%p#ki%t#ki%u#ki&Z#ki&[#ki&]#ki&^#ki&_#ki&`#ki&a#ki&b#ki&c#ki&d#ki&e#ki&f#ki&g#ki&h#ki&i#ki&j#ki%Z#ki%_#ki~OV)kOn&wa~P'vOz)lOn&wa~Oz)lOn&wa~P%SOn)pO~O%Y)tO~Ot)wO#p'WO#q)vOP#niV#nif#nih#nio#nis#niv#ni!P#ni!Q#ni!T#ni!U#ni!X#ni!]#ni!h#ni!r#ni!s#ni!t#ni!{#ni!}#ni#P#ni#R#ni#T#ni#X#ni#Z#ni#^#ni#_#ni#a#ni#c#ni#l#ni#o#ni#s#ni#u#ni#z#ni#}#ni$P#ni%X#ni%o#ni%p#ni%t#ni%u#ni&Z#ni&[#ni&]#ni&^#ni&_#ni&`#ni&a#ni&b#ni&c#ni&d#ni&e#ni&f#ni&g#ni&h#ni&i#ni&j#ni%Z#ni%_#ni~OV)zOo0cOv0qO{$jO~P'vOo0cOv0qO{&xa~P'vOz*OO{&xa~OV*SOa*TOg*WO%q*UO%uWO~O{$jO&{*YO~Oh'_O~Oh!iO{$jO~O%[*_O~O%[*aO%_*aO~OV$}Oa$}Oo0cOv0qOg&Ua~P'vOz*dOg&Ua~Oo0cOv0qO{*gO!W&Xa~P'vOz*hO!W&Xa~Oo0cOv0qOz*hO{*kO!W&Xa~P'vOo0cOv0qOz*hO!W&Xa~P'vOz*hO{*kO!W&Xa~Om0dOn0dOo0mOp0nOgjikjisjizji!Tji!Uji%{ji!Wji{ji![ji#gji%[ji%_ji!Qji#[jitji!mji%zji~Ol0fO~P!NkOlji~P!NkOV'|Og*pOo0cOv0qO~P'vOn*rO~Og*pOz*tO~Og*uO~OV'|Oo0cOv0qO!W&Si~P'vOz*vO!W&Si~O!W*wO~OV(]Oo0cOv0qO![%}i#g%}i%[%}i%_%}ig%}i{%}i!m%}i%z%}i~P'vOz*zO!T%dO!U%cO![&Ti~Oz*}O![%}i#g%}i%[%}i%_%}ig%}i{%}i!m%}i%z%}i~O![+OO~Oa+QOo0cOv0qO![&Ti~P'vOz*zO![&Ti~O![+SO~OV+UOo0cOv0qO{&la![&la!m&la%z&la~P'vOz+VO{&la![&la!m&la%z&la~O!]+YO&n+[O![!nX~O![+^O~O{(kO![+_O~O{(kO![+_O!m+`O~OV&OOopOvqO{%hq!x%hq#g%hq%[%hq%_%hq%z%hq~P'vOz$ri{$ri!x$ri#g$ri%[$ri%_$ri%z$ri~P%SOV&OOopOvqO~P'vOV&OOo0cOv0qO#g%ha%[%ha%_%ha%z%ha~P'vOz+aO#g%ha%[%ha%_%ha%z%ha~Oz$ia#g$ia%[$ia%_$ian$ia~P%SO#g&Pi%[&Pi%_&Pin&Pi~P'vOz+dO#g#Wq%[#Wq%_#Wq~O#[+eOz$va#g$va%[$va%_$vag$va~O%uWO#g&ri%[&ri%_&rig&ri~Oz+gO#g&ri%[&ri%_&rig&ri~OV+iOh$WO%uWO~O%uWO#g&ti%[&ti%_&ti~Oo0cOv0qO#g&pi%[&pi%_&pi{&pi~P'vO{#{Oz#eX!W#eX~Oz+mO!W&uX~O!W+oO~Ot+rO#j)gOP#hqV#hqf#hqh#hqo#hqs#hqv#hq!P#hq!Q#hq!T#hq!U#hq!X#hq!]#hq!h#hq!r#hq!s#hq!t#hq!{#hq!}#hq#P#hq#R#hq#T#hq#X#hq#Z#hq#^#hq#_#hq#a#hq#c#hq#l#hq#o#hq#s#hq#u#hq#z#hq#}#hq$P#hq%X#hq%o#hq%p#hq%t#hq%u#hq&Z#hq&[#hq&]#hq&^#hq&_#hq&`#hq&a#hq&b#hq&c#hq&d#hq&e#hq&f#hq&g#hq&h#hq&i#hq&j#hq%Z#hq%_#hq~On$|az$|a~P%SOV)kOn&wi~P'vOz+yOn&wi~Oz,TO{$jO#[,TO~O#q,VOP#nqV#nqf#nqh#nqo#nqs#nqv#nq!P#nq!Q#nq!T#nq!U#nq!X#nq!]#nq!h#nq!r#nq!s#nq!t#nq!{#nq!}#nq#P#nq#R#nq#T#nq#X#nq#Z#nq#^#nq#_#nq#a#nq#c#nq#l#nq#o#nq#s#nq#u#nq#z#nq#}#nq$P#nq%X#nq%o#nq%p#nq%t#nq%u#nq&Z#nq&[#nq&]#nq&^#nq&_#nq&`#nq&a#nq&b#nq&c#nq&d#nq&e#nq&f#nq&g#nq&h#nq&i#nq&j#nq%Z#nq%_#nq~O#[,WOz%Oa{%Oa~Oo0cOv0qO{&xi~P'vOz,YO{&xi~O{#{O%z,[Og&zXz&zX~O%uWOg&zXz&zX~Oz,`Og&yX~Og,bO~O%Y,eO~O!T%dO!U%cOg&Viz&Vi~OV$}Oa$}Oo0cOv0qOg&Ui~P'vO{,hOz$la!W$la~Oo0cOv0qO{,iOz$la!W$la~P'vOo0cOv0qO{*gO!W&Xi~P'vOz,lO!W&Xi~Oo0cOv0qOz,lO!W&Xi~P'vOz,lO{,oO!W&Xi~Og$hiz$hi!W$hi~P%SOV'|Oo0cOv0qO~P'vOn,qO~OV'|Og,rOo0cOv0qO~P'vOV'|Oo0cOv0qO!W&Sq~P'vOz$gi![$gi#g$gi%[$gi%_$gig$gi{$gi!m$gi%z$gi~P%SOV(]Oo0cOv0qO~P'vOa+QOo0cOv0qO![&Tq~P'vOz,sO![&Tq~O![,tO~OV(]Oo0cOv0qO![%}q#g%}q%[%}q%_%}qg%}q{%}q!m%}q%z%}q~P'vO{,uO~OV+UOo0cOv0qO{&li![&li!m&li%z&li~P'vOz,zO{&li![&li!m&li%z&li~O!]+YO&n+[O![!na~O{(kO![,}O~OV&OOo0cOv0qO#g%hi%[%hi%_%hi%z%hi~P'vOz-OO#g%hi%[%hi%_%hi%z%hi~O%uWO#g&rq%[&rq%_&rqg&rq~Oz-RO#g&rq%[&rq%_&rqg&rq~OV)`Oa)`O%uWO!W&ua~Oz-TO!W&ua~On$|iz$|i~P%SOV)kO~P'vOV)kOn&wq~P'vOt-XOP#myV#myf#myh#myo#mys#myv#my!P#my!Q#my!T#my!U#my!X#my!]#my!h#my!r#my!s#my!t#my!{#my!}#my#P#my#R#my#T#my#X#my#Z#my#^#my#_#my#a#my#c#my#l#my#o#my#s#my#u#my#z#my#}#my$P#my%X#my%o#my%p#my%t#my%u#my&Z#my&[#my&]#my&^#my&_#my&`#my&a#my&b#my&c#my&d#my&e#my&f#my&g#my&h#my&i#my&j#my%Z#my%_#my~O%Z-]O%_-]O~P`O#q-^OP#nyV#nyf#nyh#nyo#nys#nyv#ny!P#ny!Q#ny!T#ny!U#ny!X#ny!]#ny!h#ny!r#ny!s#ny!t#ny!{#ny!}#ny#P#ny#R#ny#T#ny#X#ny#Z#ny#^#ny#_#ny#a#ny#c#ny#l#ny#o#ny#s#ny#u#ny#z#ny#}#ny$P#ny%X#ny%o#ny%p#ny%t#ny%u#ny&Z#ny&[#ny&]#ny&^#ny&_#ny&`#ny&a#ny&b#ny&c#ny&d#ny&e#ny&f#ny&g#ny&h#ny&i#ny&j#ny%Z#ny%_#ny~Oz-aO{$jO#[-aO~Oo0cOv0qO{&xq~P'vOz-dO{&xq~O%z,[Og&zaz&za~O{#{Og&zaz&za~OV*SOa*TO%q*UO%uWOg&ya~Oz-hOg&ya~O$S-lO~OV$}Oa$}Oo0cOv0qO~P'vOo0cOv0qO{-mOz$li!W$li~P'vOo0cOv0qOz$li!W$li~P'vO{-mOz$li!W$li~Oo0cOv0qO{*gO~P'vOo0cOv0qO{*gO!W&Xq~P'vOz-pO!W&Xq~Oo0cOv0qOz-pO!W&Xq~P'vOs-sO!T%dO!U%cOg&Oq!W&Oq![&Oqz&Oq~P!/jOa+QOo0cOv0qO![&Ty~P'vOz$ji![$ji~P%SOa+QOo0cOv0qO~P'vOV+UOo0cOv0qO~P'vOV+UOo0cOv0qO{&lq![&lq!m&lq%z&lq~P'vO{(kO![-xO!m-yO%z-wO~OV&OOo0cOv0qO#g%hq%[%hq%_%hq%z%hq~P'vO%uWO#g&ry%[&ry%_&ryg&ry~OV)`Oa)`O%uWO!W&ui~Ot-}OP#m!RV#m!Rf#m!Rh#m!Ro#m!Rs#m!Rv#m!R!P#m!R!Q#m!R!T#m!R!U#m!R!X#m!R!]#m!R!h#m!R!r#m!R!s#m!R!t#m!R!{#m!R!}#m!R#P#m!R#R#m!R#T#m!R#X#m!R#Z#m!R#^#m!R#_#m!R#a#m!R#c#m!R#l#m!R#o#m!R#s#m!R#u#m!R#z#m!R#}#m!R$P#m!R%X#m!R%o#m!R%p#m!R%t#m!R%u#m!R&Z#m!R&[#m!R&]#m!R&^#m!R&_#m!R&`#m!R&a#m!R&b#m!R&c#m!R&d#m!R&e#m!R&f#m!R&g#m!R&h#m!R&i#m!R&j#m!R%Z#m!R%_#m!R~Oo0cOv0qO{&xy~P'vOV*SOa*TO%q*UO%uWOg&yi~O$S-lO%Z.VO%_.VO~OV.aOh._O!X.^O!].`O!h.YO!s.[O!t.[O%p.XO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O~Oo0cOv0qOz$lq!W$lq~P'vO{.fOz$lq!W$lq~Oo0cOv0qO{*gO!W&Xy~P'vOz.gO!W&Xy~Oo0cOv.kO~P'vOs-sO!T%dO!U%cOg&Oy!W&Oy![&Oyz&Oy~P!/jO{(kO![.nO~O{(kO![.nO!m.oO~OV*SOa*TO%q*UO%uWO~Oh.tO!f.rOz$TX#[$TX%j$TXg$TX~Os$TX{$TX!W$TX![$TX~P$-bO%o.vO%p.vOs$UXz$UX{$UX#[$UX%j$UX!W$UXg$UX![$UX~O!h.xO~Oz.|O#[/OO%j.yOs&|X{&|X!W&|Xg&|X~Oa/RO~P$)zOh.tOs&}Xz&}X{&}X#[&}X%j&}X!W&}Xg&}X![&}X~Os/VO{$jO~Oo0cOv0qOz$ly!W$ly~P'vOo0cOv0qO{*gO!W&X!R~P'vOz/ZO!W&X!R~Og&RXs&RX!T&RX!U&RX!W&RX![&RXz&RX~P!/jOs-sO!T%dO!U%cOg&Qa!W&Qa![&Qaz&Qa~O{(kO![/^O~O!f.rOh$[as$[az$[a{$[a#[$[a%j$[a!W$[ag$[a![$[a~O!h/eO~O%o.vO%p.vOs$Uaz$Ua{$Ua#[$Ua%j$Ua!W$Uag$Ua![$Ua~O%j.yOs$Yaz$Ya{$Ya#[$Ya!W$Yag$Ya![$Ya~Os&|a{&|a!W&|ag&|a~P$)nOz/jOs&|a{&|a!W&|ag&|a~O!W/mO~Og/mO~O{/oO~O![/pO~Oo0cOv0qO{*gO!W&X!Z~P'vO{/sO~O%z/tO~P$-bOz/uO#[/OO%j.yOg'PX~Oz/uOg'PX~Og/wO~O!h/xO~O#[/OOs%Saz%Sa{%Sa%j%Sa!W%Sag%Sa![%Sa~O#[/OO%j.yOs%Waz%Wa{%Wa!W%Wag%Wa~Os&|i{&|i!W&|ig&|i~P$)nOz/zO#[/OO%j.yO!['Oa~Og'Pa~P$)nOz0SOg'Pa~Oa0UO!['Oi~P$)zOz0WO!['Oi~Oz0WO#[/OO%j.yO!['Oi~O#[/OO%j.yOg$biz$bi~O%z0ZO~P$-bO#[/OO%j.yOg%Vaz%Va~Og'Pi~P$)nO{0^O~Oa0UO!['Oq~P$)zOz0`O!['Oq~O#[/OO%j.yOz%Ui![%Ui~Oa0UO~P$)zOa0UO!['Oy~P$)zO#[/OO%j.yOg$ciz$ci~O#[/OO%j.yOz%Uq![%Uq~Oz+aO#g%ha%[%ha%_%ha%z%ha~P%SOV&OOo0cOv0qO~P'vOn0hO~Oo0hO~P'vO{0iO~Ot0jO~P!/jO&]&Z&j&h&i&g&f&d&e&c&b&`&a&_&^&[%u~",goto:"!=j'QPPPPPP'RP'Z*s+[+t,_,y-fP.SP'Z.r.r'ZPPP'Z2[PPPPPP2[5PPP5PP7b7k=sPP=v>h>kPP'Z'ZPP>zPP'Z'ZPP'Z'Z'Z'Z'Z?O?w'ZP?zP@QDXGuGyPG|HWH['ZPPPH_Hk'RP'R'RP'RP'RP'RP'RP'R'R'RP'RPP'RPP'RP'RPHqH}IVPI^IdPI^PI^I^PPPI^PKrPK{LVL]KrPI^LfPI^PLmLsPLwM]MzNeLwLwNkNxLwLwLwLw! ^! d! g! l! o! y!!P!!]!!o!!u!#P!#V!#s!#y!$P!$Z!$a!$g!$y!%T!%Z!%a!%k!%q!%w!%}!&T!&Z!&e!&k!&u!&{!'U!'[!'k!'s!'}!(UPPPPPPPPPPP!([!(_!(e!(n!(x!)TPPPPPPPPPPPP!-u!/Z!3^!6oPP!6w!7W!7a!8Y!8P!8c!8i!8l!8o!8r!8z!9jPPPPPPPPPPPPPPPPP!9m!9q!9wP!:]!:a!:m!:v!;S!;j!;m!;p!;v!;|!_![!]Do!]!^Es!^!_FZ!_!`Gk!`!aHX!a!b%T!b!cIf!c!dJU!d!eK^!e!hJU!h!i!#f!i!tJU!t!u!,|!u!wJU!w!x!.t!x!}JU!}#O!0S#O#P&o#P#Q!0j#Q#R!1Q#R#SJU#S#T%T#T#UJU#U#VK^#V#YJU#Y#Z!#f#Z#fJU#f#g!,|#g#iJU#i#j!.t#j#oJU#o#p!1n#p#q!1s#q#r!2a#r#s!2f#s$g%T$g;'SJU;'S;=`KW<%lOJU`%YT&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T`%lP;=`<%l%To%v]&n`%c_OX%TXY%oY[%T[]%o]p%Tpq%oq#O%T#O#P&o#P#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To&tX&n`OY%TYZ%oZ]%T]^%o^#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc'f[&n`O!_%T!_!`([!`#T%T#T#U(r#U#f%T#f#g(r#g#h(r#h#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc(cTmR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc(yT!mR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk)aV&n`&[ZOr%Trs)vs#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk){V&n`Or%Trs*bs#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk*iT&n`&^ZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To+PZS_&n`OY*xYZ%TZ]*x]^%T^#o*x#o#p+r#p#q*x#q#r+r#r;'S*x;'S;=`,^<%lO*x_+wTS_OY+rZ]+r^;'S+r;'S;=`,W<%lO+r_,ZP;=`<%l+ro,aP;=`<%l*xj,kV%rQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj-XT!xY&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj-oV%lQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk.]V&n`&ZZOw%Twx.rx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk.wV&n`Ow%Twx/^x#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk/eT&n`&]ZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk/{ThZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc0cTgR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk0yXVZ&n`Oz%Tz{1f{!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk1mVaR&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk2ZV%oZ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc2wTzR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To3_W%pZ&n`O!_%T!_!`-Q!`!a3w!a#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Td4OT&{S&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk4fX!fQ&n`O!O%T!O!P5R!P!Q%T!Q![6T![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk5WV&n`O!O%T!O!P5m!P#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk5tT!rZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti6[a!hX&n`O!Q%T!Q![6T![!g%T!g!h7a!h!l%T!l!m9s!m#R%T#R#S6T#S#X%T#X#Y7a#Y#^%T#^#_9s#_#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti7fZ&n`O{%T{|8X|}%T}!O8X!O!Q%T!Q![8s![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti8^V&n`O!Q%T!Q![8s![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti8z]!hX&n`O!Q%T!Q![8s![!l%T!l!m9s!m#R%T#R#S8s#S#^%T#^#_9s#_#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti9zT!hX&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk:bX%qR&n`O!P%T!P!Q:}!Q!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj;UV%sQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti;ro!hX&n`O!O%T!O!P=s!P!Q%T!Q![>_![!d%T!d!e?q!e!g%T!g!h7a!h!l%T!l!m9s!m!q%T!q!rA]!r!z%T!z!{Bq!{#R%T#R#S>_#S#U%T#U#V?q#V#X%T#X#Y7a#Y#^%T#^#_9s#_#c%T#c#dA]#d#l%T#l#mBq#m#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti=xV&n`O!Q%T!Q![6T![#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti>fc!hX&n`O!O%T!O!P=s!P!Q%T!Q![>_![!g%T!g!h7a!h!l%T!l!m9s!m#R%T#R#S>_#S#X%T#X#Y7a#Y#^%T#^#_9s#_#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti?vY&n`O!Q%T!Q!R@f!R!S@f!S#R%T#R#S@f#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Ti@mY!hX&n`O!Q%T!Q!R@f!R!S@f!S#R%T#R#S@f#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiAbX&n`O!Q%T!Q!YA}!Y#R%T#R#SA}#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiBUX!hX&n`O!Q%T!Q!YA}!Y#R%T#R#SA}#S#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiBv]&n`O!Q%T!Q![Co![!c%T!c!iCo!i#R%T#R#SCo#S#T%T#T#ZCo#Z#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TiCv]!hX&n`O!Q%T!Q![Co![!c%T!c!iCo!i#R%T#R#SCo#S#T%T#T#ZCo#Z#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%ToDvV{_&n`O!_%T!_!`E]!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TcEdT%{R&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkEzT#gZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkFbXmR&n`O!^%T!^!_F}!_!`([!`!a([!a#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TjGUV%mQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkGrV%zZ&n`O!_%T!_!`([!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkH`WmR&n`O!_%T!_!`([!`!aHx!a#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TjIPV%nQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkIoV_Q#}P&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%ToJ_]&n`&YS%uZO!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUoKZP;=`<%lJUoKge&n`&YS%uZOr%Trs)Ysw%Twx.Ux!Q%T!Q![JU![!c%T!c!tJU!t!uLx!u!}JU!}#R%T#R#SJU#S#T%T#T#fJU#f#gLx#g#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUoMRa&n`&YS%uZOr%TrsNWsw%Twx! vx!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUkN_V&n`&`ZOr%TrsNts#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%TkNyV&n`Or%Trs! `s#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk! gT&n`&bZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk! }V&n`&_ZOw%Twx!!dx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!!iV&n`Ow%Twx!#Ox#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!#VT&n`&aZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To!#oe&n`&YS%uZOr%Trs!%Qsw%Twx!&px!Q%T!Q![JU![!c%T!c!tJU!t!u!(`!u!}JU!}#R%T#R#SJU#S#T%T#T#fJU#f#g!(`#g#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUk!%XV&n`&dZOr%Trs!%ns#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!%sV&n`Or%Trs!&Ys#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!&aT&n`&fZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!&wV&n`&cZOw%Twx!'^x#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!'cV&n`Ow%Twx!'xx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!(PT&n`&eZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To!(ia&n`&YS%uZOr%Trs!)nsw%Twx!+^x!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUk!)uV&n`&hZOr%Trs!*[s#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!*aV&n`Or%Trs!*vs#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!*}T&n`&jZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!+eV&n`&gZOw%Twx!+zx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!,PV&n`Ow%Twx!,fx#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tk!,mT&n`&iZO#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%To!-Vi&n`&YS%uZOr%TrsNWsw%Twx! vx!Q%T!Q![JU![!c%T!c!dJU!d!eLx!e!hJU!h!i!(`!i!}JU!}#R%T#R#SJU#S#T%T#T#UJU#U#VLx#V#YJU#Y#Z!(`#Z#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUo!.}a&n`&YS%uZOr%Trs)Ysw%Twx.Ux!Q%T!Q![JU![!c%T!c!}JU!}#R%T#R#SJU#S#T%T#T#oJU#p#q%T#r$g%T$g;'SJU;'S;=`KW<%lOJUk!0ZT!XZ&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tc!0qT!WR&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%Tj!1XV%kQ&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T~!1sO!]~k!1zV%jR&n`O!_%T!_!`-Q!`#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T~!2fO![~i!2mT%tX&n`O#o%T#p#q%T#r;'S%T;'S;=`%i<%lO%T",tokenizers:[jee,wee,bee,Nee,0,1,2,3,4],topRules:{Script:[0,5]},specialized:[{term:221,get:t=>Mee[t]||-1}],tokenPrec:7668}),s8=new WG,z_=new Set(["Script","Body","FunctionDefinition","ClassDefinition","LambdaExpression","ForStatement","MatchClause"]);function kp(t){return(e,n,r)=>{if(r)return!1;let s=e.node.getChild("VariableName");return s&&n(s,t),!0}}const Eee={FunctionDefinition:kp("function"),ClassDefinition:kp("class"),ForStatement(t,e,n){if(n){for(let r=t.node.firstChild;r;r=r.nextSibling)if(r.name=="VariableName")e(r,"variable");else if(r.name=="in")break}},ImportStatement(t,e){var n,r;let{node:s}=t,i=((n=s.firstChild)===null||n===void 0?void 0:n.name)=="from";for(let l=s.getChild("import");l;l=l.nextSibling)l.name=="VariableName"&&((r=l.nextSibling)===null||r===void 0?void 0:r.name)!="as"&&e(l,i?"variable":"namespace")},AssignStatement(t,e){for(let n=t.node.firstChild;n;n=n.nextSibling)if(n.name=="VariableName")e(n,"variable");else if(n.name==":"||n.name=="AssignOp")break},ParamList(t,e){for(let n=null,r=t.node.firstChild;r;r=r.nextSibling)r.name=="VariableName"&&(!n||!/\*|AssignOp/.test(n.name))&&e(r,"variable"),n=r},CapturePattern:kp("variable"),AsPattern:kp("variable"),__proto__:null};function P_(t,e){let n=s8.get(e);if(n)return n;let r=[],s=!0;function i(l,c){let d=t.sliceString(l.from,l.to);r.push({label:d,type:c})}return e.cursor(Or.IncludeAnonymous).iterate(l=>{if(l.name){let c=Eee[l.name];if(c&&c(l,i,s)||!s&&z_.has(l.name))return!1;s=!1}else if(l.to-l.from>8192){for(let c of P_(t,l.node))r.push(c);return!1}}),s8.set(e,r),r}const i8=/^[\w\xa1-\uffff][\w\d\xa1-\uffff]*$/,L_=["String","FormatString","Comment","PropertyName"];function _ee(t){let e=zr(t.state).resolveInner(t.pos,-1);if(L_.indexOf(e.name)>-1)return null;let n=e.name=="VariableName"||e.to-e.from<20&&i8.test(t.state.sliceDoc(e.from,e.to));if(!n&&!t.explicit)return null;let r=[];for(let s=e;s;s=s.parent)z_.has(s.name)&&(r=r.concat(P_(t.state.doc,s)));return{options:r,from:n?e.from:t.pos,validFor:i8}}const Dee=["__annotations__","__builtins__","__debug__","__doc__","__import__","__name__","__loader__","__package__","__spec__","False","None","True"].map(t=>({label:t,type:"constant"})).concat(["ArithmeticError","AssertionError","AttributeError","BaseException","BlockingIOError","BrokenPipeError","BufferError","BytesWarning","ChildProcessError","ConnectionAbortedError","ConnectionError","ConnectionRefusedError","ConnectionResetError","DeprecationWarning","EOFError","Ellipsis","EncodingWarning","EnvironmentError","Exception","FileExistsError","FileNotFoundError","FloatingPointError","FutureWarning","GeneratorExit","IOError","ImportError","ImportWarning","IndentationError","IndexError","InterruptedError","IsADirectoryError","KeyError","KeyboardInterrupt","LookupError","MemoryError","ModuleNotFoundError","NameError","NotADirectoryError","NotImplemented","NotImplementedError","OSError","OverflowError","PendingDeprecationWarning","PermissionError","ProcessLookupError","RecursionError","ReferenceError","ResourceWarning","RuntimeError","RuntimeWarning","StopAsyncIteration","StopIteration","SyntaxError","SyntaxWarning","SystemError","SystemExit","TabError","TimeoutError","TypeError","UnboundLocalError","UnicodeDecodeError","UnicodeEncodeError","UnicodeError","UnicodeTranslateError","UnicodeWarning","UserWarning","ValueError","Warning","ZeroDivisionError"].map(t=>({label:t,type:"type"}))).concat(["bool","bytearray","bytes","classmethod","complex","float","frozenset","int","list","map","memoryview","object","range","set","staticmethod","str","super","tuple","type"].map(t=>({label:t,type:"class"}))).concat(["abs","aiter","all","anext","any","ascii","bin","breakpoint","callable","chr","compile","delattr","dict","dir","divmod","enumerate","eval","exec","exit","filter","format","getattr","globals","hasattr","hash","help","hex","id","input","isinstance","issubclass","iter","len","license","locals","max","min","next","oct","open","ord","pow","print","property","quit","repr","reversed","round","setattr","slice","sorted","sum","vars","zip"].map(t=>({label:t,type:"function"}))),Ree=[Xa("def ${name}(${params}):\n ${}",{label:"def",detail:"function",type:"keyword"}),Xa("for ${name} in ${collection}:\n ${}",{label:"for",detail:"loop",type:"keyword"}),Xa("while ${}:\n ${}",{label:"while",detail:"loop",type:"keyword"}),Xa("try:\n ${}\nexcept ${error}:\n ${}",{label:"try",detail:"/ except block",type:"keyword"}),Xa(`if \${}: - -`,{label:"if",detail:"block",type:"keyword"}),Xa("if ${}:\n ${}\nelse:\n ${}",{label:"if",detail:"/ else block",type:"keyword"}),Xa("class ${name}:\n def __init__(self, ${params}):\n ${}",{label:"class",detail:"definition",type:"keyword"}),Xa("import ${module}",{label:"import",detail:"statement",type:"keyword"}),Xa("from ${module} import ${names}",{label:"from",detail:"import",type:"keyword"})],zee=LK(L_,d_(Dee.concat(Ree)));function ab(t){let{node:e,pos:n}=t,r=t.lineIndent(n,-1),s=null;for(;;){let i=e.childBefore(n);if(i)if(i.name=="Comment")n=i.from;else if(i.name=="Body"||i.name=="MatchBody")t.baseIndentFor(i)+t.unit<=r&&(s=i),e=i;else if(i.name=="MatchClause")e=i;else if(i.type.is("Statement"))e=i;else break;else break}return s}function lb(t,e){let n=t.baseIndentFor(e),r=t.lineAt(t.pos,-1),s=r.from+r.text.length;return/^\s*($|#)/.test(r.text)&&t.node.ton?null:n+t.unit}const ob=jf.define({name:"python",parser:Aee.configure({props:[Cx.add({Body:t=>{var e;let n=/^\s*(#|$)/.test(t.textAfter)&&ab(t)||t.node;return(e=lb(t,n))!==null&&e!==void 0?e:t.continue()},MatchBody:t=>{var e;let n=ab(t);return(e=lb(t,n||t.node))!==null&&e!==void 0?e:t.continue()},IfStatement:t=>/^\s*(else:|elif )/.test(t.textAfter)?t.baseIndent:t.continue(),"ForStatement WhileStatement":t=>/^\s*else:/.test(t.textAfter)?t.baseIndent:t.continue(),TryStatement:t=>/^\s*(except[ :]|finally:|else:)/.test(t.textAfter)?t.baseIndent:t.continue(),MatchStatement:t=>/^\s*case /.test(t.textAfter)?t.baseIndent+t.unit:t.continue(),"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression":Hy({closing:")"}),"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression":Hy({closing:"}"}),"ArrayExpression ArrayComprehensionExpression":Hy({closing:"]"}),MemberExpression:t=>t.baseIndent+t.unit,"String FormatString":()=>null,Script:t=>{var e;let n=ab(t);return(e=n&&lb(t,n))!==null&&e!==void 0?e:t.continue()}}),Fw.add({"ArrayExpression DictionaryExpression SetExpression TupleExpression":rE,Body:(t,e)=>({from:t.from+1,to:t.to-(t.to==e.doc.length?0:1)}),"String FormatString":(t,e)=>({from:e.doc.lineAt(t.from).to,to:t.to})})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"'''",'"""'],stringPrefixes:["f","fr","rf","r","u","b","br","rb","F","FR","RF","R","U","B","BR","RB"]},commentTokens:{line:"#"},indentOnInput:/^\s*([\}\]\)]|else:|elif |except |finally:|case\s+[^:]*:?)$/}});function Pee(){return new eE(ob,[ob.data.of({autocomplete:_ee}),ob.data.of({autocomplete:zee})])}const Lee=Bw({String:he.string,Number:he.number,"True False":he.bool,PropertyName:he.propertyName,Null:he.null,", :":he.separator,"[ ]":he.squareBracket,"{ }":he.brace}),Bee=Rf.deserialize({version:14,states:"$bOVQPOOOOQO'#Cb'#CbOnQPO'#CeOvQPO'#ClOOQO'#Cr'#CrQOQPOOOOQO'#Cg'#CgO}QPO'#CfO!SQPO'#CtOOQO,59P,59PO![QPO,59PO!aQPO'#CuOOQO,59W,59WO!iQPO,59WOVQPO,59QOqQPO'#CmO!nQPO,59`OOQO1G.k1G.kOVQPO'#CnO!vQPO,59aOOQO1G.r1G.rOOQO1G.l1G.lOOQO,59X,59XOOQO-E6k-E6kOOQO,59Y,59YOOQO-E6l-E6l",stateData:"#O~OeOS~OQSORSOSSOTSOWQO_ROgPO~OVXOgUO~O^[O~PVO[^O~O]_OVhX~OVaO~O]bO^iX~O^dO~O]_OVha~O]bO^ia~O",goto:"!kjPPPPPPkPPkqwPPPPk{!RPPP!XP!e!hXSOR^bQWQRf_TVQ_Q`WRg`QcZRicQTOQZRQe^RhbRYQR]R",nodeNames:"⚠ JsonText True False Null Number String } { Object Property PropertyName : , ] [ Array",maxTerm:25,nodeProps:[["isolate",-2,6,11,""],["openedBy",7,"{",14,"["],["closedBy",8,"}",15,"]"]],propSources:[Lee],skippedNodes:[0],repeatNodeCount:2,tokenData:"(|~RaXY!WYZ!W]^!Wpq!Wrs!]|}$u}!O$z!Q!R%T!R![&c![!]&t!}#O&y#P#Q'O#Y#Z'T#b#c'r#h#i(Z#o#p(r#q#r(w~!]Oe~~!`Wpq!]qr!]rs!xs#O!]#O#P!}#P;'S!];'S;=`$o<%lO!]~!}Og~~#QXrs!]!P!Q!]#O#P!]#U#V!]#Y#Z!]#b#c!]#f#g!]#h#i!]#i#j#m~#pR!Q![#y!c!i#y#T#Z#y~#|R!Q![$V!c!i$V#T#Z$V~$YR!Q![$c!c!i$c#T#Z$c~$fR!Q![!]!c!i!]#T#Z!]~$rP;=`<%l!]~$zO]~~$}Q!Q!R%T!R![&c~%YRT~!O!P%c!g!h%w#X#Y%w~%fP!Q![%i~%nRT~!Q![%i!g!h%w#X#Y%w~%zR{|&T}!O&T!Q![&Z~&WP!Q![&Z~&`PT~!Q![&Z~&hST~!O!P%c!Q![&c!g!h%w#X#Y%w~&yO[~~'OO_~~'TO^~~'WP#T#U'Z~'^P#`#a'a~'dP#g#h'g~'jP#X#Y'm~'rOR~~'uP#i#j'x~'{P#`#a(O~(RP#`#a(U~(ZOS~~(^P#f#g(a~(dP#i#j(g~(jP#X#Y(m~(rOQ~~(wOW~~(|OV~",tokenizers:[0],topRules:{JsonText:[0,1]},tokenPrec:0}),Iee=()=>t=>{try{JSON.parse(t.state.doc.toString())}catch(e){if(!(e instanceof SyntaxError))throw e;const n=qee(e,t.state.doc);return[{from:n,message:e.message,severity:"error",to:n}]}return[]};function qee(t,e){let n;return(n=t.message.match(/at position (\d+)/))?Math.min(+n[1],e.length):(n=t.message.match(/at line (\d+) column (\d+)/))?Math.min(e.line(+n[1]).from+ +n[2]-1,e.length):0}const Fee=jf.define({name:"json",parser:Bee.configure({props:[Cx.add({Object:a7({except:/^\s*\}/}),Array:a7({except:/^\s*\]/})}),Fw.add({"Object Array":rE})]}),languageData:{closeBrackets:{brackets:["[","{",'"']},indentOnInput:/^\s*[\}\]]$/}});function Qee(){return new eE(Fee)}const $ee={name:"toml",startState:function(){return{inString:!1,stringType:"",lhs:!0,inArray:0}},token:function(t,e){let n;if(!e.inString&&(n=t.match(/^('''|"""|'|")/))&&(e.stringType=n[0],e.inString=!0),t.sol()&&!e.inString&&e.inArray===0&&(e.lhs=!0),e.inString){for(;e.inString;)if(t.match(e.stringType))e.inString=!1;else if(t.peek()==="\\")t.next(),t.next();else{if(t.eol())break;t.match(/^.[^\\\"\']*/)}return e.lhs?"property":"string"}else{if(e.inArray&&t.peek()==="]")return t.next(),e.inArray--,"bracket";if(e.lhs&&t.peek()==="["&&t.skipTo("]"))return t.next(),t.peek()==="]"&&t.next(),"atom";if(t.peek()==="#")return t.skipToEnd(),"comment";if(t.eatSpace())return null;if(e.lhs&&t.eatWhile(function(r){return r!="="&&r!=" "}))return"property";if(e.lhs&&t.peek()==="=")return t.next(),e.lhs=!1,null;if(!e.lhs&&t.match(/^\d\d\d\d[\d\-\:\.T]*Z/))return"atom";if(!e.lhs&&(t.match("true")||t.match("false")))return"atom";if(!e.lhs&&t.peek()==="[")return e.inArray++,t.next(),"bracket";if(!e.lhs&&t.match(/^\-?\d+(?:\.\d+)?/))return"number";t.eatSpace()||t.next()}return null},languageData:{commentTokens:{line:"#"}}},Hee={python:[Pee()],json:[Qee(),Iee()],toml:[Qw.define($ee)],text:[]};function Uee({value:t,onChange:e,language:n="text",readOnly:r=!1,height:s="400px",minHeight:i,maxHeight:l,placeholder:c,theme:d="dark",className:h=""}){const[m,p]=S.useState(!1);if(S.useEffect(()=>{p(!0)},[]),!m)return a.jsx("div",{className:`rounded-md border bg-muted animate-pulse ${h}`,style:{height:s,minHeight:i,maxHeight:l}});const x=[...Hee[n]||[],qe.lineWrapping];return r&&x.push(qe.editable.of(!1)),a.jsx("div",{className:`rounded-md overflow-hidden border ${h}`,children:a.jsx(C_,{value:t,height:s,minHeight:i,maxHeight:l,theme:d==="dark"?N_:void 0,extensions:x,onChange:e,placeholder:c,basicSetup:{lineNumbers:!0,highlightActiveLineGutter:!0,highlightSpecialChars:!0,history:!0,foldGutter:!0,drawSelection:!0,dropCursor:!0,allowMultipleSelections:!0,indentOnInput:!0,syntaxHighlighting:!0,bracketMatching:!0,closeBrackets:!0,autocompletion:!0,rectangularSelection:!0,crosshairCursor:!0,highlightActiveLine:!0,highlightSelectionMatches:!0,closeBracketsKeymap:!0,defaultKeymap:!0,searchKeymap:!0,historyKeymap:!0,foldKeymap:!0,completionKeymap:!0,lintKeymap:!0}})})}function Vee(){const[t,e]=S.useState(!0),[n,r]=S.useState(!1),[s,i]=S.useState(!1),[l,c]=S.useState(!1),[d,h]=S.useState(!1),[m,p]=S.useState(!1),[x,v]=S.useState("visual"),[b,k]=S.useState(""),[O,j]=S.useState(!1),{toast:T}=Pr(),[M,_]=S.useState(null),[D,E]=S.useState(null),[z,Q]=S.useState(null),[F,B]=S.useState(null),[U,V]=S.useState(null),[ce,W]=S.useState(null),[J,H]=S.useState(null),[ae,ne]=S.useState(null),[ue,R]=S.useState(null),[me,Y]=S.useState(null),[P,K]=S.useState(null),[$,fe]=S.useState(null),[ve,Re]=S.useState(null),[de,We]=S.useState(null),[ct,Oe]=S.useState(null),[nt,ut]=S.useState(null),[Ct,Bn]=S.useState(null),[Tn,Jn]=S.useState(null),nn=S.useRef(null),_t=S.useRef(!0),Yr=S.useRef({}),In=S.useCallback(async()=>{try{const re=await RU();k(re),j(!1)}catch(re){T({variant:"destructive",title:"加载失败",description:re instanceof Error?re.message:"加载源代码失败"})}},[T]),or=S.useCallback(async()=>{try{e(!0);const re=await DU();Yr.current=re,_(re.bot),E(re.personality);const Me=re.chat;Me.talk_value_rules||(Me.talk_value_rules=[]),Q(Me),B(re.expression),V(re.emoji),W(re.memory),H(re.tool),ne(re.mood),R(re.voice),Y(re.lpmm_knowledge),K(re.keyword_reaction),fe(re.response_post_process),Re(re.chinese_typo),We(re.response_splitter),Oe(re.log),ut(re.debug),Bn(re.maim_message),Jn(re.telemetry),c(!1),_t.current=!1,await In()}catch(re){console.error("加载配置失败:",re),T({title:"加载失败",description:"无法加载配置文件",variant:"destructive"})}finally{e(!1)}},[T,In]);S.useEffect(()=>{or()},[or]);const yn=S.useCallback(async(re,Me)=>{if(!_t.current)try{i(!0),await PU(re,Me),c(!1)}catch(pt){console.error(`自动保存 ${re} 失败:`,pt),c(!0)}finally{i(!1)}},[]),ft=S.useCallback((re,Me)=>{_t.current||(c(!0),nn.current&&clearTimeout(nn.current),nn.current=setTimeout(()=>{yn(re,Me)},2e3))},[yn]);S.useEffect(()=>{M&&!_t.current&&ft("bot",M)},[M,ft]),S.useEffect(()=>{D&&!_t.current&&ft("personality",D)},[D,ft]),S.useEffect(()=>{z&&!_t.current&&ft("chat",z)},[z,ft]),S.useEffect(()=>{F&&!_t.current&&ft("expression",F)},[F,ft]),S.useEffect(()=>{U&&!_t.current&&ft("emoji",U)},[U,ft]),S.useEffect(()=>{ce&&!_t.current&&ft("memory",ce)},[ce,ft]),S.useEffect(()=>{J&&!_t.current&&ft("tool",J)},[J,ft]),S.useEffect(()=>{ae&&!_t.current&&ft("mood",ae)},[ae,ft]),S.useEffect(()=>{ue&&!_t.current&&ft("voice",ue)},[ue,ft]),S.useEffect(()=>{me&&!_t.current&&ft("lpmm_knowledge",me)},[me,ft]),S.useEffect(()=>{P&&!_t.current&&ft("keyword_reaction",P)},[P,ft]),S.useEffect(()=>{$&&!_t.current&&ft("response_post_process",$)},[$,ft]),S.useEffect(()=>{ve&&!_t.current&&ft("chinese_typo",ve)},[ve,ft]),S.useEffect(()=>{de&&!_t.current&&ft("response_splitter",de)},[de,ft]),S.useEffect(()=>{ct&&!_t.current&&ft("log",ct)},[ct,ft]),S.useEffect(()=>{nt&&!_t.current&&ft("debug",nt)},[nt,ft]),S.useEffect(()=>{Ct&&!_t.current&&ft("maim_message",Ct)},[Ct,ft]),S.useEffect(()=>{Tn&&!_t.current&&ft("telemetry",Tn)},[Tn,ft]);const ee=async()=>{try{r(!0),await zU(b),c(!1),j(!1),T({title:"保存成功",description:"配置已保存"}),await or()}catch(re){j(!0),T({variant:"destructive",title:"保存失败",description:re instanceof Error?re.message:"保存配置失败"})}finally{r(!1)}},Se=async re=>{if(l){T({variant:"destructive",title:"切换失败",description:"请先保存当前更改"});return}v(re),re==="source"?await In():await or()},Le=async()=>{try{r(!0),nn.current&&clearTimeout(nn.current);const re={...Yr.current,bot:M,personality:D,chat:z,expression:F,emoji:U,memory:ce,tool:J,mood:ae,voice:ue,lpmm_knowledge:me,keyword_reaction:P,response_post_process:$,chinese_typo:ve,response_splitter:de,log:ct,debug:nt,maim_message:Ct,telemetry:Tn};await XO(re),c(!1),T({title:"保存成功",description:"麦麦主程序配置已保存"})}catch(re){console.error("保存配置失败:",re),T({title:"保存失败",description:re.message,variant:"destructive"})}finally{r(!1)}},rt=async()=>{try{h(!0),xw().catch(()=>{}),p(!0)}catch(re){console.error("重启失败:",re),p(!1),T({title:"重启失败",description:"无法发送重启请求,请手动重启",variant:"destructive"}),h(!1)}},Tt=async()=>{try{r(!0),nn.current&&clearTimeout(nn.current);const re={...Yr.current,bot:M,personality:D,chat:z,expression:F,emoji:U,memory:ce,tool:J,mood:ae,voice:ue,lpmm_knowledge:me,keyword_reaction:P,response_post_process:$,chinese_typo:ve,response_splitter:de,log:ct,debug:nt,maim_message:Ct,telemetry:Tn};await XO(re),c(!1),T({title:"保存成功",description:"配置已保存,即将重启麦麦..."}),await new Promise(Me=>setTimeout(Me,500)),await rt()}catch(re){console.error("保存失败:",re),T({title:"保存失败",description:re.message,variant:"destructive"})}finally{r(!1)}},cr=()=>{localStorage.removeItem("access-token"),window.location.href="/auth"},Kr=()=>{p(!1),h(!1),T({title:"重启失败",description:"服务器未能在预期时间内恢复,请手动检查",variant:"destructive"})};return t?a.jsx(fn,{className:"h-full",children:a.jsx("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:a.jsx("div",{className:"flex items-center justify-center h-64",children:a.jsx("p",{className:"text-muted-foreground",children:"加载中..."})})})}):a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"麦麦主程序配置"}),a.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理麦麦的核心功能和行为设置"})]}),a.jsxs("div",{className:"flex gap-2 w-full sm:w-auto items-center",children:[a.jsx(dl,{value:x,onValueChange:re=>Se(re),className:"w-auto",children:a.jsxs(va,{className:"h-9",children:[a.jsxs($t,{value:"visual",className:"text-xs sm:text-sm px-2 sm:px-3",children:[a.jsx(bq,{className:"h-3 w-3 sm:h-4 sm:w-4 mr-1"}),"可视化"]}),a.jsxs($t,{value:"source",className:"text-xs sm:text-sm px-2 sm:px-3",children:[a.jsx(wq,{className:"h-3 w-3 sm:h-4 sm:w-4 mr-1"}),"源代码"]})]})}),a.jsxs(ie,{onClick:x==="visual"?Le:ee,disabled:n||s||!l||d,size:"sm",variant:"outline",className:"flex-1 sm:flex-none",children:[a.jsx(lx,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),n?"保存中...":s?"自动保存中...":l?"保存配置":"已保存"]}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsxs(ie,{disabled:n||s||d,size:"sm",className:"flex-1 sm:flex-none",children:[a.jsx(Z4,{className:"mr-2 h-4 w-4"}),d?"重启中...":l?"保存并重启":"重启麦麦"]})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认重启麦麦?"}),a.jsx(un,{children:l?"当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。":"即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。"})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:l?Tt:rt,children:l?"保存并重启":"确认重启"})]})]})]})]})]}),a.jsxs(ld,{children:[a.jsx(oo,{className:"h-4 w-4"}),a.jsxs(od,{children:["配置更新后需要",a.jsx("strong",{children:"重启麦麦"}),'才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。']})]}),x==="source"&&a.jsxs("div",{className:"space-y-4",children:[a.jsxs(ld,{children:[a.jsx(oo,{className:"h-4 w-4"}),a.jsxs(od,{children:[a.jsx("strong",{children:"源代码模式(高级功能):"}),"直接编辑 TOML 配置文件。此功能仅适用于熟悉 TOML 语法的高级用户。保存时会在后端验证格式,只有格式完全正确才能保存。",O&&a.jsx("span",{className:"text-destructive font-semibold ml-2",children:"⚠️ 上次保存失败,请检查 TOML 格式"})]})]}),a.jsx(Uee,{value:b,onChange:re=>{k(re),c(!0),O&&j(!1)},language:"toml",theme:"dark",height:"calc(100vh - 280px)",minHeight:"500px",placeholder:"TOML 配置内容"})]}),x==="visual"&&a.jsx(a.Fragment,{children:a.jsxs(dl,{defaultValue:"bot",className:"w-full",children:[a.jsx("div",{className:"overflow-x-auto -mx-4 px-4 sm:mx-0 sm:px-0",children:a.jsxs(va,{className:"inline-flex w-auto min-w-full sm:grid sm:w-full sm:grid-cols-5 lg:grid-cols-10",children:[a.jsx($t,{value:"bot",className:"flex-shrink-0",children:"基本信息"}),a.jsx($t,{value:"personality",className:"flex-shrink-0",children:"人格"}),a.jsx($t,{value:"chat",className:"flex-shrink-0",children:"聊天"}),a.jsx($t,{value:"expression",className:"flex-shrink-0",children:"表达"}),a.jsx($t,{value:"features",className:"flex-shrink-0",children:"功能"}),a.jsx($t,{value:"processing",className:"flex-shrink-0",children:"处理"}),a.jsx($t,{value:"mood",className:"flex-shrink-0",children:"情绪"}),a.jsx($t,{value:"voice",className:"flex-shrink-0",children:"语音"}),a.jsx($t,{value:"lpmm",className:"flex-shrink-0",children:"知识库"}),a.jsx($t,{value:"other",className:"flex-shrink-0",children:"其他"})]})}),a.jsx(kn,{value:"bot",className:"space-y-4",children:M&&a.jsx(Wee,{config:M,onChange:_})}),a.jsx(kn,{value:"personality",className:"space-y-4",children:D&&a.jsx(Gee,{config:D,onChange:E})}),a.jsx(kn,{value:"chat",className:"space-y-4",children:z&&a.jsx(Xee,{config:z,onChange:Q})}),a.jsx(kn,{value:"expression",className:"space-y-4",children:F&&a.jsx(Yee,{config:F,onChange:B})}),a.jsx(kn,{value:"features",className:"space-y-4",children:U&&ce&&J&&a.jsx(Kee,{emojiConfig:U,memoryConfig:ce,toolConfig:J,onEmojiChange:V,onMemoryChange:W,onToolChange:H})}),a.jsx(kn,{value:"processing",className:"space-y-4",children:P&&$&&ve&&de&&a.jsx(Zee,{keywordReactionConfig:P,responsePostProcessConfig:$,chineseTypoConfig:ve,responseSplitterConfig:de,onKeywordReactionChange:K,onResponsePostProcessChange:fe,onChineseTypoChange:Re,onResponseSplitterChange:We})}),a.jsx(kn,{value:"mood",className:"space-y-4",children:ae&&a.jsx(Jee,{config:ae,onChange:ne})}),a.jsx(kn,{value:"voice",className:"space-y-4",children:ue&&a.jsx(ete,{config:ue,onChange:R})}),a.jsx(kn,{value:"lpmm",className:"space-y-4",children:me&&a.jsx(tte,{config:me,onChange:Y})}),a.jsxs(kn,{value:"other",className:"space-y-4",children:[ct&&a.jsx(nte,{config:ct,onChange:Oe}),nt&&a.jsx(rte,{config:nt,onChange:ut}),Ct&&a.jsx(ste,{config:Ct,onChange:Bn}),Tn&&a.jsx(ite,{config:Tn,onChange:Jn})]})]})}),m&&a.jsx(vw,{onRestartComplete:cr,onRestartFailed:Kr})]})})}function Wee({config:t,onChange:e}){const n=()=>{e({...t,platforms:[...t.platforms,""]})},r=d=>{e({...t,platforms:t.platforms.filter((h,m)=>m!==d)})},s=(d,h)=>{const m=[...t.platforms];m[d]=h,e({...t,platforms:m})},i=()=>{e({...t,alias_names:[...t.alias_names,""]})},l=d=>{e({...t,alias_names:t.alias_names.filter((h,m)=>m!==d)})},c=(d,h)=>{const m=[...t.alias_names];m[d]=h,e({...t,alias_names:m})};return a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"基本信息"}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"platform",children:"平台"}),a.jsx(Ae,{id:"platform",value:t.platform,onChange:d=>e({...t,platform:d.target.value}),placeholder:"qq"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"qq_account",children:"QQ账号"}),a.jsx(Ae,{id:"qq_account",value:t.qq_account,onChange:d=>e({...t,qq_account:d.target.value}),placeholder:"123456789"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"nickname",children:"昵称"}),a.jsx(Ae,{id:"nickname",value:t.nickname,onChange:d=>e({...t,nickname:d.target.value}),placeholder:"麦麦"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{children:"其他平台账号"}),a.jsxs(ie,{onClick:n,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加"]})]}),a.jsxs("div",{className:"space-y-2",children:[t.platforms.map((d,h)=>a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{value:d,onChange:m=>s(h,m.target.value),placeholder:"wx:114514"}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除平台账号 "',d||"(空)",'" 吗?此操作无法撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r(h),children:"删除"})]})]})]})]},h)),t.platforms.length===0&&a.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无其他平台账号"})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{children:"别名"}),a.jsxs(ie,{onClick:i,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加"]})]}),a.jsxs("div",{className:"space-y-2",children:[t.alias_names.map((d,h)=>a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{value:d,onChange:m=>c(h,m.target.value),placeholder:"小麦"}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除别名 "',d||"(空)",'" 吗?此操作无法撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>l(h),children:"删除"})]})]})]})]},h)),t.alias_names.length===0&&a.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无别名"})]})]})]})]})})}function Gee({config:t,onChange:e}){const n=()=>{e({...t,states:[...t.states,""]})},r=i=>{e({...t,states:t.states.filter((l,c)=>c!==i)})},s=(i,l)=>{const c=[...t.states];c[i]=l,e({...t,states:c})};return a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"人格设置"}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"personality",children:"人格特质"}),a.jsx(On,{id:"personality",value:t.personality,onChange:i=>e({...t,personality:i.target.value}),placeholder:"描述人格特质和身份特征(建议120字以内)",rows:3}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"建议120字以内,描述人格特质和身份特征"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"reply_style",children:"表达风格"}),a.jsx(On,{id:"reply_style",value:t.reply_style,onChange:i=>e({...t,reply_style:i.target.value}),placeholder:"描述说话的表达风格和习惯",rows:3})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"interest",children:"兴趣"}),a.jsx(On,{id:"interest",value:t.interest,onChange:i=>e({...t,interest:i.target.value}),placeholder:"会影响麦麦对什么话题进行回复",rows:2})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"plan_style",children:"说话规则与行为风格"}),a.jsx(On,{id:"plan_style",value:t.plan_style,onChange:i=>e({...t,plan_style:i.target.value}),placeholder:"麦麦的说话规则和行为风格",rows:5})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"visual_style",children:"识图规则"}),a.jsx(On,{id:"visual_style",value:t.visual_style,onChange:i=>e({...t,visual_style:i.target.value}),placeholder:"识图时的处理规则",rows:3})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"private_plan_style",children:"私聊规则"}),a.jsx(On,{id:"private_plan_style",value:t.private_plan_style,onChange:i=>e({...t,private_plan_style:i.target.value}),placeholder:"私聊的说话规则和行为风格",rows:4})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{children:"状态列表(人格多样性)"}),a.jsxs(ie,{onClick:n,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加状态"]})]}),a.jsx("div",{className:"space-y-2",children:t.states.map((i,l)=>a.jsxs("div",{className:"flex gap-2",children:[a.jsx(On,{value:i,onChange:c=>s(l,c.target.value),placeholder:"描述一个人格状态",rows:2}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsx(un,{children:"确定要删除这个人格状态吗?此操作无法撤销。"})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r(l),children:"删除"})]})]})]})]},l))})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"state_probability",children:"状态替换概率"}),a.jsx(Ae,{id:"state_probability",type:"number",step:"0.1",min:"0",max:"1",value:t.state_probability,onChange:i=>e({...t,state_probability:parseFloat(i.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"每次构建人格时替换 personality 的概率(0.0-1.0)"})]})]})]})})}function Xee({config:t,onChange:e}){const n=()=>{e({...t,talk_value_rules:[...t.talk_value_rules,{target:"",time:"00:00-23:59",value:1}]})},r=c=>{e({...t,talk_value_rules:t.talk_value_rules.filter((d,h)=>h!==c)})},s=(c,d,h)=>{const m=[...t.talk_value_rules];m[c]={...m[c],[d]:h},e({...t,talk_value_rules:m})},i=({value:c,onChange:d})=>{const[h,m]=S.useState("00"),[p,x]=S.useState("00"),[v,b]=S.useState("23"),[k,O]=S.useState("59");S.useEffect(()=>{const T=c.split("-");if(T.length===2){const[M,_]=T,[D,E]=M.split(":"),[z,Q]=_.split(":");D&&m(D.padStart(2,"0")),E&&x(E.padStart(2,"0")),z&&b(z.padStart(2,"0")),Q&&O(Q.padStart(2,"0"))}},[c]);const j=(T,M,_,D)=>{const E=`${T}:${M}-${_}:${D}`;d(E)};return a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",className:"w-full justify-start font-mono text-sm",children:[a.jsx(uc,{className:"h-4 w-4 mr-2"}),c||"选择时间段"]})}),a.jsx(hl,{className:"w-80",children:a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{children:[a.jsx("h4",{className:"font-medium text-sm mb-3",children:"开始时间"}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:gap-3",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-xs",children:"小时"}),a.jsxs(Bt,{value:h,onValueChange:T=>{m(T),j(T,p,v,k)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:Array.from({length:24},(T,M)=>M).map(T=>a.jsx(Pe,{value:T.toString().padStart(2,"0"),children:T.toString().padStart(2,"0")},T))})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-xs",children:"分钟"}),a.jsxs(Bt,{value:p,onValueChange:T=>{x(T),j(h,T,v,k)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:Array.from({length:60},(T,M)=>M).map(T=>a.jsx(Pe,{value:T.toString().padStart(2,"0"),children:T.toString().padStart(2,"0")},T))})]})]})]})]}),a.jsxs("div",{children:[a.jsx("h4",{className:"font-medium text-sm mb-3",children:"结束时间"}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:gap-3",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-xs",children:"小时"}),a.jsxs(Bt,{value:v,onValueChange:T=>{b(T),j(h,p,T,k)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:Array.from({length:24},(T,M)=>M).map(T=>a.jsx(Pe,{value:T.toString().padStart(2,"0"),children:T.toString().padStart(2,"0")},T))})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-xs",children:"分钟"}),a.jsxs(Bt,{value:k,onValueChange:T=>{O(T),j(h,p,v,T)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:Array.from({length:60},(T,M)=>M).map(T=>a.jsx(Pe,{value:T.toString().padStart(2,"0"),children:T.toString().padStart(2,"0")},T))})]})]})]})]})]})})]})},l=({rule:c})=>{const d=`{ target = "${c.target}", time = "${c.time}", value = ${c.value.toFixed(1)} }`;return a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",children:[a.jsx(Fi,{className:"h-4 w-4 mr-1"}),"预览"]})}),a.jsx(hl,{className:"w-96",children:a.jsxs("div",{className:"space-y-2",children:[a.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),a.jsx("div",{className:"rounded-md bg-muted p-3 font-mono text-xs break-all",children:d}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})};return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"聊天设置"}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"talk_value",children:"聊天频率(基础值)"}),a.jsx(Ae,{id:"talk_value",type:"number",step:"0.1",min:"0",max:"1",value:t.talk_value,onChange:c=>e({...t,talk_value:parseFloat(c.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"越小越沉默,范围 0-1"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"mentioned_bot_reply",children:"提及回复增幅"}),a.jsx(Ae,{id:"mentioned_bot_reply",type:"number",step:"0.1",min:"0",max:"1",value:t.mentioned_bot_reply,onChange:c=>e({...t,mentioned_bot_reply:parseFloat(c.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"提及时回复概率增幅,1 为 100% 回复"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"max_context_size",children:"上下文长度"}),a.jsx(Ae,{id:"max_context_size",type:"number",min:"1",value:t.max_context_size,onChange:c=>e({...t,max_context_size:parseInt(c.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"planner_smooth",children:"规划器平滑"}),a.jsx(Ae,{id:"planner_smooth",type:"number",step:"1",min:"0",value:t.planner_smooth,onChange:c=>e({...t,planner_smooth:parseFloat(c.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"增大数值会减小 planner 负荷,推荐 1-5,0 为关闭"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"enable_talk_value_rules",checked:t.enable_talk_value_rules,onCheckedChange:c=>e({...t,enable_talk_value_rules:c})}),a.jsx(te,{htmlFor:"enable_talk_value_rules",className:"cursor-pointer",children:"启用动态发言频率规则"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"include_planner_reasoning",checked:t.include_planner_reasoning,onCheckedChange:c=>e({...t,include_planner_reasoning:c})}),a.jsx(te,{htmlFor:"include_planner_reasoning",className:"cursor-pointer",children:"将 planner 推理加入 replyer"})]})]})]}),t.enable_talk_value_rules&&a.jsxs("div",{className:"border-t pt-6",children:[a.jsxs("div",{className:"flex items-center justify-between mb-4",children:[a.jsxs("div",{children:[a.jsx("h4",{className:"text-base font-semibold",children:"动态发言频率规则"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"按时段或聊天流ID调整发言频率,优先匹配具体聊天,再匹配全局规则"})]}),a.jsxs(ie,{onClick:n,size:"sm",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加规则"]})]}),t.talk_value_rules&&t.talk_value_rules.length>0?a.jsx("div",{className:"space-y-4",children:t.talk_value_rules.map((c,d)=>a.jsxs("div",{className:"rounded-lg border p-4 bg-muted/50 space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("span",{className:"text-sm font-medium text-muted-foreground",children:["规则 #",d+1]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(l,{rule:c}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{variant:"ghost",size:"sm",children:a.jsx(Ht,{className:"h-4 w-4 text-destructive"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除规则 #",d+1," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r(d),children:"删除"})]})]})]})]})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"配置类型"}),a.jsxs(Bt,{value:c.target===""?"global":"specific",onValueChange:h=>{h==="global"?s(d,"target",""):s(d,"target","qq::group")},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"global",children:"全局配置"}),a.jsx(Pe,{value:"specific",children:"详细配置"})]})]})]}),c.target!==""&&(()=>{const h=c.target.split(":"),m=h[0]||"qq",p=h[1]||"",x=h[2]||"group";return a.jsxs("div",{className:"grid gap-4 p-4 rounded-lg bg-muted/50",children:[a.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"平台"}),a.jsxs(Bt,{value:m,onValueChange:v=>{s(d,"target",`${v}:${p}:${x}`)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"qq",children:"QQ"}),a.jsx(Pe,{value:"wx",children:"微信"})]})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"群 ID"}),a.jsx(Ae,{value:p,onChange:v=>{s(d,"target",`${m}:${v.target.value}:${x}`)},placeholder:"输入群 ID",className:"font-mono text-sm"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"类型"}),a.jsxs(Bt,{value:x,onValueChange:v=>{s(d,"target",`${m}:${p}:${v}`)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"group",children:"群组(group)"}),a.jsx(Pe,{value:"private",children:"私聊(private)"})]})]})]})]}),a.jsxs("p",{className:"text-xs text-muted-foreground",children:["当前聊天流 ID:",c.target||"(未设置)"]})]})})(),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"时间段 (Time)"}),a.jsx(i,{value:c.time,onChange:h=>s(d,"time",h)}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"支持跨夜区间,例如 23:00-02:00"})]}),a.jsxs("div",{className:"grid gap-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{htmlFor:`rule-value-${d}`,className:"text-xs font-medium",children:"发言频率值 (Value)"}),a.jsx(Ae,{id:`rule-value-${d}`,type:"number",step:"0.01",min:"0",max:"1",value:c.value,onChange:h=>{const m=parseFloat(h.target.value);isNaN(m)||s(d,"value",Math.max(0,Math.min(1,m)))},className:"w-20 h-8 text-xs"})]}),a.jsx(yx,{value:[c.value],onValueChange:h=>s(d,"value",h[0]),min:0,max:1,step:.01,className:"w-full"}),a.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[a.jsx("span",{children:"0 (完全沉默)"}),a.jsx("span",{children:"0.5"}),a.jsx("span",{children:"1.0 (正常)"})]})]})]})]},d))}):a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:a.jsx("p",{className:"text-sm",children:'暂无规则,点击"添加规则"按钮创建'})}),a.jsxs("div",{className:"mt-4 p-4 bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-800 rounded-lg",children:[a.jsx("h5",{className:"text-sm font-semibold text-blue-900 dark:text-blue-100 mb-2",children:"📝 规则说明"}),a.jsxs("ul",{className:"text-xs text-blue-800 dark:text-blue-200 space-y-1",children:[a.jsxs("li",{children:["• ",a.jsx("strong",{children:"Target 为空"}),":全局规则,对所有聊天生效"]}),a.jsxs("li",{children:["• ",a.jsx("strong",{children:"Target 指定"}),":仅对特定聊天流生效(格式:platform:id:type)"]}),a.jsxs("li",{children:["• ",a.jsx("strong",{children:"优先级"}),":先匹配具体聊天流规则,再匹配全局规则"]}),a.jsxs("li",{children:["• ",a.jsx("strong",{children:"时间支持跨夜"}),":例如 23:00-02:00 表示晚上11点到次日凌晨2点"]}),a.jsxs("li",{children:["• ",a.jsx("strong",{children:"数值范围"}),":建议 0-1,0 表示完全沉默,1 表示正常发言"]})]})]})]})]})}function Yee({config:t,onChange:e}){const n=()=>{e({...t,learning_list:[...t.learning_list,["","enable","enable","1.0"]]})},r=x=>{e({...t,learning_list:t.learning_list.filter((v,b)=>b!==x)})},s=(x,v,b)=>{const k=[...t.learning_list];k[x][v]=b,e({...t,learning_list:k})},i=({rule:x})=>{const v=`["${x[0]}", "${x[1]}", "${x[2]}", "${x[3]}"]`;return a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",children:[a.jsx(Fi,{className:"h-4 w-4 mr-1"}),"预览"]})}),a.jsx(hl,{className:"w-96",children:a.jsxs("div",{className:"space-y-2",children:[a.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),a.jsx("div",{className:"rounded-md bg-muted p-3 font-mono text-xs break-all",children:v}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})},l=({member:x,groupIndex:v,memberIndex:b,availableChatIds:k})=>{const O=k.includes(x)||x==="*",[j,T]=S.useState(!O);return a.jsxs("div",{className:"flex gap-2",children:[a.jsx("div",{className:"flex-1 flex gap-2",children:j?a.jsxs(a.Fragment,{children:[a.jsx(Ae,{value:x,onChange:M=>p(v,b,M.target.value),placeholder:'输入 "*" 或 "qq:123456:group"',className:"flex-1"}),k.length>0&&a.jsx(ie,{size:"sm",variant:"outline",onClick:()=>T(!1),title:"切换到下拉选择",children:"下拉"})]}):a.jsxs(a.Fragment,{children:[a.jsxs(Bt,{value:x,onValueChange:M=>p(v,b,M),children:[a.jsx(Dt,{className:"flex-1",children:a.jsx(It,{placeholder:"选择聊天流"})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"*",children:"* (全局共享)"}),k.map((M,_)=>a.jsx(Pe,{value:M,children:M},_))]})]}),a.jsx(ie,{size:"sm",variant:"outline",onClick:()=>T(!0),title:"切换到手动输入",children:"输入"})]})}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除组成员 "',x||"(空)",'" 吗?此操作无法撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>m(v,b),children:"删除"})]})]})]})]})},c=()=>{e({...t,expression_groups:[...t.expression_groups,[]]})},d=x=>{e({...t,expression_groups:t.expression_groups.filter((v,b)=>b!==x)})},h=x=>{const v=[...t.expression_groups];v[x]=[...v[x],""],e({...t,expression_groups:v})},m=(x,v)=>{const b=[...t.expression_groups];b[x]=b[x].filter((k,O)=>O!==v),e({...t,expression_groups:b})},p=(x,v,b)=>{const k=[...t.expression_groups];k[x][v]=b,e({...t,expression_groups:k})};return a.jsxs("div",{className:"space-y-6",children:[a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-center justify-between mb-4",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold",children:"表达学习配置"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"配置麦麦如何学习和使用表达方式"})]}),a.jsxs(ie,{onClick:n,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加规则"]})]}),a.jsxs("div",{className:"space-y-4",children:[t.learning_list.map((x,v)=>{const b=t.learning_list.some((_,D)=>D!==v&&_[0]===""),k=x[0]==="",O=x[0].split(":"),j=O[0]||"qq",T=O[1]||"",M=O[2]||"group";return a.jsxs("div",{className:"rounded-lg border p-4 space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("span",{className:"text-sm font-medium",children:["规则 ",v+1," ",k&&"(全局配置)"]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(i,{rule:x}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"sm",variant:"ghost",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除学习规则 ",v+1," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r(v),children:"删除"})]})]})]})]})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"配置类型"}),a.jsxs(Bt,{value:k?"global":"specific",onValueChange:_=>{_==="global"?s(v,0,""):s(v,0,"qq::group")},disabled:b&&!k,children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"global",children:"全局配置"}),a.jsx(Pe,{value:"specific",disabled:b&&!k,children:"详细配置"})]})]}),b&&!k&&a.jsx("p",{className:"text-xs text-amber-600",children:"已存在全局配置,无法创建新的全局配置"})]}),!k&&a.jsxs("div",{className:"grid gap-4 p-4 rounded-lg bg-muted/50",children:[a.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"平台"}),a.jsxs(Bt,{value:j,onValueChange:_=>{s(v,0,`${_}:${T}:${M}`)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"qq",children:"QQ"}),a.jsx(Pe,{value:"wx",children:"微信"})]})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"群 ID"}),a.jsx(Ae,{value:T,onChange:_=>{s(v,0,`${j}:${_.target.value}:${M}`)},placeholder:"输入群 ID",className:"font-mono text-sm"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"类型"}),a.jsxs(Bt,{value:M,onValueChange:_=>{s(v,0,`${j}:${T}:${_}`)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"group",children:"群组(group)"}),a.jsx(Pe,{value:"private",children:"私聊(private)"})]})]})]})]}),a.jsxs("p",{className:"text-xs text-muted-foreground",children:["当前聊天流 ID:",x[0]||"(未设置)"]})]}),a.jsx("div",{className:"grid gap-2",children:a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-xs font-medium",children:"使用学到的表达"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"允许麦麦使用从聊天中学到的表达方式"})]}),a.jsx(jt,{checked:x[1]==="enable",onCheckedChange:_=>s(v,1,_?"enable":"disable")})]})}),a.jsx("div",{className:"grid gap-2",children:a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-xs font-medium",children:"学习表达"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"允许麦麦从聊天中学习新的表达方式"})]}),a.jsx(jt,{checked:x[2]==="enable",onCheckedChange:_=>s(v,2,_?"enable":"disable")})]})}),a.jsxs("div",{className:"grid gap-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{className:"text-xs font-medium",children:"学习强度"}),a.jsx(Ae,{type:"number",step:"0.1",min:"0",max:"5",value:x[3],onChange:_=>{const D=parseFloat(_.target.value);isNaN(D)||s(v,3,Math.max(0,Math.min(5,D)).toFixed(1))},className:"w-20 h-8 text-xs"})]}),a.jsx(yx,{value:[parseFloat(x[3])||1],onValueChange:_=>s(v,3,_[0].toFixed(1)),min:0,max:5,step:.1,className:"w-full"}),a.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[a.jsx("span",{children:"0 (不学习)"}),a.jsx("span",{children:"2.5"}),a.jsx("span",{children:"5.0 (快速学习)"})]}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"影响学习频率,最短学习间隔 = 300/学习强度(秒)"})]})]})]},v)}),t.learning_list.length===0&&a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无学习规则,点击"添加规则"开始配置'})]})]})}),a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-center justify-between mb-4",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold",children:"表达共享组配置"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"配置不同聊天流之间如何共享学到的表达方式"})]}),a.jsxs(ie,{onClick:c,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加共享组"]})]}),a.jsxs("div",{className:"space-y-4",children:[t.expression_groups.map((x,v)=>{const b=t.learning_list.map(k=>k[0]).filter(k=>k!=="");return a.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("span",{className:"text-sm font-medium",children:["共享组 ",v+1,x.length===1&&x[0]==="*"&&"(全局共享)"]}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx(ie,{onClick:()=>h(v),size:"sm",variant:"outline",children:a.jsx(Wr,{className:"h-4 w-4"})}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"sm",variant:"ghost",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除共享组 ",v+1," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>d(v),children:"删除"})]})]})]})]})]}),a.jsx("div",{className:"space-y-2",children:x.map((k,O)=>a.jsx(l,{member:k,groupIndex:v,memberIndex:O,availableChatIds:b},O))}),a.jsx("p",{className:"text-xs text-muted-foreground",children:'提示:可以从下拉框选择已配置的聊天流,或手动输入。输入 "*" 启用全局共享'})]},v)}),t.expression_groups.length===0&&a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无共享组,点击"添加共享组"开始配置'})]})]})})]})}function Kee({emojiConfig:t,memoryConfig:e,toolConfig:n,onEmojiChange:r,onMemoryChange:s,onToolChange:i}){return a.jsxs("div",{className:"space-y-6",children:[a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"工具设置"}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"enable_tool",checked:n.enable_tool,onCheckedChange:l=>i({...n,enable_tool:l})}),a.jsx(te,{htmlFor:"enable_tool",className:"cursor-pointer",children:"启用工具系统"})]}),a.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"允许麦麦使用各种工具来增强功能"})]})}),a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"记忆设置"}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"max_agent_iterations",children:"记忆思考深度"}),a.jsx(Ae,{id:"max_agent_iterations",type:"number",min:"1",value:e.max_agent_iterations,onChange:l=>s({...e,max_agent_iterations:parseInt(l.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"最低为 1(不深入思考)"})]})]})}),a.jsx("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"表情包设置"}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"emoji_chance",children:"表情包激活概率"}),a.jsx(Ae,{id:"emoji_chance",type:"number",step:"0.1",min:"0",max:"1",value:t.emoji_chance,onChange:l=>r({...t,emoji_chance:parseFloat(l.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"范围 0-1,越大越容易发送表情包"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"max_reg_num",children:"最大注册数量"}),a.jsx(Ae,{id:"max_reg_num",type:"number",min:"1",value:t.max_reg_num,onChange:l=>r({...t,max_reg_num:parseInt(l.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦最多可以注册的表情包数量"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"check_interval",children:"检查间隔(分钟)"}),a.jsx(Ae,{id:"check_interval",type:"number",min:"1",value:t.check_interval,onChange:l=>r({...t,check_interval:parseInt(l.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"检查表情包(注册、破损、删除)的时间间隔"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"do_replace",checked:t.do_replace,onCheckedChange:l=>r({...t,do_replace:l})}),a.jsx(te,{htmlFor:"do_replace",className:"cursor-pointer",children:"达到最大数量时替换表情包"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"steal_emoji",checked:t.steal_emoji,onCheckedChange:l=>r({...t,steal_emoji:l})}),a.jsx(te,{htmlFor:"steal_emoji",className:"cursor-pointer",children:"偷取表情包"})]}),a.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"允许麦麦将看到的表情包据为己有"}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"content_filtration",checked:t.content_filtration,onCheckedChange:l=>r({...t,content_filtration:l})}),a.jsx(te,{htmlFor:"content_filtration",className:"cursor-pointer",children:"启用表情包过滤"})]}),t.content_filtration&&a.jsxs("div",{className:"grid gap-2 pl-6 border-l-2 border-primary/20",children:[a.jsx(te,{htmlFor:"filtration_prompt",children:"过滤要求"}),a.jsx(Ae,{id:"filtration_prompt",value:t.filtration_prompt,onChange:l=>r({...t,filtration_prompt:l.target.value}),placeholder:"符合公序良俗"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"只有符合此要求的表情包才会被保存"})]})]})]})})]})}function Zee({keywordReactionConfig:t,responsePostProcessConfig:e,chineseTypoConfig:n,responseSplitterConfig:r,onKeywordReactionChange:s,onResponsePostProcessChange:i,onChineseTypoChange:l,onResponseSplitterChange:c}){const d=()=>{s({...t,regex_rules:[...t.regex_rules,{regex:[""],reaction:""}]})},h=_=>{s({...t,regex_rules:t.regex_rules.filter((D,E)=>E!==_)})},m=(_,D,E)=>{const z=[...t.regex_rules];D==="regex"&&typeof E=="string"?z[_]={...z[_],regex:[E]}:D==="reaction"&&typeof E=="string"&&(z[_]={...z[_],reaction:E}),s({...t,regex_rules:z})},p=({regex:_,reaction:D,onRegexChange:E,onReactionChange:z})=>{const[Q,F]=S.useState(!1),[B,U]=S.useState(""),[V,ce]=S.useState(null),[W,J]=S.useState(""),[H,ae]=S.useState({}),[ne,ue]=S.useState(""),R=S.useRef(null),[me,Y]=S.useState("build"),P=ve=>ve.replace(/\(\?P<([^>]+)>/g,"(?<$1>"),K=(ve,Re=0)=>{const de=R.current;if(!de)return;const We=de.selectionStart||0,ct=de.selectionEnd||0,Oe=_.substring(0,We)+ve+_.substring(ct);E(Oe),setTimeout(()=>{const nt=We+ve.length+Re;de.setSelectionRange(nt,nt),de.focus()},0)};S.useEffect(()=>{if(!_||!B){ce(null),ae({}),ue(D),J("");return}try{const ve=P(_),Re=new RegExp(ve,"g"),de=B.match(Re);ce(de),J("");const ct=new RegExp(ve).exec(B);if(ct&&ct.groups){ae(ct.groups);let Oe=D;Object.entries(ct.groups).forEach(([nt,ut])=>{Oe=Oe.replace(new RegExp(`\\[${nt}\\]`,"g"),ut||"")}),ue(Oe)}else ae({}),ue(D)}catch(ve){J(ve.message),ce(null),ae({}),ue(D)}},[_,B,D]);const $=()=>{if(!B||!V||V.length===0)return a.jsx("span",{className:"text-muted-foreground",children:B||"请输入测试文本"});try{const ve=P(_),Re=new RegExp(ve,"g");let de=0;const We=[];let ct;for(;(ct=Re.exec(B))!==null;)ct.index>de&&We.push(a.jsx("span",{children:B.substring(de,ct.index)},`text-${de}`)),We.push(a.jsx("span",{className:"bg-yellow-200 dark:bg-yellow-900 font-semibold",children:ct[0]},`match-${ct.index}`)),de=ct.index+ct[0].length;return de)",desc:"Python风格命名捕获组",moveCursor:-1},{label:"非捕获组",pattern:"(?:)",desc:"分组但不保存匹配结果",moveCursor:-1}]},{category:"字符类",items:[{label:"字符集",pattern:"[]",desc:"匹配括号内的任意字符",moveCursor:-1},{label:"排除字符",pattern:"[^]",desc:"匹配不在括号内的字符",moveCursor:-1},{label:"范围",pattern:"[a-z]",desc:"匹配a到z的字符"},{label:"中文字符",pattern:"[\\u4e00-\\u9fa5]",desc:"匹配中文汉字"}]},{category:"常用模板",items:[{label:"捕获词语",pattern:"(?P\\S+)",desc:"捕获一个词语"},{label:"捕获句子",pattern:"(?P.+)",desc:"捕获整个句子"},{label:"捕获数字",pattern:"(?P\\d+)",desc:"捕获一个或多个数字"},{label:"可选词语",pattern:"(?:词语1|词语2)",desc:"匹配多个可选项之一"}]}];return a.jsxs(Rr,{open:Q,onOpenChange:F,children:[a.jsx(mw,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",children:[a.jsx(fg,{className:"h-4 w-4 mr-1"}),"正则编辑器"]})}),a.jsxs(Nr,{className:"max-w-[95vw] sm:max-w-[900px] max-h-[90vh]",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"正则表达式编辑器"}),a.jsx(Gr,{className:"text-sm",children:"使用可视化工具构建正则表达式,并实时测试效果"})]}),a.jsx(fn,{className:"max-h-[calc(90vh-120px)]",children:a.jsxs(dl,{value:me,onValueChange:ve=>Y(ve),className:"w-full",children:[a.jsxs(va,{className:"grid w-full grid-cols-2",children:[a.jsx($t,{value:"build",children:"🔧 构建器"}),a.jsx($t,{value:"test",children:"🧪 测试器"})]}),a.jsxs(kn,{value:"build",className:"space-y-4 mt-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{className:"text-sm font-medium",children:"正则表达式"}),a.jsx(Ae,{ref:R,value:_,onChange:ve=>E(ve.target.value),className:"font-mono text-sm",placeholder:"点击下方按钮构建正则表达式..."})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{className:"text-sm font-medium",children:"Reaction 内容"}),a.jsx(On,{value:D,onChange:ve=>z(ve.target.value),placeholder:"使用 [捕获组名] 引用捕获的内容...",rows:3,className:"text-sm"})]}),a.jsxs("div",{className:"space-y-4 border-t pt-4",children:[fe.map(ve=>a.jsxs("div",{className:"space-y-2",children:[a.jsx("h5",{className:"text-xs font-semibold text-primary",children:ve.category}),a.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2",children:ve.items.map(Re=>a.jsx(ie,{variant:"outline",size:"sm",className:"justify-start h-auto py-2 px-3",onClick:()=>K(Re.pattern,Re.moveCursor||0),children:a.jsxs("div",{className:"flex flex-col items-start w-full",children:[a.jsxs("div",{className:"flex items-center gap-2 w-full",children:[a.jsx("span",{className:"text-xs font-medium",children:Re.label}),a.jsx("code",{className:"ml-auto text-xs bg-muted px-1.5 py-0.5 rounded font-mono",children:Re.pattern})]}),a.jsx("span",{className:"text-xs text-muted-foreground mt-0.5",children:Re.desc})]})},Re.label))})]},ve.category)),a.jsxs("div",{className:"space-y-2 border-t pt-4",children:[a.jsx("h5",{className:"text-xs font-semibold text-primary",children:"完整示例模板"}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(ie,{variant:"outline",size:"sm",className:"w-full justify-start h-auto py-2 px-3",onClick:()=>E("^(?P\\S{1,20})是这样的$"),children:a.jsxs("div",{className:"flex flex-col items-start w-full",children:[a.jsxs("code",{className:"text-xs font-mono bg-muted px-2 py-1 rounded w-full overflow-x-auto",children:["^(?P\\S","{1,20}",")是这样的$"]}),a.jsx("span",{className:"text-xs text-muted-foreground mt-1",children:"匹配「某事物是这样的」并捕获事物名称"})]})}),a.jsx(ie,{variant:"outline",size:"sm",className:"w-full justify-start h-auto py-2 px-3",onClick:()=>E("(?:[^,。.\\s]+,\\s*)?我(?:也)?[没沒]要求你\\s*(?P.+?)[.。,,]?$"),children:a.jsxs("div",{className:"flex flex-col items-start w-full",children:[a.jsx("code",{className:"text-xs font-mono bg-muted px-2 py-1 rounded w-full overflow-x-auto",children:"(?:[^,。.\\s]+,\\s*)?我(?:也)?[没沒]要求你\\s*(?P.+?)[.。,,]?$"}),a.jsx("span",{className:"text-xs text-muted-foreground mt-1",children:"匹配「我没要求你做某事」并捕获具体行为"})]})}),a.jsx(ie,{variant:"outline",size:"sm",className:"w-full justify-start h-auto py-2 px-3",onClick:()=>E("(?P.+?)(?:是|为什么|怎么)"),children:a.jsxs("div",{className:"flex flex-col items-start w-full",children:[a.jsx("code",{className:"text-xs font-mono bg-muted px-2 py-1 rounded w-full overflow-x-auto",children:"(?P.+?)(?:是|为什么|怎么)"}),a.jsx("span",{className:"text-xs text-muted-foreground mt-1",children:"捕获问题主题词"})]})})]})]})]}),a.jsxs("div",{className:"rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3 space-y-1",children:[a.jsx("p",{className:"text-xs font-medium text-blue-900 dark:text-blue-100",children:"💡 使用提示"}),a.jsxs("ul",{className:"text-xs text-blue-700 dark:text-blue-300 space-y-1 list-disc list-inside",children:[a.jsx("li",{children:"点击输入框设置光标位置,然后点击按钮插入模式"}),a.jsxs("li",{children:["命名捕获组格式:",a.jsx("code",{className:"bg-blue-100 dark:bg-blue-900 px-1 rounded",children:"(?P<名称>模式)"})]}),a.jsxs("li",{children:["在 reaction 中使用 ",a.jsx("code",{className:"bg-blue-100 dark:bg-blue-900 px-1 rounded",children:"[名称]"})," 引用捕获的内容"]}),a.jsx("li",{children:"切换到测试器标签页验证正则表达式效果"})]})]})]}),a.jsxs(kn,{value:"test",className:"space-y-4 mt-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{className:"text-sm font-medium",children:"当前正则表达式"}),a.jsx("div",{className:"rounded-md bg-muted p-3 font-mono text-xs break-all",children:_||"(未设置)"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"test-text",className:"text-sm font-medium",children:"测试文本"}),a.jsx(On,{id:"test-text",value:B,onChange:ve=>U(ve.target.value),placeholder:`在此输入要测试的文本... -例如:打游戏是这样的`,className:"min-h-[100px] text-sm"})]}),W&&a.jsxs("div",{className:"rounded-md bg-destructive/10 border border-destructive/20 p-3",children:[a.jsx("p",{className:"text-sm text-destructive font-medium",children:"正则表达式错误"}),a.jsx("p",{className:"text-xs text-destructive/80 mt-1",children:W})]}),!W&&B&&a.jsxs("div",{className:"space-y-3",children:[a.jsx("div",{className:"flex items-center gap-2",children:V&&V.length>0?a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"h-2 w-2 rounded-full bg-green-500"}),a.jsxs("span",{className:"text-sm font-medium text-green-600 dark:text-green-400",children:["匹配成功 (",V.length," 处)"]})]}):a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"h-2 w-2 rounded-full bg-gray-400"}),a.jsx("span",{className:"text-sm font-medium text-muted-foreground",children:"无匹配"})]})}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{className:"text-sm font-medium",children:"匹配高亮"}),a.jsx(fn,{className:"h-40 rounded-md bg-muted p-3",children:a.jsx("div",{className:"text-sm break-words",children:$()})})]}),Object.keys(H).length>0&&a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{className:"text-sm font-medium",children:"命名捕获组"}),a.jsx(fn,{className:"h-32 rounded-md border p-3",children:a.jsx("div",{className:"space-y-2",children:Object.entries(H).map(([ve,Re])=>a.jsxs("div",{className:"flex items-start gap-2 text-sm",children:[a.jsxs("span",{className:"font-mono font-semibold text-primary min-w-[80px]",children:["[",ve,"]"]}),a.jsx("span",{className:"text-muted-foreground",children:"="}),a.jsx("span",{className:"font-mono bg-muted px-2 py-0.5 rounded",children:Re})]},ve))})})]}),Object.keys(H).length>0&&D&&a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{className:"text-sm font-medium",children:"Reaction 替换预览"}),a.jsx(fn,{className:"h-48 rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3",children:a.jsx("div",{className:"text-sm break-words",children:ne})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"reaction 中的 [name] 已被替换为对应的捕获组值"})]})]}),a.jsxs("div",{className:"rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3 space-y-1",children:[a.jsx("p",{className:"text-xs font-medium text-blue-900 dark:text-blue-100",children:"💡 测试说明"}),a.jsxs("ul",{className:"text-xs text-blue-700 dark:text-blue-300 space-y-1 list-disc list-inside",children:[a.jsx("li",{children:"匹配的文本会以黄色背景高亮显示"}),a.jsx("li",{children:"命名捕获组的值会显示在下方列表中"}),a.jsx("li",{children:"Reaction 替换预览显示最终生成的反应内容"}),a.jsx("li",{children:"如需修改正则,切换回构建器标签页"})]})]})]})]})})]})]})},x=()=>{s({...t,keyword_rules:[...t.keyword_rules,{keywords:[],reaction:""}]})},v=_=>{s({...t,keyword_rules:t.keyword_rules.filter((D,E)=>E!==_)})},b=(_,D,E)=>{const z=[...t.keyword_rules];typeof E=="string"&&(z[_]={...z[_],reaction:E}),s({...t,keyword_rules:z})},k=_=>{const D=[...t.keyword_rules];D[_]={...D[_],keywords:[...D[_].keywords||[],""]},s({...t,keyword_rules:D})},O=(_,D)=>{const E=[...t.keyword_rules];E[_]={...E[_],keywords:(E[_].keywords||[]).filter((z,Q)=>Q!==D)},s({...t,keyword_rules:E})},j=(_,D,E)=>{const z=[...t.keyword_rules],Q=[...z[_].keywords||[]];Q[D]=E,z[_]={...z[_],keywords:Q},s({...t,keyword_rules:z})},T=({rule:_})=>{const D=`{ regex = [${(_.regex||[]).map(E=>`"${E}"`).join(", ")}], reaction = "${_.reaction}" }`;return a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",children:[a.jsx(Fi,{className:"h-4 w-4 mr-1"}),"预览"]})}),a.jsx(hl,{className:"w-[95vw] sm:w-[500px]",children:a.jsxs("div",{className:"space-y-2",children:[a.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),a.jsx(fn,{className:"h-60 rounded-md bg-muted p-3",children:a.jsx("pre",{className:"font-mono text-xs break-all",children:D})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})},M=({rule:_})=>{const D=`[[keyword_reaction.keyword_rules]] -keywords = [${(_.keywords||[]).map(E=>`"${E}"`).join(", ")}] -reaction = "${_.reaction}"`;return a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",children:[a.jsx(Fi,{className:"h-4 w-4 mr-1"}),"预览"]})}),a.jsx(hl,{className:"w-[95vw] sm:w-[500px]",children:a.jsxs("div",{className:"space-y-2",children:[a.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),a.jsx(fn,{className:"h-60 rounded-md bg-muted p-3",children:a.jsx("pre",{className:"font-mono text-xs whitespace-pre-wrap break-all",children:D})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})};return a.jsxs("div",{className:"space-y-6",children:[a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-2",children:"关键词反应配置"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"配置触发特定反应的关键词和正则表达式规则"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx("h4",{className:"text-base font-semibold",children:"正则表达式规则"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"使用正则表达式匹配消息内容"})]}),a.jsxs(ie,{onClick:d,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加正则规则"]})]}),a.jsxs("div",{className:"space-y-3",children:[t.regex_rules.map((_,D)=>a.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("span",{className:"text-sm font-medium",children:["正则规则 ",D+1]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(p,{regex:_.regex&&_.regex[0]||"",reaction:_.reaction,onRegexChange:E=>m(D,"regex",E),onReactionChange:E=>m(D,"reaction",E)}),a.jsx(T,{rule:_}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"sm",variant:"ghost",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除正则规则 ",D+1," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>h(D),children:"删除"})]})]})]})]})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"正则表达式(Python 语法)"}),a.jsx(Ae,{value:_.regex&&_.regex[0]||"",onChange:E=>m(D,"regex",E.target.value),placeholder:"例如:^(?P\\\\S{1,20})是这样的$ (点击正则编辑器按钮可视化构建)",className:"font-mono text-sm"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:'支持命名捕获组 (?Ppattern),可在 reaction 中使用 [name] 引用。点击"正则编辑器"可视化构建和测试!'})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"反应内容"}),a.jsx(On,{value:_.reaction,onChange:E=>m(D,"reaction",E.target.value),placeholder:`触发后麦麦的反应... -可以使用 [捕获组名] 来引用正则表达式中的内容`,rows:3,className:"text-sm"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"使用 [捕获组名] 引用正则表达式中的命名捕获组,例如 [n] 会被替换为捕获的内容"})]})]})]},D)),t.regex_rules.length===0&&a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无正则规则,点击"添加正则规则"开始配置'})]})]}),a.jsxs("div",{className:"space-y-4 border-t pt-6",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx("h4",{className:"text-base font-semibold",children:"关键词规则"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"使用关键词列表匹配消息内容"})]}),a.jsxs(ie,{onClick:x,size:"sm",variant:"outline",children:[a.jsx(Wr,{className:"h-4 w-4 mr-1"}),"添加关键词规则"]})]}),a.jsxs("div",{className:"space-y-3",children:[t.keyword_rules.map((_,D)=>a.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("span",{className:"text-sm font-medium",children:["关键词规则 ",D+1]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(M,{rule:_}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"sm",variant:"ghost",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除关键词规则 ",D+1," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>v(D),children:"删除"})]})]})]})]})]}),a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{className:"text-xs font-medium",children:"关键词列表"}),a.jsxs(ie,{onClick:()=>k(D),size:"sm",variant:"ghost",children:[a.jsx(Wr,{className:"h-3 w-3 mr-1"}),"添加关键词"]})]}),a.jsxs("div",{className:"space-y-2",children:[(_.keywords||[]).map((E,z)=>a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(Ae,{value:E,onChange:Q=>j(D,z,Q.target.value),placeholder:"关键词",className:"flex-1"}),a.jsx(ie,{onClick:()=>O(D,z),size:"sm",variant:"ghost",children:a.jsx(Ht,{className:"h-4 w-4"})})]},z)),(!_.keywords||_.keywords.length===0)&&a.jsx("p",{className:"text-xs text-muted-foreground text-center py-2",children:'暂无关键词,点击"添加关键词"开始配置'})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-xs font-medium",children:"反应内容"}),a.jsx(On,{value:_.reaction,onChange:E=>b(D,"reaction",E.target.value),placeholder:"触发后麦麦的反应...",rows:3,className:"text-sm"})]})]})]},D)),t.keyword_rules.length===0&&a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无关键词规则,点击"添加关键词规则"开始配置'})]})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"回复后处理配置"}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"enable_response_post_process",checked:e.enable_response_post_process,onCheckedChange:_=>i({...e,enable_response_post_process:_})}),a.jsx(te,{htmlFor:"enable_response_post_process",className:"cursor-pointer",children:"启用回复后处理"})]}),a.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"包括错别字生成器和回复分割器"})]}),e.enable_response_post_process&&a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"border-t pt-6 space-y-4",children:a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-center space-x-2 mb-4",children:[a.jsx(jt,{id:"enable_chinese_typo",checked:n.enable,onCheckedChange:_=>l({...n,enable:_})}),a.jsx(te,{htmlFor:"enable_chinese_typo",className:"cursor-pointer font-semibold",children:"中文错别字生成器"})]}),a.jsx("p",{className:"text-xs text-muted-foreground mb-4",children:"为回复添加随机错别字,让麦麦的回复更自然"}),n.enable&&a.jsxs("div",{className:"grid gap-4 pl-6 border-l-2 border-primary/20",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"error_rate",className:"text-xs font-medium",children:"单字替换概率"}),a.jsx(Ae,{id:"error_rate",type:"number",step:"0.001",min:"0",max:"1",value:n.error_rate,onChange:_=>l({...n,error_rate:parseFloat(_.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"min_freq",className:"text-xs font-medium",children:"最小字频阈值"}),a.jsx(Ae,{id:"min_freq",type:"number",min:"0",value:n.min_freq,onChange:_=>l({...n,min_freq:parseInt(_.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"tone_error_rate",className:"text-xs font-medium",children:"声调错误概率"}),a.jsx(Ae,{id:"tone_error_rate",type:"number",step:"0.01",min:"0",max:"1",value:n.tone_error_rate,onChange:_=>l({...n,tone_error_rate:parseFloat(_.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"word_replace_rate",className:"text-xs font-medium",children:"整词替换概率"}),a.jsx(Ae,{id:"word_replace_rate",type:"number",step:"0.001",min:"0",max:"1",value:n.word_replace_rate,onChange:_=>l({...n,word_replace_rate:parseFloat(_.target.value)})})]})]})]})}),a.jsx("div",{className:"border-t pt-6 space-y-4",children:a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-center space-x-2 mb-4",children:[a.jsx(jt,{id:"enable_response_splitter",checked:r.enable,onCheckedChange:_=>c({...r,enable:_})}),a.jsx(te,{htmlFor:"enable_response_splitter",className:"cursor-pointer font-semibold",children:"回复分割器"})]}),a.jsx("p",{className:"text-xs text-muted-foreground mb-4",children:"控制回复的长度和句子数量"}),r.enable&&a.jsxs("div",{className:"grid gap-4 pl-6 border-l-2 border-primary/20",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"max_length",className:"text-xs font-medium",children:"最大长度"}),a.jsx(Ae,{id:"max_length",type:"number",min:"1",value:r.max_length,onChange:_=>c({...r,max_length:parseInt(_.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"回复允许的最大字符数"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"max_sentence_num",className:"text-xs font-medium",children:"最大句子数"}),a.jsx(Ae,{id:"max_sentence_num",type:"number",min:"1",value:r.max_sentence_num,onChange:_=>c({...r,max_sentence_num:parseInt(_.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"回复允许的最大句子数量"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"enable_kaomoji_protection",checked:r.enable_kaomoji_protection,onCheckedChange:_=>c({...r,enable_kaomoji_protection:_})}),a.jsx(te,{htmlFor:"enable_kaomoji_protection",className:"cursor-pointer",children:"启用颜文字保护"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"enable_overflow_return_all",checked:r.enable_overflow_return_all,onCheckedChange:_=>c({...r,enable_overflow_return_all:_})}),a.jsx(te,{htmlFor:"enable_overflow_return_all",className:"cursor-pointer",children:"超出时一次性返回全部"})]}),a.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"当句子数量超出限制时,合并后一次性返回所有内容"})]})]})})]})]})]})}function Jee({config:t,onChange:e}){return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[a.jsx("h3",{className:"text-lg font-semibold",children:"情绪设置"}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{checked:t.enable_mood,onCheckedChange:n=>e({...t,enable_mood:n})}),a.jsx(te,{className:"cursor-pointer",children:"启用情绪系统"})]}),t.enable_mood&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"情绪更新阈值"}),a.jsx(Ae,{type:"number",min:"1",value:t.mood_update_threshold,onChange:n=>e({...t,mood_update_threshold:parseInt(n.target.value)})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"越高,更新越慢"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"情感特征"}),a.jsx(On,{value:t.emotion_style,onChange:n=>e({...t,emotion_style:n.target.value}),placeholder:"影响情绪的变化情况",rows:2})]})]})]})]})}function ete({config:t,onChange:e}){return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[a.jsx("h3",{className:"text-lg font-semibold",children:"语音设置"}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{checked:t.enable_asr,onCheckedChange:n=>e({...t,enable_asr:n})}),a.jsx(te,{className:"cursor-pointer",children:"启用语音识别"})]}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"启用后麦麦可以识别语音消息,需要配置语音识别模型"})]})}function tte({config:t,onChange:e}){return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[a.jsx("h3",{className:"text-lg font-semibold",children:"LPMM 知识库设置"}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{checked:t.enable,onCheckedChange:n=>e({...t,enable:n})}),a.jsx(te,{className:"cursor-pointer",children:"启用 LPMM 知识库"})]}),t.enable&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"LPMM 模式"}),a.jsxs(Bt,{value:t.lpmm_mode,onValueChange:n=>e({...t,lpmm_mode:n}),children:[a.jsx(Dt,{children:a.jsx(It,{placeholder:"选择 LPMM 模式"})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"classic",children:"经典模式"}),a.jsx(Pe,{value:"agent",children:"Agent 模式"})]})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"同义词搜索 TopK"}),a.jsx(Ae,{type:"number",min:"1",value:t.rag_synonym_search_top_k,onChange:n=>e({...t,rag_synonym_search_top_k:parseInt(n.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"同义词阈值"}),a.jsx(Ae,{type:"number",step:"0.1",min:"0",max:"1",value:t.rag_synonym_threshold,onChange:n=>e({...t,rag_synonym_threshold:parseFloat(n.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"实体提取线程数"}),a.jsx(Ae,{type:"number",min:"1",value:t.info_extraction_workers,onChange:n=>e({...t,info_extraction_workers:parseInt(n.target.value)})})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"嵌入向量维度"}),a.jsx(Ae,{type:"number",min:"1",value:t.embedding_dimension,onChange:n=>e({...t,embedding_dimension:parseInt(n.target.value)})})]})]})]})]})]})}function nte({config:t,onChange:e}){const[n,r]=S.useState(""),[s,i]=S.useState("WARNING"),l=()=>{n&&!t.suppress_libraries.includes(n)&&(e({...t,suppress_libraries:[...t.suppress_libraries,n]}),r(""))},c=v=>{e({...t,suppress_libraries:t.suppress_libraries.filter(b=>b!==v)})},d=()=>{n&&!t.library_log_levels[n]&&(e({...t,library_log_levels:{...t.library_log_levels,[n]:s}}),r(""),i("WARNING"))},h=v=>{const b={...t.library_log_levels};delete b[v],e({...t,library_log_levels:b})},m=["DEBUG","INFO","WARNING","ERROR","CRITICAL"],p=["FULL","compact","lite"],x=["none","title","full"];return a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"日志配置"}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"日期格式"}),a.jsx(Ae,{value:t.date_style,onChange:v=>e({...t,date_style:v.target.value}),placeholder:"例如: m-d H:i:s"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"m=月, d=日, H=时, i=分, s=秒"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"日志级别样式"}),a.jsxs(Bt,{value:t.log_level_style,onValueChange:v=>e({...t,log_level_style:v}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:p.map(v=>a.jsx(Pe,{value:v,children:v},v))})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"日志文本颜色"}),a.jsxs(Bt,{value:t.color_text,onValueChange:v=>e({...t,color_text:v}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:x.map(v=>a.jsx(Pe,{value:v,children:v},v))})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"全局日志级别"}),a.jsxs(Bt,{value:t.log_level,onValueChange:v=>e({...t,log_level:v}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:m.map(v=>a.jsx(Pe,{value:v,children:v},v))})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"控制台日志级别"}),a.jsxs(Bt,{value:t.console_log_level,onValueChange:v=>e({...t,console_log_level:v}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:m.map(v=>a.jsx(Pe,{value:v,children:v},v))})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"文件日志级别"}),a.jsxs(Bt,{value:t.file_log_level,onValueChange:v=>e({...t,file_log_level:v}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsx(Rt,{children:m.map(v=>a.jsx(Pe,{value:v,children:v},v))})]})]})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"mb-2 block",children:"完全屏蔽的库"}),a.jsxs("div",{className:"flex gap-2 mb-2",children:[a.jsx(Ae,{value:n,onChange:v=>r(v.target.value),placeholder:"输入库名",className:"flex-1",onKeyDown:v=>{v.key==="Enter"&&(v.preventDefault(),l())}}),a.jsx(ie,{onClick:l,size:"sm",className:"flex-shrink-0",children:a.jsx(Wr,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),a.jsx("div",{className:"flex flex-wrap gap-2",children:t.suppress_libraries.map(v=>a.jsxs("div",{className:"flex items-center gap-1 bg-secondary px-3 py-1 rounded-md",children:[a.jsx("span",{className:"text-sm",children:v}),a.jsx(ie,{variant:"ghost",size:"sm",className:"h-5 w-5 p-0",onClick:()=>c(v),children:a.jsx(Ht,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]},v))})]}),a.jsxs("div",{children:[a.jsx(te,{className:"mb-2 block",children:"特定库的日志级别"}),a.jsxs("div",{className:"flex gap-2 mb-2",children:[a.jsx(Ae,{value:n,onChange:v=>r(v.target.value),placeholder:"输入库名",className:"flex-1"}),a.jsxs(Bt,{value:s,onValueChange:i,children:[a.jsx(Dt,{className:"w-32",children:a.jsx(It,{})}),a.jsx(Rt,{children:m.map(v=>a.jsx(Pe,{value:v,children:v},v))})]}),a.jsx(ie,{onClick:d,size:"sm",children:a.jsx(Wr,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),a.jsx("div",{className:"space-y-2",children:Object.entries(t.library_log_levels).map(([v,b])=>a.jsxs("div",{className:"flex items-center justify-between bg-secondary px-3 py-2 rounded-md",children:[a.jsx("span",{className:"text-sm font-medium",children:v}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"text-sm text-muted-foreground",children:b}),a.jsx(ie,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0",onClick:()=>h(v),children:a.jsx(Ht,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]})]},v))})]})]})}function rte({config:t,onChange:e}){return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[a.jsx("h3",{className:"text-lg font-semibold",children:"调试配置"}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5",children:[a.jsx(te,{children:"显示 Prompt"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"是否在日志中显示提示词"})]}),a.jsx(jt,{checked:t.show_prompt,onCheckedChange:n=>e({...t,show_prompt:n})})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5",children:[a.jsx(te,{children:"显示回复器 Prompt"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示回复器的提示词"})]}),a.jsx(jt,{checked:t.show_replyer_prompt,onCheckedChange:n=>e({...t,show_replyer_prompt:n})})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5",children:[a.jsx(te,{children:"显示回复器推理"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示回复器的推理过程"})]}),a.jsx(jt,{checked:t.show_replyer_reasoning,onCheckedChange:n=>e({...t,show_replyer_reasoning:n})})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5",children:[a.jsx(te,{children:"显示 Jargon Prompt"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示术语相关的提示词"})]}),a.jsx(jt,{checked:t.show_jargon_prompt,onCheckedChange:n=>e({...t,show_jargon_prompt:n})})]})]})]})}function ste({config:t,onChange:e}){const[n,r]=S.useState(""),s=()=>{n&&!t.auth_token.includes(n)&&(e({...t,auth_token:[...t.auth_token,n]}),r(""))},i=l=>{e({...t,auth_token:t.auth_token.filter((c,d)=>d!==l)})};return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-6",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-lg font-semibold mb-4",children:"MaimMessage 服务配置"}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5",children:[a.jsx(te,{children:"启用自定义服务器"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"是否使用自定义的 MaimMessage 服务器"})]}),a.jsx(jt,{checked:t.use_custom,onCheckedChange:l=>e({...t,use_custom:l})})]}),t.use_custom&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"主机地址"}),a.jsx(Ae,{value:t.host,onChange:l=>e({...t,host:l.target.value}),placeholder:"127.0.0.1"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"端口号"}),a.jsx(Ae,{type:"number",value:t.port,onChange:l=>e({...t,port:parseInt(l.target.value)}),placeholder:"8090"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"连接模式"}),a.jsxs(Bt,{value:t.mode,onValueChange:l=>e({...t,mode:l}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"ws",children:"WebSocket (ws)"}),a.jsx(Pe,{value:"tcp",children:"TCP"})]})]})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{checked:t.use_wss,onCheckedChange:l=>e({...t,use_wss:l}),disabled:t.mode!=="ws"}),a.jsx(te,{children:"使用 WSS 安全连接"})]})]}),t.use_wss&&t.mode==="ws"&&a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"SSL 证书文件路径"}),a.jsx(Ae,{value:t.cert_file,onChange:l=>e({...t,cert_file:l.target.value}),placeholder:"cert.pem"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"SSL 密钥文件路径"}),a.jsx(Ae,{value:t.key_file,onChange:l=>e({...t,key_file:l.target.value}),placeholder:"key.pem"})]})]})]})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"mb-2 block",children:"认证令牌"}),a.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"用于 API 验证,为空则不启用验证"}),a.jsxs("div",{className:"flex gap-2 mb-2",children:[a.jsx(Ae,{value:n,onChange:l=>r(l.target.value),placeholder:"输入认证令牌",onKeyDown:l=>{l.key==="Enter"&&(l.preventDefault(),s())}}),a.jsx(ie,{onClick:s,size:"sm",children:a.jsx(Wr,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),a.jsx("div",{className:"space-y-2",children:t.auth_token.map((l,c)=>a.jsxs("div",{className:"flex items-center justify-between bg-secondary px-3 py-2 rounded-md",children:[a.jsx("span",{className:"text-sm font-mono",children:l}),a.jsx(ie,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0",onClick:()=>i(c),children:a.jsx(Ht,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]},c))})]})]})}function ite({config:t,onChange:e}){return a.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[a.jsx("h3",{className:"text-lg font-semibold",children:"统计信息"}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"space-y-0.5",children:[a.jsx(te,{children:"启用统计信息发送"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"发送匿名统计信息,帮助我们了解全球有多少只麦麦在运行"})]}),a.jsx(jt,{checked:t.enable,onCheckedChange:n=>e({...t,enable:n})})]})]})}const Ac=S.forwardRef(({className:t,...e},n)=>a.jsx("div",{className:"relative w-full overflow-auto",children:a.jsx("table",{ref:n,className:ye("w-full caption-bottom text-sm",t),...e})}));Ac.displayName="Table";const Ec=S.forwardRef(({className:t,...e},n)=>a.jsx("thead",{ref:n,className:ye("[&_tr]:border-b",t),...e}));Ec.displayName="TableHeader";const _c=S.forwardRef(({className:t,...e},n)=>a.jsx("tbody",{ref:n,className:ye("[&_tr:last-child]:border-0",t),...e}));_c.displayName="TableBody";const ate=S.forwardRef(({className:t,...e},n)=>a.jsx("tfoot",{ref:n,className:ye("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",t),...e}));ate.displayName="TableFooter";const xr=S.forwardRef(({className:t,...e},n)=>a.jsx("tr",{ref:n,className:ye("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",t),...e}));xr.displayName="TableRow";const gt=S.forwardRef(({className:t,...e},n)=>a.jsx("th",{ref:n,className:ye("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",t),...e}));gt.displayName="TableHead";const it=S.forwardRef(({className:t,...e},n)=>a.jsx("td",{ref:n,className:ye("px-4 py-3 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",t),...e}));it.displayName="TableCell";const lte=S.forwardRef(({className:t,...e},n)=>a.jsx("caption",{ref:n,className:ye("mt-4 text-sm text-muted-foreground",t),...e}));lte.displayName="TableCaption";const ss=S.forwardRef(({className:t,...e},n)=>a.jsx(M9,{ref:n,className:ye("grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",t),...e,children:a.jsx(rq,{className:ye("grid place-content-center text-current"),children:a.jsx(hc,{className:"h-4 w-4"})})}));ss.displayName=M9.displayName;function ote(){const[t,e]=S.useState([]),[n,r]=S.useState(!0),[s,i]=S.useState(!1),[l,c]=S.useState(!1),[d,h]=S.useState(!1),[m,p]=S.useState(!1),[x,v]=S.useState(!1),[b,k]=S.useState(!1),[O,j]=S.useState(null),[T,M]=S.useState(null),[_,D]=S.useState(!1),[E,z]=S.useState(null),[Q,F]=S.useState(!1),[B,U]=S.useState(""),[V,ce]=S.useState(new Set),[W,J]=S.useState(!1),[H,ae]=S.useState(1),[ne,ue]=S.useState(20),[R,me]=S.useState(""),{toast:Y}=Pr(),P=S.useRef(null),K=S.useRef(!0);S.useEffect(()=>{$()},[]);const $=async()=>{try{r(!0);const ee=await Vu();e(ee.api_providers||[]),h(!1),K.current=!1}catch(ee){console.error("加载配置失败:",ee)}finally{r(!1)}},fe=async()=>{try{p(!0),xw().catch(()=>{}),v(!0)}catch(ee){console.error("重启失败:",ee),v(!1),Y({title:"重启失败",description:"无法发送重启请求,请手动重启",variant:"destructive"}),p(!1)}},ve=async()=>{try{i(!0),P.current&&clearTimeout(P.current);const ee=await Vu();ee.api_providers=t,await wg(ee),h(!1),Y({title:"保存成功",description:"正在重启麦麦..."}),await fe()}catch(ee){console.error("保存配置失败:",ee),Y({title:"保存失败",description:ee.message,variant:"destructive"}),i(!1)}},Re=()=>{localStorage.removeItem("access-token"),window.location.href="/auth"},de=()=>{v(!1),p(!1),Y({title:"重启超时",description:"服务未能在预期时间内恢复,请手动检查或刷新页面",variant:"destructive"})},We=S.useCallback(async ee=>{if(!K.current)try{c(!0),await h2("api_providers",ee),h(!1)}catch(Se){console.error("自动保存失败:",Se),h(!0)}finally{c(!1)}},[]);S.useEffect(()=>{if(!K.current)return h(!0),P.current&&clearTimeout(P.current),P.current=setTimeout(()=>{We(t)},2e3),()=>{P.current&&clearTimeout(P.current)}},[t,We]);const ct=async()=>{try{i(!0),P.current&&clearTimeout(P.current);const ee=await Vu();ee.api_providers=t,await wg(ee),h(!1),Y({title:"保存成功",description:"模型提供商配置已保存"})}catch(ee){console.error("保存配置失败:",ee),Y({title:"保存失败",description:ee.message,variant:"destructive"})}finally{i(!1)}},Oe=(ee,Se)=>{j(ee||{name:"",base_url:"",api_key:"",client_type:"openai",max_retry:2,timeout:30,retry_interval:10}),M(Se),F(!1),k(!0)},nt=async()=>{if(O?.api_key)try{await navigator.clipboard.writeText(O.api_key),Y({title:"复制成功",description:"API Key 已复制到剪贴板"})}catch{Y({title:"复制失败",description:"无法访问剪贴板",variant:"destructive"})}},ut=()=>{if(!O)return;const ee={...O,max_retry:O.max_retry??2,timeout:O.timeout??30,retry_interval:O.retry_interval??10};if(T!==null){const Se=[...t];Se[T]=ee,e(Se)}else e([...t,ee]);k(!1),j(null),M(null)},Ct=ee=>{if(!ee&&O){const Se={...O,max_retry:O.max_retry??2,timeout:O.timeout??30,retry_interval:O.retry_interval??10};j(Se)}k(ee)},Bn=ee=>{z(ee),D(!0)},Tn=()=>{if(E!==null){const ee=t.filter((Se,Le)=>Le!==E);e(ee),Y({title:"删除成功",description:"提供商已从列表中移除"})}D(!1),z(null)},Jn=ee=>{const Se=new Set(V);Se.has(ee)?Se.delete(ee):Se.add(ee),ce(Se)},nn=()=>{if(V.size===In.length)ce(new Set);else{const ee=In.map((Se,Le)=>t.findIndex(rt=>rt===In[Le]));ce(new Set(ee))}},_t=()=>{if(V.size===0){Y({title:"提示",description:"请先选择要删除的提供商",variant:"default"});return}J(!0)},Yr=()=>{const ee=t.filter((Se,Le)=>!V.has(Le));e(ee),ce(new Set),J(!1),Y({title:"批量删除成功",description:`已删除 ${V.size} 个提供商`})},In=t.filter(ee=>{if(!B)return!0;const Se=B.toLowerCase();return ee.name.toLowerCase().includes(Se)||ee.base_url.toLowerCase().includes(Se)||ee.client_type.toLowerCase().includes(Se)}),or=Math.ceil(In.length/ne),yn=In.slice((H-1)*ne,H*ne),ft=()=>{const ee=parseInt(R);ee>=1&&ee<=or&&(ae(ee),me(""))};return n?a.jsx("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:a.jsx("div",{className:"flex items-center justify-center h-64",children:a.jsx("p",{className:"text-muted-foreground",children:"加载中..."})})}):a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"模型提供商配置"}),a.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理 API 提供商配置"})]}),a.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[V.size>0&&a.jsxs(ie,{onClick:_t,size:"sm",variant:"destructive",className:"w-full sm:w-auto",children:[a.jsx(Ht,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"批量删除 (",V.size,")"]}),a.jsxs(ie,{onClick:()=>Oe(null,null),size:"sm",className:"w-full sm:w-auto",children:[a.jsx(Wr,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"添加提供商"]}),a.jsxs(ie,{onClick:ct,disabled:s||l||!d||m,size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[a.jsx(lx,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),s?"保存中...":l?"自动保存中...":d?"保存配置":"已保存"]}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsxs(ie,{disabled:s||l||m,size:"sm",className:"w-full sm:w-auto",children:[a.jsx(Z4,{className:"mr-2 h-4 w-4"}),m?"重启中...":d?"保存并重启":"重启麦麦"]})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认重启麦麦?"}),a.jsx(un,{children:d?"当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。":"即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。"})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:d?ve:fe,children:d?"保存并重启":"确认重启"})]})]})]})]})]}),a.jsxs(ld,{children:[a.jsx(oo,{className:"h-4 w-4"}),a.jsxs(od,{children:["配置更新后需要",a.jsx("strong",{children:"重启麦麦"}),'才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。']})]}),a.jsxs(fn,{className:"h-[calc(100vh-260px)]",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center gap-2 mb-4",children:[a.jsxs("div",{className:"relative w-full sm:flex-1 sm:max-w-sm",children:[a.jsx(Ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{placeholder:"搜索提供商名称、URL 或类型...",value:B,onChange:ee=>U(ee.target.value),className:"pl-9"})]}),B&&a.jsxs("p",{className:"text-sm text-muted-foreground whitespace-nowrap",children:["找到 ",In.length," 个结果"]})]}),a.jsx("div",{className:"md:hidden space-y-3",children:In.length===0?a.jsx("div",{className:"text-center text-muted-foreground py-8 rounded-lg border bg-card",children:B?"未找到匹配的提供商":'暂无提供商配置,点击"添加提供商"开始配置'}):yn.map((ee,Se)=>{const Le=t.findIndex(rt=>rt===ee);return a.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3",children:[a.jsxs("div",{className:"flex items-start justify-between gap-2",children:[a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("h3",{className:"font-semibold text-base truncate",children:ee.name}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1 break-all",children:ee.base_url})]}),a.jsxs("div",{className:"flex gap-1 flex-shrink-0",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>Oe(ee,Le),children:[a.jsx(nd,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),a.jsxs(ie,{size:"sm",onClick:()=>Bn(Le),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"客户端类型"}),a.jsx("p",{className:"font-medium",children:ee.client_type})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"最大重试"}),a.jsx("p",{className:"font-medium",children:ee.max_retry})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"超时(秒)"}),a.jsx("p",{className:"font-medium",children:ee.timeout})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"重试间隔(秒)"}),a.jsx("p",{className:"font-medium",children:ee.retry_interval})]})]})]},Se)})}),a.jsx("div",{className:"hidden md:block rounded-lg border bg-card overflow-hidden",children:a.jsxs(Ac,{children:[a.jsx(Ec,{children:a.jsxs(xr,{children:[a.jsx(gt,{className:"w-12",children:a.jsx(ss,{checked:V.size===In.length&&In.length>0,onCheckedChange:nn})}),a.jsx(gt,{children:"名称"}),a.jsx(gt,{children:"基础URL"}),a.jsx(gt,{children:"客户端类型"}),a.jsx(gt,{className:"text-right",children:"最大重试"}),a.jsx(gt,{className:"text-right",children:"超时(秒)"}),a.jsx(gt,{className:"text-right",children:"重试间隔(秒)"}),a.jsx(gt,{className:"text-right",children:"操作"})]})}),a.jsx(_c,{children:yn.length===0?a.jsx(xr,{children:a.jsx(it,{colSpan:8,className:"text-center text-muted-foreground py-8",children:B?"未找到匹配的提供商":'暂无提供商配置,点击"添加提供商"开始配置'})}):yn.map((ee,Se)=>{const Le=t.findIndex(rt=>rt===ee);return a.jsxs(xr,{children:[a.jsx(it,{children:a.jsx(ss,{checked:V.has(Le),onCheckedChange:()=>Jn(Le)})}),a.jsx(it,{className:"font-medium",children:ee.name}),a.jsx(it,{className:"max-w-xs truncate",title:ee.base_url,children:ee.base_url}),a.jsx(it,{children:ee.client_type}),a.jsx(it,{className:"text-right",children:ee.max_retry}),a.jsx(it,{className:"text-right",children:ee.timeout}),a.jsx(it,{className:"text-right",children:ee.retry_interval}),a.jsx(it,{className:"text-right",children:a.jsxs("div",{className:"flex justify-end gap-2",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>Oe(ee,Le),children:[a.jsx(nd,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),a.jsxs(ie,{size:"sm",onClick:()=>Bn(Le),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})})]},Se)})})]})}),In.length>0&&a.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(te,{htmlFor:"page-size-provider",className:"text-sm whitespace-nowrap",children:"每页显示"}),a.jsxs(Bt,{value:ne.toString(),onValueChange:ee=>{ue(parseInt(ee)),ae(1),ce(new Set)},children:[a.jsx(Dt,{id:"page-size-provider",className:"w-20",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"10",children:"10"}),a.jsx(Pe,{value:"20",children:"20"}),a.jsx(Pe,{value:"50",children:"50"}),a.jsx(Pe,{value:"100",children:"100"})]})]}),a.jsxs("span",{className:"text-sm text-muted-foreground",children:["显示 ",(H-1)*ne+1," 到"," ",Math.min(H*ne,In.length)," 条,共 ",In.length," 条"]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>ae(1),disabled:H===1,className:"hidden sm:flex",children:a.jsx(Xf,{className:"h-4 w-4"})}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>ae(ee=>Math.max(1,ee-1)),disabled:H===1,children:[a.jsx(Tc,{className:"h-4 w-4 sm:mr-1"}),a.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(Ae,{type:"number",value:R,onChange:ee=>me(ee.target.value),onKeyDown:ee=>ee.key==="Enter"&&ft(),placeholder:H.toString(),className:"w-16 h-8 text-center",min:1,max:or}),a.jsx(ie,{variant:"outline",size:"sm",onClick:ft,disabled:!R,className:"h-8",children:"跳转"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>ae(ee=>ee+1),disabled:H>=or,children:[a.jsx("span",{className:"hidden sm:inline",children:"下一页"}),a.jsx(Mc,{className:"h-4 w-4 sm:ml-1"})]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>ae(or),disabled:H>=or,className:"hidden sm:flex",children:a.jsx(Yf,{className:"h-4 w-4"})})]})]})]}),a.jsx(Rr,{open:b,onOpenChange:Ct,children:a.jsxs(Nr,{className:"max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:T!==null?"编辑提供商":"添加提供商"}),a.jsx(Gr,{children:"配置 API 提供商的连接信息和参数"})]}),a.jsxs("div",{className:"grid gap-4 py-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"name",children:"名称 *"}),a.jsx(Ae,{id:"name",value:O?.name||"",onChange:ee=>j(Se=>Se?{...Se,name:ee.target.value}:null),placeholder:"例如: DeepSeek, SiliconFlow"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"base_url",children:"基础 URL *"}),a.jsx(Ae,{id:"base_url",value:O?.base_url||"",onChange:ee=>j(Se=>Se?{...Se,base_url:ee.target.value}:null),placeholder:"https://api.example.com/v1"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"api_key",children:"API Key *"}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{id:"api_key",type:Q?"text":"password",value:O?.api_key||"",onChange:ee=>j(Se=>Se?{...Se,api_key:ee.target.value}:null),placeholder:"sk-...",className:"flex-1"}),a.jsx(ie,{type:"button",variant:"outline",size:"icon",onClick:()=>F(!Q),title:Q?"隐藏密钥":"显示密钥",children:Q?a.jsx(Yb,{className:"h-4 w-4"}):a.jsx(Fi,{className:"h-4 w-4"})}),a.jsx(ie,{type:"button",variant:"outline",size:"icon",onClick:nt,title:"复制密钥",children:a.jsx(Xb,{className:"h-4 w-4"})})]})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"client_type",children:"客户端类型"}),a.jsxs(Bt,{value:O?.client_type||"openai",onValueChange:ee=>j(Se=>Se?{...Se,client_type:ee}:null),children:[a.jsx(Dt,{id:"client_type",children:a.jsx(It,{placeholder:"选择客户端类型"})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"openai",children:"OpenAI"}),a.jsx(Pe,{value:"gemini",children:"Gemini"})]})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"max_retry",children:"最大重试"}),a.jsx(Ae,{id:"max_retry",type:"number",min:"0",value:O?.max_retry??"",onChange:ee=>{const Se=ee.target.value===""?null:parseInt(ee.target.value);j(Le=>Le?{...Le,max_retry:Se}:null)},placeholder:"默认: 2"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"timeout",children:"超时(秒)"}),a.jsx(Ae,{id:"timeout",type:"number",min:"1",value:O?.timeout??"",onChange:ee=>{const Se=ee.target.value===""?null:parseInt(ee.target.value);j(Le=>Le?{...Le,timeout:Se}:null)},placeholder:"默认: 30"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"retry_interval",children:"重试间隔(秒)"}),a.jsx(Ae,{id:"retry_interval",type:"number",min:"1",value:O?.retry_interval??"",onChange:ee=>{const Se=ee.target.value===""?null:parseInt(ee.target.value);j(Le=>Le?{...Le,retry_interval:Se}:null)},placeholder:"默认: 10"})]})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>k(!1),children:"取消"}),a.jsx(ie,{onClick:ut,children:"保存"})]})]})}),a.jsx(mn,{open:_,onOpenChange:D,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除提供商 "',E!==null?t[E]?.name:"",'" 吗? 此操作无法撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:Tn,children:"删除"})]})]})}),a.jsx(mn,{open:W,onOpenChange:J,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认批量删除"}),a.jsxs(un,{children:["确定要删除选中的 ",V.size," 个提供商吗? 此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:Yr,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"批量删除"})]})]})}),x&&a.jsx(vw,{onRestartComplete:Re,onRestartFailed:de})]})}var a8=1,cte=.9,ute=.8,dte=.17,cb=.1,ub=.999,hte=.9999,fte=.99,mte=/[\\\/_+.#"@\[\(\{&]/,pte=/[\\\/_+.#"@\[\(\{&]/g,gte=/[\s-]/,B_=/[\s-]/g;function u4(t,e,n,r,s,i,l){if(i===e.length)return s===t.length?a8:fte;var c=`${s},${i}`;if(l[c]!==void 0)return l[c];for(var d=r.charAt(i),h=n.indexOf(d,s),m=0,p,x,v,b;h>=0;)p=u4(t,e,n,r,h+1,i+1,l),p>m&&(h===s?p*=a8:mte.test(t.charAt(h-1))?(p*=ute,v=t.slice(s,h-1).match(pte),v&&s>0&&(p*=Math.pow(ub,v.length))):gte.test(t.charAt(h-1))?(p*=cte,b=t.slice(s,h-1).match(B_),b&&s>0&&(p*=Math.pow(ub,b.length))):(p*=dte,s>0&&(p*=Math.pow(ub,h-s))),t.charAt(h)!==e.charAt(i)&&(p*=hte)),(pp&&(p=x*cb)),p>m&&(m=p),h=n.indexOf(d,h+1);return l[c]=m,m}function l8(t){return t.toLowerCase().replace(B_," ")}function xte(t,e,n){return t=n&&n.length>0?`${t+" "+n.join(" ")}`:t,u4(t,e,l8(t),l8(e),0,0,{})}var vte=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Co=vte.reduce((t,e)=>{const n=Q4(`Primitive.${e}`),r=S.forwardRef((s,i)=>{const{asChild:l,...c}=s,d=l?n:e;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),a.jsx(d,{...c,ref:i})});return r.displayName=`Primitive.${e}`,{...t,[e]:r}},{}),Lh='[cmdk-group=""]',db='[cmdk-group-items=""]',yte='[cmdk-group-heading=""]',I_='[cmdk-item=""]',o8=`${I_}:not([aria-disabled="true"])`,d4="cmdk-item-select",Pu="data-value",bte=(t,e,n)=>xte(t,e,n),q_=S.createContext(void 0),g0=()=>S.useContext(q_),F_=S.createContext(void 0),o5=()=>S.useContext(F_),Q_=S.createContext(void 0),$_=S.forwardRef((t,e)=>{let n=Lu(()=>{var Y,P;return{search:"",value:(P=(Y=t.value)!=null?Y:t.defaultValue)!=null?P:"",selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}}}),r=Lu(()=>new Set),s=Lu(()=>new Map),i=Lu(()=>new Map),l=Lu(()=>new Set),c=H_(t),{label:d,children:h,value:m,onValueChange:p,filter:x,shouldFilter:v,loop:b,disablePointerSelection:k=!1,vimBindings:O=!0,...j}=t,T=Oi(),M=Oi(),_=Oi(),D=S.useRef(null),E=Ete();Nc(()=>{if(m!==void 0){let Y=m.trim();n.current.value=Y,z.emit()}},[m]),Nc(()=>{E(6,ce)},[]);let z=S.useMemo(()=>({subscribe:Y=>(l.current.add(Y),()=>l.current.delete(Y)),snapshot:()=>n.current,setState:(Y,P,K)=>{var $,fe,ve,Re;if(!Object.is(n.current[Y],P)){if(n.current[Y]=P,Y==="search")V(),B(),E(1,U);else if(Y==="value"){if(document.activeElement.hasAttribute("cmdk-input")||document.activeElement.hasAttribute("cmdk-root")){let de=document.getElementById(_);de?de.focus():($=document.getElementById(T))==null||$.focus()}if(E(7,()=>{var de;n.current.selectedItemId=(de=W())==null?void 0:de.id,z.emit()}),K||E(5,ce),((fe=c.current)==null?void 0:fe.value)!==void 0){let de=P??"";(Re=(ve=c.current).onValueChange)==null||Re.call(ve,de);return}}z.emit()}},emit:()=>{l.current.forEach(Y=>Y())}}),[]),Q=S.useMemo(()=>({value:(Y,P,K)=>{var $;P!==(($=i.current.get(Y))==null?void 0:$.value)&&(i.current.set(Y,{value:P,keywords:K}),n.current.filtered.items.set(Y,F(P,K)),E(2,()=>{B(),z.emit()}))},item:(Y,P)=>(r.current.add(Y),P&&(s.current.has(P)?s.current.get(P).add(Y):s.current.set(P,new Set([Y]))),E(3,()=>{V(),B(),n.current.value||U(),z.emit()}),()=>{i.current.delete(Y),r.current.delete(Y),n.current.filtered.items.delete(Y);let K=W();E(4,()=>{V(),K?.getAttribute("id")===Y&&U(),z.emit()})}),group:Y=>(s.current.has(Y)||s.current.set(Y,new Set),()=>{i.current.delete(Y),s.current.delete(Y)}),filter:()=>c.current.shouldFilter,label:d||t["aria-label"],getDisablePointerSelection:()=>c.current.disablePointerSelection,listId:T,inputId:_,labelId:M,listInnerRef:D}),[]);function F(Y,P){var K,$;let fe=($=(K=c.current)==null?void 0:K.filter)!=null?$:bte;return Y?fe(Y,n.current.search,P):0}function B(){if(!n.current.search||c.current.shouldFilter===!1)return;let Y=n.current.filtered.items,P=[];n.current.filtered.groups.forEach($=>{let fe=s.current.get($),ve=0;fe.forEach(Re=>{let de=Y.get(Re);ve=Math.max(de,ve)}),P.push([$,ve])});let K=D.current;J().sort(($,fe)=>{var ve,Re;let de=$.getAttribute("id"),We=fe.getAttribute("id");return((ve=Y.get(We))!=null?ve:0)-((Re=Y.get(de))!=null?Re:0)}).forEach($=>{let fe=$.closest(db);fe?fe.appendChild($.parentElement===fe?$:$.closest(`${db} > *`)):K.appendChild($.parentElement===K?$:$.closest(`${db} > *`))}),P.sort(($,fe)=>fe[1]-$[1]).forEach($=>{var fe;let ve=(fe=D.current)==null?void 0:fe.querySelector(`${Lh}[${Pu}="${encodeURIComponent($[0])}"]`);ve?.parentElement.appendChild(ve)})}function U(){let Y=J().find(K=>K.getAttribute("aria-disabled")!=="true"),P=Y?.getAttribute(Pu);z.setState("value",P||void 0)}function V(){var Y,P,K,$;if(!n.current.search||c.current.shouldFilter===!1){n.current.filtered.count=r.current.size;return}n.current.filtered.groups=new Set;let fe=0;for(let ve of r.current){let Re=(P=(Y=i.current.get(ve))==null?void 0:Y.value)!=null?P:"",de=($=(K=i.current.get(ve))==null?void 0:K.keywords)!=null?$:[],We=F(Re,de);n.current.filtered.items.set(ve,We),We>0&&fe++}for(let[ve,Re]of s.current)for(let de of Re)if(n.current.filtered.items.get(de)>0){n.current.filtered.groups.add(ve);break}n.current.filtered.count=fe}function ce(){var Y,P,K;let $=W();$&&(((Y=$.parentElement)==null?void 0:Y.firstChild)===$&&((K=(P=$.closest(Lh))==null?void 0:P.querySelector(yte))==null||K.scrollIntoView({block:"nearest"})),$.scrollIntoView({block:"nearest"}))}function W(){var Y;return(Y=D.current)==null?void 0:Y.querySelector(`${I_}[aria-selected="true"]`)}function J(){var Y;return Array.from(((Y=D.current)==null?void 0:Y.querySelectorAll(o8))||[])}function H(Y){let P=J()[Y];P&&z.setState("value",P.getAttribute(Pu))}function ae(Y){var P;let K=W(),$=J(),fe=$.findIndex(Re=>Re===K),ve=$[fe+Y];(P=c.current)!=null&&P.loop&&(ve=fe+Y<0?$[$.length-1]:fe+Y===$.length?$[0]:$[fe+Y]),ve&&z.setState("value",ve.getAttribute(Pu))}function ne(Y){let P=W(),K=P?.closest(Lh),$;for(;K&&!$;)K=Y>0?Mte(K,Lh):Ate(K,Lh),$=K?.querySelector(o8);$?z.setState("value",$.getAttribute(Pu)):ae(Y)}let ue=()=>H(J().length-1),R=Y=>{Y.preventDefault(),Y.metaKey?ue():Y.altKey?ne(1):ae(1)},me=Y=>{Y.preventDefault(),Y.metaKey?H(0):Y.altKey?ne(-1):ae(-1)};return S.createElement(Co.div,{ref:e,tabIndex:-1,...j,"cmdk-root":"",onKeyDown:Y=>{var P;(P=j.onKeyDown)==null||P.call(j,Y);let K=Y.nativeEvent.isComposing||Y.keyCode===229;if(!(Y.defaultPrevented||K))switch(Y.key){case"n":case"j":{O&&Y.ctrlKey&&R(Y);break}case"ArrowDown":{R(Y);break}case"p":case"k":{O&&Y.ctrlKey&&me(Y);break}case"ArrowUp":{me(Y);break}case"Home":{Y.preventDefault(),H(0);break}case"End":{Y.preventDefault(),ue();break}case"Enter":{Y.preventDefault();let $=W();if($){let fe=new Event(d4);$.dispatchEvent(fe)}}}}},S.createElement("label",{"cmdk-label":"",htmlFor:Q.inputId,id:Q.labelId,style:Dte},d),Px(t,Y=>S.createElement(F_.Provider,{value:z},S.createElement(q_.Provider,{value:Q},Y))))}),wte=S.forwardRef((t,e)=>{var n,r;let s=Oi(),i=S.useRef(null),l=S.useContext(Q_),c=g0(),d=H_(t),h=(r=(n=d.current)==null?void 0:n.forceMount)!=null?r:l?.forceMount;Nc(()=>{if(!h)return c.item(s,l?.id)},[h]);let m=U_(s,i,[t.value,t.children,i],t.keywords),p=o5(),x=xo(E=>E.value&&E.value===m.current),v=xo(E=>h||c.filter()===!1?!0:E.search?E.filtered.items.get(s)>0:!0);S.useEffect(()=>{let E=i.current;if(!(!E||t.disabled))return E.addEventListener(d4,b),()=>E.removeEventListener(d4,b)},[v,t.onSelect,t.disabled]);function b(){var E,z;k(),(z=(E=d.current).onSelect)==null||z.call(E,m.current)}function k(){p.setState("value",m.current,!0)}if(!v)return null;let{disabled:O,value:j,onSelect:T,forceMount:M,keywords:_,...D}=t;return S.createElement(Co.div,{ref:lo(i,e),...D,id:s,"cmdk-item":"",role:"option","aria-disabled":!!O,"aria-selected":!!x,"data-disabled":!!O,"data-selected":!!x,onPointerMove:O||c.getDisablePointerSelection()?void 0:k,onClick:O?void 0:b},t.children)}),Ste=S.forwardRef((t,e)=>{let{heading:n,children:r,forceMount:s,...i}=t,l=Oi(),c=S.useRef(null),d=S.useRef(null),h=Oi(),m=g0(),p=xo(v=>s||m.filter()===!1?!0:v.search?v.filtered.groups.has(l):!0);Nc(()=>m.group(l),[]),U_(l,c,[t.value,t.heading,d]);let x=S.useMemo(()=>({id:l,forceMount:s}),[s]);return S.createElement(Co.div,{ref:lo(c,e),...i,"cmdk-group":"",role:"presentation",hidden:p?void 0:!0},n&&S.createElement("div",{ref:d,"cmdk-group-heading":"","aria-hidden":!0,id:h},n),Px(t,v=>S.createElement("div",{"cmdk-group-items":"",role:"group","aria-labelledby":n?h:void 0},S.createElement(Q_.Provider,{value:x},v))))}),kte=S.forwardRef((t,e)=>{let{alwaysRender:n,...r}=t,s=S.useRef(null),i=xo(l=>!l.search);return!n&&!i?null:S.createElement(Co.div,{ref:lo(s,e),...r,"cmdk-separator":"",role:"separator"})}),Ote=S.forwardRef((t,e)=>{let{onValueChange:n,...r}=t,s=t.value!=null,i=o5(),l=xo(h=>h.search),c=xo(h=>h.selectedItemId),d=g0();return S.useEffect(()=>{t.value!=null&&i.setState("search",t.value)},[t.value]),S.createElement(Co.input,{ref:e,...r,"cmdk-input":"",autoComplete:"off",autoCorrect:"off",spellCheck:!1,"aria-autocomplete":"list",role:"combobox","aria-expanded":!0,"aria-controls":d.listId,"aria-labelledby":d.labelId,"aria-activedescendant":c,id:d.inputId,type:"text",value:s?t.value:l,onChange:h=>{s||i.setState("search",h.target.value),n?.(h.target.value)}})}),jte=S.forwardRef((t,e)=>{let{children:n,label:r="Suggestions",...s}=t,i=S.useRef(null),l=S.useRef(null),c=xo(h=>h.selectedItemId),d=g0();return S.useEffect(()=>{if(l.current&&i.current){let h=l.current,m=i.current,p,x=new ResizeObserver(()=>{p=requestAnimationFrame(()=>{let v=h.offsetHeight;m.style.setProperty("--cmdk-list-height",v.toFixed(1)+"px")})});return x.observe(h),()=>{cancelAnimationFrame(p),x.unobserve(h)}}},[]),S.createElement(Co.div,{ref:lo(i,e),...s,"cmdk-list":"",role:"listbox",tabIndex:-1,"aria-activedescendant":c,"aria-label":r,id:d.listId},Px(t,h=>S.createElement("div",{ref:lo(l,d.listInnerRef),"cmdk-list-sizer":""},h)))}),Nte=S.forwardRef((t,e)=>{let{open:n,onOpenChange:r,overlayClassName:s,contentClassName:i,container:l,...c}=t;return S.createElement(W4,{open:n,onOpenChange:r},S.createElement($4,{container:l},S.createElement(nx,{"cmdk-overlay":"",className:s}),S.createElement(rx,{"aria-label":t.label,"cmdk-dialog":"",className:i},S.createElement($_,{ref:e,...c}))))}),Cte=S.forwardRef((t,e)=>xo(n=>n.filtered.count===0)?S.createElement(Co.div,{ref:e,...t,"cmdk-empty":"",role:"presentation"}):null),Tte=S.forwardRef((t,e)=>{let{progress:n,children:r,label:s="Loading...",...i}=t;return S.createElement(Co.div,{ref:e,...i,"cmdk-loading":"",role:"progressbar","aria-valuenow":n,"aria-valuemin":0,"aria-valuemax":100,"aria-label":s},Px(t,l=>S.createElement("div",{"aria-hidden":!0},l)))}),Bs=Object.assign($_,{List:jte,Item:wte,Input:Ote,Group:Ste,Separator:kte,Dialog:Nte,Empty:Cte,Loading:Tte});function Mte(t,e){let n=t.nextElementSibling;for(;n;){if(n.matches(e))return n;n=n.nextElementSibling}}function Ate(t,e){let n=t.previousElementSibling;for(;n;){if(n.matches(e))return n;n=n.previousElementSibling}}function H_(t){let e=S.useRef(t);return Nc(()=>{e.current=t}),e}var Nc=typeof window>"u"?S.useEffect:S.useLayoutEffect;function Lu(t){let e=S.useRef();return e.current===void 0&&(e.current=t()),e}function xo(t){let e=o5(),n=()=>t(e.snapshot());return S.useSyncExternalStore(e.subscribe,n,n)}function U_(t,e,n,r=[]){let s=S.useRef(),i=g0();return Nc(()=>{var l;let c=(()=>{var h;for(let m of n){if(typeof m=="string")return m.trim();if(typeof m=="object"&&"current"in m)return m.current?(h=m.current.textContent)==null?void 0:h.trim():s.current}})(),d=r.map(h=>h.trim());i.value(t,c,d),(l=e.current)==null||l.setAttribute(Pu,c),s.current=c}),s}var Ete=()=>{let[t,e]=S.useState(),n=Lu(()=>new Map);return Nc(()=>{n.current.forEach(r=>r()),n.current=new Map},[t]),(r,s)=>{n.current.set(r,s),e({})}};function _te(t){let e=t.type;return typeof e=="function"?e(t.props):"render"in e?e.render(t.props):t}function Px({asChild:t,children:e},n){return t&&S.isValidElement(e)?S.cloneElement(_te(e),{ref:e.ref},n(e.props.children)):n(e)}var Dte={position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"};const V_=S.forwardRef(({className:t,...e},n)=>a.jsx(Bs,{ref:n,className:ye("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",t),...e}));V_.displayName=Bs.displayName;const W_=S.forwardRef(({className:t,...e},n)=>a.jsxs("div",{className:"flex items-center border-b px-3","cmdk-input-wrapper":"",children:[a.jsx(Ps,{className:"mr-2 h-4 w-4 shrink-0 opacity-50"}),a.jsx(Bs.Input,{ref:n,className:ye("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",t),...e})]}));W_.displayName=Bs.Input.displayName;const G_=S.forwardRef(({className:t,...e},n)=>a.jsx(Bs.List,{ref:n,className:ye("max-h-[300px] overflow-y-auto overflow-x-hidden",t),...e}));G_.displayName=Bs.List.displayName;const X_=S.forwardRef((t,e)=>a.jsx(Bs.Empty,{ref:e,className:"py-6 text-center text-sm",...t}));X_.displayName=Bs.Empty.displayName;const Y_=S.forwardRef(({className:t,...e},n)=>a.jsx(Bs.Group,{ref:n,className:ye("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",t),...e}));Y_.displayName=Bs.Group.displayName;const Rte=S.forwardRef(({className:t,...e},n)=>a.jsx(Bs.Separator,{ref:n,className:ye("-mx-1 h-px bg-border",t),...e}));Rte.displayName=Bs.Separator.displayName;const K_=S.forwardRef(({className:t,...e},n)=>a.jsx(Bs.Item,{ref:n,className:ye("relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",t),...e}));K_.displayName=Bs.Item.displayName;function zte({options:t,selected:e,onChange:n,placeholder:r="选择选项...",emptyText:s="未找到选项",className:i}){const[l,c]=S.useState(!1),d=m=>{e.includes(m)?n(e.filter(p=>p!==m)):n([...e,m])},h=m=>{n(e.filter(p=>p!==m))};return a.jsxs(co,{open:l,onOpenChange:c,children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",role:"combobox","aria-expanded":l,className:ye("w-full justify-between min-h-10 h-auto",i),children:[a.jsx("div",{className:"flex gap-1 flex-wrap flex-1",children:e.length===0?a.jsx("span",{className:"text-muted-foreground",children:r}):e.map(m=>{const p=t.find(x=>x.value===m);return a.jsxs($n,{variant:"secondary",className:"cursor-pointer hover:bg-secondary/80",onClick:x=>{x.stopPropagation(),h(m)},children:[p?.label||m,a.jsx(Gf,{className:"ml-1 h-3 w-3",strokeWidth:2,fill:"none"})]},m)})}),a.jsx(Sq,{className:"ml-2 h-4 w-4 shrink-0 opacity-50",strokeWidth:2,fill:"none"})]})}),a.jsx(hl,{className:"w-full p-0",align:"start",children:a.jsxs(V_,{children:[a.jsx(W_,{placeholder:"搜索...",className:"h-9"}),a.jsxs(G_,{children:[a.jsx(X_,{children:s}),a.jsx(Y_,{children:t.map(m=>{const p=e.includes(m.value);return a.jsxs(K_,{value:m.value,onSelect:()=>d(m.value),children:[a.jsx("div",{className:ye("mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",p?"bg-primary text-primary-foreground":"opacity-50 [&_svg]:invisible"),children:a.jsx(hc,{className:"h-3 w-3",strokeWidth:2,fill:"none"})}),a.jsx("span",{children:m.label})]},m.value)})})]})]})})]})}function Pte(){const[t,e]=S.useState([]),[n,r]=S.useState([]),[s,i]=S.useState([]),[l,c]=S.useState(null),[d,h]=S.useState(!0),[m,p]=S.useState(!1),[x,v]=S.useState(!1),[b,k]=S.useState(!1),[O,j]=S.useState(!1),[T,M]=S.useState(!1),[_,D]=S.useState(!1),[E,z]=S.useState(null),[Q,F]=S.useState(null),[B,U]=S.useState(!1),[V,ce]=S.useState(null),[W,J]=S.useState(""),[H,ae]=S.useState(new Set),[ne,ue]=S.useState(!1),[R,me]=S.useState(1),[Y,P]=S.useState(20),[K,$]=S.useState(""),{toast:fe}=Pr(),ve=S.useRef(null),Re=S.useRef(null),de=S.useRef(!0);S.useEffect(()=>{We()},[]);const We=async()=>{try{h(!0);const re=await Vu(),Me=re.models||[];e(Me),i(Me.map(vt=>vt.name));const pt=re.api_providers||[];r(pt.map(vt=>vt.name)),c(re.model_task_config||null),k(!1),de.current=!1}catch(re){console.error("加载配置失败:",re)}finally{h(!1)}},ct=async()=>{try{j(!0),xw().catch(()=>{}),M(!0)}catch(re){console.error("重启失败:",re),M(!1),fe({title:"重启失败",description:"无法发送重启请求,请手动重启",variant:"destructive"}),j(!1)}},Oe=async()=>{try{p(!0),ve.current&&clearTimeout(ve.current),Re.current&&clearTimeout(Re.current);const re=await Vu();re.models=t,re.model_task_config=l,await wg(re),k(!1),fe({title:"保存成功",description:"正在重启麦麦..."}),await ct()}catch(re){console.error("保存配置失败:",re),fe({title:"保存失败",description:re.message,variant:"destructive"}),p(!1)}},nt=()=>{localStorage.removeItem("access-token"),window.location.href="/auth"},ut=()=>{M(!1),j(!1),fe({title:"重启超时",description:"服务未能在预期时间内恢复,请手动检查或刷新页面",variant:"destructive"})},Ct=S.useCallback(async re=>{if(!de.current)try{v(!0),await h2("models",re),k(!1)}catch(Me){console.error("自动保存模型列表失败:",Me),k(!0)}finally{v(!1)}},[]),Bn=S.useCallback(async re=>{if(!de.current)try{v(!0),await h2("model_task_config",re),k(!1)}catch(Me){console.error("自动保存任务配置失败:",Me),k(!0)}finally{v(!1)}},[]);S.useEffect(()=>{if(!de.current)return k(!0),ve.current&&clearTimeout(ve.current),ve.current=setTimeout(()=>{Ct(t)},2e3),()=>{ve.current&&clearTimeout(ve.current)}},[t,Ct]),S.useEffect(()=>{if(!(de.current||!l))return k(!0),Re.current&&clearTimeout(Re.current),Re.current=setTimeout(()=>{Bn(l)},2e3),()=>{Re.current&&clearTimeout(Re.current)}},[l,Bn]);const Tn=async()=>{try{p(!0),ve.current&&clearTimeout(ve.current),Re.current&&clearTimeout(Re.current);const re=await Vu();re.models=t,re.model_task_config=l,await wg(re),k(!1),fe({title:"保存成功",description:"模型配置已保存"}),await We()}catch(re){console.error("保存配置失败:",re),fe({title:"保存失败",description:re.message,variant:"destructive"})}finally{p(!1)}},Jn=(re,Me)=>{z(re||{model_identifier:"",name:"",api_provider:n[0]||"",price_in:0,price_out:0,force_stream_mode:!1,extra_params:{}}),F(Me),D(!0)},nn=()=>{if(!E)return;const re={...E,price_in:E.price_in??0,price_out:E.price_out??0};let Me;Q!==null?(Me=[...t],Me[Q]=re):Me=[...t,re],e(Me),i(Me.map(pt=>pt.name)),D(!1),z(null),F(null)},_t=re=>{if(!re&&E){const Me={...E,price_in:E.price_in??0,price_out:E.price_out??0};z(Me)}D(re)},Yr=re=>{ce(re),U(!0)},In=()=>{if(V!==null){const re=t.filter((Me,pt)=>pt!==V);e(re),i(re.map(Me=>Me.name)),fe({title:"删除成功",description:"模型已从列表中移除"})}U(!1),ce(null)},or=re=>{const Me=new Set(H);Me.has(re)?Me.delete(re):Me.add(re),ae(Me)},yn=()=>{if(H.size===Le.length)ae(new Set);else{const re=Le.map((Me,pt)=>t.findIndex(vt=>vt===Le[pt]));ae(new Set(re))}},ft=()=>{if(H.size===0){fe({title:"提示",description:"请先选择要删除的模型",variant:"default"});return}ue(!0)},ee=()=>{const re=t.filter((Me,pt)=>!H.has(pt));e(re),i(re.map(Me=>Me.name)),ae(new Set),ue(!1),fe({title:"批量删除成功",description:`已删除 ${H.size} 个模型`})},Se=(re,Me,pt)=>{l&&c({...l,[re]:{...l[re],[Me]:pt}})},Le=t.filter(re=>{if(!W)return!0;const Me=W.toLowerCase();return re.name.toLowerCase().includes(Me)||re.model_identifier.toLowerCase().includes(Me)||re.api_provider.toLowerCase().includes(Me)}),rt=Math.ceil(Le.length/Y),Tt=Le.slice((R-1)*Y,R*Y),cr=()=>{const re=parseInt(K);re>=1&&re<=rt&&(me(re),$(""))},Kr=re=>l?[l.utils?.model_list||[],l.utils_small?.model_list||[],l.tool_use?.model_list||[],l.replyer?.model_list||[],l.planner?.model_list||[],l.vlm?.model_list||[],l.voice?.model_list||[],l.embedding?.model_list||[],l.lpmm_entity_extract?.model_list||[],l.lpmm_rdf_build?.model_list||[],l.lpmm_qa?.model_list||[]].some(pt=>pt.includes(re)):!1;return d?a.jsx(fn,{className:"h-full",children:a.jsx("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:a.jsx("div",{className:"flex items-center justify-center h-64",children:a.jsx("p",{className:"text-muted-foreground",children:"加载中..."})})})}):a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"模型配置"}),a.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理模型和任务配置"})]}),a.jsxs("div",{className:"flex gap-2 w-full sm:w-auto",children:[a.jsxs(ie,{onClick:Tn,disabled:m||x||!b||O,size:"sm",variant:"outline",className:"flex-1 sm:flex-none",children:[a.jsx(lx,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),m?"保存中...":x?"自动保存中...":b?"保存配置":"已保存"]}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsxs(ie,{disabled:m||x||O,size:"sm",className:"flex-1 sm:flex-none",children:[a.jsx(Z4,{className:"mr-2 h-4 w-4"}),O?"重启中...":b?"保存并重启":"重启麦麦"]})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认重启麦麦?"}),a.jsx(un,{children:b?"当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。":"即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。"})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:b?Oe:ct,children:b?"保存并重启":"确认重启"})]})]})]})]})]}),a.jsxs(ld,{children:[a.jsx(oo,{className:"h-4 w-4"}),a.jsxs(od,{children:["配置更新后需要",a.jsx("strong",{children:"重启麦麦"}),'才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。']})]}),a.jsxs(dl,{defaultValue:"models",className:"w-full",children:[a.jsxs(va,{className:"grid w-full max-w-full sm:max-w-md grid-cols-2",children:[a.jsx($t,{value:"models",children:"模型配置"}),a.jsx($t,{value:"tasks",children:"模型任务配置"})]}),a.jsxs(kn,{value:"models",className:"space-y-4 mt-0",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-2",children:[a.jsx("p",{className:"text-sm text-muted-foreground",children:"配置可用的模型列表"}),a.jsxs("div",{className:"flex gap-2 w-full sm:w-auto",children:[H.size>0&&a.jsxs(ie,{onClick:ft,size:"sm",variant:"destructive",className:"w-full sm:w-auto",children:[a.jsx(Ht,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"批量删除 (",H.size,")"]}),a.jsxs(ie,{onClick:()=>Jn(null,null),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[a.jsx(Wr,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"添加模型"]})]})]}),a.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center gap-2",children:[a.jsxs("div",{className:"relative w-full sm:flex-1 sm:max-w-sm",children:[a.jsx(Ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{placeholder:"搜索模型名称、标识符或提供商...",value:W,onChange:re=>J(re.target.value),className:"pl-9"})]}),W&&a.jsxs("p",{className:"text-sm text-muted-foreground whitespace-nowrap",children:["找到 ",Le.length," 个结果"]})]}),a.jsx("div",{className:"md:hidden space-y-3",children:Tt.length===0?a.jsx("div",{className:"text-center text-muted-foreground py-8 rounded-lg border bg-card",children:W?"未找到匹配的模型":"暂无模型配置"}):Tt.map((re,Me)=>{const pt=t.findIndex(vs=>vs===re),vt=Kr(re.name);return a.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3",children:[a.jsxs("div",{className:"flex items-start justify-between gap-2",children:[a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[a.jsx("h3",{className:"font-semibold text-base",children:re.name}),a.jsx($n,{variant:vt?"default":"secondary",className:vt?"bg-green-600 hover:bg-green-700":"",children:vt?"已使用":"未使用"})]}),a.jsx("p",{className:"text-xs text-muted-foreground break-all",title:re.model_identifier,children:re.model_identifier})]}),a.jsxs("div",{className:"flex gap-1 flex-shrink-0",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>Jn(re,pt),children:[a.jsx(nd,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),a.jsxs(ie,{size:"sm",onClick:()=>Yr(pt),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"提供商"}),a.jsx("p",{className:"font-medium",children:re.api_provider})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"强制流式"}),a.jsx("p",{className:"font-medium",children:re.force_stream_mode?"是":"否"})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"输入价格"}),a.jsxs("p",{className:"font-medium",children:["¥",re.price_in,"/M"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"text-muted-foreground text-xs",children:"输出价格"}),a.jsxs("p",{className:"font-medium",children:["¥",re.price_out,"/M"]})]})]})]},Me)})}),a.jsx("div",{className:"hidden md:block rounded-lg border bg-card overflow-hidden",children:a.jsxs(Ac,{children:[a.jsx(Ec,{children:a.jsxs(xr,{children:[a.jsx(gt,{className:"w-12",children:a.jsx(ss,{checked:H.size===Le.length&&Le.length>0,onCheckedChange:yn})}),a.jsx(gt,{className:"w-24",children:"使用状态"}),a.jsx(gt,{children:"模型名称"}),a.jsx(gt,{children:"模型标识符"}),a.jsx(gt,{children:"提供商"}),a.jsx(gt,{className:"text-right",children:"输入价格"}),a.jsx(gt,{className:"text-right",children:"输出价格"}),a.jsx(gt,{className:"text-center",children:"强制流式"}),a.jsx(gt,{className:"text-right",children:"操作"})]})}),a.jsx(_c,{children:Tt.length===0?a.jsx(xr,{children:a.jsx(it,{colSpan:9,className:"text-center text-muted-foreground py-8",children:W?"未找到匹配的模型":"暂无模型配置"})}):Tt.map((re,Me)=>{const pt=t.findIndex(vs=>vs===re),vt=Kr(re.name);return a.jsxs(xr,{children:[a.jsx(it,{children:a.jsx(ss,{checked:H.has(pt),onCheckedChange:()=>or(pt)})}),a.jsx(it,{children:a.jsx($n,{variant:vt?"default":"secondary",className:vt?"bg-green-600 hover:bg-green-700":"",children:vt?"已使用":"未使用"})}),a.jsx(it,{className:"font-medium",children:re.name}),a.jsx(it,{className:"max-w-xs truncate",title:re.model_identifier,children:re.model_identifier}),a.jsx(it,{children:re.api_provider}),a.jsxs(it,{className:"text-right",children:["¥",re.price_in,"/M"]}),a.jsxs(it,{className:"text-right",children:["¥",re.price_out,"/M"]}),a.jsx(it,{className:"text-center",children:re.force_stream_mode?"是":"否"}),a.jsx(it,{className:"text-right",children:a.jsxs("div",{className:"flex justify-end gap-2",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>Jn(re,pt),children:[a.jsx(nd,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),a.jsxs(ie,{size:"sm",onClick:()=>Yr(pt),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})})]},Me)})})]})}),Le.length>0&&a.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(te,{htmlFor:"page-size-model",className:"text-sm whitespace-nowrap",children:"每页显示"}),a.jsxs(Bt,{value:Y.toString(),onValueChange:re=>{P(parseInt(re)),me(1),ae(new Set)},children:[a.jsx(Dt,{id:"page-size-model",className:"w-20",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"10",children:"10"}),a.jsx(Pe,{value:"20",children:"20"}),a.jsx(Pe,{value:"50",children:"50"}),a.jsx(Pe,{value:"100",children:"100"})]})]}),a.jsxs("span",{className:"text-sm text-muted-foreground",children:["显示 ",(R-1)*Y+1," 到"," ",Math.min(R*Y,Le.length)," 条,共 ",Le.length," 条"]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>me(1),disabled:R===1,className:"hidden sm:flex",children:a.jsx(Xf,{className:"h-4 w-4"})}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>me(re=>Math.max(1,re-1)),disabled:R===1,children:[a.jsx(Tc,{className:"h-4 w-4 sm:mr-1"}),a.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(Ae,{type:"number",value:K,onChange:re=>$(re.target.value),onKeyDown:re=>re.key==="Enter"&&cr(),placeholder:R.toString(),className:"w-16 h-8 text-center",min:1,max:rt}),a.jsx(ie,{variant:"outline",size:"sm",onClick:cr,disabled:!K,className:"h-8",children:"跳转"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>me(re=>re+1),disabled:R>=rt,children:[a.jsx("span",{className:"hidden sm:inline",children:"下一页"}),a.jsx(Mc,{className:"h-4 w-4 sm:ml-1"})]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>me(rt),disabled:R>=rt,className:"hidden sm:flex",children:a.jsx(Yf,{className:"h-4 w-4"})})]})]})]}),a.jsxs(kn,{value:"tasks",className:"space-y-6 mt-0",children:[a.jsx("p",{className:"text-sm text-muted-foreground",children:"为不同的任务配置使用的模型和参数"}),l&&a.jsxs("div",{className:"grid gap-4 sm:gap-6",children:[a.jsx(zi,{title:"组件模型 (utils)",description:"用于表情包、取名、关系、情绪变化等组件",taskConfig:l.utils,modelNames:s,onChange:(re,Me)=>Se("utils",re,Me)}),a.jsx(zi,{title:"组件小模型 (utils_small)",description:"消耗量较大的组件,建议使用速度较快的小模型",taskConfig:l.utils_small,modelNames:s,onChange:(re,Me)=>Se("utils_small",re,Me)}),a.jsx(zi,{title:"工具调用模型 (tool_use)",description:"需要使用支持工具调用的模型",taskConfig:l.tool_use,modelNames:s,onChange:(re,Me)=>Se("tool_use",re,Me)}),a.jsx(zi,{title:"首要回复模型 (replyer)",description:"用于表达器和表达方式学习",taskConfig:l.replyer,modelNames:s,onChange:(re,Me)=>Se("replyer",re,Me)}),a.jsx(zi,{title:"决策模型 (planner)",description:"负责决定麦麦该什么时候回复",taskConfig:l.planner,modelNames:s,onChange:(re,Me)=>Se("planner",re,Me)}),a.jsx(zi,{title:"图像识别模型 (vlm)",description:"视觉语言模型",taskConfig:l.vlm,modelNames:s,onChange:(re,Me)=>Se("vlm",re,Me),hideTemperature:!0}),a.jsx(zi,{title:"语音识别模型 (voice)",description:"语音转文字",taskConfig:l.voice,modelNames:s,onChange:(re,Me)=>Se("voice",re,Me),hideTemperature:!0,hideMaxTokens:!0}),a.jsx(zi,{title:"嵌入模型 (embedding)",description:"用于向量化",taskConfig:l.embedding,modelNames:s,onChange:(re,Me)=>Se("embedding",re,Me),hideTemperature:!0,hideMaxTokens:!0}),a.jsxs("div",{className:"space-y-4",children:[a.jsx("h3",{className:"text-lg font-semibold",children:"LPMM 知识库模型"}),a.jsx(zi,{title:"实体提取模型 (lpmm_entity_extract)",description:"从文本中提取实体",taskConfig:l.lpmm_entity_extract,modelNames:s,onChange:(re,Me)=>Se("lpmm_entity_extract",re,Me)}),a.jsx(zi,{title:"RDF 构建模型 (lpmm_rdf_build)",description:"构建知识图谱",taskConfig:l.lpmm_rdf_build,modelNames:s,onChange:(re,Me)=>Se("lpmm_rdf_build",re,Me)}),a.jsx(zi,{title:"问答模型 (lpmm_qa)",description:"知识库问答",taskConfig:l.lpmm_qa,modelNames:s,onChange:(re,Me)=>Se("lpmm_qa",re,Me)})]})]})]})]}),a.jsx(Rr,{open:_,onOpenChange:_t,children:a.jsxs(Nr,{className:"max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:Q!==null?"编辑模型":"添加模型"}),a.jsx(Gr,{children:"配置模型的基本信息和参数"})]}),a.jsxs("div",{className:"grid gap-4 py-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"model_name",children:"模型名称 *"}),a.jsx(Ae,{id:"model_name",value:E?.name||"",onChange:re=>z(Me=>Me?{...Me,name:re.target.value}:null),placeholder:"例如: qwen3-30b"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"用于在任务配置中引用此模型"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"model_identifier",children:"模型标识符 *"}),a.jsx(Ae,{id:"model_identifier",value:E?.model_identifier||"",onChange:re=>z(Me=>Me?{...Me,model_identifier:re.target.value}:null),placeholder:"Qwen/Qwen3-30B-A3B-Instruct-2507"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"API 提供商提供的模型 ID"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"api_provider",children:"API 提供商 *"}),a.jsxs(Bt,{value:E?.api_provider||"",onValueChange:re=>z(Me=>Me?{...Me,api_provider:re}:null),children:[a.jsx(Dt,{id:"api_provider",children:a.jsx(It,{placeholder:"选择提供商"})}),a.jsx(Rt,{children:n.map(re=>a.jsx(Pe,{value:re,children:re},re))})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"price_in",children:"输入价格 (¥/M token)"}),a.jsx(Ae,{id:"price_in",type:"number",step:"0.1",min:"0",value:E?.price_in??"",onChange:re=>{const Me=re.target.value===""?null:parseFloat(re.target.value);z(pt=>pt?{...pt,price_in:Me}:null)},placeholder:"默认: 0"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"price_out",children:"输出价格 (¥/M token)"}),a.jsx(Ae,{id:"price_out",type:"number",step:"0.1",min:"0",value:E?.price_out??"",onChange:re=>{const Me=re.target.value===""?null:parseFloat(re.target.value);z(pt=>pt?{...pt,price_out:Me}:null)},placeholder:"默认: 0"})]})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"force_stream_mode",checked:E?.force_stream_mode||!1,onCheckedChange:re=>z(Me=>Me?{...Me,force_stream_mode:re}:null)}),a.jsx(te,{htmlFor:"force_stream_mode",className:"cursor-pointer",children:"强制流式输出模式"})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>D(!1),children:"取消"}),a.jsx(ie,{onClick:nn,children:"保存"})]})]})}),a.jsx(mn,{open:B,onOpenChange:U,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除模型 "',V!==null?t[V]?.name:"",'" 吗? 此操作无法撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:In,children:"删除"})]})]})}),a.jsx(mn,{open:ne,onOpenChange:ue,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认批量删除"}),a.jsxs(un,{children:["确定要删除选中的 ",H.size," 个模型吗? 此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:ee,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"批量删除"})]})]})}),T&&a.jsx(vw,{onRestartComplete:nt,onRestartFailed:ut})]})})}function zi({title:t,description:e,taskConfig:n,modelNames:r,onChange:s,hideTemperature:i=!1,hideMaxTokens:l=!1}){const c=d=>{s("model_list",d)};return a.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[a.jsxs("div",{children:[a.jsx("h4",{className:"font-semibold text-base sm:text-lg",children:t}),a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground mt-1",children:e})]}),a.jsxs("div",{className:"grid gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"模型列表"}),a.jsx(zte,{options:r.map(d=>({label:d,value:d})),selected:n.model_list||[],onChange:c,placeholder:"选择模型...",emptyText:"暂无可用模型"})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[!i&&a.jsxs("div",{className:"grid gap-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx(te,{children:"温度"}),a.jsx(Ae,{type:"number",step:"0.1",min:"0",max:"1",value:n.temperature??.3,onChange:d=>{const h=parseFloat(d.target.value);!isNaN(h)&&h>=0&&h<=1&&s("temperature",h)},className:"w-20 h-8 text-sm"})]}),a.jsx(yx,{value:[n.temperature??.3],onValueChange:d=>s("temperature",d[0]),min:0,max:1,step:.1,className:"w-full"})]}),!l&&a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{children:"最大 Token"}),a.jsx(Ae,{type:"number",step:"1",min:"1",value:n.max_tokens??1024,onChange:d=>s("max_tokens",parseInt(d.target.value))})]})]})]})]})}const Lx="/api/webui/config";async function Lte(){const e=await(await ot(`${Lx}/adapter-config/path`)).json();return!e.success||!e.path?null:{path:e.path,lastModified:e.lastModified}}async function Bte(t){const n=await(await ot(`${Lx}/adapter-config/path`,{method:"POST",headers:bt(),body:JSON.stringify({path:t})})).json();if(!n.success)throw new Error(n.message||"保存路径失败")}async function Ite(t){const n=await(await ot(`${Lx}/adapter-config?path=${encodeURIComponent(t)}`)).json();if(!n.success)throw new Error("读取配置文件失败");return n.content}async function c8(t,e){const r=await(await ot(`${Lx}/adapter-config`,{method:"POST",headers:bt(),body:JSON.stringify({path:t,content:e})})).json();if(!r.success)throw new Error(r.message||"保存配置失败")}const Ks={inner:{version:"0.1.2"},nickname:{nickname:""},napcat_server:{host:"localhost",port:8095,token:"",heartbeat_interval:30},maibot_server:{host:"localhost",port:8e3},chat:{group_list_type:"whitelist",group_list:[],private_list_type:"whitelist",private_list:[],ban_user_id:[],ban_qq_bot:!1,enable_poke:!0},voice:{use_tts:!1},debug:{level:"INFO"}};function qte(){const[t,e]=S.useState("upload"),[n,r]=S.useState(null),[s,i]=S.useState(""),[l,c]=S.useState(""),[d,h]=S.useState(""),[m,p]=S.useState(!1),[x,v]=S.useState(!1),[b,k]=S.useState(!1),[O,j]=S.useState(!1),[T,M]=S.useState(null),_=S.useRef(null),{toast:D}=Pr(),E=S.useRef(null),z=K=>{if(!K.trim())return{valid:!1,error:"路径不能为空"};const $=/^([a-zA-Z]:\\|\\\\[^\\]+\\[^\\]+\\).+\.toml$/i,fe=/^(\/|~\/).+\.toml$/i,ve=$.test(K),Re=fe.test(K);return!ve&&!Re?{valid:!1,error:"路径格式错误。Windows: C:\\path\\file.toml,Linux: /path/file.toml"}:K.toLowerCase().endsWith(".toml")?/[<>"|?*\x00-\x1F]/.test(K)?{valid:!1,error:"路径包含非法字符"}:{valid:!0,error:""}:{valid:!1,error:"文件必须是 .toml 格式"}},Q=K=>{if(c(K),K.trim()){const $=z(K);h($.error)}else h("")};S.useEffect(()=>{(async()=>{try{const $=await Lte();$&&$.path&&(c($.path),e("path"),await F($.path))}catch($){console.error("加载保存的路径失败:",$)}})()},[]);const F=async K=>{const $=z(K);if(!$.valid){h($.error),D({title:"路径无效",description:$.error,variant:"destructive"});return}h(""),v(!0);try{const fe=await Ite(K),ve=ue(fe);r(ve),c(K),await Bte(K),D({title:"加载成功",description:"已从配置文件加载"})}catch(fe){console.error("加载配置失败:",fe),D({title:"加载失败",description:fe instanceof Error?fe.message:"无法读取配置文件",variant:"destructive"})}finally{v(!1)}},B=S.useCallback(K=>{t!=="path"||!l||(E.current&&clearTimeout(E.current),E.current=setTimeout(async()=>{p(!0);try{const $=R(K);await c8(l,$),D({title:"自动保存成功",description:"配置已保存到文件"})}catch($){console.error("自动保存失败:",$),D({title:"自动保存失败",description:$ instanceof Error?$.message:"保存配置失败",variant:"destructive"})}finally{p(!1)}},1e3))},[t,l,D]),U=async()=>{if(!n||!l)return;const K=z(l);if(!K.valid){D({title:"保存失败",description:K.error,variant:"destructive"});return}p(!0);try{const $=R(n);await c8(l,$),D({title:"保存成功",description:"配置已保存到文件"})}catch($){console.error("保存失败:",$),D({title:"保存失败",description:$ instanceof Error?$.message:"保存配置失败",variant:"destructive"})}finally{p(!1)}},V=async()=>{l&&await F(l)},ce=K=>{if(K!==t){if(n){M(K),k(!0);return}W(K)}},W=K=>{r(null),i(""),h(""),e(K),D({title:"已切换模式",description:K==="upload"?"现在可以上传配置文件":"现在可以指定配置文件路径"})},J=()=>{T&&(W(T),M(null)),k(!1)},H=()=>{if(n){j(!0);return}ae()},ae=()=>{c(""),r(null),h(""),D({title:"已清空",description:"路径和配置已清空"})},ne=()=>{ae(),j(!1)},ue=K=>{const $=JSON.parse(JSON.stringify(Ks)),fe=K.split(` -`);let ve="";for(const Re of fe){const de=Re.trim();if(!de||de.startsWith("#"))continue;const We=de.match(/^\[(\w+)\]$/);if(We){ve=We[1];continue}const ct=de.match(/^(\w+)\s*=\s*(.+)$/);if(ct&&ve){const[,Oe,nt]=ct,ut=nt.trim();let Ct;if(ut==="true")Ct=!0;else if(ut==="false")Ct=!1;else if(ut.startsWith("[")&&ut.endsWith("]")){const Bn=ut.slice(1,-1).trim();if(Bn){const Tn=Bn.split(",").map(nn=>{const _t=nn.trim();return isNaN(Number(_t))?_t.replace(/"/g,""):Number(_t)}),Jn=typeof Tn[0];Ct=Tn.every(nn=>typeof nn===Jn)?Tn:Tn.filter(nn=>typeof nn=="number")}else Ct=[]}else ut.startsWith('"')&&ut.endsWith('"')?Ct=ut.slice(1,-1):isNaN(Number(ut))?Ct=ut.replace(/"/g,""):Ct=Number(ut);if(ve in $){const Bn=$[ve];Bn[Oe]=Ct}}}return $},R=K=>{const $=[],fe=(ve,Re)=>ve===""||ve===null||ve===void 0?Re:ve;return $.push("[inner]"),$.push(`version = "${fe(K.inner.version,Ks.inner.version)}" # 版本号`),$.push("# 请勿修改版本号,除非你知道自己在做什么"),$.push(""),$.push("[nickname] # 现在没用"),$.push(`nickname = "${fe(K.nickname.nickname,Ks.nickname.nickname)}"`),$.push(""),$.push("[napcat_server] # Napcat连接的ws服务设置"),$.push(`host = "${fe(K.napcat_server.host,Ks.napcat_server.host)}" # Napcat设定的主机地址`),$.push(`port = ${fe(K.napcat_server.port||0,Ks.napcat_server.port)} # Napcat设定的端口`),$.push(`token = "${fe(K.napcat_server.token,Ks.napcat_server.token)}" # Napcat设定的访问令牌,若无则留空`),$.push(`heartbeat_interval = ${fe(K.napcat_server.heartbeat_interval||0,Ks.napcat_server.heartbeat_interval)} # 与Napcat设置的心跳相同(按秒计)`),$.push(""),$.push("[maibot_server] # 连接麦麦的ws服务设置"),$.push(`host = "${fe(K.maibot_server.host,Ks.maibot_server.host)}" # 麦麦在.env文件中设置的主机地址,即HOST字段`),$.push(`port = ${fe(K.maibot_server.port||0,Ks.maibot_server.port)} # 麦麦在.env文件中设置的端口,即PORT字段`),$.push(""),$.push("[chat] # 黑白名单功能"),$.push(`group_list_type = "${fe(K.chat.group_list_type,Ks.chat.group_list_type)}" # 群组名单类型,可选为:whitelist, blacklist`),$.push(`group_list = [${K.chat.group_list.join(", ")}] # 群组名单`),$.push("# 当group_list_type为whitelist时,只有群组名单中的群组可以聊天"),$.push("# 当group_list_type为blacklist时,群组名单中的任何群组无法聊天"),$.push(`private_list_type = "${fe(K.chat.private_list_type,Ks.chat.private_list_type)}" # 私聊名单类型,可选为:whitelist, blacklist`),$.push(`private_list = [${K.chat.private_list.join(", ")}] # 私聊名单`),$.push("# 当private_list_type为whitelist时,只有私聊名单中的用户可以聊天"),$.push("# 当private_list_type为blacklist时,私聊名单中的任何用户无法聊天"),$.push(`ban_user_id = [${K.chat.ban_user_id.join(", ")}] # 全局禁止名单(全局禁止名单中的用户无法进行任何聊天)`),$.push(`ban_qq_bot = ${K.chat.ban_qq_bot} # 是否屏蔽QQ官方机器人`),$.push(`enable_poke = ${K.chat.enable_poke} # 是否启用戳一戳功能`),$.push(""),$.push("[voice] # 发送语音设置"),$.push(`use_tts = ${K.voice.use_tts} # 是否使用tts语音(请确保你配置了tts并有对应的adapter)`),$.push(""),$.push("[debug]"),$.push(`level = "${fe(K.debug.level,Ks.debug.level)}" # 日志等级(DEBUG, INFO, WARNING, ERROR, CRITICAL)`),$.join(` -`)},me=K=>{const $=K.target.files?.[0];if(!$)return;const fe=new FileReader;fe.onload=ve=>{try{const Re=ve.target?.result,de=ue(Re);r(de),i($.name),D({title:"上传成功",description:`已加载配置文件:${$.name}`})}catch(Re){console.error("解析配置文件失败:",Re),D({title:"解析失败",description:"配置文件格式错误,请检查文件内容",variant:"destructive"})}},fe.readAsText($)},Y=()=>{if(!n)return;const K=R(n),$=new Blob([K],{type:"text/plain;charset=utf-8"}),fe=URL.createObjectURL($),ve=document.createElement("a");ve.href=fe,ve.download=s||"config.toml",document.body.appendChild(ve),ve.click(),document.body.removeChild(ve),URL.revokeObjectURL(fe),D({title:"下载成功",description:"配置文件已下载,请手动覆盖并重启适配器"})},P=()=>{r(JSON.parse(JSON.stringify(Ks))),i("config.toml"),D({title:"已加载默认配置",description:"可以开始编辑配置"})};return a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"麦麦适配器配置"}),a.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理麦麦的 QQ 适配器的配置文件"})]})}),a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"工作模式"}),a.jsx(Sr,{children:"选择配置文件的管理方式"})]}),a.jsxs(vn,{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3 md:gap-4",children:[a.jsx("div",{className:`border-2 rounded-lg p-3 md:p-4 cursor-pointer transition-all ${t==="upload"?"border-primary bg-primary/5":"border-muted hover:border-primary/50 active:border-primary/70"}`,onClick:()=>ce("upload"),children:a.jsxs("div",{className:"flex items-start gap-2 md:gap-3",children:[a.jsx(oO,{className:"h-4 w-4 md:h-5 md:w-5 mt-0.5 flex-shrink-0"}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("h3",{className:"font-semibold text-sm md:text-base",children:"上传文件模式"}),a.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-1 line-clamp-2",children:"上传配置文件,编辑后下载并手动覆盖"})]})]})}),a.jsx("div",{className:`border-2 rounded-lg p-3 md:p-4 cursor-pointer transition-all ${t==="path"?"border-primary bg-primary/5":"border-muted hover:border-primary/50 active:border-primary/70"}`,onClick:()=>ce("path"),children:a.jsxs("div",{className:"flex items-start gap-2 md:gap-3",children:[a.jsx(kq,{className:"h-4 w-4 md:h-5 md:w-5 mt-0.5 flex-shrink-0"}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("h3",{className:"font-semibold text-sm md:text-base",children:"指定路径模式"}),a.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-1 line-clamp-2",children:"指定配置文件路径,自动加载和保存"})]})]})})]}),t==="path"&&a.jsxs("div",{className:"space-y-3 pt-2 border-t",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"config-path",className:"text-sm md:text-base",children:"配置文件路径"}),a.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[a.jsxs("div",{className:"flex-1 space-y-1",children:[a.jsx(Ae,{id:"config-path",value:l,onChange:K=>Q(K.target.value),placeholder:"例: C:\\Adapter\\config.toml",className:`text-sm ${d?"border-destructive":""}`}),d&&a.jsx("p",{className:"text-xs text-destructive",children:d})]}),a.jsx(ie,{onClick:()=>F(l),disabled:x||!l||!!d,className:"w-full sm:w-auto",children:x?a.jsxs(a.Fragment,{children:[a.jsx(Ii,{className:"h-4 w-4 animate-spin mr-2"}),a.jsx("span",{className:"sm:hidden",children:"加载中..."})]}):a.jsxs(a.Fragment,{children:[a.jsx("span",{className:"sm:hidden",children:"加载配置"}),a.jsx("span",{className:"hidden sm:inline",children:"加载"})]})})]})]}),a.jsxs("details",{className:"rounded-lg bg-muted/50 p-3 group",children:[a.jsxs("summary",{className:"text-xs font-medium cursor-pointer select-none list-none flex items-center justify-between",children:[a.jsx("span",{children:"路径格式说明"}),a.jsx("svg",{className:"h-4 w-4 transition-transform group-open:rotate-180",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:a.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a.jsxs("div",{className:"mt-2 space-y-2 text-xs text-muted-foreground",children:[a.jsxs("div",{className:"space-y-1",children:[a.jsx("div",{className:"flex items-center gap-2",children:a.jsx("span",{className:"font-mono bg-background px-1.5 py-0.5 rounded text-[10px] md:text-xs whitespace-nowrap",children:"Windows"})}),a.jsxs("div",{className:"pl-2 space-y-0.5 text-[10px] md:text-xs break-all",children:[a.jsx("div",{children:"C:\\Adapter\\config.toml"}),a.jsx("div",{className:"hidden sm:block",children:"D:\\MaiBot\\adapter\\config.toml"}),a.jsx("div",{className:"hidden sm:block",children:"\\\\server\\share\\config.toml"})]})]}),a.jsxs("div",{className:"space-y-1",children:[a.jsx("div",{className:"flex items-center gap-2",children:a.jsx("span",{className:"font-mono bg-background px-1.5 py-0.5 rounded text-[10px] md:text-xs whitespace-nowrap",children:"Linux"})}),a.jsxs("div",{className:"pl-2 space-y-0.5 text-[10px] md:text-xs break-all",children:[a.jsx("div",{children:"/opt/adapter/config.toml"}),a.jsx("div",{className:"hidden sm:block",children:"/home/user/adapter/config.toml"}),a.jsx("div",{className:"hidden sm:block",children:"~/adapter/config.toml"})]})]}),a.jsx("p",{className:"pt-1 border-t text-[10px] md:text-xs",children:"💡 配置会自动保存到指定文件,修改后 1 秒自动保存"})]})]})]})]})]}),a.jsxs(ld,{children:[a.jsx(oo,{className:"h-4 w-4"}),a.jsx(od,{children:t==="upload"?a.jsxs(a.Fragment,{children:[a.jsx("strong",{children:"上传文件模式:"}),"上传配置文件 → 在线编辑 → 下载文件 → 手动覆盖并重启适配器"]}):a.jsxs(a.Fragment,{children:[a.jsx("strong",{children:"指定路径模式:"}),"指定配置文件路径后,配置会自动加载,修改后 1 秒自动保存",m&&" (正在保存...)"]})})]}),t==="upload"&&!n&&a.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 w-full",children:[a.jsx("input",{ref:_,type:"file",accept:".toml",className:"hidden",onChange:me}),a.jsxs(ie,{onClick:()=>_.current?.click(),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[a.jsx(oO,{className:"mr-2 h-4 w-4"}),"上传配置"]}),a.jsxs(ie,{onClick:P,size:"sm",className:"w-full sm:w-auto",children:[a.jsx(io,{className:"mr-2 h-4 w-4"}),"使用默认配置"]})]}),t==="upload"&&n&&a.jsx("div",{className:"flex gap-2",children:a.jsxs(ie,{onClick:Y,size:"sm",className:"w-full sm:w-auto",children:[a.jsx(fc,{className:"mr-2 h-4 w-4"}),"下载配置"]})}),t==="path"&&n&&a.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[a.jsxs(ie,{onClick:U,size:"sm",disabled:m||!!d,className:"w-full sm:w-auto",children:[a.jsx(lx,{className:"mr-2 h-4 w-4"}),m?"保存中...":"立即保存"]}),a.jsxs(ie,{onClick:V,size:"sm",variant:"outline",disabled:x,className:"w-full sm:w-auto",children:[a.jsx(Ii,{className:`mr-2 h-4 w-4 ${x?"animate-spin":""}`}),"刷新"]}),a.jsxs(ie,{onClick:H,size:"sm",variant:"destructive",className:"w-full sm:w-auto",children:[a.jsx(Ht,{className:"mr-2 h-4 w-4"}),"清空路径"]})]}),n?a.jsxs(dl,{defaultValue:"napcat",className:"w-full",children:[a.jsx("div",{className:"overflow-x-auto -mx-4 px-4 sm:mx-0 sm:px-0",children:a.jsxs(va,{className:"inline-flex w-auto min-w-full sm:grid sm:w-full sm:grid-cols-5",children:[a.jsxs($t,{value:"napcat",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[a.jsx("span",{className:"hidden sm:inline",children:"Napcat 连接"}),a.jsx("span",{className:"sm:hidden",children:"Napcat"})]}),a.jsxs($t,{value:"maibot",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[a.jsx("span",{className:"hidden sm:inline",children:"麦麦连接"}),a.jsx("span",{className:"sm:hidden",children:"麦麦"})]}),a.jsxs($t,{value:"chat",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[a.jsx("span",{className:"hidden sm:inline",children:"聊天控制"}),a.jsx("span",{className:"sm:hidden",children:"聊天"})]}),a.jsxs($t,{value:"voice",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[a.jsx("span",{className:"hidden sm:inline",children:"语音设置"}),a.jsx("span",{className:"sm:hidden",children:"语音"})]}),a.jsx($t,{value:"debug",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:"调试"})]})}),a.jsx(kn,{value:"napcat",className:"space-y-4",children:a.jsx(Fte,{config:n,onChange:K=>{r(K),B(K)}})}),a.jsx(kn,{value:"maibot",className:"space-y-4",children:a.jsx(Qte,{config:n,onChange:K=>{r(K),B(K)}})}),a.jsx(kn,{value:"chat",className:"space-y-4",children:a.jsx($te,{config:n,onChange:K=>{r(K),B(K)}})}),a.jsx(kn,{value:"voice",className:"space-y-4",children:a.jsx(Hte,{config:n,onChange:K=>{r(K),B(K)}})}),a.jsx(kn,{value:"debug",className:"space-y-4",children:a.jsx(Ute,{config:n,onChange:K=>{r(K),B(K)}})})]}):a.jsx("div",{className:"rounded-lg border bg-card p-6 md:p-12",children:a.jsxs("div",{className:"text-center space-y-3 md:space-y-4",children:[a.jsx(io,{className:"h-12 w-12 md:h-16 md:w-16 mx-auto text-muted-foreground"}),a.jsxs("div",{children:[a.jsx("h3",{className:"text-base md:text-lg font-semibold",children:"尚未加载配置"}),a.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-2 px-4",children:t==="upload"?"请上传现有配置文件,或使用默认配置开始编辑":"请指定配置文件路径并点击加载按钮"})]})]})}),a.jsx(mn,{open:b,onOpenChange:k,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认切换模式"}),a.jsxs(un,{children:["切换模式将清空当前配置,确定要继续吗?",a.jsx("br",{}),a.jsx("span",{className:"text-destructive font-medium",children:"请确保已保存重要配置"})]})]}),a.jsxs(on,{children:[a.jsx(hn,{onClick:()=>{k(!1),M(null)},children:"取消"}),a.jsx(dn,{onClick:J,children:"确认切换"})]})]})}),a.jsx(mn,{open:O,onOpenChange:j,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认清空路径"}),a.jsxs(un,{children:["清空路径将清除当前配置,确定要继续吗?",a.jsx("br",{}),a.jsx("span",{className:"text-muted-foreground text-sm",children:"此操作不会删除配置文件,只是清除界面中的配置"})]})]}),a.jsxs(on,{children:[a.jsx(hn,{onClick:()=>j(!1),children:"取消"}),a.jsx(dn,{onClick:ne,className:"bg-destructive hover:bg-destructive/90",children:"确认清空"})]})]})})]})})}function Fte({config:t,onChange:e}){return a.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"Napcat WebSocket 服务设置"}),a.jsxs("div",{className:"grid gap-3 md:gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"napcat-host",className:"text-sm md:text-base",children:"主机地址"}),a.jsx(Ae,{id:"napcat-host",value:t.napcat_server.host,onChange:n=>e({...t,napcat_server:{...t.napcat_server,host:n.target.value}}),placeholder:"localhost",className:"text-sm md:text-base"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"Napcat 设定的主机地址"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"napcat-port",className:"text-sm md:text-base",children:"端口"}),a.jsx(Ae,{id:"napcat-port",type:"number",value:t.napcat_server.port||"",onChange:n=>e({...t,napcat_server:{...t.napcat_server,port:n.target.value?parseInt(n.target.value):0}}),placeholder:"8095",className:"text-sm md:text-base"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"Napcat 设定的端口(留空使用默认值 8095)"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"napcat-token",className:"text-sm md:text-base",children:"访问令牌(Token)"}),a.jsx(Ae,{id:"napcat-token",type:"password",value:t.napcat_server.token,onChange:n=>e({...t,napcat_server:{...t.napcat_server,token:n.target.value}}),placeholder:"留空表示无需令牌",className:"text-sm md:text-base"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"Napcat 设定的访问令牌,若无则留空"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"napcat-heartbeat",className:"text-sm md:text-base",children:"心跳间隔(秒)"}),a.jsx(Ae,{id:"napcat-heartbeat",type:"number",value:t.napcat_server.heartbeat_interval||"",onChange:n=>e({...t,napcat_server:{...t.napcat_server,heartbeat_interval:n.target.value?parseInt(n.target.value):0}}),placeholder:"30",className:"text-sm md:text-base"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"与 Napcat 设置的心跳间隔保持一致(留空使用默认值 30)"})]})]})]})})}function Qte({config:t,onChange:e}){return a.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"麦麦 WebSocket 服务设置"}),a.jsxs("div",{className:"grid gap-3 md:gap-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"maibot-host",className:"text-sm md:text-base",children:"主机地址"}),a.jsx(Ae,{id:"maibot-host",value:t.maibot_server.host,onChange:n=>e({...t,maibot_server:{...t.maibot_server,host:n.target.value}}),placeholder:"localhost",className:"text-sm md:text-base"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦在 .env 文件中设置的 HOST 字段"})]}),a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{htmlFor:"maibot-port",className:"text-sm md:text-base",children:"端口"}),a.jsx(Ae,{id:"maibot-port",type:"number",value:t.maibot_server.port||"",onChange:n=>e({...t,maibot_server:{...t.maibot_server,port:n.target.value?parseInt(n.target.value):0}}),placeholder:"8000",className:"text-sm md:text-base"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦在 .env 文件中设置的 PORT 字段(留空使用默认值 8000)"})]})]})]})})}function $te({config:t,onChange:e}){const n=i=>{const l={...t};i==="group"?l.chat.group_list=[...l.chat.group_list,0]:i==="private"?l.chat.private_list=[...l.chat.private_list,0]:l.chat.ban_user_id=[...l.chat.ban_user_id,0],e(l)},r=(i,l)=>{const c={...t};i==="group"?c.chat.group_list=c.chat.group_list.filter((d,h)=>h!==l):i==="private"?c.chat.private_list=c.chat.private_list.filter((d,h)=>h!==l):c.chat.ban_user_id=c.chat.ban_user_id.filter((d,h)=>h!==l),e(c)},s=(i,l,c)=>{const d={...t};i==="group"?d.chat.group_list[l]=c:i==="private"?d.chat.private_list[l]=c:d.chat.ban_user_id[l]=c,e(d)};return a.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"聊天黑白名单功能"}),a.jsxs("div",{className:"grid gap-4 md:gap-6",children:[a.jsxs("div",{className:"space-y-3 md:space-y-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-sm md:text-base",children:"群组名单类型"}),a.jsxs(Bt,{value:t.chat.group_list_type,onValueChange:i=>e({...t,chat:{...t.chat,group_list_type:i}}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"whitelist",children:"白名单(仅名单内可聊天)"}),a.jsx(Pe,{value:"blacklist",children:"黑名单(名单内禁止聊天)"})]})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-0",children:[a.jsx(te,{className:"text-sm md:text-base",children:"群组列表"}),a.jsxs(ie,{onClick:()=>n("group"),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[a.jsx(io,{className:"mr-1 h-4 w-4"}),"添加群号"]})]}),t.chat.group_list.map((i,l)=>a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{type:"number",value:i,onChange:c=>s("group",l,parseInt(c.target.value)||0),placeholder:"输入群号",className:"text-sm md:text-base"}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除群号 ",i," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r("group",l),children:"删除"})]})]})]})]},l)),t.chat.group_list.length===0&&a.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无群组"})]})]}),a.jsxs("div",{className:"space-y-3 md:space-y-4",children:[a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-sm md:text-base",children:"私聊名单类型"}),a.jsxs(Bt,{value:t.chat.private_list_type,onValueChange:i=>e({...t,chat:{...t.chat,private_list_type:i}}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"whitelist",children:"白名单(仅名单内可聊天)"}),a.jsx(Pe,{value:"blacklist",children:"黑名单(名单内禁止聊天)"})]})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-0",children:[a.jsx(te,{className:"text-sm md:text-base",children:"私聊列表"}),a.jsxs(ie,{onClick:()=>n("private"),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[a.jsx(io,{className:"mr-1 h-4 w-4"}),"添加用户"]})]}),t.chat.private_list.map((i,l)=>a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{type:"number",value:i,onChange:c=>s("private",l,parseInt(c.target.value)||0),placeholder:"输入QQ号",className:"text-sm md:text-base"}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要删除用户 ",i," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r("private",l),children:"删除"})]})]})]})]},l)),t.chat.private_list.length===0&&a.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无用户"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-0",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-sm md:text-base",children:"全局禁止名单"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"名单中的用户无法进行任何聊天"})]}),a.jsxs(ie,{onClick:()=>n("ban"),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[a.jsx(io,{className:"mr-1 h-4 w-4"}),"添加用户"]})]}),t.chat.ban_user_id.map((i,l)=>a.jsxs("div",{className:"flex gap-2",children:[a.jsx(Ae,{type:"number",value:i,onChange:c=>s("ban",l,parseInt(c.target.value)||0),placeholder:"输入QQ号",className:"text-sm md:text-base"}),a.jsxs(mn,{children:[a.jsx(jr,{asChild:!0,children:a.jsx(ie,{size:"icon",variant:"outline",children:a.jsx(Ht,{className:"h-4 w-4"})})}),a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:["确定要从全局禁止名单中删除用户 ",i," 吗?此操作无法撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>r("ban",l),children:"删除"})]})]})]})]},l)),t.chat.ban_user_id.length===0&&a.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无禁止用户"})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-sm md:text-base",children:"屏蔽QQ官方机器人"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"是否屏蔽来自QQ官方机器人的消息"})]}),a.jsx(jt,{checked:t.chat.ban_qq_bot,onCheckedChange:i=>e({...t,chat:{...t.chat,ban_qq_bot:i}})})]}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-sm md:text-base",children:"启用戳一戳功能"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"是否响应戳一戳消息"})]}),a.jsx(jt,{checked:t.chat.enable_poke,onCheckedChange:i=>e({...t,chat:{...t.chat,enable_poke:i}})})]})]})]})})}function Hte({config:t,onChange:e}){return a.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"发送语音设置"}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-sm md:text-base",children:"使用 TTS 语音"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"请确保已配置 TTS 并有对应的适配器"})]}),a.jsx(jt,{checked:t.voice.use_tts,onCheckedChange:n=>e({...t,voice:{use_tts:n}})})]})]})})}function Ute({config:t,onChange:e}){return a.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"调试设置"}),a.jsx("div",{className:"grid gap-3 md:gap-4",children:a.jsxs("div",{className:"grid gap-2",children:[a.jsx(te,{className:"text-sm md:text-base",children:"日志等级"}),a.jsxs(Bt,{value:t.debug.level,onValueChange:n=>e({...t,debug:{level:n}}),children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"DEBUG",children:"DEBUG(调试)"}),a.jsx(Pe,{value:"INFO",children:"INFO(信息)"}),a.jsx(Pe,{value:"WARNING",children:"WARNING(警告)"}),a.jsx(Pe,{value:"ERROR",children:"ERROR(错误)"}),a.jsx(Pe,{value:"CRITICAL",children:"CRITICAL(严重)"})]})]}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"设置适配器的日志输出等级"})]})})]})})}function u8(t){const e=[],n=String(t||"");let r=n.indexOf(","),s=0,i=!1;for(;!i;){r===-1&&(r=n.length,i=!0);const l=n.slice(s,r).trim();(l||!i)&&e.push(l),s=r+1,r=n.indexOf(",",s)}return e}function Vte(t,e){const n={};return(t[t.length-1]===""?[...t,""]:t).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}const Wte=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,Gte=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,Xte={};function d8(t,e){return(Xte.jsx?Gte:Wte).test(t)}const Yte=/[ \t\n\f\r]/g;function Kte(t){return typeof t=="object"?t.type==="text"?h8(t.value):!1:h8(t)}function h8(t){return t.replace(Yte,"")===""}class x0{constructor(e,n,r){this.normal=n,this.property=e,r&&(this.space=r)}}x0.prototype.normal={};x0.prototype.property={};x0.prototype.space=void 0;function Z_(t,e){const n={},r={};for(const s of t)Object.assign(n,s.property),Object.assign(r,s.normal);return new x0(n,r,e)}function Pf(t){return t.toLowerCase()}class Is{constructor(e,n){this.attribute=n,this.property=e}}Is.prototype.attribute="";Is.prototype.booleanish=!1;Is.prototype.boolean=!1;Is.prototype.commaOrSpaceSeparated=!1;Is.prototype.commaSeparated=!1;Is.prototype.defined=!1;Is.prototype.mustUseProperty=!1;Is.prototype.number=!1;Is.prototype.overloadedBoolean=!1;Is.prototype.property="";Is.prototype.spaceSeparated=!1;Is.prototype.space=void 0;let Zte=0;const Ot=Dc(),mr=Dc(),h4=Dc(),ze=Dc(),Pn=Dc(),Ju=Dc(),Zs=Dc();function Dc(){return 2**++Zte}const f4=Object.freeze(Object.defineProperty({__proto__:null,boolean:Ot,booleanish:mr,commaOrSpaceSeparated:Zs,commaSeparated:Ju,number:ze,overloadedBoolean:h4,spaceSeparated:Pn},Symbol.toStringTag,{value:"Module"})),hb=Object.keys(f4);class c5 extends Is{constructor(e,n,r,s){let i=-1;if(super(e,n),f8(this,"space",s),typeof r=="number")for(;++i4&&n.slice(0,4)==="data"&&rne.test(e)){if(e.charAt(4)==="-"){const i=e.slice(5).replace(m8,ine);r="data"+i.charAt(0).toUpperCase()+i.slice(1)}else{const i=e.slice(4);if(!m8.test(i)){let l=i.replace(nne,sne);l.charAt(0)!=="-"&&(l="-"+l),e="data"+l}}s=c5}return new s(r,e)}function sne(t){return"-"+t.toLowerCase()}function ine(t){return t.charAt(1).toUpperCase()}const aD=Z_([J_,Jte,nD,rD,sD],"html"),Bx=Z_([J_,ene,nD,rD,sD],"svg");function p8(t){const e=String(t||"").trim();return e?e.split(/[ \t\n\r\f]+/g):[]}function ane(t){return t.join(" ").trim()}var Nu={},fb,g8;function lne(){if(g8)return fb;g8=1;var t=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,e=/\n/g,n=/^\s*/,r=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,s=/^:\s*/,i=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,l=/^[;\s]*/,c=/^\s+|\s+$/g,d=` -`,h="/",m="*",p="",x="comment",v="declaration";function b(O,j){if(typeof O!="string")throw new TypeError("First argument must be a string");if(!O)return[];j=j||{};var T=1,M=1;function _(W){var J=W.match(e);J&&(T+=J.length);var H=W.lastIndexOf(d);M=~H?W.length-H:M+W.length}function D(){var W={line:T,column:M};return function(J){return J.position=new E(W),F(),J}}function E(W){this.start=W,this.end={line:T,column:M},this.source=j.source}E.prototype.content=O;function z(W){var J=new Error(j.source+":"+T+":"+M+": "+W);if(J.reason=W,J.filename=j.source,J.line=T,J.column=M,J.source=O,!j.silent)throw J}function Q(W){var J=W.exec(O);if(J){var H=J[0];return _(H),O=O.slice(H.length),J}}function F(){Q(n)}function B(W){var J;for(W=W||[];J=U();)J!==!1&&W.push(J);return W}function U(){var W=D();if(!(h!=O.charAt(0)||m!=O.charAt(1))){for(var J=2;p!=O.charAt(J)&&(m!=O.charAt(J)||h!=O.charAt(J+1));)++J;if(J+=2,p===O.charAt(J-1))return z("End of comment missing");var H=O.slice(2,J-2);return M+=2,_(H),O=O.slice(J),M+=2,W({type:x,comment:H})}}function V(){var W=D(),J=Q(r);if(J){if(U(),!Q(s))return z("property missing ':'");var H=Q(i),ae=W({type:v,property:k(J[0].replace(t,p)),value:H?k(H[0].replace(t,p)):p});return Q(l),ae}}function ce(){var W=[];B(W);for(var J;J=V();)J!==!1&&(W.push(J),B(W));return W}return F(),ce()}function k(O){return O?O.replace(c,p):p}return fb=b,fb}var x8;function one(){if(x8)return Nu;x8=1;var t=Nu&&Nu.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(Nu,"__esModule",{value:!0}),Nu.default=n;const e=t(lne());function n(r,s){let i=null;if(!r||typeof r!="string")return i;const l=(0,e.default)(r),c=typeof s=="function";return l.forEach(d=>{if(d.type!=="declaration")return;const{property:h,value:m}=d;c?s(h,m,d):m&&(i=i||{},i[h]=m)}),i}return Nu}var Bh={},v8;function cne(){if(v8)return Bh;v8=1,Object.defineProperty(Bh,"__esModule",{value:!0}),Bh.camelCase=void 0;var t=/^--[a-zA-Z0-9_-]+$/,e=/-([a-z])/g,n=/^[^-]+$/,r=/^-(webkit|moz|ms|o|khtml)-/,s=/^-(ms)-/,i=function(h){return!h||n.test(h)||t.test(h)},l=function(h,m){return m.toUpperCase()},c=function(h,m){return"".concat(m,"-")},d=function(h,m){return m===void 0&&(m={}),i(h)?h:(h=h.toLowerCase(),m.reactCompat?h=h.replace(s,c):h=h.replace(r,c),h.replace(e,l))};return Bh.camelCase=d,Bh}var Ih,y8;function une(){if(y8)return Ih;y8=1;var t=Ih&&Ih.__importDefault||function(s){return s&&s.__esModule?s:{default:s}},e=t(one()),n=cne();function r(s,i){var l={};return!s||typeof s!="string"||(0,e.default)(s,function(c,d){c&&d&&(l[(0,n.camelCase)(c,i)]=d)}),l}return r.default=r,Ih=r,Ih}var dne=une();const hne=u9(dne),lD=oD("end"),u5=oD("start");function oD(t){return e;function e(n){const r=n&&n.position&&n.position[t]||{};if(typeof r.line=="number"&&r.line>0&&typeof r.column=="number"&&r.column>0)return{line:r.line,column:r.column,offset:typeof r.offset=="number"&&r.offset>-1?r.offset:void 0}}}function fne(t){const e=u5(t),n=lD(t);if(e&&n)return{start:e,end:n}}function af(t){return!t||typeof t!="object"?"":"position"in t||"type"in t?b8(t.position):"start"in t||"end"in t?b8(t):"line"in t||"column"in t?m4(t):""}function m4(t){return w8(t&&t.line)+":"+w8(t&&t.column)}function b8(t){return m4(t&&t.start)+"-"+m4(t&&t.end)}function w8(t){return t&&typeof t=="number"?t:1}class as extends Error{constructor(e,n,r){super(),typeof n=="string"&&(r=n,n=void 0);let s="",i={},l=!1;if(n&&("line"in n&&"column"in n?i={place:n}:"start"in n&&"end"in n?i={place:n}:"type"in n?i={ancestors:[n],place:n.position}:i={...n}),typeof e=="string"?s=e:!i.cause&&e&&(l=!0,s=e.message,i.cause=e),!i.ruleId&&!i.source&&typeof r=="string"){const d=r.indexOf(":");d===-1?i.ruleId=r:(i.source=r.slice(0,d),i.ruleId=r.slice(d+1))}if(!i.place&&i.ancestors&&i.ancestors){const d=i.ancestors[i.ancestors.length-1];d&&(i.place=d.position)}const c=i.place&&"start"in i.place?i.place.start:i.place;this.ancestors=i.ancestors||void 0,this.cause=i.cause||void 0,this.column=c?c.column:void 0,this.fatal=void 0,this.file="",this.message=s,this.line=c?c.line:void 0,this.name=af(i.place)||"1:1",this.place=i.place||void 0,this.reason=this.message,this.ruleId=i.ruleId||void 0,this.source=i.source||void 0,this.stack=l&&i.cause&&typeof i.cause.stack=="string"?i.cause.stack:"",this.actual=void 0,this.expected=void 0,this.note=void 0,this.url=void 0}}as.prototype.file="";as.prototype.name="";as.prototype.reason="";as.prototype.message="";as.prototype.stack="";as.prototype.column=void 0;as.prototype.line=void 0;as.prototype.ancestors=void 0;as.prototype.cause=void 0;as.prototype.fatal=void 0;as.prototype.place=void 0;as.prototype.ruleId=void 0;as.prototype.source=void 0;const d5={}.hasOwnProperty,mne=new Map,pne=/[A-Z]/g,gne=new Set(["table","tbody","thead","tfoot","tr"]),xne=new Set(["td","th"]),cD="https://github.com/syntax-tree/hast-util-to-jsx-runtime";function vne(t,e){if(!e||e.Fragment===void 0)throw new TypeError("Expected `Fragment` in options");const n=e.filePath||void 0;let r;if(e.development){if(typeof e.jsxDEV!="function")throw new TypeError("Expected `jsxDEV` in options when `development: true`");r=Nne(n,e.jsxDEV)}else{if(typeof e.jsx!="function")throw new TypeError("Expected `jsx` in production options");if(typeof e.jsxs!="function")throw new TypeError("Expected `jsxs` in production options");r=jne(n,e.jsx,e.jsxs)}const s={Fragment:e.Fragment,ancestors:[],components:e.components||{},create:r,elementAttributeNameCase:e.elementAttributeNameCase||"react",evaluater:e.createEvaluater?e.createEvaluater():void 0,filePath:n,ignoreInvalidStyle:e.ignoreInvalidStyle||!1,passKeys:e.passKeys!==!1,passNode:e.passNode||!1,schema:e.space==="svg"?Bx:aD,stylePropertyNameCase:e.stylePropertyNameCase||"dom",tableCellAlignToStyle:e.tableCellAlignToStyle!==!1},i=uD(s,t,void 0);return i&&typeof i!="string"?i:s.create(t,s.Fragment,{children:i||void 0},void 0)}function uD(t,e,n){if(e.type==="element")return yne(t,e,n);if(e.type==="mdxFlowExpression"||e.type==="mdxTextExpression")return bne(t,e);if(e.type==="mdxJsxFlowElement"||e.type==="mdxJsxTextElement")return Sne(t,e,n);if(e.type==="mdxjsEsm")return wne(t,e);if(e.type==="root")return kne(t,e,n);if(e.type==="text")return One(t,e)}function yne(t,e,n){const r=t.schema;let s=r;e.tagName.toLowerCase()==="svg"&&r.space==="html"&&(s=Bx,t.schema=s),t.ancestors.push(e);const i=hD(t,e.tagName,!1),l=Cne(t,e);let c=f5(t,e);return gne.has(e.tagName)&&(c=c.filter(function(d){return typeof d=="string"?!Kte(d):!0})),dD(t,l,i,e),h5(l,c),t.ancestors.pop(),t.schema=r,t.create(e,i,l,n)}function bne(t,e){if(e.data&&e.data.estree&&t.evaluater){const r=e.data.estree.body[0];return r.type,t.evaluater.evaluateExpression(r.expression)}Lf(t,e.position)}function wne(t,e){if(e.data&&e.data.estree&&t.evaluater)return t.evaluater.evaluateProgram(e.data.estree);Lf(t,e.position)}function Sne(t,e,n){const r=t.schema;let s=r;e.name==="svg"&&r.space==="html"&&(s=Bx,t.schema=s),t.ancestors.push(e);const i=e.name===null?t.Fragment:hD(t,e.name,!0),l=Tne(t,e),c=f5(t,e);return dD(t,l,i,e),h5(l,c),t.ancestors.pop(),t.schema=r,t.create(e,i,l,n)}function kne(t,e,n){const r={};return h5(r,f5(t,e)),t.create(e,t.Fragment,r,n)}function One(t,e){return e.value}function dD(t,e,n,r){typeof n!="string"&&n!==t.Fragment&&t.passNode&&(e.node=r)}function h5(t,e){if(e.length>0){const n=e.length>1?e:e[0];n&&(t.children=n)}}function jne(t,e,n){return r;function r(s,i,l,c){const h=Array.isArray(l.children)?n:e;return c?h(i,l,c):h(i,l)}}function Nne(t,e){return n;function n(r,s,i,l){const c=Array.isArray(i.children),d=u5(r);return e(s,i,l,c,{columnNumber:d?d.column-1:void 0,fileName:t,lineNumber:d?d.line:void 0},void 0)}}function Cne(t,e){const n={};let r,s;for(s in e.properties)if(s!=="children"&&d5.call(e.properties,s)){const i=Mne(t,s,e.properties[s]);if(i){const[l,c]=i;t.tableCellAlignToStyle&&l==="align"&&typeof c=="string"&&xne.has(e.tagName)?r=c:n[l]=c}}if(r){const i=n.style||(n.style={});i[t.stylePropertyNameCase==="css"?"text-align":"textAlign"]=r}return n}function Tne(t,e){const n={};for(const r of e.attributes)if(r.type==="mdxJsxExpressionAttribute")if(r.data&&r.data.estree&&t.evaluater){const i=r.data.estree.body[0];i.type;const l=i.expression;l.type;const c=l.properties[0];c.type,Object.assign(n,t.evaluater.evaluateExpression(c.argument))}else Lf(t,e.position);else{const s=r.name;let i;if(r.value&&typeof r.value=="object")if(r.value.data&&r.value.data.estree&&t.evaluater){const c=r.value.data.estree.body[0];c.type,i=t.evaluater.evaluateExpression(c.expression)}else Lf(t,e.position);else i=r.value===null?!0:r.value;n[s]=i}return n}function f5(t,e){const n=[];let r=-1;const s=t.passKeys?new Map:mne;for(;++rs?0:s+e:e=e>s?s:e,n=n>0?n:0,r.length<1e4)l=Array.from(r),l.unshift(e,n),t.splice(...l);else for(n&&t.splice(e,n);i0?(ri(t,t.length,0,e),t):e}const O8={}.hasOwnProperty;function mD(t){const e={};let n=-1;for(;++n13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||(n&65535)===65535||(n&65535)===65534||n>1114111?"�":String.fromCodePoint(n)}function qi(t){return t.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ds=To(/[A-Za-z]/),rs=To(/[\dA-Za-z]/),Bne=To(/[#-'*+\--9=?A-Z^-~]/);function Hg(t){return t!==null&&(t<32||t===127)}const p4=To(/\d/),Ine=To(/[\dA-Fa-f]/),qne=To(/[!-/:-@[-`{-~]/);function Ze(t){return t!==null&&t<-2}function Dn(t){return t!==null&&(t<0||t===32)}function qt(t){return t===-2||t===-1||t===32}const Ix=To(new RegExp("\\p{P}|\\p{S}","u")),Cc=To(/\s/);function To(t){return e;function e(n){return n!==null&&n>-1&&t.test(String.fromCharCode(n))}}function Dd(t){const e=[];let n=-1,r=0,s=0;for(;++n55295&&i<57344){const c=t.charCodeAt(n+1);i<56320&&c>56319&&c<57344?(l=String.fromCharCode(i,c),s=1):l="�"}else l=String.fromCharCode(i);l&&(e.push(t.slice(r,n),encodeURIComponent(l)),r=n+s+1,l=""),s&&(n+=s,s=0)}return e.join("")+t.slice(r)}function zt(t,e,n,r){const s=r?r-1:Number.POSITIVE_INFINITY;let i=0;return l;function l(d){return qt(d)?(t.enter(n),c(d)):e(d)}function c(d){return qt(d)&&i++l))return;const z=e.events.length;let Q=z,F,B;for(;Q--;)if(e.events[Q][0]==="exit"&&e.events[Q][1].type==="chunkFlow"){if(F){B=e.events[Q][1].end;break}F=!0}for(j(r),E=z;EM;){const D=n[_];e.containerState=D[1],D[0].exit.call(e,t)}n.length=M}function T(){s.write([null]),i=void 0,s=void 0,e.containerState._closeFlow=void 0}}function Une(t,e,n){return zt(t,t.attempt(this.parser.constructs.document,e,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function vd(t){if(t===null||Dn(t)||Cc(t))return 1;if(Ix(t))return 2}function qx(t,e,n){const r=[];let s=-1;for(;++s1&&t[n][1].end.offset-t[n][1].start.offset>1?2:1;const p={...t[r][1].end},x={...t[n][1].start};N8(p,-d),N8(x,d),l={type:d>1?"strongSequence":"emphasisSequence",start:p,end:{...t[r][1].end}},c={type:d>1?"strongSequence":"emphasisSequence",start:{...t[n][1].start},end:x},i={type:d>1?"strongText":"emphasisText",start:{...t[r][1].end},end:{...t[n][1].start}},s={type:d>1?"strong":"emphasis",start:{...l.start},end:{...c.end}},t[r][1].end={...l.start},t[n][1].start={...c.end},h=[],t[r][1].end.offset-t[r][1].start.offset&&(h=yi(h,[["enter",t[r][1],e],["exit",t[r][1],e]])),h=yi(h,[["enter",s,e],["enter",l,e],["exit",l,e],["enter",i,e]]),h=yi(h,qx(e.parser.constructs.insideSpan.null,t.slice(r+1,n),e)),h=yi(h,[["exit",i,e],["enter",c,e],["exit",c,e],["exit",s,e]]),t[n][1].end.offset-t[n][1].start.offset?(m=2,h=yi(h,[["enter",t[n][1],e],["exit",t[n][1],e]])):m=0,ri(t,r-1,n-r+3,h),n=r+h.length-m-2;break}}for(n=-1;++n0&&qt(E)?zt(t,T,"linePrefix",i+1)(E):T(E)}function T(E){return E===null||Ze(E)?t.check(C8,k,_)(E):(t.enter("codeFlowValue"),M(E))}function M(E){return E===null||Ze(E)?(t.exit("codeFlowValue"),T(E)):(t.consume(E),M)}function _(E){return t.exit("codeFenced"),e(E)}function D(E,z,Q){let F=0;return B;function B(J){return E.enter("lineEnding"),E.consume(J),E.exit("lineEnding"),U}function U(J){return E.enter("codeFencedFence"),qt(J)?zt(E,V,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(J):V(J)}function V(J){return J===c?(E.enter("codeFencedFenceSequence"),ce(J)):Q(J)}function ce(J){return J===c?(F++,E.consume(J),ce):F>=l?(E.exit("codeFencedFenceSequence"),qt(J)?zt(E,W,"whitespace")(J):W(J)):Q(J)}function W(J){return J===null||Ze(J)?(E.exit("codeFencedFence"),z(J)):Q(J)}}}function rre(t,e,n){const r=this;return s;function s(l){return l===null?n(l):(t.enter("lineEnding"),t.consume(l),t.exit("lineEnding"),i)}function i(l){return r.parser.lazy[r.now().line]?n(l):e(l)}}const pb={name:"codeIndented",tokenize:ire},sre={partial:!0,tokenize:are};function ire(t,e,n){const r=this;return s;function s(h){return t.enter("codeIndented"),zt(t,i,"linePrefix",5)(h)}function i(h){const m=r.events[r.events.length-1];return m&&m[1].type==="linePrefix"&&m[2].sliceSerialize(m[1],!0).length>=4?l(h):n(h)}function l(h){return h===null?d(h):Ze(h)?t.attempt(sre,l,d)(h):(t.enter("codeFlowValue"),c(h))}function c(h){return h===null||Ze(h)?(t.exit("codeFlowValue"),l(h)):(t.consume(h),c)}function d(h){return t.exit("codeIndented"),e(h)}}function are(t,e,n){const r=this;return s;function s(l){return r.parser.lazy[r.now().line]?n(l):Ze(l)?(t.enter("lineEnding"),t.consume(l),t.exit("lineEnding"),s):zt(t,i,"linePrefix",5)(l)}function i(l){const c=r.events[r.events.length-1];return c&&c[1].type==="linePrefix"&&c[2].sliceSerialize(c[1],!0).length>=4?e(l):Ze(l)?s(l):n(l)}}const lre={name:"codeText",previous:cre,resolve:ore,tokenize:ure};function ore(t){let e=t.length-4,n=3,r,s;if((t[n][1].type==="lineEnding"||t[n][1].type==="space")&&(t[e][1].type==="lineEnding"||t[e][1].type==="space")){for(r=n;++r=this.left.length+this.right.length)throw new RangeError("Cannot access index `"+e+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return ethis.left.length?this.right.slice(this.right.length-r+this.left.length,this.right.length-e+this.left.length).reverse():this.left.slice(e).concat(this.right.slice(this.right.length-r+this.left.length).reverse())}splice(e,n,r){const s=n||0;this.setCursor(Math.trunc(e));const i=this.right.splice(this.right.length-s,Number.POSITIVE_INFINITY);return r&&qh(this.left,r),i.reverse()}pop(){return this.setCursor(Number.POSITIVE_INFINITY),this.left.pop()}push(e){this.setCursor(Number.POSITIVE_INFINITY),this.left.push(e)}pushMany(e){this.setCursor(Number.POSITIVE_INFINITY),qh(this.left,e)}unshift(e){this.setCursor(0),this.right.push(e)}unshiftMany(e){this.setCursor(0),qh(this.right,e.reverse())}setCursor(e){if(!(e===this.left.length||e>this.left.length&&this.right.length===0||e<0&&this.left.length===0))if(e=4?e(l):t.interrupt(r.parser.constructs.flow,n,e)(l)}}function bD(t,e,n,r,s,i,l,c,d){const h=d||Number.POSITIVE_INFINITY;let m=0;return p;function p(j){return j===60?(t.enter(r),t.enter(s),t.enter(i),t.consume(j),t.exit(i),x):j===null||j===32||j===41||Hg(j)?n(j):(t.enter(r),t.enter(l),t.enter(c),t.enter("chunkString",{contentType:"string"}),k(j))}function x(j){return j===62?(t.enter(i),t.consume(j),t.exit(i),t.exit(s),t.exit(r),e):(t.enter(c),t.enter("chunkString",{contentType:"string"}),v(j))}function v(j){return j===62?(t.exit("chunkString"),t.exit(c),x(j)):j===null||j===60||Ze(j)?n(j):(t.consume(j),j===92?b:v)}function b(j){return j===60||j===62||j===92?(t.consume(j),v):v(j)}function k(j){return!m&&(j===null||j===41||Dn(j))?(t.exit("chunkString"),t.exit(c),t.exit(l),t.exit(r),e(j)):m999||v===null||v===91||v===93&&!d||v===94&&!c&&"_hiddenFootnoteSupport"in l.parser.constructs?n(v):v===93?(t.exit(i),t.enter(s),t.consume(v),t.exit(s),t.exit(r),e):Ze(v)?(t.enter("lineEnding"),t.consume(v),t.exit("lineEnding"),m):(t.enter("chunkString",{contentType:"string"}),p(v))}function p(v){return v===null||v===91||v===93||Ze(v)||c++>999?(t.exit("chunkString"),m(v)):(t.consume(v),d||(d=!qt(v)),v===92?x:p)}function x(v){return v===91||v===92||v===93?(t.consume(v),c++,p):p(v)}}function SD(t,e,n,r,s,i){let l;return c;function c(x){return x===34||x===39||x===40?(t.enter(r),t.enter(s),t.consume(x),t.exit(s),l=x===40?41:x,d):n(x)}function d(x){return x===l?(t.enter(s),t.consume(x),t.exit(s),t.exit(r),e):(t.enter(i),h(x))}function h(x){return x===l?(t.exit(i),d(l)):x===null?n(x):Ze(x)?(t.enter("lineEnding"),t.consume(x),t.exit("lineEnding"),zt(t,h,"linePrefix")):(t.enter("chunkString",{contentType:"string"}),m(x))}function m(x){return x===l||x===null||Ze(x)?(t.exit("chunkString"),h(x)):(t.consume(x),x===92?p:m)}function p(x){return x===l||x===92?(t.consume(x),m):m(x)}}function lf(t,e){let n;return r;function r(s){return Ze(s)?(t.enter("lineEnding"),t.consume(s),t.exit("lineEnding"),n=!0,r):qt(s)?zt(t,r,n?"linePrefix":"lineSuffix")(s):e(s)}}const vre={name:"definition",tokenize:bre},yre={partial:!0,tokenize:wre};function bre(t,e,n){const r=this;let s;return i;function i(v){return t.enter("definition"),l(v)}function l(v){return wD.call(r,t,c,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(v)}function c(v){return s=qi(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),v===58?(t.enter("definitionMarker"),t.consume(v),t.exit("definitionMarker"),d):n(v)}function d(v){return Dn(v)?lf(t,h)(v):h(v)}function h(v){return bD(t,m,n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(v)}function m(v){return t.attempt(yre,p,p)(v)}function p(v){return qt(v)?zt(t,x,"whitespace")(v):x(v)}function x(v){return v===null||Ze(v)?(t.exit("definition"),r.parser.defined.push(s),e(v)):n(v)}}function wre(t,e,n){return r;function r(c){return Dn(c)?lf(t,s)(c):n(c)}function s(c){return SD(t,i,n,"definitionTitle","definitionTitleMarker","definitionTitleString")(c)}function i(c){return qt(c)?zt(t,l,"whitespace")(c):l(c)}function l(c){return c===null||Ze(c)?e(c):n(c)}}const Sre={name:"hardBreakEscape",tokenize:kre};function kre(t,e,n){return r;function r(i){return t.enter("hardBreakEscape"),t.consume(i),s}function s(i){return Ze(i)?(t.exit("hardBreakEscape"),e(i)):n(i)}}const Ore={name:"headingAtx",resolve:jre,tokenize:Nre};function jre(t,e){let n=t.length-2,r=3,s,i;return t[r][1].type==="whitespace"&&(r+=2),n-2>r&&t[n][1].type==="whitespace"&&(n-=2),t[n][1].type==="atxHeadingSequence"&&(r===n-1||n-4>r&&t[n-2][1].type==="whitespace")&&(n-=r+1===n?2:4),n>r&&(s={type:"atxHeadingText",start:t[r][1].start,end:t[n][1].end},i={type:"chunkText",start:t[r][1].start,end:t[n][1].end,contentType:"text"},ri(t,r,n-r+1,[["enter",s,e],["enter",i,e],["exit",i,e],["exit",s,e]])),t}function Nre(t,e,n){let r=0;return s;function s(m){return t.enter("atxHeading"),i(m)}function i(m){return t.enter("atxHeadingSequence"),l(m)}function l(m){return m===35&&r++<6?(t.consume(m),l):m===null||Dn(m)?(t.exit("atxHeadingSequence"),c(m)):n(m)}function c(m){return m===35?(t.enter("atxHeadingSequence"),d(m)):m===null||Ze(m)?(t.exit("atxHeading"),e(m)):qt(m)?zt(t,c,"whitespace")(m):(t.enter("atxHeadingText"),h(m))}function d(m){return m===35?(t.consume(m),d):(t.exit("atxHeadingSequence"),c(m))}function h(m){return m===null||m===35||Dn(m)?(t.exit("atxHeadingText"),c(m)):(t.consume(m),h)}}const Cre=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],M8=["pre","script","style","textarea"],Tre={concrete:!0,name:"htmlFlow",resolveTo:Ere,tokenize:_re},Mre={partial:!0,tokenize:Rre},Are={partial:!0,tokenize:Dre};function Ere(t){let e=t.length;for(;e--&&!(t[e][0]==="enter"&&t[e][1].type==="htmlFlow"););return e>1&&t[e-2][1].type==="linePrefix"&&(t[e][1].start=t[e-2][1].start,t[e+1][1].start=t[e-2][1].start,t.splice(e-2,2)),t}function _re(t,e,n){const r=this;let s,i,l,c,d;return h;function h(P){return m(P)}function m(P){return t.enter("htmlFlow"),t.enter("htmlFlowData"),t.consume(P),p}function p(P){return P===33?(t.consume(P),x):P===47?(t.consume(P),i=!0,k):P===63?(t.consume(P),s=3,r.interrupt?e:R):ds(P)?(t.consume(P),l=String.fromCharCode(P),O):n(P)}function x(P){return P===45?(t.consume(P),s=2,v):P===91?(t.consume(P),s=5,c=0,b):ds(P)?(t.consume(P),s=4,r.interrupt?e:R):n(P)}function v(P){return P===45?(t.consume(P),r.interrupt?e:R):n(P)}function b(P){const K="CDATA[";return P===K.charCodeAt(c++)?(t.consume(P),c===K.length?r.interrupt?e:V:b):n(P)}function k(P){return ds(P)?(t.consume(P),l=String.fromCharCode(P),O):n(P)}function O(P){if(P===null||P===47||P===62||Dn(P)){const K=P===47,$=l.toLowerCase();return!K&&!i&&M8.includes($)?(s=1,r.interrupt?e(P):V(P)):Cre.includes(l.toLowerCase())?(s=6,K?(t.consume(P),j):r.interrupt?e(P):V(P)):(s=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(P):i?T(P):M(P))}return P===45||rs(P)?(t.consume(P),l+=String.fromCharCode(P),O):n(P)}function j(P){return P===62?(t.consume(P),r.interrupt?e:V):n(P)}function T(P){return qt(P)?(t.consume(P),T):B(P)}function M(P){return P===47?(t.consume(P),B):P===58||P===95||ds(P)?(t.consume(P),_):qt(P)?(t.consume(P),M):B(P)}function _(P){return P===45||P===46||P===58||P===95||rs(P)?(t.consume(P),_):D(P)}function D(P){return P===61?(t.consume(P),E):qt(P)?(t.consume(P),D):M(P)}function E(P){return P===null||P===60||P===61||P===62||P===96?n(P):P===34||P===39?(t.consume(P),d=P,z):qt(P)?(t.consume(P),E):Q(P)}function z(P){return P===d?(t.consume(P),d=null,F):P===null||Ze(P)?n(P):(t.consume(P),z)}function Q(P){return P===null||P===34||P===39||P===47||P===60||P===61||P===62||P===96||Dn(P)?D(P):(t.consume(P),Q)}function F(P){return P===47||P===62||qt(P)?M(P):n(P)}function B(P){return P===62?(t.consume(P),U):n(P)}function U(P){return P===null||Ze(P)?V(P):qt(P)?(t.consume(P),U):n(P)}function V(P){return P===45&&s===2?(t.consume(P),H):P===60&&s===1?(t.consume(P),ae):P===62&&s===4?(t.consume(P),me):P===63&&s===3?(t.consume(P),R):P===93&&s===5?(t.consume(P),ue):Ze(P)&&(s===6||s===7)?(t.exit("htmlFlowData"),t.check(Mre,Y,ce)(P)):P===null||Ze(P)?(t.exit("htmlFlowData"),ce(P)):(t.consume(P),V)}function ce(P){return t.check(Are,W,Y)(P)}function W(P){return t.enter("lineEnding"),t.consume(P),t.exit("lineEnding"),J}function J(P){return P===null||Ze(P)?ce(P):(t.enter("htmlFlowData"),V(P))}function H(P){return P===45?(t.consume(P),R):V(P)}function ae(P){return P===47?(t.consume(P),l="",ne):V(P)}function ne(P){if(P===62){const K=l.toLowerCase();return M8.includes(K)?(t.consume(P),me):V(P)}return ds(P)&&l.length<8?(t.consume(P),l+=String.fromCharCode(P),ne):V(P)}function ue(P){return P===93?(t.consume(P),R):V(P)}function R(P){return P===62?(t.consume(P),me):P===45&&s===2?(t.consume(P),R):V(P)}function me(P){return P===null||Ze(P)?(t.exit("htmlFlowData"),Y(P)):(t.consume(P),me)}function Y(P){return t.exit("htmlFlow"),e(P)}}function Dre(t,e,n){const r=this;return s;function s(l){return Ze(l)?(t.enter("lineEnding"),t.consume(l),t.exit("lineEnding"),i):n(l)}function i(l){return r.parser.lazy[r.now().line]?n(l):e(l)}}function Rre(t,e,n){return r;function r(s){return t.enter("lineEnding"),t.consume(s),t.exit("lineEnding"),t.attempt(v0,e,n)}}const zre={name:"htmlText",tokenize:Pre};function Pre(t,e,n){const r=this;let s,i,l;return c;function c(R){return t.enter("htmlText"),t.enter("htmlTextData"),t.consume(R),d}function d(R){return R===33?(t.consume(R),h):R===47?(t.consume(R),D):R===63?(t.consume(R),M):ds(R)?(t.consume(R),Q):n(R)}function h(R){return R===45?(t.consume(R),m):R===91?(t.consume(R),i=0,b):ds(R)?(t.consume(R),T):n(R)}function m(R){return R===45?(t.consume(R),v):n(R)}function p(R){return R===null?n(R):R===45?(t.consume(R),x):Ze(R)?(l=p,ae(R)):(t.consume(R),p)}function x(R){return R===45?(t.consume(R),v):p(R)}function v(R){return R===62?H(R):R===45?x(R):p(R)}function b(R){const me="CDATA[";return R===me.charCodeAt(i++)?(t.consume(R),i===me.length?k:b):n(R)}function k(R){return R===null?n(R):R===93?(t.consume(R),O):Ze(R)?(l=k,ae(R)):(t.consume(R),k)}function O(R){return R===93?(t.consume(R),j):k(R)}function j(R){return R===62?H(R):R===93?(t.consume(R),j):k(R)}function T(R){return R===null||R===62?H(R):Ze(R)?(l=T,ae(R)):(t.consume(R),T)}function M(R){return R===null?n(R):R===63?(t.consume(R),_):Ze(R)?(l=M,ae(R)):(t.consume(R),M)}function _(R){return R===62?H(R):M(R)}function D(R){return ds(R)?(t.consume(R),E):n(R)}function E(R){return R===45||rs(R)?(t.consume(R),E):z(R)}function z(R){return Ze(R)?(l=z,ae(R)):qt(R)?(t.consume(R),z):H(R)}function Q(R){return R===45||rs(R)?(t.consume(R),Q):R===47||R===62||Dn(R)?F(R):n(R)}function F(R){return R===47?(t.consume(R),H):R===58||R===95||ds(R)?(t.consume(R),B):Ze(R)?(l=F,ae(R)):qt(R)?(t.consume(R),F):H(R)}function B(R){return R===45||R===46||R===58||R===95||rs(R)?(t.consume(R),B):U(R)}function U(R){return R===61?(t.consume(R),V):Ze(R)?(l=U,ae(R)):qt(R)?(t.consume(R),U):F(R)}function V(R){return R===null||R===60||R===61||R===62||R===96?n(R):R===34||R===39?(t.consume(R),s=R,ce):Ze(R)?(l=V,ae(R)):qt(R)?(t.consume(R),V):(t.consume(R),W)}function ce(R){return R===s?(t.consume(R),s=void 0,J):R===null?n(R):Ze(R)?(l=ce,ae(R)):(t.consume(R),ce)}function W(R){return R===null||R===34||R===39||R===60||R===61||R===96?n(R):R===47||R===62||Dn(R)?F(R):(t.consume(R),W)}function J(R){return R===47||R===62||Dn(R)?F(R):n(R)}function H(R){return R===62?(t.consume(R),t.exit("htmlTextData"),t.exit("htmlText"),e):n(R)}function ae(R){return t.exit("htmlTextData"),t.enter("lineEnding"),t.consume(R),t.exit("lineEnding"),ne}function ne(R){return qt(R)?zt(t,ue,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(R):ue(R)}function ue(R){return t.enter("htmlTextData"),l(R)}}const g5={name:"labelEnd",resolveAll:qre,resolveTo:Fre,tokenize:Qre},Lre={tokenize:$re},Bre={tokenize:Hre},Ire={tokenize:Ure};function qre(t){let e=-1;const n=[];for(;++e=3&&(h===null||Ze(h))?(t.exit("thematicBreak"),e(h)):n(h)}function d(h){return h===s?(t.consume(h),r++,d):(t.exit("thematicBreakSequence"),qt(h)?zt(t,c,"whitespace")(h):c(h))}}const Ns={continuation:{tokenize:tse},exit:rse,name:"list",tokenize:ese},Zre={partial:!0,tokenize:sse},Jre={partial:!0,tokenize:nse};function ese(t,e,n){const r=this,s=r.events[r.events.length-1];let i=s&&s[1].type==="linePrefix"?s[2].sliceSerialize(s[1],!0).length:0,l=0;return c;function c(v){const b=r.containerState.type||(v===42||v===43||v===45?"listUnordered":"listOrdered");if(b==="listUnordered"?!r.containerState.marker||v===r.containerState.marker:p4(v)){if(r.containerState.type||(r.containerState.type=b,t.enter(b,{_container:!0})),b==="listUnordered")return t.enter("listItemPrefix"),v===42||v===45?t.check(og,n,h)(v):h(v);if(!r.interrupt||v===49)return t.enter("listItemPrefix"),t.enter("listItemValue"),d(v)}return n(v)}function d(v){return p4(v)&&++l<10?(t.consume(v),d):(!r.interrupt||l<2)&&(r.containerState.marker?v===r.containerState.marker:v===41||v===46)?(t.exit("listItemValue"),h(v)):n(v)}function h(v){return t.enter("listItemMarker"),t.consume(v),t.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||v,t.check(v0,r.interrupt?n:m,t.attempt(Zre,x,p))}function m(v){return r.containerState.initialBlankLine=!0,i++,x(v)}function p(v){return qt(v)?(t.enter("listItemPrefixWhitespace"),t.consume(v),t.exit("listItemPrefixWhitespace"),x):n(v)}function x(v){return r.containerState.size=i+r.sliceSerialize(t.exit("listItemPrefix"),!0).length,e(v)}}function tse(t,e,n){const r=this;return r.containerState._closeFlow=void 0,t.check(v0,s,i);function s(c){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,zt(t,e,"listItemIndent",r.containerState.size+1)(c)}function i(c){return r.containerState.furtherBlankLines||!qt(c)?(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,l(c)):(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,t.attempt(Jre,e,l)(c))}function l(c){return r.containerState._closeFlow=!0,r.interrupt=void 0,zt(t,t.attempt(Ns,e,n),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(c)}}function nse(t,e,n){const r=this;return zt(t,s,"listItemIndent",r.containerState.size+1);function s(i){const l=r.events[r.events.length-1];return l&&l[1].type==="listItemIndent"&&l[2].sliceSerialize(l[1],!0).length===r.containerState.size?e(i):n(i)}}function rse(t){t.exit(this.containerState.type)}function sse(t,e,n){const r=this;return zt(t,s,"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function s(i){const l=r.events[r.events.length-1];return!qt(i)&&l&&l[1].type==="listItemPrefixWhitespace"?e(i):n(i)}}const A8={name:"setextUnderline",resolveTo:ise,tokenize:ase};function ise(t,e){let n=t.length,r,s,i;for(;n--;)if(t[n][0]==="enter"){if(t[n][1].type==="content"){r=n;break}t[n][1].type==="paragraph"&&(s=n)}else t[n][1].type==="content"&&t.splice(n,1),!i&&t[n][1].type==="definition"&&(i=n);const l={type:"setextHeading",start:{...t[r][1].start},end:{...t[t.length-1][1].end}};return t[s][1].type="setextHeadingText",i?(t.splice(s,0,["enter",l,e]),t.splice(i+1,0,["exit",t[r][1],e]),t[r][1].end={...t[i][1].end}):t[r][1]=l,t.push(["exit",l,e]),t}function ase(t,e,n){const r=this;let s;return i;function i(h){let m=r.events.length,p;for(;m--;)if(r.events[m][1].type!=="lineEnding"&&r.events[m][1].type!=="linePrefix"&&r.events[m][1].type!=="content"){p=r.events[m][1].type==="paragraph";break}return!r.parser.lazy[r.now().line]&&(r.interrupt||p)?(t.enter("setextHeadingLine"),s=h,l(h)):n(h)}function l(h){return t.enter("setextHeadingLineSequence"),c(h)}function c(h){return h===s?(t.consume(h),c):(t.exit("setextHeadingLineSequence"),qt(h)?zt(t,d,"lineSuffix")(h):d(h))}function d(h){return h===null||Ze(h)?(t.exit("setextHeadingLine"),e(h)):n(h)}}const lse={tokenize:ose};function ose(t){const e=this,n=t.attempt(v0,r,t.attempt(this.parser.constructs.flowInitial,s,zt(t,t.attempt(this.parser.constructs.flow,s,t.attempt(fre,s)),"linePrefix")));return n;function r(i){if(i===null){t.consume(i);return}return t.enter("lineEndingBlank"),t.consume(i),t.exit("lineEndingBlank"),e.currentConstruct=void 0,n}function s(i){if(i===null){t.consume(i);return}return t.enter("lineEnding"),t.consume(i),t.exit("lineEnding"),e.currentConstruct=void 0,n}}const cse={resolveAll:OD()},use=kD("string"),dse=kD("text");function kD(t){return{resolveAll:OD(t==="text"?hse:void 0),tokenize:e};function e(n){const r=this,s=this.parser.constructs[t],i=n.attempt(s,l,c);return l;function l(m){return h(m)?i(m):c(m)}function c(m){if(m===null){n.consume(m);return}return n.enter("data"),n.consume(m),d}function d(m){return h(m)?(n.exit("data"),i(m)):(n.consume(m),d)}function h(m){if(m===null)return!0;const p=s[m];let x=-1;if(p)for(;++x-1){const c=l[0];typeof c=="string"?l[0]=c.slice(r):l.shift()}i>0&&l.push(t[s].slice(0,i))}return l}function jse(t,e){let n=-1;const r=[];let s;for(;++n0){const cr=Le.tokenStack[Le.tokenStack.length-1];(cr[1]||_8).call(Le,void 0,cr[0])}for(Se.position={start:Gl(ee.length>0?ee[0][1].start:{line:1,column:1,offset:0}),end:Gl(ee.length>0?ee[ee.length-2][1].end:{line:1,column:1,offset:0})},Tt=-1;++Tt1?"-"+c:""),dataFootnoteRef:!0,ariaDescribedBy:["footnote-label"]},children:[{type:"text",value:String(l)}]};t.patch(e,d);const h={type:"element",tagName:"sup",properties:{},children:[d]};return t.patch(e,h),t.applyData(e,h)}function Qse(t,e){const n={type:"element",tagName:"h"+e.depth,properties:{},children:t.all(e)};return t.patch(e,n),t.applyData(e,n)}function $se(t,e){if(t.options.allowDangerousHtml){const n={type:"raw",value:e.value};return t.patch(e,n),t.applyData(e,n)}}function CD(t,e){const n=e.referenceType;let r="]";if(n==="collapsed"?r+="[]":n==="full"&&(r+="["+(e.label||e.identifier)+"]"),e.type==="imageReference")return[{type:"text",value:"!["+e.alt+r}];const s=t.all(e),i=s[0];i&&i.type==="text"?i.value="["+i.value:s.unshift({type:"text",value:"["});const l=s[s.length-1];return l&&l.type==="text"?l.value+=r:s.push({type:"text",value:r}),s}function Hse(t,e){const n=String(e.identifier).toUpperCase(),r=t.definitionById.get(n);if(!r)return CD(t,e);const s={src:Dd(r.url||""),alt:e.alt};r.title!==null&&r.title!==void 0&&(s.title=r.title);const i={type:"element",tagName:"img",properties:s,children:[]};return t.patch(e,i),t.applyData(e,i)}function Use(t,e){const n={src:Dd(e.url)};e.alt!==null&&e.alt!==void 0&&(n.alt=e.alt),e.title!==null&&e.title!==void 0&&(n.title=e.title);const r={type:"element",tagName:"img",properties:n,children:[]};return t.patch(e,r),t.applyData(e,r)}function Vse(t,e){const n={type:"text",value:e.value.replace(/\r?\n|\r/g," ")};t.patch(e,n);const r={type:"element",tagName:"code",properties:{},children:[n]};return t.patch(e,r),t.applyData(e,r)}function Wse(t,e){const n=String(e.identifier).toUpperCase(),r=t.definitionById.get(n);if(!r)return CD(t,e);const s={href:Dd(r.url||"")};r.title!==null&&r.title!==void 0&&(s.title=r.title);const i={type:"element",tagName:"a",properties:s,children:t.all(e)};return t.patch(e,i),t.applyData(e,i)}function Gse(t,e){const n={href:Dd(e.url)};e.title!==null&&e.title!==void 0&&(n.title=e.title);const r={type:"element",tagName:"a",properties:n,children:t.all(e)};return t.patch(e,r),t.applyData(e,r)}function Xse(t,e,n){const r=t.all(e),s=n?Yse(n):TD(e),i={},l=[];if(typeof e.checked=="boolean"){const m=r[0];let p;m&&m.type==="element"&&m.tagName==="p"?p=m:(p={type:"element",tagName:"p",properties:{},children:[]},r.unshift(p)),p.children.length>0&&p.children.unshift({type:"text",value:" "}),p.children.unshift({type:"element",tagName:"input",properties:{type:"checkbox",checked:e.checked,disabled:!0},children:[]}),i.className=["task-list-item"]}let c=-1;for(;++c1}function Kse(t,e){const n={},r=t.all(e);let s=-1;for(typeof e.start=="number"&&e.start!==1&&(n.start=e.start);++s0){const l={type:"element",tagName:"tbody",properties:{},children:t.wrap(n,!0)},c=u5(e.children[1]),d=lD(e.children[e.children.length-1]);c&&d&&(l.position={start:c,end:d}),s.push(l)}const i={type:"element",tagName:"table",properties:{},children:t.wrap(s,!0)};return t.patch(e,i),t.applyData(e,i)}function nie(t,e,n){const r=n?n.children:void 0,i=(r?r.indexOf(e):1)===0?"th":"td",l=n&&n.type==="table"?n.align:void 0,c=l?l.length:e.children.length;let d=-1;const h=[];for(;++d0,!0),r[0]),s=r.index+r[0].length,r=n.exec(e);return i.push(z8(e.slice(s),s>0,!1)),i.join("")}function z8(t,e,n){let r=0,s=t.length;if(e){let i=t.codePointAt(r);for(;i===D8||i===R8;)r++,i=t.codePointAt(r)}if(n){let i=t.codePointAt(s-1);for(;i===D8||i===R8;)s--,i=t.codePointAt(s-1)}return s>r?t.slice(r,s):""}function iie(t,e){const n={type:"text",value:sie(String(e.value))};return t.patch(e,n),t.applyData(e,n)}function aie(t,e){const n={type:"element",tagName:"hr",properties:{},children:[]};return t.patch(e,n),t.applyData(e,n)}const lie={blockquote:Pse,break:Lse,code:Bse,delete:Ise,emphasis:qse,footnoteReference:Fse,heading:Qse,html:$se,imageReference:Hse,image:Use,inlineCode:Vse,linkReference:Wse,link:Gse,listItem:Xse,list:Kse,paragraph:Zse,root:Jse,strong:eie,table:tie,tableCell:rie,tableRow:nie,text:iie,thematicBreak:aie,toml:Op,yaml:Op,definition:Op,footnoteDefinition:Op};function Op(){}const MD=-1,Fx=0,of=1,Ug=2,x5=3,v5=4,y5=5,b5=6,AD=7,ED=8,P8=typeof self=="object"?self:globalThis,oie=(t,e)=>{const n=(s,i)=>(t.set(i,s),s),r=s=>{if(t.has(s))return t.get(s);const[i,l]=e[s];switch(i){case Fx:case MD:return n(l,s);case of:{const c=n([],s);for(const d of l)c.push(r(d));return c}case Ug:{const c=n({},s);for(const[d,h]of l)c[r(d)]=r(h);return c}case x5:return n(new Date(l),s);case v5:{const{source:c,flags:d}=l;return n(new RegExp(c,d),s)}case y5:{const c=n(new Map,s);for(const[d,h]of l)c.set(r(d),r(h));return c}case b5:{const c=n(new Set,s);for(const d of l)c.add(r(d));return c}case AD:{const{name:c,message:d}=l;return n(new P8[c](d),s)}case ED:return n(BigInt(l),s);case"BigInt":return n(Object(BigInt(l)),s);case"ArrayBuffer":return n(new Uint8Array(l).buffer,l);case"DataView":{const{buffer:c}=new Uint8Array(l);return n(new DataView(c),l)}}return n(new P8[i](l),s)};return r},L8=t=>oie(new Map,t)(0),Cu="",{toString:cie}={},{keys:uie}=Object,Fh=t=>{const e=typeof t;if(e!=="object"||!t)return[Fx,e];const n=cie.call(t).slice(8,-1);switch(n){case"Array":return[of,Cu];case"Object":return[Ug,Cu];case"Date":return[x5,Cu];case"RegExp":return[v5,Cu];case"Map":return[y5,Cu];case"Set":return[b5,Cu];case"DataView":return[of,n]}return n.includes("Array")?[of,n]:n.includes("Error")?[AD,n]:[Ug,n]},jp=([t,e])=>t===Fx&&(e==="function"||e==="symbol"),die=(t,e,n,r)=>{const s=(l,c)=>{const d=r.push(l)-1;return n.set(c,d),d},i=l=>{if(n.has(l))return n.get(l);let[c,d]=Fh(l);switch(c){case Fx:{let m=l;switch(d){case"bigint":c=ED,m=l.toString();break;case"function":case"symbol":if(t)throw new TypeError("unable to serialize "+d);m=null;break;case"undefined":return s([MD],l)}return s([c,m],l)}case of:{if(d){let x=l;return d==="DataView"?x=new Uint8Array(l.buffer):d==="ArrayBuffer"&&(x=new Uint8Array(l)),s([d,[...x]],l)}const m=[],p=s([c,m],l);for(const x of l)m.push(i(x));return p}case Ug:{if(d)switch(d){case"BigInt":return s([d,l.toString()],l);case"Boolean":case"Number":case"String":return s([d,l.valueOf()],l)}if(e&&"toJSON"in l)return i(l.toJSON());const m=[],p=s([c,m],l);for(const x of uie(l))(t||!jp(Fh(l[x])))&&m.push([i(x),i(l[x])]);return p}case x5:return s([c,l.toISOString()],l);case v5:{const{source:m,flags:p}=l;return s([c,{source:m,flags:p}],l)}case y5:{const m=[],p=s([c,m],l);for(const[x,v]of l)(t||!(jp(Fh(x))||jp(Fh(v))))&&m.push([i(x),i(v)]);return p}case b5:{const m=[],p=s([c,m],l);for(const x of l)(t||!jp(Fh(x)))&&m.push(i(x));return p}}const{message:h}=l;return s([c,{name:d,message:h}],l)};return i},B8=(t,{json:e,lossy:n}={})=>{const r=[];return die(!(e||n),!!e,new Map,r)(t),r},Vg=typeof structuredClone=="function"?(t,e)=>e&&("json"in e||"lossy"in e)?L8(B8(t,e)):structuredClone(t):(t,e)=>L8(B8(t,e));function hie(t,e){const n=[{type:"text",value:"↩"}];return e>1&&n.push({type:"element",tagName:"sup",properties:{},children:[{type:"text",value:String(e)}]}),n}function fie(t,e){return"Back to reference "+(t+1)+(e>1?"-"+e:"")}function mie(t){const e=typeof t.options.clobberPrefix=="string"?t.options.clobberPrefix:"user-content-",n=t.options.footnoteBackContent||hie,r=t.options.footnoteBackLabel||fie,s=t.options.footnoteLabel||"Footnotes",i=t.options.footnoteLabelTagName||"h2",l=t.options.footnoteLabelProperties||{className:["sr-only"]},c=[];let d=-1;for(;++d0&&b.push({type:"text",value:" "});let T=typeof n=="string"?n:n(d,v);typeof T=="string"&&(T={type:"text",value:T}),b.push({type:"element",tagName:"a",properties:{href:"#"+e+"fnref-"+x+(v>1?"-"+v:""),dataFootnoteBackref:"",ariaLabel:typeof r=="string"?r:r(d,v),className:["data-footnote-backref"]},children:Array.isArray(T)?T:[T]})}const O=m[m.length-1];if(O&&O.type==="element"&&O.tagName==="p"){const T=O.children[O.children.length-1];T&&T.type==="text"?T.value+=" ":O.children.push({type:"text",value:" "}),O.children.push(...b)}else m.push(...b);const j={type:"element",tagName:"li",properties:{id:e+"fn-"+x},children:t.wrap(m,!0)};t.patch(h,j),c.push(j)}if(c.length!==0)return{type:"element",tagName:"section",properties:{dataFootnotes:!0,className:["footnotes"]},children:[{type:"element",tagName:i,properties:{...Vg(l),id:"footnote-label"},children:[{type:"text",value:s}]},{type:"text",value:` -`},{type:"element",tagName:"ol",properties:{},children:t.wrap(c,!0)},{type:"text",value:` -`}]}}const y0=(function(t){if(t==null)return vie;if(typeof t=="function")return Qx(t);if(typeof t=="object")return Array.isArray(t)?pie(t):gie(t);if(typeof t=="string")return xie(t);throw new Error("Expected function, string, or object as test")});function pie(t){const e=[];let n=-1;for(;++n":""))+")"})}return x;function x(){let v=_D,b,k,O;if((!e||i(d,h,m[m.length-1]||void 0))&&(v=wie(n(d,m)),v[0]===x4))return v;if("children"in d&&d.children){const j=d;if(j.children&&v[0]!==DD)for(k=(r?j.children.length:-1)+l,O=m.concat(j);k>-1&&k0&&n.push({type:"text",value:` -`}),n}function I8(t){let e=0,n=t.charCodeAt(e);for(;n===9||n===32;)e++,n=t.charCodeAt(e);return t.slice(e)}function q8(t,e){const n=kie(t,e),r=n.one(t,void 0),s=mie(n),i=Array.isArray(r)?{type:"root",children:r}:r||{type:"root",children:[]};return s&&i.children.push({type:"text",value:` -`},s),i}function Tie(t,e){return t&&"run"in t?async function(n,r){const s=q8(n,{file:r,...e});await t.run(s,r)}:function(n,r){return q8(n,{file:r,...t||e})}}function F8(t){if(t)throw t}var xb,Q8;function Mie(){if(Q8)return xb;Q8=1;var t=Object.prototype.hasOwnProperty,e=Object.prototype.toString,n=Object.defineProperty,r=Object.getOwnPropertyDescriptor,s=function(h){return typeof Array.isArray=="function"?Array.isArray(h):e.call(h)==="[object Array]"},i=function(h){if(!h||e.call(h)!=="[object Object]")return!1;var m=t.call(h,"constructor"),p=h.constructor&&h.constructor.prototype&&t.call(h.constructor.prototype,"isPrototypeOf");if(h.constructor&&!m&&!p)return!1;var x;for(x in h);return typeof x>"u"||t.call(h,x)},l=function(h,m){n&&m.name==="__proto__"?n(h,m.name,{enumerable:!0,configurable:!0,value:m.newValue,writable:!0}):h[m.name]=m.newValue},c=function(h,m){if(m==="__proto__")if(t.call(h,m)){if(r)return r(h,m).value}else return;return h[m]};return xb=function d(){var h,m,p,x,v,b,k=arguments[0],O=1,j=arguments.length,T=!1;for(typeof k=="boolean"&&(T=k,k=arguments[1]||{},O=2),(k==null||typeof k!="object"&&typeof k!="function")&&(k={});Ol.length;let d;c&&l.push(s);try{d=t.apply(this,l)}catch(h){const m=h;if(c&&n)throw m;return s(m)}c||(d&&d.then&&typeof d.then=="function"?d.then(i,s):d instanceof Error?s(d):i(d))}function s(l,...c){n||(n=!0,e(l,...c))}function i(l){s(null,l)}}const ra={basename:Die,dirname:Rie,extname:zie,join:Pie,sep:"/"};function Die(t,e){if(e!==void 0&&typeof e!="string")throw new TypeError('"ext" argument must be a string');b0(t);let n=0,r=-1,s=t.length,i;if(e===void 0||e.length===0||e.length>t.length){for(;s--;)if(t.codePointAt(s)===47){if(i){n=s+1;break}}else r<0&&(i=!0,r=s+1);return r<0?"":t.slice(n,r)}if(e===t)return"";let l=-1,c=e.length-1;for(;s--;)if(t.codePointAt(s)===47){if(i){n=s+1;break}}else l<0&&(i=!0,l=s+1),c>-1&&(t.codePointAt(s)===e.codePointAt(c--)?c<0&&(r=s):(c=-1,r=l));return n===r?r=l:r<0&&(r=t.length),t.slice(n,r)}function Rie(t){if(b0(t),t.length===0)return".";let e=-1,n=t.length,r;for(;--n;)if(t.codePointAt(n)===47){if(r){e=n;break}}else r||(r=!0);return e<0?t.codePointAt(0)===47?"/":".":e===1&&t.codePointAt(0)===47?"//":t.slice(0,e)}function zie(t){b0(t);let e=t.length,n=-1,r=0,s=-1,i=0,l;for(;e--;){const c=t.codePointAt(e);if(c===47){if(l){r=e+1;break}continue}n<0&&(l=!0,n=e+1),c===46?s<0?s=e:i!==1&&(i=1):s>-1&&(i=-1)}return s<0||n<0||i===0||i===1&&s===n-1&&s===r+1?"":t.slice(s,n)}function Pie(...t){let e=-1,n;for(;++e0&&t.codePointAt(t.length-1)===47&&(n+="/"),e?"/"+n:n}function Bie(t,e){let n="",r=0,s=-1,i=0,l=-1,c,d;for(;++l<=t.length;){if(l2){if(d=n.lastIndexOf("/"),d!==n.length-1){d<0?(n="",r=0):(n=n.slice(0,d),r=n.length-1-n.lastIndexOf("/")),s=l,i=0;continue}}else if(n.length>0){n="",r=0,s=l,i=0;continue}}e&&(n=n.length>0?n+"/..":"..",r=2)}else n.length>0?n+="/"+t.slice(s+1,l):n=t.slice(s+1,l),r=l-s-1;s=l,i=0}else c===46&&i>-1?i++:i=-1}return n}function b0(t){if(typeof t!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(t))}const Iie={cwd:qie};function qie(){return"/"}function b4(t){return!!(t!==null&&typeof t=="object"&&"href"in t&&t.href&&"protocol"in t&&t.protocol&&t.auth===void 0)}function Fie(t){if(typeof t=="string")t=new URL(t);else if(!b4(t)){const e=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+t+"`");throw e.code="ERR_INVALID_ARG_TYPE",e}if(t.protocol!=="file:"){const e=new TypeError("The URL must be of scheme file");throw e.code="ERR_INVALID_URL_SCHEME",e}return Qie(t)}function Qie(t){if(t.hostname!==""){const r=new TypeError('File URL host must be "localhost" or empty on darwin');throw r.code="ERR_INVALID_FILE_URL_HOST",r}const e=t.pathname;let n=-1;for(;++n0){let[v,...b]=m;const k=r[x][1];y4(k)&&y4(v)&&(v=vb(!0,k,v)),r[x]=[h,v,...b]}}}}const Vie=new k5().freeze();function Sb(t,e){if(typeof e!="function")throw new TypeError("Cannot `"+t+"` without `parser`")}function kb(t,e){if(typeof e!="function")throw new TypeError("Cannot `"+t+"` without `compiler`")}function Ob(t,e){if(e)throw new Error("Cannot call `"+t+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function H8(t){if(!y4(t)||typeof t.type!="string")throw new TypeError("Expected node, got `"+t+"`")}function U8(t,e,n){if(!n)throw new Error("`"+t+"` finished async. Use `"+e+"` instead")}function Np(t){return Wie(t)?t:new RD(t)}function Wie(t){return!!(t&&typeof t=="object"&&"message"in t&&"messages"in t)}function Gie(t){return typeof t=="string"||Xie(t)}function Xie(t){return!!(t&&typeof t=="object"&&"byteLength"in t&&"byteOffset"in t)}const Yie="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",V8=[],W8={allowDangerousHtml:!0},Kie=/^(https?|ircs?|mailto|xmpp)$/i,Zie=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"className",id:"remove-classname"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function Jie(t){const e=eae(t),n=tae(t);return nae(e.runSync(e.parse(n),n),t)}function eae(t){const e=t.rehypePlugins||V8,n=t.remarkPlugins||V8,r=t.remarkRehypeOptions?{...t.remarkRehypeOptions,...W8}:W8;return Vie().use(zse).use(n).use(Tie,r).use(e)}function tae(t){const e=t.children||"",n=new RD;return typeof e=="string"&&(n.value=e),n}function nae(t,e){const n=e.allowedElements,r=e.allowElement,s=e.components,i=e.disallowedElements,l=e.skipHtml,c=e.unwrapDisallowed,d=e.urlTransform||rae;for(const m of Zie)Object.hasOwn(e,m.from)&&(""+m.from+(m.to?"use `"+m.to+"` instead":"remove it")+Yie+m.id,void 0);return S5(t,h),vne(t,{Fragment:a.Fragment,components:s,ignoreInvalidStyle:!0,jsx:a.jsx,jsxs:a.jsxs,passKeys:!0,passNode:!0});function h(m,p,x){if(m.type==="raw"&&x&&typeof p=="number")return l?x.children.splice(p,1):x.children[p]={type:"text",value:m.value},p;if(m.type==="element"){let v;for(v in mb)if(Object.hasOwn(mb,v)&&Object.hasOwn(m.properties,v)){const b=m.properties[v],k=mb[v];(k===null||k.includes(m.tagName))&&(m.properties[v]=d(String(b||""),v,m))}}if(m.type==="element"){let v=n?!n.includes(m.tagName):i?i.includes(m.tagName):!1;if(!v&&r&&typeof p=="number"&&(v=!r(m,p,x)),v&&x&&typeof p=="number")return c&&m.children?x.children.splice(p,1,...m.children):x.children.splice(p,1),p}}}function rae(t){const e=t.indexOf(":"),n=t.indexOf("?"),r=t.indexOf("#"),s=t.indexOf("/");return e===-1||s!==-1&&e>s||n!==-1&&e>n||r!==-1&&e>r||Kie.test(t.slice(0,e))?t:""}function G8(t,e){const n=String(t);if(typeof e!="string")throw new TypeError("Expected character");let r=0,s=n.indexOf(e);for(;s!==-1;)r++,s=n.indexOf(e,s+e.length);return r}function sae(t){if(typeof t!="string")throw new TypeError("Expected a string");return t.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}function iae(t,e,n){const s=y0((n||{}).ignore||[]),i=aae(e);let l=-1;for(;++l0?{type:"text",value:E}:void 0),E===!1?x.lastIndex=_+1:(b!==_&&T.push({type:"text",value:h.value.slice(b,_)}),Array.isArray(E)?T.push(...E):E&&T.push(E),b=_+M[0].length,j=!0),!x.global)break;M=x.exec(h.value)}return j?(b?\]}]+$/.exec(t);if(!e)return[t,void 0];t=t.slice(0,e.index);let n=e[0],r=n.indexOf(")");const s=G8(t,"(");let i=G8(t,")");for(;r!==-1&&s>i;)t+=n.slice(0,r+1),n=n.slice(r+1),r=n.indexOf(")"),i++;return[t,n]}function zD(t,e){const n=t.input.charCodeAt(t.index-1);return(t.index===0||Cc(n)||Ix(n))&&(!e||n!==47)}PD.peek=Mae;function wae(){this.buffer()}function Sae(t){this.enter({type:"footnoteReference",identifier:"",label:""},t)}function kae(){this.buffer()}function Oae(t){this.enter({type:"footnoteDefinition",identifier:"",label:"",children:[]},t)}function jae(t){const e=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=qi(this.sliceSerialize(t)).toLowerCase(),n.label=e}function Nae(t){this.exit(t)}function Cae(t){const e=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=qi(this.sliceSerialize(t)).toLowerCase(),n.label=e}function Tae(t){this.exit(t)}function Mae(){return"["}function PD(t,e,n,r){const s=n.createTracker(r);let i=s.move("[^");const l=n.enter("footnoteReference"),c=n.enter("reference");return i+=s.move(n.safe(n.associationId(t),{after:"]",before:i})),c(),l(),i+=s.move("]"),i}function Aae(){return{enter:{gfmFootnoteCallString:wae,gfmFootnoteCall:Sae,gfmFootnoteDefinitionLabelString:kae,gfmFootnoteDefinition:Oae},exit:{gfmFootnoteCallString:jae,gfmFootnoteCall:Nae,gfmFootnoteDefinitionLabelString:Cae,gfmFootnoteDefinition:Tae}}}function Eae(t){let e=!1;return t&&t.firstLineBlank&&(e=!0),{handlers:{footnoteDefinition:n,footnoteReference:PD},unsafe:[{character:"[",inConstruct:["label","phrasing","reference"]}]};function n(r,s,i,l){const c=i.createTracker(l);let d=c.move("[^");const h=i.enter("footnoteDefinition"),m=i.enter("label");return d+=c.move(i.safe(i.associationId(r),{before:d,after:"]"})),m(),d+=c.move("]:"),r.children&&r.children.length>0&&(c.shift(4),d+=c.move((e?` -`:" ")+i.indentLines(i.containerFlow(r,c.current()),e?LD:_ae))),h(),d}}function _ae(t,e,n){return e===0?t:LD(t,e,n)}function LD(t,e,n){return(n?"":" ")+t}const Dae=["autolink","destinationLiteral","destinationRaw","reference","titleQuote","titleApostrophe"];BD.peek=Bae;function Rae(){return{canContainEols:["delete"],enter:{strikethrough:Pae},exit:{strikethrough:Lae}}}function zae(){return{unsafe:[{character:"~",inConstruct:"phrasing",notInConstruct:Dae}],handlers:{delete:BD}}}function Pae(t){this.enter({type:"delete",children:[]},t)}function Lae(t){this.exit(t)}function BD(t,e,n,r){const s=n.createTracker(r),i=n.enter("strikethrough");let l=s.move("~~");return l+=n.containerPhrasing(t,{...s.current(),before:l,after:"~"}),l+=s.move("~~"),i(),l}function Bae(){return"~"}function Iae(t){return t.length}function qae(t,e){const n=e||{},r=(n.align||[]).concat(),s=n.stringLength||Iae,i=[],l=[],c=[],d=[];let h=0,m=-1;for(;++mh&&(h=t[m].length);++jd[j])&&(d[j]=M)}k.push(T)}l[m]=k,c[m]=O}let p=-1;if(typeof r=="object"&&"length"in r)for(;++pd[p]&&(d[p]=T),v[p]=T),x[p]=M}l.splice(1,0,x),c.splice(1,0,v),m=-1;const b=[];for(;++m "),i.shift(2);const l=n.indentLines(n.containerFlow(t,i.current()),$ae);return s(),l}function $ae(t,e,n){return">"+(n?"":" ")+t}function Hae(t,e){return Y8(t,e.inConstruct,!0)&&!Y8(t,e.notInConstruct,!1)}function Y8(t,e,n){if(typeof e=="string"&&(e=[e]),!e||e.length===0)return n;let r=-1;for(;++rl&&(l=i):i=1,s=r+e.length,r=n.indexOf(e,s);return l}function Uae(t,e){return!!(e.options.fences===!1&&t.value&&!t.lang&&/[^ \r\n]/.test(t.value)&&!/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(t.value))}function Vae(t){const e=t.options.fence||"`";if(e!=="`"&&e!=="~")throw new Error("Cannot serialize code with `"+e+"` for `options.fence`, expected `` ` `` or `~`");return e}function Wae(t,e,n,r){const s=Vae(n),i=t.value||"",l=s==="`"?"GraveAccent":"Tilde";if(Uae(t,n)){const p=n.enter("codeIndented"),x=n.indentLines(i,Gae);return p(),x}const c=n.createTracker(r),d=s.repeat(Math.max(ID(i,s)+1,3)),h=n.enter("codeFenced");let m=c.move(d);if(t.lang){const p=n.enter(`codeFencedLang${l}`);m+=c.move(n.safe(t.lang,{before:m,after:" ",encode:["`"],...c.current()})),p()}if(t.lang&&t.meta){const p=n.enter(`codeFencedMeta${l}`);m+=c.move(" "),m+=c.move(n.safe(t.meta,{before:m,after:` -`,encode:["`"],...c.current()})),p()}return m+=c.move(` -`),i&&(m+=c.move(i+` -`)),m+=c.move(d),h(),m}function Gae(t,e,n){return(n?"":" ")+t}function O5(t){const e=t.options.quote||'"';if(e!=='"'&&e!=="'")throw new Error("Cannot serialize title with `"+e+"` for `options.quote`, expected `\"`, or `'`");return e}function Xae(t,e,n,r){const s=O5(n),i=s==='"'?"Quote":"Apostrophe",l=n.enter("definition");let c=n.enter("label");const d=n.createTracker(r);let h=d.move("[");return h+=d.move(n.safe(n.associationId(t),{before:h,after:"]",...d.current()})),h+=d.move("]: "),c(),!t.url||/[\0- \u007F]/.test(t.url)?(c=n.enter("destinationLiteral"),h+=d.move("<"),h+=d.move(n.safe(t.url,{before:h,after:">",...d.current()})),h+=d.move(">")):(c=n.enter("destinationRaw"),h+=d.move(n.safe(t.url,{before:h,after:t.title?" ":` -`,...d.current()}))),c(),t.title&&(c=n.enter(`title${i}`),h+=d.move(" "+s),h+=d.move(n.safe(t.title,{before:h,after:s,...d.current()})),h+=d.move(s),c()),l(),h}function Yae(t){const e=t.options.emphasis||"*";if(e!=="*"&&e!=="_")throw new Error("Cannot serialize emphasis with `"+e+"` for `options.emphasis`, expected `*`, or `_`");return e}function Bf(t){return"&#x"+t.toString(16).toUpperCase()+";"}function Wg(t,e,n){const r=vd(t),s=vd(e);return r===void 0?s===void 0?n==="_"?{inside:!0,outside:!0}:{inside:!1,outside:!1}:s===1?{inside:!0,outside:!0}:{inside:!1,outside:!0}:r===1?s===void 0?{inside:!1,outside:!1}:s===1?{inside:!0,outside:!0}:{inside:!1,outside:!1}:s===void 0?{inside:!1,outside:!1}:s===1?{inside:!0,outside:!1}:{inside:!1,outside:!1}}qD.peek=Kae;function qD(t,e,n,r){const s=Yae(n),i=n.enter("emphasis"),l=n.createTracker(r),c=l.move(s);let d=l.move(n.containerPhrasing(t,{after:s,before:c,...l.current()}));const h=d.charCodeAt(0),m=Wg(r.before.charCodeAt(r.before.length-1),h,s);m.inside&&(d=Bf(h)+d.slice(1));const p=d.charCodeAt(d.length-1),x=Wg(r.after.charCodeAt(0),p,s);x.inside&&(d=d.slice(0,-1)+Bf(p));const v=l.move(s);return i(),n.attentionEncodeSurroundingInfo={after:x.outside,before:m.outside},c+d+v}function Kae(t,e,n){return n.options.emphasis||"*"}function Zae(t,e){let n=!1;return S5(t,function(r){if("value"in r&&/\r?\n|\r/.test(r.value)||r.type==="break")return n=!0,x4}),!!((!t.depth||t.depth<3)&&m5(t)&&(e.options.setext||n))}function Jae(t,e,n,r){const s=Math.max(Math.min(6,t.depth||1),1),i=n.createTracker(r);if(Zae(t,n)){const m=n.enter("headingSetext"),p=n.enter("phrasing"),x=n.containerPhrasing(t,{...i.current(),before:` -`,after:` -`});return p(),m(),x+` -`+(s===1?"=":"-").repeat(x.length-(Math.max(x.lastIndexOf("\r"),x.lastIndexOf(` -`))+1))}const l="#".repeat(s),c=n.enter("headingAtx"),d=n.enter("phrasing");i.move(l+" ");let h=n.containerPhrasing(t,{before:"# ",after:` -`,...i.current()});return/^[\t ]/.test(h)&&(h=Bf(h.charCodeAt(0))+h.slice(1)),h=h?l+" "+h:l,n.options.closeAtx&&(h+=" "+l),d(),c(),h}FD.peek=ele;function FD(t){return t.value||""}function ele(){return"<"}QD.peek=tle;function QD(t,e,n,r){const s=O5(n),i=s==='"'?"Quote":"Apostrophe",l=n.enter("image");let c=n.enter("label");const d=n.createTracker(r);let h=d.move("![");return h+=d.move(n.safe(t.alt,{before:h,after:"]",...d.current()})),h+=d.move("]("),c(),!t.url&&t.title||/[\0- \u007F]/.test(t.url)?(c=n.enter("destinationLiteral"),h+=d.move("<"),h+=d.move(n.safe(t.url,{before:h,after:">",...d.current()})),h+=d.move(">")):(c=n.enter("destinationRaw"),h+=d.move(n.safe(t.url,{before:h,after:t.title?" ":")",...d.current()}))),c(),t.title&&(c=n.enter(`title${i}`),h+=d.move(" "+s),h+=d.move(n.safe(t.title,{before:h,after:s,...d.current()})),h+=d.move(s),c()),h+=d.move(")"),l(),h}function tle(){return"!"}$D.peek=nle;function $D(t,e,n,r){const s=t.referenceType,i=n.enter("imageReference");let l=n.enter("label");const c=n.createTracker(r);let d=c.move("![");const h=n.safe(t.alt,{before:d,after:"]",...c.current()});d+=c.move(h+"]["),l();const m=n.stack;n.stack=[],l=n.enter("reference");const p=n.safe(n.associationId(t),{before:d,after:"]",...c.current()});return l(),n.stack=m,i(),s==="full"||!h||h!==p?d+=c.move(p+"]"):s==="shortcut"?d=d.slice(0,-1):d+=c.move("]"),d}function nle(){return"!"}HD.peek=rle;function HD(t,e,n){let r=t.value||"",s="`",i=-1;for(;new RegExp("(^|[^`])"+s+"([^`]|$)").test(r);)s+="`";for(/[^ \r\n]/.test(r)&&(/^[ \r\n]/.test(r)&&/[ \r\n]$/.test(r)||/^`|`$/.test(r))&&(r=" "+r+" ");++i\u007F]/.test(t.url))}VD.peek=sle;function VD(t,e,n,r){const s=O5(n),i=s==='"'?"Quote":"Apostrophe",l=n.createTracker(r);let c,d;if(UD(t,n)){const m=n.stack;n.stack=[],c=n.enter("autolink");let p=l.move("<");return p+=l.move(n.containerPhrasing(t,{before:p,after:">",...l.current()})),p+=l.move(">"),c(),n.stack=m,p}c=n.enter("link"),d=n.enter("label");let h=l.move("[");return h+=l.move(n.containerPhrasing(t,{before:h,after:"](",...l.current()})),h+=l.move("]("),d(),!t.url&&t.title||/[\0- \u007F]/.test(t.url)?(d=n.enter("destinationLiteral"),h+=l.move("<"),h+=l.move(n.safe(t.url,{before:h,after:">",...l.current()})),h+=l.move(">")):(d=n.enter("destinationRaw"),h+=l.move(n.safe(t.url,{before:h,after:t.title?" ":")",...l.current()}))),d(),t.title&&(d=n.enter(`title${i}`),h+=l.move(" "+s),h+=l.move(n.safe(t.title,{before:h,after:s,...l.current()})),h+=l.move(s),d()),h+=l.move(")"),c(),h}function sle(t,e,n){return UD(t,n)?"<":"["}WD.peek=ile;function WD(t,e,n,r){const s=t.referenceType,i=n.enter("linkReference");let l=n.enter("label");const c=n.createTracker(r);let d=c.move("[");const h=n.containerPhrasing(t,{before:d,after:"]",...c.current()});d+=c.move(h+"]["),l();const m=n.stack;n.stack=[],l=n.enter("reference");const p=n.safe(n.associationId(t),{before:d,after:"]",...c.current()});return l(),n.stack=m,i(),s==="full"||!h||h!==p?d+=c.move(p+"]"):s==="shortcut"?d=d.slice(0,-1):d+=c.move("]"),d}function ile(){return"["}function j5(t){const e=t.options.bullet||"*";if(e!=="*"&&e!=="+"&&e!=="-")throw new Error("Cannot serialize items with `"+e+"` for `options.bullet`, expected `*`, `+`, or `-`");return e}function ale(t){const e=j5(t),n=t.options.bulletOther;if(!n)return e==="*"?"-":"*";if(n!=="*"&&n!=="+"&&n!=="-")throw new Error("Cannot serialize items with `"+n+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(n===e)throw new Error("Expected `bullet` (`"+e+"`) and `bulletOther` (`"+n+"`) to be different");return n}function lle(t){const e=t.options.bulletOrdered||".";if(e!=="."&&e!==")")throw new Error("Cannot serialize items with `"+e+"` for `options.bulletOrdered`, expected `.` or `)`");return e}function GD(t){const e=t.options.rule||"*";if(e!=="*"&&e!=="-"&&e!=="_")throw new Error("Cannot serialize rules with `"+e+"` for `options.rule`, expected `*`, `-`, or `_`");return e}function ole(t,e,n,r){const s=n.enter("list"),i=n.bulletCurrent;let l=t.ordered?lle(n):j5(n);const c=t.ordered?l==="."?")":".":ale(n);let d=e&&n.bulletLastUsed?l===n.bulletLastUsed:!1;if(!t.ordered){const m=t.children?t.children[0]:void 0;if((l==="*"||l==="-")&&m&&(!m.children||!m.children[0])&&n.stack[n.stack.length-1]==="list"&&n.stack[n.stack.length-2]==="listItem"&&n.stack[n.stack.length-3]==="list"&&n.stack[n.stack.length-4]==="listItem"&&n.indexStack[n.indexStack.length-1]===0&&n.indexStack[n.indexStack.length-2]===0&&n.indexStack[n.indexStack.length-3]===0&&(d=!0),GD(n)===l&&m){let p=-1;for(;++p-1?e.start:1)+(n.options.incrementListMarker===!1?0:e.children.indexOf(t))+i);let l=i.length+1;(s==="tab"||s==="mixed"&&(e&&e.type==="list"&&e.spread||t.spread))&&(l=Math.ceil(l/4)*4);const c=n.createTracker(r);c.move(i+" ".repeat(l-i.length)),c.shift(l);const d=n.enter("listItem"),h=n.indentLines(n.containerFlow(t,c.current()),m);return d(),h;function m(p,x,v){return x?(v?"":" ".repeat(l))+p:(v?i:i+" ".repeat(l-i.length))+p}}function dle(t,e,n,r){const s=n.enter("paragraph"),i=n.enter("phrasing"),l=n.containerPhrasing(t,r);return i(),s(),l}const hle=y0(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function fle(t,e,n,r){return(t.children.some(function(l){return hle(l)})?n.containerPhrasing:n.containerFlow).call(n,t,r)}function mle(t){const e=t.options.strong||"*";if(e!=="*"&&e!=="_")throw new Error("Cannot serialize strong with `"+e+"` for `options.strong`, expected `*`, or `_`");return e}XD.peek=ple;function XD(t,e,n,r){const s=mle(n),i=n.enter("strong"),l=n.createTracker(r),c=l.move(s+s);let d=l.move(n.containerPhrasing(t,{after:s,before:c,...l.current()}));const h=d.charCodeAt(0),m=Wg(r.before.charCodeAt(r.before.length-1),h,s);m.inside&&(d=Bf(h)+d.slice(1));const p=d.charCodeAt(d.length-1),x=Wg(r.after.charCodeAt(0),p,s);x.inside&&(d=d.slice(0,-1)+Bf(p));const v=l.move(s+s);return i(),n.attentionEncodeSurroundingInfo={after:x.outside,before:m.outside},c+d+v}function ple(t,e,n){return n.options.strong||"*"}function gle(t,e,n,r){return n.safe(t.value,r)}function xle(t){const e=t.options.ruleRepetition||3;if(e<3)throw new Error("Cannot serialize rules with repetition `"+e+"` for `options.ruleRepetition`, expected `3` or more");return e}function vle(t,e,n){const r=(GD(n)+(n.options.ruleSpaces?" ":"")).repeat(xle(n));return n.options.ruleSpaces?r.slice(0,-1):r}const YD={blockquote:Qae,break:K8,code:Wae,definition:Xae,emphasis:qD,hardBreak:K8,heading:Jae,html:FD,image:QD,imageReference:$D,inlineCode:HD,link:VD,linkReference:WD,list:ole,listItem:ule,paragraph:dle,root:fle,strong:XD,text:gle,thematicBreak:vle};function yle(){return{enter:{table:ble,tableData:Z8,tableHeader:Z8,tableRow:Sle},exit:{codeText:kle,table:wle,tableData:Tb,tableHeader:Tb,tableRow:Tb}}}function ble(t){const e=t._align;this.enter({type:"table",align:e.map(function(n){return n==="none"?null:n}),children:[]},t),this.data.inTable=!0}function wle(t){this.exit(t),this.data.inTable=void 0}function Sle(t){this.enter({type:"tableRow",children:[]},t)}function Tb(t){this.exit(t)}function Z8(t){this.enter({type:"tableCell",children:[]},t)}function kle(t){let e=this.resume();this.data.inTable&&(e=e.replace(/\\([\\|])/g,Ole));const n=this.stack[this.stack.length-1];n.type,n.value=e,this.exit(t)}function Ole(t,e){return e==="|"?e:t}function jle(t){const e=t||{},n=e.tableCellPadding,r=e.tablePipeAlign,s=e.stringLength,i=n?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:` -`,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:x,table:l,tableCell:d,tableRow:c}};function l(v,b,k,O){return h(m(v,k,O),v.align)}function c(v,b,k,O){const j=p(v,k,O),T=h([j]);return T.slice(0,T.indexOf(` -`))}function d(v,b,k,O){const j=k.enter("tableCell"),T=k.enter("phrasing"),M=k.containerPhrasing(v,{...O,before:i,after:i});return T(),j(),M}function h(v,b){return qae(v,{align:b,alignDelimiters:r,padding:n,stringLength:s})}function m(v,b,k){const O=v.children;let j=-1;const T=[],M=b.enter("table");for(;++j0&&!n&&(t[t.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),n}const $le={tokenize:Kle,partial:!0};function Hle(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:Gle,continuation:{tokenize:Xle},exit:Yle}},text:{91:{name:"gfmFootnoteCall",tokenize:Wle},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:Ule,resolveTo:Vle}}}}function Ule(t,e,n){const r=this;let s=r.events.length;const i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let l;for(;s--;){const d=r.events[s][1];if(d.type==="labelImage"){l=d;break}if(d.type==="gfmFootnoteCall"||d.type==="labelLink"||d.type==="label"||d.type==="image"||d.type==="link")break}return c;function c(d){if(!l||!l._balanced)return n(d);const h=qi(r.sliceSerialize({start:l.end,end:r.now()}));return h.codePointAt(0)!==94||!i.includes(h.slice(1))?n(d):(t.enter("gfmFootnoteCallLabelMarker"),t.consume(d),t.exit("gfmFootnoteCallLabelMarker"),e(d))}}function Vle(t,e){let n=t.length;for(;n--;)if(t[n][1].type==="labelImage"&&t[n][0]==="enter"){t[n][1];break}t[n+1][1].type="data",t[n+3][1].type="gfmFootnoteCallLabelMarker";const r={type:"gfmFootnoteCall",start:Object.assign({},t[n+3][1].start),end:Object.assign({},t[t.length-1][1].end)},s={type:"gfmFootnoteCallMarker",start:Object.assign({},t[n+3][1].end),end:Object.assign({},t[n+3][1].end)};s.end.column++,s.end.offset++,s.end._bufferIndex++;const i={type:"gfmFootnoteCallString",start:Object.assign({},s.end),end:Object.assign({},t[t.length-1][1].start)},l={type:"chunkString",contentType:"string",start:Object.assign({},i.start),end:Object.assign({},i.end)},c=[t[n+1],t[n+2],["enter",r,e],t[n+3],t[n+4],["enter",s,e],["exit",s,e],["enter",i,e],["enter",l,e],["exit",l,e],["exit",i,e],t[t.length-2],t[t.length-1],["exit",r,e]];return t.splice(n,t.length-n+1,...c),t}function Wle(t,e,n){const r=this,s=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let i=0,l;return c;function c(p){return t.enter("gfmFootnoteCall"),t.enter("gfmFootnoteCallLabelMarker"),t.consume(p),t.exit("gfmFootnoteCallLabelMarker"),d}function d(p){return p!==94?n(p):(t.enter("gfmFootnoteCallMarker"),t.consume(p),t.exit("gfmFootnoteCallMarker"),t.enter("gfmFootnoteCallString"),t.enter("chunkString").contentType="string",h)}function h(p){if(i>999||p===93&&!l||p===null||p===91||Dn(p))return n(p);if(p===93){t.exit("chunkString");const x=t.exit("gfmFootnoteCallString");return s.includes(qi(r.sliceSerialize(x)))?(t.enter("gfmFootnoteCallLabelMarker"),t.consume(p),t.exit("gfmFootnoteCallLabelMarker"),t.exit("gfmFootnoteCall"),e):n(p)}return Dn(p)||(l=!0),i++,t.consume(p),p===92?m:h}function m(p){return p===91||p===92||p===93?(t.consume(p),i++,h):h(p)}}function Gle(t,e,n){const r=this,s=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let i,l=0,c;return d;function d(b){return t.enter("gfmFootnoteDefinition")._container=!0,t.enter("gfmFootnoteDefinitionLabel"),t.enter("gfmFootnoteDefinitionLabelMarker"),t.consume(b),t.exit("gfmFootnoteDefinitionLabelMarker"),h}function h(b){return b===94?(t.enter("gfmFootnoteDefinitionMarker"),t.consume(b),t.exit("gfmFootnoteDefinitionMarker"),t.enter("gfmFootnoteDefinitionLabelString"),t.enter("chunkString").contentType="string",m):n(b)}function m(b){if(l>999||b===93&&!c||b===null||b===91||Dn(b))return n(b);if(b===93){t.exit("chunkString");const k=t.exit("gfmFootnoteDefinitionLabelString");return i=qi(r.sliceSerialize(k)),t.enter("gfmFootnoteDefinitionLabelMarker"),t.consume(b),t.exit("gfmFootnoteDefinitionLabelMarker"),t.exit("gfmFootnoteDefinitionLabel"),x}return Dn(b)||(c=!0),l++,t.consume(b),b===92?p:m}function p(b){return b===91||b===92||b===93?(t.consume(b),l++,m):m(b)}function x(b){return b===58?(t.enter("definitionMarker"),t.consume(b),t.exit("definitionMarker"),s.includes(i)||s.push(i),zt(t,v,"gfmFootnoteDefinitionWhitespace")):n(b)}function v(b){return e(b)}}function Xle(t,e,n){return t.check(v0,e,t.attempt($le,e,n))}function Yle(t){t.exit("gfmFootnoteDefinition")}function Kle(t,e,n){const r=this;return zt(t,s,"gfmFootnoteDefinitionIndent",5);function s(i){const l=r.events[r.events.length-1];return l&&l[1].type==="gfmFootnoteDefinitionIndent"&&l[2].sliceSerialize(l[1],!0).length===4?e(i):n(i)}}function Zle(t){let n=(t||{}).singleTilde;const r={name:"strikethrough",tokenize:i,resolveAll:s};return n==null&&(n=!0),{text:{126:r},insideSpan:{null:[r]},attentionMarkers:{null:[126]}};function s(l,c){let d=-1;for(;++d1?d(b):(l.consume(b),p++,v);if(p<2&&!n)return d(b);const O=l.exit("strikethroughSequenceTemporary"),j=vd(b);return O._open=!j||j===2&&!!k,O._close=!k||k===2&&!!j,c(b)}}}class Jle{constructor(){this.map=[]}add(e,n,r){eoe(this,e,n,r)}consume(e){if(this.map.sort(function(i,l){return i[0]-l[0]}),this.map.length===0)return;let n=this.map.length;const r=[];for(;n>0;)n-=1,r.push(e.slice(this.map[n][0]+this.map[n][1]),this.map[n][2]),e.length=this.map[n][0];r.push(e.slice()),e.length=0;let s=r.pop();for(;s;){for(const i of s)e.push(i);s=r.pop()}this.map.length=0}}function eoe(t,e,n,r){let s=0;if(!(n===0&&r.length===0)){for(;s-1;){const W=r.events[U][1].type;if(W==="lineEnding"||W==="linePrefix")U--;else break}const V=U>-1?r.events[U][1].type:null,ce=V==="tableHead"||V==="tableRow"?E:d;return ce===E&&r.parser.lazy[r.now().line]?n(B):ce(B)}function d(B){return t.enter("tableHead"),t.enter("tableRow"),h(B)}function h(B){return B===124||(l=!0,i+=1),m(B)}function m(B){return B===null?n(B):Ze(B)?i>1?(i=0,r.interrupt=!0,t.exit("tableRow"),t.enter("lineEnding"),t.consume(B),t.exit("lineEnding"),v):n(B):qt(B)?zt(t,m,"whitespace")(B):(i+=1,l&&(l=!1,s+=1),B===124?(t.enter("tableCellDivider"),t.consume(B),t.exit("tableCellDivider"),l=!0,m):(t.enter("data"),p(B)))}function p(B){return B===null||B===124||Dn(B)?(t.exit("data"),m(B)):(t.consume(B),B===92?x:p)}function x(B){return B===92||B===124?(t.consume(B),p):p(B)}function v(B){return r.interrupt=!1,r.parser.lazy[r.now().line]?n(B):(t.enter("tableDelimiterRow"),l=!1,qt(B)?zt(t,b,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(B):b(B))}function b(B){return B===45||B===58?O(B):B===124?(l=!0,t.enter("tableCellDivider"),t.consume(B),t.exit("tableCellDivider"),k):D(B)}function k(B){return qt(B)?zt(t,O,"whitespace")(B):O(B)}function O(B){return B===58?(i+=1,l=!0,t.enter("tableDelimiterMarker"),t.consume(B),t.exit("tableDelimiterMarker"),j):B===45?(i+=1,j(B)):B===null||Ze(B)?_(B):D(B)}function j(B){return B===45?(t.enter("tableDelimiterFiller"),T(B)):D(B)}function T(B){return B===45?(t.consume(B),T):B===58?(l=!0,t.exit("tableDelimiterFiller"),t.enter("tableDelimiterMarker"),t.consume(B),t.exit("tableDelimiterMarker"),M):(t.exit("tableDelimiterFiller"),M(B))}function M(B){return qt(B)?zt(t,_,"whitespace")(B):_(B)}function _(B){return B===124?b(B):B===null||Ze(B)?!l||s!==i?D(B):(t.exit("tableDelimiterRow"),t.exit("tableHead"),e(B)):D(B)}function D(B){return n(B)}function E(B){return t.enter("tableRow"),z(B)}function z(B){return B===124?(t.enter("tableCellDivider"),t.consume(B),t.exit("tableCellDivider"),z):B===null||Ze(B)?(t.exit("tableRow"),e(B)):qt(B)?zt(t,z,"whitespace")(B):(t.enter("data"),Q(B))}function Q(B){return B===null||B===124||Dn(B)?(t.exit("data"),z(B)):(t.consume(B),B===92?F:Q)}function F(B){return B===92||B===124?(t.consume(B),Q):Q(B)}}function soe(t,e){let n=-1,r=!0,s=0,i=[0,0,0,0],l=[0,0,0,0],c=!1,d=0,h,m,p;const x=new Jle;for(;++nn[2]+1){const b=n[2]+1,k=n[3]-n[2]-1;t.add(b,k,[])}}t.add(n[3]+1,0,[["exit",p,e]])}return s!==void 0&&(i.end=Object.assign({},Bu(e.events,s)),t.add(s,0,[["exit",i,e]]),i=void 0),i}function eN(t,e,n,r,s){const i=[],l=Bu(e.events,n);s&&(s.end=Object.assign({},l),i.push(["exit",s,e])),r.end=Object.assign({},l),i.push(["exit",r,e]),t.add(n+1,0,i)}function Bu(t,e){const n=t[e],r=n[0]==="enter"?"start":"end";return n[1][r]}const ioe={name:"tasklistCheck",tokenize:loe};function aoe(){return{text:{91:ioe}}}function loe(t,e,n){const r=this;return s;function s(d){return r.previous!==null||!r._gfmTasklistFirstContentOfListItem?n(d):(t.enter("taskListCheck"),t.enter("taskListCheckMarker"),t.consume(d),t.exit("taskListCheckMarker"),i)}function i(d){return Dn(d)?(t.enter("taskListCheckValueUnchecked"),t.consume(d),t.exit("taskListCheckValueUnchecked"),l):d===88||d===120?(t.enter("taskListCheckValueChecked"),t.consume(d),t.exit("taskListCheckValueChecked"),l):n(d)}function l(d){return d===93?(t.enter("taskListCheckMarker"),t.consume(d),t.exit("taskListCheckMarker"),t.exit("taskListCheck"),c):n(d)}function c(d){return Ze(d)?e(d):qt(d)?t.check({tokenize:ooe},e,n)(d):n(d)}}function ooe(t,e,n){return zt(t,r,"whitespace");function r(s){return s===null?n(s):e(s)}}function coe(t){return mD([Rle(),Hle(),Zle(t),noe(),aoe()])}const uoe={};function doe(t){const e=this,n=t||uoe,r=e.data(),s=r.micromarkExtensions||(r.micromarkExtensions=[]),i=r.fromMarkdownExtensions||(r.fromMarkdownExtensions=[]),l=r.toMarkdownExtensions||(r.toMarkdownExtensions=[]);s.push(coe(n)),i.push(Ale()),l.push(Ele(n))}function hoe(){return{enter:{mathFlow:t,mathFlowFenceMeta:e,mathText:i},exit:{mathFlow:s,mathFlowFence:r,mathFlowFenceMeta:n,mathFlowValue:c,mathText:l,mathTextData:c}};function t(d){const h={type:"element",tagName:"code",properties:{className:["language-math","math-display"]},children:[]};this.enter({type:"math",meta:null,value:"",data:{hName:"pre",hChildren:[h]}},d)}function e(){this.buffer()}function n(){const d=this.resume(),h=this.stack[this.stack.length-1];h.type,h.meta=d}function r(){this.data.mathFlowInside||(this.buffer(),this.data.mathFlowInside=!0)}function s(d){const h=this.resume().replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),m=this.stack[this.stack.length-1];m.type,this.exit(d),m.value=h;const p=m.data.hChildren[0];p.type,p.tagName,p.children.push({type:"text",value:h}),this.data.mathFlowInside=void 0}function i(d){this.enter({type:"inlineMath",value:"",data:{hName:"code",hProperties:{className:["language-math","math-inline"]},hChildren:[]}},d),this.buffer()}function l(d){const h=this.resume(),m=this.stack[this.stack.length-1];m.type,this.exit(d),m.value=h,m.data.hChildren.push({type:"text",value:h})}function c(d){this.config.enter.data.call(this,d),this.config.exit.data.call(this,d)}}function foe(t){let e=(t||{}).singleDollarTextMath;return e==null&&(e=!0),r.peek=s,{unsafe:[{character:"\r",inConstruct:"mathFlowMeta"},{character:` -`,inConstruct:"mathFlowMeta"},{character:"$",after:e?void 0:"\\$",inConstruct:"phrasing"},{character:"$",inConstruct:"mathFlowMeta"},{atBreak:!0,character:"$",after:"\\$"}],handlers:{math:n,inlineMath:r}};function n(i,l,c,d){const h=i.value||"",m=c.createTracker(d),p="$".repeat(Math.max(ID(h,"$")+1,2)),x=c.enter("mathFlow");let v=m.move(p);if(i.meta){const b=c.enter("mathFlowMeta");v+=m.move(c.safe(i.meta,{after:` -`,before:v,encode:["$"],...m.current()})),b()}return v+=m.move(` -`),h&&(v+=m.move(h+` -`)),v+=m.move(p),x(),v}function r(i,l,c){let d=i.value||"",h=1;for(e||h++;new RegExp("(^|[^$])"+"\\$".repeat(h)+"([^$]|$)").test(d);)h++;const m="$".repeat(h);/[^ \r\n]/.test(d)&&(/^[ \r\n]/.test(d)&&/[ \r\n]$/.test(d)||/^\$|\$$/.test(d))&&(d=" "+d+" ");let p=-1;for(;++p15?h="…"+c.slice(s-15,s):h=c.slice(0,s);var m;i+15":">","<":"<",'"':""","'":"'"},joe=/[&><"']/g;function Noe(t){return String(t).replace(joe,e=>Ooe[e])}var iR=function t(e){return e.type==="ordgroup"||e.type==="color"?e.body.length===1?t(e.body[0]):e:e.type==="font"?t(e.body):e},Coe=function(e){var n=iR(e);return n.type==="mathord"||n.type==="textord"||n.type==="atom"},Toe=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e},Moe=function(e){var n=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return n?n[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(n[1])?null:n[1].toLowerCase():"_relative"},tn={deflt:woe,escape:Noe,hyphenate:koe,getBaseElem:iR,isCharacterBox:Coe,protocolFromUrl:Moe},cg={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:t=>"#"+t},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(t,e)=>(e.push(t),e)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:t=>Math.max(0,t),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:t=>Math.max(0,t),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:t=>Math.max(0,t),cli:"-e, --max-expand ",cliProcessor:t=>t==="Infinity"?1/0:parseInt(t)},globalGroup:{type:"boolean",cli:!1}};function Aoe(t){if(t.default)return t.default;var e=t.type,n=Array.isArray(e)?e[0]:e;if(typeof n!="string")return n.enum[0];switch(n){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class C5{constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(var n in cg)if(cg.hasOwnProperty(n)){var r=cg[n];this[n]=e[n]!==void 0?r.processor?r.processor(e[n]):e[n]:Aoe(r)}}reportNonstrict(e,n,r){var s=this.strict;if(typeof s=="function"&&(s=s(e,n,r)),!(!s||s==="ignore")){if(s===!0||s==="error")throw new De("LaTeX-incompatible input and strict mode is set to 'error': "+(n+" ["+e+"]"),r);s==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(n+" ["+e+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+s+"': "+n+" ["+e+"]"))}}useStrictBehavior(e,n,r){var s=this.strict;if(typeof s=="function")try{s=s(e,n,r)}catch{s="error"}return!s||s==="ignore"?!1:s===!0||s==="error"?!0:s==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(n+" ["+e+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+s+"': "+n+" ["+e+"]")),!1)}isTrusted(e){if(e.url&&!e.protocol){var n=tn.protocolFromUrl(e.url);if(n==null)return!1;e.protocol=n}var r=typeof this.trust=="function"?this.trust(e):this.trust;return!!r}}class Xl{constructor(e,n,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=n,this.cramped=r}sup(){return ia[Eoe[this.id]]}sub(){return ia[_oe[this.id]]}fracNum(){return ia[Doe[this.id]]}fracDen(){return ia[Roe[this.id]]}cramp(){return ia[zoe[this.id]]}text(){return ia[Poe[this.id]]}isTight(){return this.size>=2}}var T5=0,Gg=1,ed=2,cl=3,If=4,ki=5,yd=6,hs=7,ia=[new Xl(T5,0,!1),new Xl(Gg,0,!0),new Xl(ed,1,!1),new Xl(cl,1,!0),new Xl(If,2,!1),new Xl(ki,2,!0),new Xl(yd,3,!1),new Xl(hs,3,!0)],Eoe=[If,ki,If,ki,yd,hs,yd,hs],_oe=[ki,ki,ki,ki,hs,hs,hs,hs],Doe=[ed,cl,If,ki,yd,hs,yd,hs],Roe=[cl,cl,ki,ki,hs,hs,hs,hs],zoe=[Gg,Gg,cl,cl,ki,ki,hs,hs],Poe=[T5,Gg,ed,cl,ed,cl,ed,cl],at={DISPLAY:ia[T5],TEXT:ia[ed],SCRIPT:ia[If],SCRIPTSCRIPT:ia[yd]},S4=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];function Loe(t){for(var e=0;e=s[0]&&t<=s[1])return n.name}return null}var ug=[];S4.forEach(t=>t.blocks.forEach(e=>ug.push(...e)));function aR(t){for(var e=0;e=ug[e]&&t<=ug[e+1])return!0;return!1}var Tu=80,Boe=function(e,n){return"M95,"+(622+e+n)+` -c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14 -c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54 -c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10 -s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429 -c69,-144,104.5,-217.7,106.5,-221 -l`+e/2.075+" -"+e+` -c5.3,-9.3,12,-14,20,-14 -H400000v`+(40+e)+`H845.2724 -s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7 -c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z -M`+(834+e)+" "+n+"h400000v"+(40+e)+"h-400000z"},Ioe=function(e,n){return"M263,"+(601+e+n)+`c0.7,0,18,39.7,52,119 -c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120 -c340,-704.7,510.7,-1060.3,512,-1067 -l`+e/2.084+" -"+e+` -c4.7,-7.3,11,-11,19,-11 -H40000v`+(40+e)+`H1012.3 -s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232 -c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1 -s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26 -c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z -M`+(1001+e)+" "+n+"h400000v"+(40+e)+"h-400000z"},qoe=function(e,n){return"M983 "+(10+e+n)+` -l`+e/3.13+" -"+e+` -c4,-6.7,10,-10,18,-10 H400000v`+(40+e)+` -H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7 -s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744 -c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30 -c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722 -c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5 -c53.7,-170.3,84.5,-266.8,92.5,-289.5z -M`+(1001+e)+" "+n+"h400000v"+(40+e)+"h-400000z"},Foe=function(e,n){return"M424,"+(2398+e+n)+` -c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514 -c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20 -s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121 -s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081 -l`+e/4.223+" -"+e+`c4,-6.7,10,-10,18,-10 H400000 -v`+(40+e)+`H1014.6 -s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185 -c-2,6,-10,9,-24,9 -c-8,0,-12,-0.7,-12,-2z M`+(1001+e)+" "+n+` -h400000v`+(40+e)+"h-400000z"},Qoe=function(e,n){return"M473,"+(2713+e+n)+` -c339.3,-1799.3,509.3,-2700,510,-2702 l`+e/5.298+" -"+e+` -c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+e)+`H1017.7 -s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9 -c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200 -c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26 -s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104, -606zM`+(1001+e)+" "+n+"h400000v"+(40+e)+"H1017.7z"},$oe=function(e){var n=e/2;return"M400000 "+e+" H0 L"+n+" 0 l65 45 L145 "+(e-80)+" H400000z"},Hoe=function(e,n,r){var s=r-54-n-e;return"M702 "+(e+n)+"H400000"+(40+e)+` -H742v`+s+`l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1 -h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170 -c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667 -219 661 l218 661zM702 `+n+"H400000v"+(40+e)+"H742z"},Uoe=function(e,n,r){n=1e3*n;var s="";switch(e){case"sqrtMain":s=Boe(n,Tu);break;case"sqrtSize1":s=Ioe(n,Tu);break;case"sqrtSize2":s=qoe(n,Tu);break;case"sqrtSize3":s=Foe(n,Tu);break;case"sqrtSize4":s=Qoe(n,Tu);break;case"sqrtTall":s=Hoe(n,Tu,r)}return s},Voe=function(e,n){switch(e){case"⎜":return"M291 0 H417 V"+n+" H291z M291 0 H417 V"+n+" H291z";case"∣":return"M145 0 H188 V"+n+" H145z M145 0 H188 V"+n+" H145z";case"∥":return"M145 0 H188 V"+n+" H145z M145 0 H188 V"+n+" H145z"+("M367 0 H410 V"+n+" H367z M367 0 H410 V"+n+" H367z");case"⎟":return"M457 0 H583 V"+n+" H457z M457 0 H583 V"+n+" H457z";case"⎢":return"M319 0 H403 V"+n+" H319z M319 0 H403 V"+n+" H319z";case"⎥":return"M263 0 H347 V"+n+" H263z M263 0 H347 V"+n+" H263z";case"⎪":return"M384 0 H504 V"+n+" H384z M384 0 H504 V"+n+" H384z";case"⏐":return"M312 0 H355 V"+n+" H312z M312 0 H355 V"+n+" H312z";case"‖":return"M257 0 H300 V"+n+" H257z M257 0 H300 V"+n+" H257z"+("M478 0 H521 V"+n+" H478z M478 0 H521 V"+n+" H478z");default:return""}},nN={doubleleftarrow:`M262 157 -l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3 - 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28 - 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5 -c2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5 - 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87 --86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7 --2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z -m8 0v40h399730v-40zm0 194v40h399730v-40z`,doublerightarrow:`M399738 392l --10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5 - 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88 --33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68 --17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18 --13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782 -c-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3 --107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z`,leftarrow:`M400000 241H110l3-3c68.7-52.7 113.7-120 - 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8 --5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247 -c-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208 - 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3 - 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202 - l-3-3h399890zM100 241v40h399900v-40z`,leftbrace:`M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117 --45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7 - 5-6 9-10 13-.7 1-7.3 1-20 1H6z`,leftbraceunder:`M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13 - 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688 - 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7 --331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z`,leftgroup:`M400000 80 -H435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0 - 435 0h399565z`,leftgroupunder:`M400000 262 -H435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219 - 435 219h399565z`,leftharpoon:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3 --3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5 --18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7 --196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z`,leftharpoonplus:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5 - 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3 --4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7 --10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z -m0 0v40h400000v-40z`,leftharpoondown:`M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333 - 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5 - 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667 --152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z`,leftharpoondownplus:`M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12 - 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7 --2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0 -v40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,lefthook:`M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5 --83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3 --68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21 - 71.5 23h399859zM103 281v-40h399897v40z`,leftlinesegment:`M40 281 V428 H0 V94 H40 V241 H400000 v40z -M40 281 V428 H0 V94 H40 V241 H400000 v40z`,leftmapsto:`M40 281 V448H0V74H40V241H400000v40z -M40 281 V448H0V74H40V241H400000v40z`,leftToFrom:`M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23 --.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8 -c28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3 - 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,longequal:`M0 50 h400000 v40H0z m0 194h40000v40H0z -M0 50 h400000 v40H0z m0 194h40000v40H0z`,midbrace:`M200428 334 -c-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14 --53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7 - 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11 - 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z`,midbraceunder:`M199572 214 -c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14 - 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3 - 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0 --5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z`,oiintSize1:`M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6 --320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z -m368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8 -60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z`,oiintSize2:`M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8 --451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z -m502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2 -c0 110 84 276 504 276s502.4-166 502.4-276z`,oiiintSize1:`M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6 --480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z -m525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0 -85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z`,oiiintSize2:`M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8 --707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z -m770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1 -c0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z`,rightarrow:`M0 241v40h399891c-47.3 35.3-84 78-110 128 --16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 - 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 - 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85 --40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 --12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 - 151.7 139 205zm0 0v40h399900v-40z`,rightbrace:`M400000 542l --6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5 -s-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1 -c124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z`,rightbraceunder:`M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3 - 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237 --174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z`,rightgroup:`M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0 - 3-1 3-3v-38c-76-158-257-219-435-219H0z`,rightgroupunder:`M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18 - 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z`,rightharpoon:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3 --3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2 --10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 - 69.2 92 94.5zm0 0v40h399900v-40z`,rightharpoonplus:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11 --18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7 - 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z -m0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z`,rightharpoondown:`M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8 - 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5 --7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95 --27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z`,rightharpoondownplus:`M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8 - 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 - 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3 --64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z -m0-194v40h400000v-40zm0 0v40h400000v-40z`,righthook:`M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3 - 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0 --13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21 - 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,rightlinesegment:`M399960 241 V94 h40 V428 h-40 V281 H0 v-40z -M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,rightToFrom:`M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23 - 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32 --52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142 --167z M100 147v40h399900v-40zM0 341v40h399900v-40z`,twoheadleftarrow:`M0 167c68 40 - 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69 --70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3 --40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19 --37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101 - 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z`,twoheadrightarrow:`M400000 167 -c-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3 - 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42 - 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333 --19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70 - 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z`,tilde1:`M200 55.538c-77 0-168 73.953-177 73.953-3 0-7 --2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0 - 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0 - 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128 --68.267.847-113-73.952-191-73.952z`,tilde2:`M344 55.266c-142 0-300.638 81.316-311.5 86.418 --8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9 - 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114 -c1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751 - 181.476 676 181.476c-149 0-189-126.21-332-126.21z`,tilde3:`M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457 --11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0 - 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697 - 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696 - -338 0-409-156.573-744-156.573z`,tilde4:`M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345 --11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409 - 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9 - 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409 - -175.236-744-175.236z`,vec:`M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5 -3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11 -10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63 --1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1 --7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59 -H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359 -c-16-25.333-24-45-24-59z`,widehat1:`M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22 -c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,widehat2:`M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10 --11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat3:`M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10 --11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat4:`M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10 --11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widecheck1:`M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1, --5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`,widecheck2:`M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, --11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck3:`M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, --11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck4:`M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, --11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,baraboveleftarrow:`M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202 -c4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5 -c-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130 -s-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47 -121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6 -s2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11 -c0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z -M100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z`,rightarrowabovebar:`M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32 --27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0 -13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39 --84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5 --119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 --12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 -151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z`,baraboveshortleftharpoon:`M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 -c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17 -c2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21 -c-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40 -c-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z -M0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z`,rightharpoonaboveshortbar:`M0,241 l0,40c399126,0,399993,0,399993,0 -c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, --231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 -c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z -M0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z`,shortbaraboveleftharpoon:`M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 -c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9, -1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7, --152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z -M93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z`,shortrightharpoonabovebar:`M53,241l0,40c398570,0,399437,0,399437,0 -c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, --231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 -c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z -M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},Woe=function(e,n){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+n+` v1759 h347 v-84 -H403z M403 1759 V0 H319 V1759 v`+n+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+n+` v1759 H0 v84 H347z -M347 1759 V0 H263 V1759 v`+n+" v1759 h84z";case"vert":return"M145 15 v585 v"+n+` v585 c2.667,10,9.667,15,21,15 -c10,0,16.667,-5,20,-15 v-585 v`+-n+` v-585 c-2.667,-10,-9.667,-15,-21,-15 -c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+n+" v585 h43z";case"doublevert":return"M145 15 v585 v"+n+` v585 c2.667,10,9.667,15,21,15 -c10,0,16.667,-5,20,-15 v-585 v`+-n+` v-585 c-2.667,-10,-9.667,-15,-21,-15 -c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+n+` v585 h43z -M367 15 v585 v`+n+` v585 c2.667,10,9.667,15,21,15 -c10,0,16.667,-5,20,-15 v-585 v`+-n+` v-585 c-2.667,-10,-9.667,-15,-21,-15 -c-10,0,-16.667,5,-20,15z M410 15 H367 v585 v`+n+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+n+` v1715 h263 v84 H319z -MM319 602 V0 H403 V602 v`+n+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+n+` v1799 H0 v-84 H319z -MM319 602 V0 H403 V602 v`+n+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+n+` v602 h84z -M403 1759 V0 H319 V1759 v`+n+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+n+` v602 h84z -M347 1759 V0 h-84 V1759 v`+n+" v602 h84z";case"lparen":return`M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1 -c-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349, --36,557 l0,`+(n+84)+`c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210, -949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9 -c0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5, --544.7,-112.5,-882c-2,-104,-3,-167,-3,-189 -l0,-`+(n+92)+`c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3, --210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z`;case"rparen":return`M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3, -63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5 -c11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,`+(n+9)+` -c-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664 -c-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11 -c0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17 -c242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558 -l0,-`+(n+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7, --470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}};class w0{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return this.classes.includes(e)}toNode(){for(var e=document.createDocumentFragment(),n=0;nn.toText();return this.children.map(e).join("")}}var ma={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},Tp={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},rN={Å:"A",Ð:"D",Þ:"o",å:"a",ð:"d",þ:"o",А:"A",Б:"B",В:"B",Г:"F",Д:"A",Е:"E",Ж:"K",З:"3",И:"N",Й:"N",К:"K",Л:"N",М:"M",Н:"H",О:"O",П:"N",Р:"P",С:"C",Т:"T",У:"y",Ф:"O",Х:"X",Ц:"U",Ч:"h",Ш:"W",Щ:"W",Ъ:"B",Ы:"X",Ь:"B",Э:"3",Ю:"X",Я:"R",а:"a",б:"b",в:"a",г:"r",д:"y",е:"e",ж:"m",з:"e",и:"n",й:"n",к:"n",л:"n",м:"m",н:"n",о:"o",п:"n",р:"p",с:"c",т:"o",у:"y",ф:"b",х:"x",ц:"n",ч:"n",ш:"w",щ:"w",ъ:"a",ы:"m",ь:"a",э:"e",ю:"m",я:"r"};function Goe(t,e){ma[t]=e}function M5(t,e,n){if(!ma[e])throw new Error("Font metrics not found for font: "+e+".");var r=t.charCodeAt(0),s=ma[e][r];if(!s&&t[0]in rN&&(r=rN[t[0]].charCodeAt(0),s=ma[e][r]),!s&&n==="text"&&aR(r)&&(s=ma[e][77]),s)return{depth:s[0],height:s[1],italic:s[2],skew:s[3],width:s[4]}}var Mb={};function Xoe(t){var e;if(t>=5?e=0:t>=3?e=1:e=2,!Mb[e]){var n=Mb[e]={cssEmPerMu:Tp.quad[e]/18};for(var r in Tp)Tp.hasOwnProperty(r)&&(n[r]=Tp[r][e])}return Mb[e]}var Yoe=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],sN=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],iN=function(e,n){return n.size<2?e:Yoe[e-1][n.size-1]};class rl{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||rl.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=sN[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var n={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);return new rl(n)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:iN(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:sN[e-1]})}havingBaseStyle(e){e=e||this.style.text();var n=iN(rl.BASESIZE,e);return this.size===n&&this.textSize===rl.BASESIZE&&this.style===e?this:this.extend({style:e,size:n})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==rl.BASESIZE?["sizing","reset-size"+this.size,"size"+rl.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=Xoe(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}rl.BASESIZE=6;var k4={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},Koe={ex:!0,em:!0,mu:!0},lR=function(e){return typeof e!="string"&&(e=e.unit),e in k4||e in Koe||e==="ex"},Kn=function(e,n){var r;if(e.unit in k4)r=k4[e.unit]/n.fontMetrics().ptPerEm/n.sizeMultiplier;else if(e.unit==="mu")r=n.fontMetrics().cssEmPerMu;else{var s;if(n.style.isTight()?s=n.havingStyle(n.style.text()):s=n,e.unit==="ex")r=s.fontMetrics().xHeight;else if(e.unit==="em")r=s.fontMetrics().quad;else throw new De("Invalid unit: '"+e.unit+"'");s!==n&&(r*=s.sizeMultiplier/n.sizeMultiplier)}return Math.min(e.number*r,n.maxSize)},Be=function(e){return+e.toFixed(4)+"em"},vo=function(e){return e.filter(n=>n).join(" ")},oR=function(e,n,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},n){n.style.isTight()&&this.classes.push("mtight");var s=n.getColor();s&&(this.style.color=s)}},cR=function(e){var n=document.createElement(e);n.className=vo(this.classes);for(var r in this.style)this.style.hasOwnProperty(r)&&(n.style[r]=this.style[r]);for(var s in this.attributes)this.attributes.hasOwnProperty(s)&&n.setAttribute(s,this.attributes[s]);for(var i=0;i/=\x00-\x1f]/,uR=function(e){var n="<"+e;this.classes.length&&(n+=' class="'+tn.escape(vo(this.classes))+'"');var r="";for(var s in this.style)this.style.hasOwnProperty(s)&&(r+=tn.hyphenate(s)+":"+this.style[s]+";");r&&(n+=' style="'+tn.escape(r)+'"');for(var i in this.attributes)if(this.attributes.hasOwnProperty(i)){if(Zoe.test(i))throw new De("Invalid attribute name '"+i+"'");n+=" "+i+'="'+tn.escape(this.attributes[i])+'"'}n+=">";for(var l=0;l",n};class S0{constructor(e,n,r,s){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,oR.call(this,e,r,s),this.children=n||[]}setAttribute(e,n){this.attributes[e]=n}hasClass(e){return this.classes.includes(e)}toNode(){return cR.call(this,"span")}toMarkup(){return uR.call(this,"span")}}class A5{constructor(e,n,r,s){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,oR.call(this,n,s),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,n){this.attributes[e]=n}hasClass(e){return this.classes.includes(e)}toNode(){return cR.call(this,"a")}toMarkup(){return uR.call(this,"a")}}class Joe{constructor(e,n,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=n,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return this.classes.includes(e)}toNode(){var e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(var n in this.style)this.style.hasOwnProperty(n)&&(e.style[n]=this.style[n]);return e}toMarkup(){var e=''+tn.escape(this.alt)+'0&&(n=document.createElement("span"),n.style.marginRight=Be(this.italic)),this.classes.length>0&&(n=n||document.createElement("span"),n.className=vo(this.classes));for(var r in this.style)this.style.hasOwnProperty(r)&&(n=n||document.createElement("span"),n.style[r]=this.style[r]);return n?(n.appendChild(e),n):e}toMarkup(){var e=!1,n="0&&(r+="margin-right:"+this.italic+"em;");for(var s in this.style)this.style.hasOwnProperty(s)&&(r+=tn.hyphenate(s)+":"+this.style[s]+";");r&&(e=!0,n+=' style="'+tn.escape(r)+'"');var i=tn.escape(this.text);return e?(n+=">",n+=i,n+="",n):i}}class gl{constructor(e,n){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=n||{}}toNode(){var e="http://www.w3.org/2000/svg",n=document.createElementNS(e,"svg");for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&n.setAttribute(r,this.attributes[r]);for(var s=0;s':''}}class O4{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e="http://www.w3.org/2000/svg",n=document.createElementNS(e,"line");for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&n.setAttribute(r,this.attributes[r]);return n}toMarkup(){var e=" but got "+String(t)+".")}var nce={bin:1,close:1,inner:1,open:1,punct:1,rel:1},rce={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},Ln={math:{},text:{}};function N(t,e,n,r,s,i){Ln[t][s]={font:e,group:n,replace:r},i&&r&&(Ln[t][r]=Ln[t][s])}var C="math",Ee="text",L="main",G="ams",Wn="accent-token",Ve="bin",xs="close",Rd="inner",st="mathord",yr="op-token",ai="open",$x="punct",X="rel",wl="spacing",le="textord";N(C,L,X,"≡","\\equiv",!0);N(C,L,X,"≺","\\prec",!0);N(C,L,X,"≻","\\succ",!0);N(C,L,X,"∼","\\sim",!0);N(C,L,X,"⊥","\\perp");N(C,L,X,"⪯","\\preceq",!0);N(C,L,X,"⪰","\\succeq",!0);N(C,L,X,"≃","\\simeq",!0);N(C,L,X,"∣","\\mid",!0);N(C,L,X,"≪","\\ll",!0);N(C,L,X,"≫","\\gg",!0);N(C,L,X,"≍","\\asymp",!0);N(C,L,X,"∥","\\parallel");N(C,L,X,"⋈","\\bowtie",!0);N(C,L,X,"⌣","\\smile",!0);N(C,L,X,"⊑","\\sqsubseteq",!0);N(C,L,X,"⊒","\\sqsupseteq",!0);N(C,L,X,"≐","\\doteq",!0);N(C,L,X,"⌢","\\frown",!0);N(C,L,X,"∋","\\ni",!0);N(C,L,X,"∝","\\propto",!0);N(C,L,X,"⊢","\\vdash",!0);N(C,L,X,"⊣","\\dashv",!0);N(C,L,X,"∋","\\owns");N(C,L,$x,".","\\ldotp");N(C,L,$x,"⋅","\\cdotp");N(C,L,le,"#","\\#");N(Ee,L,le,"#","\\#");N(C,L,le,"&","\\&");N(Ee,L,le,"&","\\&");N(C,L,le,"ℵ","\\aleph",!0);N(C,L,le,"∀","\\forall",!0);N(C,L,le,"ℏ","\\hbar",!0);N(C,L,le,"∃","\\exists",!0);N(C,L,le,"∇","\\nabla",!0);N(C,L,le,"♭","\\flat",!0);N(C,L,le,"ℓ","\\ell",!0);N(C,L,le,"♮","\\natural",!0);N(C,L,le,"♣","\\clubsuit",!0);N(C,L,le,"℘","\\wp",!0);N(C,L,le,"♯","\\sharp",!0);N(C,L,le,"♢","\\diamondsuit",!0);N(C,L,le,"ℜ","\\Re",!0);N(C,L,le,"♡","\\heartsuit",!0);N(C,L,le,"ℑ","\\Im",!0);N(C,L,le,"♠","\\spadesuit",!0);N(C,L,le,"§","\\S",!0);N(Ee,L,le,"§","\\S");N(C,L,le,"¶","\\P",!0);N(Ee,L,le,"¶","\\P");N(C,L,le,"†","\\dag");N(Ee,L,le,"†","\\dag");N(Ee,L,le,"†","\\textdagger");N(C,L,le,"‡","\\ddag");N(Ee,L,le,"‡","\\ddag");N(Ee,L,le,"‡","\\textdaggerdbl");N(C,L,xs,"⎱","\\rmoustache",!0);N(C,L,ai,"⎰","\\lmoustache",!0);N(C,L,xs,"⟯","\\rgroup",!0);N(C,L,ai,"⟮","\\lgroup",!0);N(C,L,Ve,"∓","\\mp",!0);N(C,L,Ve,"⊖","\\ominus",!0);N(C,L,Ve,"⊎","\\uplus",!0);N(C,L,Ve,"⊓","\\sqcap",!0);N(C,L,Ve,"∗","\\ast");N(C,L,Ve,"⊔","\\sqcup",!0);N(C,L,Ve,"◯","\\bigcirc",!0);N(C,L,Ve,"∙","\\bullet",!0);N(C,L,Ve,"‡","\\ddagger");N(C,L,Ve,"≀","\\wr",!0);N(C,L,Ve,"⨿","\\amalg");N(C,L,Ve,"&","\\And");N(C,L,X,"⟵","\\longleftarrow",!0);N(C,L,X,"⇐","\\Leftarrow",!0);N(C,L,X,"⟸","\\Longleftarrow",!0);N(C,L,X,"⟶","\\longrightarrow",!0);N(C,L,X,"⇒","\\Rightarrow",!0);N(C,L,X,"⟹","\\Longrightarrow",!0);N(C,L,X,"↔","\\leftrightarrow",!0);N(C,L,X,"⟷","\\longleftrightarrow",!0);N(C,L,X,"⇔","\\Leftrightarrow",!0);N(C,L,X,"⟺","\\Longleftrightarrow",!0);N(C,L,X,"↦","\\mapsto",!0);N(C,L,X,"⟼","\\longmapsto",!0);N(C,L,X,"↗","\\nearrow",!0);N(C,L,X,"↩","\\hookleftarrow",!0);N(C,L,X,"↪","\\hookrightarrow",!0);N(C,L,X,"↘","\\searrow",!0);N(C,L,X,"↼","\\leftharpoonup",!0);N(C,L,X,"⇀","\\rightharpoonup",!0);N(C,L,X,"↙","\\swarrow",!0);N(C,L,X,"↽","\\leftharpoondown",!0);N(C,L,X,"⇁","\\rightharpoondown",!0);N(C,L,X,"↖","\\nwarrow",!0);N(C,L,X,"⇌","\\rightleftharpoons",!0);N(C,G,X,"≮","\\nless",!0);N(C,G,X,"","\\@nleqslant");N(C,G,X,"","\\@nleqq");N(C,G,X,"⪇","\\lneq",!0);N(C,G,X,"≨","\\lneqq",!0);N(C,G,X,"","\\@lvertneqq");N(C,G,X,"⋦","\\lnsim",!0);N(C,G,X,"⪉","\\lnapprox",!0);N(C,G,X,"⊀","\\nprec",!0);N(C,G,X,"⋠","\\npreceq",!0);N(C,G,X,"⋨","\\precnsim",!0);N(C,G,X,"⪹","\\precnapprox",!0);N(C,G,X,"≁","\\nsim",!0);N(C,G,X,"","\\@nshortmid");N(C,G,X,"∤","\\nmid",!0);N(C,G,X,"⊬","\\nvdash",!0);N(C,G,X,"⊭","\\nvDash",!0);N(C,G,X,"⋪","\\ntriangleleft");N(C,G,X,"⋬","\\ntrianglelefteq",!0);N(C,G,X,"⊊","\\subsetneq",!0);N(C,G,X,"","\\@varsubsetneq");N(C,G,X,"⫋","\\subsetneqq",!0);N(C,G,X,"","\\@varsubsetneqq");N(C,G,X,"≯","\\ngtr",!0);N(C,G,X,"","\\@ngeqslant");N(C,G,X,"","\\@ngeqq");N(C,G,X,"⪈","\\gneq",!0);N(C,G,X,"≩","\\gneqq",!0);N(C,G,X,"","\\@gvertneqq");N(C,G,X,"⋧","\\gnsim",!0);N(C,G,X,"⪊","\\gnapprox",!0);N(C,G,X,"⊁","\\nsucc",!0);N(C,G,X,"⋡","\\nsucceq",!0);N(C,G,X,"⋩","\\succnsim",!0);N(C,G,X,"⪺","\\succnapprox",!0);N(C,G,X,"≆","\\ncong",!0);N(C,G,X,"","\\@nshortparallel");N(C,G,X,"∦","\\nparallel",!0);N(C,G,X,"⊯","\\nVDash",!0);N(C,G,X,"⋫","\\ntriangleright");N(C,G,X,"⋭","\\ntrianglerighteq",!0);N(C,G,X,"","\\@nsupseteqq");N(C,G,X,"⊋","\\supsetneq",!0);N(C,G,X,"","\\@varsupsetneq");N(C,G,X,"⫌","\\supsetneqq",!0);N(C,G,X,"","\\@varsupsetneqq");N(C,G,X,"⊮","\\nVdash",!0);N(C,G,X,"⪵","\\precneqq",!0);N(C,G,X,"⪶","\\succneqq",!0);N(C,G,X,"","\\@nsubseteqq");N(C,G,Ve,"⊴","\\unlhd");N(C,G,Ve,"⊵","\\unrhd");N(C,G,X,"↚","\\nleftarrow",!0);N(C,G,X,"↛","\\nrightarrow",!0);N(C,G,X,"⇍","\\nLeftarrow",!0);N(C,G,X,"⇏","\\nRightarrow",!0);N(C,G,X,"↮","\\nleftrightarrow",!0);N(C,G,X,"⇎","\\nLeftrightarrow",!0);N(C,G,X,"△","\\vartriangle");N(C,G,le,"ℏ","\\hslash");N(C,G,le,"▽","\\triangledown");N(C,G,le,"◊","\\lozenge");N(C,G,le,"Ⓢ","\\circledS");N(C,G,le,"®","\\circledR");N(Ee,G,le,"®","\\circledR");N(C,G,le,"∡","\\measuredangle",!0);N(C,G,le,"∄","\\nexists");N(C,G,le,"℧","\\mho");N(C,G,le,"Ⅎ","\\Finv",!0);N(C,G,le,"⅁","\\Game",!0);N(C,G,le,"‵","\\backprime");N(C,G,le,"▲","\\blacktriangle");N(C,G,le,"▼","\\blacktriangledown");N(C,G,le,"■","\\blacksquare");N(C,G,le,"⧫","\\blacklozenge");N(C,G,le,"★","\\bigstar");N(C,G,le,"∢","\\sphericalangle",!0);N(C,G,le,"∁","\\complement",!0);N(C,G,le,"ð","\\eth",!0);N(Ee,L,le,"ð","ð");N(C,G,le,"╱","\\diagup");N(C,G,le,"╲","\\diagdown");N(C,G,le,"□","\\square");N(C,G,le,"□","\\Box");N(C,G,le,"◊","\\Diamond");N(C,G,le,"¥","\\yen",!0);N(Ee,G,le,"¥","\\yen",!0);N(C,G,le,"✓","\\checkmark",!0);N(Ee,G,le,"✓","\\checkmark");N(C,G,le,"ℶ","\\beth",!0);N(C,G,le,"ℸ","\\daleth",!0);N(C,G,le,"ℷ","\\gimel",!0);N(C,G,le,"ϝ","\\digamma",!0);N(C,G,le,"ϰ","\\varkappa");N(C,G,ai,"┌","\\@ulcorner",!0);N(C,G,xs,"┐","\\@urcorner",!0);N(C,G,ai,"└","\\@llcorner",!0);N(C,G,xs,"┘","\\@lrcorner",!0);N(C,G,X,"≦","\\leqq",!0);N(C,G,X,"⩽","\\leqslant",!0);N(C,G,X,"⪕","\\eqslantless",!0);N(C,G,X,"≲","\\lesssim",!0);N(C,G,X,"⪅","\\lessapprox",!0);N(C,G,X,"≊","\\approxeq",!0);N(C,G,Ve,"⋖","\\lessdot");N(C,G,X,"⋘","\\lll",!0);N(C,G,X,"≶","\\lessgtr",!0);N(C,G,X,"⋚","\\lesseqgtr",!0);N(C,G,X,"⪋","\\lesseqqgtr",!0);N(C,G,X,"≑","\\doteqdot");N(C,G,X,"≓","\\risingdotseq",!0);N(C,G,X,"≒","\\fallingdotseq",!0);N(C,G,X,"∽","\\backsim",!0);N(C,G,X,"⋍","\\backsimeq",!0);N(C,G,X,"⫅","\\subseteqq",!0);N(C,G,X,"⋐","\\Subset",!0);N(C,G,X,"⊏","\\sqsubset",!0);N(C,G,X,"≼","\\preccurlyeq",!0);N(C,G,X,"⋞","\\curlyeqprec",!0);N(C,G,X,"≾","\\precsim",!0);N(C,G,X,"⪷","\\precapprox",!0);N(C,G,X,"⊲","\\vartriangleleft");N(C,G,X,"⊴","\\trianglelefteq");N(C,G,X,"⊨","\\vDash",!0);N(C,G,X,"⊪","\\Vvdash",!0);N(C,G,X,"⌣","\\smallsmile");N(C,G,X,"⌢","\\smallfrown");N(C,G,X,"≏","\\bumpeq",!0);N(C,G,X,"≎","\\Bumpeq",!0);N(C,G,X,"≧","\\geqq",!0);N(C,G,X,"⩾","\\geqslant",!0);N(C,G,X,"⪖","\\eqslantgtr",!0);N(C,G,X,"≳","\\gtrsim",!0);N(C,G,X,"⪆","\\gtrapprox",!0);N(C,G,Ve,"⋗","\\gtrdot");N(C,G,X,"⋙","\\ggg",!0);N(C,G,X,"≷","\\gtrless",!0);N(C,G,X,"⋛","\\gtreqless",!0);N(C,G,X,"⪌","\\gtreqqless",!0);N(C,G,X,"≖","\\eqcirc",!0);N(C,G,X,"≗","\\circeq",!0);N(C,G,X,"≜","\\triangleq",!0);N(C,G,X,"∼","\\thicksim");N(C,G,X,"≈","\\thickapprox");N(C,G,X,"⫆","\\supseteqq",!0);N(C,G,X,"⋑","\\Supset",!0);N(C,G,X,"⊐","\\sqsupset",!0);N(C,G,X,"≽","\\succcurlyeq",!0);N(C,G,X,"⋟","\\curlyeqsucc",!0);N(C,G,X,"≿","\\succsim",!0);N(C,G,X,"⪸","\\succapprox",!0);N(C,G,X,"⊳","\\vartriangleright");N(C,G,X,"⊵","\\trianglerighteq");N(C,G,X,"⊩","\\Vdash",!0);N(C,G,X,"∣","\\shortmid");N(C,G,X,"∥","\\shortparallel");N(C,G,X,"≬","\\between",!0);N(C,G,X,"⋔","\\pitchfork",!0);N(C,G,X,"∝","\\varpropto");N(C,G,X,"◀","\\blacktriangleleft");N(C,G,X,"∴","\\therefore",!0);N(C,G,X,"∍","\\backepsilon");N(C,G,X,"▶","\\blacktriangleright");N(C,G,X,"∵","\\because",!0);N(C,G,X,"⋘","\\llless");N(C,G,X,"⋙","\\gggtr");N(C,G,Ve,"⊲","\\lhd");N(C,G,Ve,"⊳","\\rhd");N(C,G,X,"≂","\\eqsim",!0);N(C,L,X,"⋈","\\Join");N(C,G,X,"≑","\\Doteq",!0);N(C,G,Ve,"∔","\\dotplus",!0);N(C,G,Ve,"∖","\\smallsetminus");N(C,G,Ve,"⋒","\\Cap",!0);N(C,G,Ve,"⋓","\\Cup",!0);N(C,G,Ve,"⩞","\\doublebarwedge",!0);N(C,G,Ve,"⊟","\\boxminus",!0);N(C,G,Ve,"⊞","\\boxplus",!0);N(C,G,Ve,"⋇","\\divideontimes",!0);N(C,G,Ve,"⋉","\\ltimes",!0);N(C,G,Ve,"⋊","\\rtimes",!0);N(C,G,Ve,"⋋","\\leftthreetimes",!0);N(C,G,Ve,"⋌","\\rightthreetimes",!0);N(C,G,Ve,"⋏","\\curlywedge",!0);N(C,G,Ve,"⋎","\\curlyvee",!0);N(C,G,Ve,"⊝","\\circleddash",!0);N(C,G,Ve,"⊛","\\circledast",!0);N(C,G,Ve,"⋅","\\centerdot");N(C,G,Ve,"⊺","\\intercal",!0);N(C,G,Ve,"⋒","\\doublecap");N(C,G,Ve,"⋓","\\doublecup");N(C,G,Ve,"⊠","\\boxtimes",!0);N(C,G,X,"⇢","\\dashrightarrow",!0);N(C,G,X,"⇠","\\dashleftarrow",!0);N(C,G,X,"⇇","\\leftleftarrows",!0);N(C,G,X,"⇆","\\leftrightarrows",!0);N(C,G,X,"⇚","\\Lleftarrow",!0);N(C,G,X,"↞","\\twoheadleftarrow",!0);N(C,G,X,"↢","\\leftarrowtail",!0);N(C,G,X,"↫","\\looparrowleft",!0);N(C,G,X,"⇋","\\leftrightharpoons",!0);N(C,G,X,"↶","\\curvearrowleft",!0);N(C,G,X,"↺","\\circlearrowleft",!0);N(C,G,X,"↰","\\Lsh",!0);N(C,G,X,"⇈","\\upuparrows",!0);N(C,G,X,"↿","\\upharpoonleft",!0);N(C,G,X,"⇃","\\downharpoonleft",!0);N(C,L,X,"⊶","\\origof",!0);N(C,L,X,"⊷","\\imageof",!0);N(C,G,X,"⊸","\\multimap",!0);N(C,G,X,"↭","\\leftrightsquigarrow",!0);N(C,G,X,"⇉","\\rightrightarrows",!0);N(C,G,X,"⇄","\\rightleftarrows",!0);N(C,G,X,"↠","\\twoheadrightarrow",!0);N(C,G,X,"↣","\\rightarrowtail",!0);N(C,G,X,"↬","\\looparrowright",!0);N(C,G,X,"↷","\\curvearrowright",!0);N(C,G,X,"↻","\\circlearrowright",!0);N(C,G,X,"↱","\\Rsh",!0);N(C,G,X,"⇊","\\downdownarrows",!0);N(C,G,X,"↾","\\upharpoonright",!0);N(C,G,X,"⇂","\\downharpoonright",!0);N(C,G,X,"⇝","\\rightsquigarrow",!0);N(C,G,X,"⇝","\\leadsto");N(C,G,X,"⇛","\\Rrightarrow",!0);N(C,G,X,"↾","\\restriction");N(C,L,le,"‘","`");N(C,L,le,"$","\\$");N(Ee,L,le,"$","\\$");N(Ee,L,le,"$","\\textdollar");N(C,L,le,"%","\\%");N(Ee,L,le,"%","\\%");N(C,L,le,"_","\\_");N(Ee,L,le,"_","\\_");N(Ee,L,le,"_","\\textunderscore");N(C,L,le,"∠","\\angle",!0);N(C,L,le,"∞","\\infty",!0);N(C,L,le,"′","\\prime");N(C,L,le,"△","\\triangle");N(C,L,le,"Γ","\\Gamma",!0);N(C,L,le,"Δ","\\Delta",!0);N(C,L,le,"Θ","\\Theta",!0);N(C,L,le,"Λ","\\Lambda",!0);N(C,L,le,"Ξ","\\Xi",!0);N(C,L,le,"Π","\\Pi",!0);N(C,L,le,"Σ","\\Sigma",!0);N(C,L,le,"Υ","\\Upsilon",!0);N(C,L,le,"Φ","\\Phi",!0);N(C,L,le,"Ψ","\\Psi",!0);N(C,L,le,"Ω","\\Omega",!0);N(C,L,le,"A","Α");N(C,L,le,"B","Β");N(C,L,le,"E","Ε");N(C,L,le,"Z","Ζ");N(C,L,le,"H","Η");N(C,L,le,"I","Ι");N(C,L,le,"K","Κ");N(C,L,le,"M","Μ");N(C,L,le,"N","Ν");N(C,L,le,"O","Ο");N(C,L,le,"P","Ρ");N(C,L,le,"T","Τ");N(C,L,le,"X","Χ");N(C,L,le,"¬","\\neg",!0);N(C,L,le,"¬","\\lnot");N(C,L,le,"⊤","\\top");N(C,L,le,"⊥","\\bot");N(C,L,le,"∅","\\emptyset");N(C,G,le,"∅","\\varnothing");N(C,L,st,"α","\\alpha",!0);N(C,L,st,"β","\\beta",!0);N(C,L,st,"γ","\\gamma",!0);N(C,L,st,"δ","\\delta",!0);N(C,L,st,"ϵ","\\epsilon",!0);N(C,L,st,"ζ","\\zeta",!0);N(C,L,st,"η","\\eta",!0);N(C,L,st,"θ","\\theta",!0);N(C,L,st,"ι","\\iota",!0);N(C,L,st,"κ","\\kappa",!0);N(C,L,st,"λ","\\lambda",!0);N(C,L,st,"μ","\\mu",!0);N(C,L,st,"ν","\\nu",!0);N(C,L,st,"ξ","\\xi",!0);N(C,L,st,"ο","\\omicron",!0);N(C,L,st,"π","\\pi",!0);N(C,L,st,"ρ","\\rho",!0);N(C,L,st,"σ","\\sigma",!0);N(C,L,st,"τ","\\tau",!0);N(C,L,st,"υ","\\upsilon",!0);N(C,L,st,"ϕ","\\phi",!0);N(C,L,st,"χ","\\chi",!0);N(C,L,st,"ψ","\\psi",!0);N(C,L,st,"ω","\\omega",!0);N(C,L,st,"ε","\\varepsilon",!0);N(C,L,st,"ϑ","\\vartheta",!0);N(C,L,st,"ϖ","\\varpi",!0);N(C,L,st,"ϱ","\\varrho",!0);N(C,L,st,"ς","\\varsigma",!0);N(C,L,st,"φ","\\varphi",!0);N(C,L,Ve,"∗","*",!0);N(C,L,Ve,"+","+");N(C,L,Ve,"−","-",!0);N(C,L,Ve,"⋅","\\cdot",!0);N(C,L,Ve,"∘","\\circ",!0);N(C,L,Ve,"÷","\\div",!0);N(C,L,Ve,"±","\\pm",!0);N(C,L,Ve,"×","\\times",!0);N(C,L,Ve,"∩","\\cap",!0);N(C,L,Ve,"∪","\\cup",!0);N(C,L,Ve,"∖","\\setminus",!0);N(C,L,Ve,"∧","\\land");N(C,L,Ve,"∨","\\lor");N(C,L,Ve,"∧","\\wedge",!0);N(C,L,Ve,"∨","\\vee",!0);N(C,L,le,"√","\\surd");N(C,L,ai,"⟨","\\langle",!0);N(C,L,ai,"∣","\\lvert");N(C,L,ai,"∥","\\lVert");N(C,L,xs,"?","?");N(C,L,xs,"!","!");N(C,L,xs,"⟩","\\rangle",!0);N(C,L,xs,"∣","\\rvert");N(C,L,xs,"∥","\\rVert");N(C,L,X,"=","=");N(C,L,X,":",":");N(C,L,X,"≈","\\approx",!0);N(C,L,X,"≅","\\cong",!0);N(C,L,X,"≥","\\ge");N(C,L,X,"≥","\\geq",!0);N(C,L,X,"←","\\gets");N(C,L,X,">","\\gt",!0);N(C,L,X,"∈","\\in",!0);N(C,L,X,"","\\@not");N(C,L,X,"⊂","\\subset",!0);N(C,L,X,"⊃","\\supset",!0);N(C,L,X,"⊆","\\subseteq",!0);N(C,L,X,"⊇","\\supseteq",!0);N(C,G,X,"⊈","\\nsubseteq",!0);N(C,G,X,"⊉","\\nsupseteq",!0);N(C,L,X,"⊨","\\models");N(C,L,X,"←","\\leftarrow",!0);N(C,L,X,"≤","\\le");N(C,L,X,"≤","\\leq",!0);N(C,L,X,"<","\\lt",!0);N(C,L,X,"→","\\rightarrow",!0);N(C,L,X,"→","\\to");N(C,G,X,"≱","\\ngeq",!0);N(C,G,X,"≰","\\nleq",!0);N(C,L,wl," ","\\ ");N(C,L,wl," ","\\space");N(C,L,wl," ","\\nobreakspace");N(Ee,L,wl," ","\\ ");N(Ee,L,wl," "," ");N(Ee,L,wl," ","\\space");N(Ee,L,wl," ","\\nobreakspace");N(C,L,wl,null,"\\nobreak");N(C,L,wl,null,"\\allowbreak");N(C,L,$x,",",",");N(C,L,$x,";",";");N(C,G,Ve,"⊼","\\barwedge",!0);N(C,G,Ve,"⊻","\\veebar",!0);N(C,L,Ve,"⊙","\\odot",!0);N(C,L,Ve,"⊕","\\oplus",!0);N(C,L,Ve,"⊗","\\otimes",!0);N(C,L,le,"∂","\\partial",!0);N(C,L,Ve,"⊘","\\oslash",!0);N(C,G,Ve,"⊚","\\circledcirc",!0);N(C,G,Ve,"⊡","\\boxdot",!0);N(C,L,Ve,"△","\\bigtriangleup");N(C,L,Ve,"▽","\\bigtriangledown");N(C,L,Ve,"†","\\dagger");N(C,L,Ve,"⋄","\\diamond");N(C,L,Ve,"⋆","\\star");N(C,L,Ve,"◃","\\triangleleft");N(C,L,Ve,"▹","\\triangleright");N(C,L,ai,"{","\\{");N(Ee,L,le,"{","\\{");N(Ee,L,le,"{","\\textbraceleft");N(C,L,xs,"}","\\}");N(Ee,L,le,"}","\\}");N(Ee,L,le,"}","\\textbraceright");N(C,L,ai,"{","\\lbrace");N(C,L,xs,"}","\\rbrace");N(C,L,ai,"[","\\lbrack",!0);N(Ee,L,le,"[","\\lbrack",!0);N(C,L,xs,"]","\\rbrack",!0);N(Ee,L,le,"]","\\rbrack",!0);N(C,L,ai,"(","\\lparen",!0);N(C,L,xs,")","\\rparen",!0);N(Ee,L,le,"<","\\textless",!0);N(Ee,L,le,">","\\textgreater",!0);N(C,L,ai,"⌊","\\lfloor",!0);N(C,L,xs,"⌋","\\rfloor",!0);N(C,L,ai,"⌈","\\lceil",!0);N(C,L,xs,"⌉","\\rceil",!0);N(C,L,le,"\\","\\backslash");N(C,L,le,"∣","|");N(C,L,le,"∣","\\vert");N(Ee,L,le,"|","\\textbar",!0);N(C,L,le,"∥","\\|");N(C,L,le,"∥","\\Vert");N(Ee,L,le,"∥","\\textbardbl");N(Ee,L,le,"~","\\textasciitilde");N(Ee,L,le,"\\","\\textbackslash");N(Ee,L,le,"^","\\textasciicircum");N(C,L,X,"↑","\\uparrow",!0);N(C,L,X,"⇑","\\Uparrow",!0);N(C,L,X,"↓","\\downarrow",!0);N(C,L,X,"⇓","\\Downarrow",!0);N(C,L,X,"↕","\\updownarrow",!0);N(C,L,X,"⇕","\\Updownarrow",!0);N(C,L,yr,"∐","\\coprod");N(C,L,yr,"⋁","\\bigvee");N(C,L,yr,"⋀","\\bigwedge");N(C,L,yr,"⨄","\\biguplus");N(C,L,yr,"⋂","\\bigcap");N(C,L,yr,"⋃","\\bigcup");N(C,L,yr,"∫","\\int");N(C,L,yr,"∫","\\intop");N(C,L,yr,"∬","\\iint");N(C,L,yr,"∭","\\iiint");N(C,L,yr,"∏","\\prod");N(C,L,yr,"∑","\\sum");N(C,L,yr,"⨂","\\bigotimes");N(C,L,yr,"⨁","\\bigoplus");N(C,L,yr,"⨀","\\bigodot");N(C,L,yr,"∮","\\oint");N(C,L,yr,"∯","\\oiint");N(C,L,yr,"∰","\\oiiint");N(C,L,yr,"⨆","\\bigsqcup");N(C,L,yr,"∫","\\smallint");N(Ee,L,Rd,"…","\\textellipsis");N(C,L,Rd,"…","\\mathellipsis");N(Ee,L,Rd,"…","\\ldots",!0);N(C,L,Rd,"…","\\ldots",!0);N(C,L,Rd,"⋯","\\@cdots",!0);N(C,L,Rd,"⋱","\\ddots",!0);N(C,L,le,"⋮","\\varvdots");N(Ee,L,le,"⋮","\\varvdots");N(C,L,Wn,"ˊ","\\acute");N(C,L,Wn,"ˋ","\\grave");N(C,L,Wn,"¨","\\ddot");N(C,L,Wn,"~","\\tilde");N(C,L,Wn,"ˉ","\\bar");N(C,L,Wn,"˘","\\breve");N(C,L,Wn,"ˇ","\\check");N(C,L,Wn,"^","\\hat");N(C,L,Wn,"⃗","\\vec");N(C,L,Wn,"˙","\\dot");N(C,L,Wn,"˚","\\mathring");N(C,L,st,"","\\@imath");N(C,L,st,"","\\@jmath");N(C,L,le,"ı","ı");N(C,L,le,"ȷ","ȷ");N(Ee,L,le,"ı","\\i",!0);N(Ee,L,le,"ȷ","\\j",!0);N(Ee,L,le,"ß","\\ss",!0);N(Ee,L,le,"æ","\\ae",!0);N(Ee,L,le,"œ","\\oe",!0);N(Ee,L,le,"ø","\\o",!0);N(Ee,L,le,"Æ","\\AE",!0);N(Ee,L,le,"Œ","\\OE",!0);N(Ee,L,le,"Ø","\\O",!0);N(Ee,L,Wn,"ˊ","\\'");N(Ee,L,Wn,"ˋ","\\`");N(Ee,L,Wn,"ˆ","\\^");N(Ee,L,Wn,"˜","\\~");N(Ee,L,Wn,"ˉ","\\=");N(Ee,L,Wn,"˘","\\u");N(Ee,L,Wn,"˙","\\.");N(Ee,L,Wn,"¸","\\c");N(Ee,L,Wn,"˚","\\r");N(Ee,L,Wn,"ˇ","\\v");N(Ee,L,Wn,"¨",'\\"');N(Ee,L,Wn,"˝","\\H");N(Ee,L,Wn,"◯","\\textcircled");var dR={"--":!0,"---":!0,"``":!0,"''":!0};N(Ee,L,le,"–","--",!0);N(Ee,L,le,"–","\\textendash");N(Ee,L,le,"—","---",!0);N(Ee,L,le,"—","\\textemdash");N(Ee,L,le,"‘","`",!0);N(Ee,L,le,"‘","\\textquoteleft");N(Ee,L,le,"’","'",!0);N(Ee,L,le,"’","\\textquoteright");N(Ee,L,le,"“","``",!0);N(Ee,L,le,"“","\\textquotedblleft");N(Ee,L,le,"”","''",!0);N(Ee,L,le,"”","\\textquotedblright");N(C,L,le,"°","\\degree",!0);N(Ee,L,le,"°","\\degree");N(Ee,L,le,"°","\\textdegree",!0);N(C,L,le,"£","\\pounds");N(C,L,le,"£","\\mathsterling",!0);N(Ee,L,le,"£","\\pounds");N(Ee,L,le,"£","\\textsterling",!0);N(C,G,le,"✠","\\maltese");N(Ee,G,le,"✠","\\maltese");var lN='0123456789/@."';for(var Ab=0;Ab0)return Li(i,h,s,n,l.concat(m));if(d){var p,x;if(d==="boldsymbol"){var v=ace(i,s,n,l,r);p=v.fontName,x=[v.fontClass]}else c?(p=mR[d].fontName,x=[d]):(p=_p(d,n.fontWeight,n.fontShape),x=[d,n.fontWeight,n.fontShape]);if(Hx(i,p,s).metrics)return Li(i,p,s,n,l.concat(x));if(dR.hasOwnProperty(i)&&p.slice(0,10)==="Typewriter"){for(var b=[],k=0;k{if(vo(t.classes)!==vo(e.classes)||t.skew!==e.skew||t.maxFontSize!==e.maxFontSize)return!1;if(t.classes.length===1){var n=t.classes[0];if(n==="mbin"||n==="mord")return!1}for(var r in t.style)if(t.style.hasOwnProperty(r)&&t.style[r]!==e.style[r])return!1;for(var s in e.style)if(e.style.hasOwnProperty(s)&&t.style[s]!==e.style[s])return!1;return!0},cce=t=>{for(var e=0;en&&(n=l.height),l.depth>r&&(r=l.depth),l.maxFontSize>s&&(s=l.maxFontSize)}e.height=n,e.depth=r,e.maxFontSize=s},Cs=function(e,n,r,s){var i=new S0(e,n,r,s);return E5(i),i},hR=(t,e,n,r)=>new S0(t,e,n,r),uce=function(e,n,r){var s=Cs([e],[],n);return s.height=Math.max(r||n.fontMetrics().defaultRuleThickness,n.minRuleThickness),s.style.borderBottomWidth=Be(s.height),s.maxFontSize=1,s},dce=function(e,n,r,s){var i=new A5(e,n,r,s);return E5(i),i},fR=function(e){var n=new w0(e);return E5(n),n},hce=function(e,n){return e instanceof w0?Cs([],[e],n):e},fce=function(e){if(e.positionType==="individualShift"){for(var n=e.children,r=[n[0]],s=-n[0].shift-n[0].elem.depth,i=s,l=1;l{var n=Cs(["mspace"],[],e),r=Kn(t,e);return n.style.marginRight=Be(r),n},_p=function(e,n,r){var s="";switch(e){case"amsrm":s="AMS";break;case"textrm":s="Main";break;case"textsf":s="SansSerif";break;case"texttt":s="Typewriter";break;default:s=e}var i;return n==="textbf"&&r==="textit"?i="BoldItalic":n==="textbf"?i="Bold":n==="textit"?i="Italic":i="Regular",s+"-"+i},mR={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},pR={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},gce=function(e,n){var[r,s,i]=pR[e],l=new yo(r),c=new gl([l],{width:Be(s),height:Be(i),style:"width:"+Be(s),viewBox:"0 0 "+1e3*s+" "+1e3*i,preserveAspectRatio:"xMinYMin"}),d=hR(["overlay"],[c],n);return d.height=i,d.style.height=Be(i),d.style.width=Be(s),d},ge={fontMap:mR,makeSymbol:Li,mathsym:ice,makeSpan:Cs,makeSvgSpan:hR,makeLineSpan:uce,makeAnchor:dce,makeFragment:fR,wrapFragment:hce,makeVList:mce,makeOrd:lce,makeGlue:pce,staticSvg:gce,svgData:pR,tryCombineChars:cce},Xn={number:3,unit:"mu"},ec={number:4,unit:"mu"},Ya={number:5,unit:"mu"},xce={mord:{mop:Xn,mbin:ec,mrel:Ya,minner:Xn},mop:{mord:Xn,mop:Xn,mrel:Ya,minner:Xn},mbin:{mord:ec,mop:ec,mopen:ec,minner:ec},mrel:{mord:Ya,mop:Ya,mopen:Ya,minner:Ya},mopen:{},mclose:{mop:Xn,mbin:ec,mrel:Ya,minner:Xn},mpunct:{mord:Xn,mop:Xn,mrel:Ya,mopen:Xn,mclose:Xn,mpunct:Xn,minner:Xn},minner:{mord:Xn,mop:Xn,mbin:ec,mrel:Ya,mopen:Xn,mpunct:Xn,minner:Xn}},vce={mord:{mop:Xn},mop:{mord:Xn,mop:Xn},mbin:{},mrel:{},mopen:{},mclose:{mop:Xn},mpunct:{},minner:{mop:Xn}},gR={},Yg={},Kg={};function Qe(t){for(var{type:e,names:n,props:r,handler:s,htmlBuilder:i,mathmlBuilder:l}=t,c={type:e,numArgs:r.numArgs,argTypes:r.argTypes,allowedInArgument:!!r.allowedInArgument,allowedInText:!!r.allowedInText,allowedInMath:r.allowedInMath===void 0?!0:r.allowedInMath,numOptionalArgs:r.numOptionalArgs||0,infix:!!r.infix,primitive:!!r.primitive,handler:s},d=0;d{var O=k.classes[0],j=b.classes[0];O==="mbin"&&bce.includes(j)?k.classes[0]="mord":j==="mbin"&&yce.includes(O)&&(b.classes[0]="mord")},{node:p},x,v),hN(i,(b,k)=>{var O=N4(k),j=N4(b),T=O&&j?b.hasClass("mtight")?vce[O][j]:xce[O][j]:null;if(T)return ge.makeGlue(T,h)},{node:p},x,v),i},hN=function t(e,n,r,s,i){s&&e.push(s);for(var l=0;lx=>{e.splice(p+1,0,x),l++})(l)}s&&e.pop()},xR=function(e){return e instanceof w0||e instanceof A5||e instanceof S0&&e.hasClass("enclosing")?e:null},kce=function t(e,n){var r=xR(e);if(r){var s=r.children;if(s.length){if(n==="right")return t(s[s.length-1],"right");if(n==="left")return t(s[0],"left")}}return e},N4=function(e,n){return e?(n&&(e=kce(e,n)),Sce[e.classes[0]]||null):null},qf=function(e,n){var r=["nulldelimiter"].concat(e.baseSizingClasses());return xl(n.concat(r))},Xt=function(e,n,r){if(!e)return xl();if(Yg[e.type]){var s=Yg[e.type](e,n);if(r&&n.size!==r.size){s=xl(n.sizingClasses(r),[s],n);var i=n.sizeMultiplier/r.sizeMultiplier;s.height*=i,s.depth*=i}return s}else throw new De("Got group of unknown type: '"+e.type+"'")};function Dp(t,e){var n=xl(["base"],t,e),r=xl(["strut"]);return r.style.height=Be(n.height+n.depth),n.depth&&(r.style.verticalAlign=Be(-n.depth)),n.children.unshift(r),n}function C4(t,e){var n=null;t.length===1&&t[0].type==="tag"&&(n=t[0].tag,t=t[0].body);var r=Mr(t,e,"root"),s;r.length===2&&r[1].hasClass("tag")&&(s=r.pop());for(var i=[],l=[],c=0;c0&&(i.push(Dp(l,e)),l=[]),i.push(r[c]));l.length>0&&i.push(Dp(l,e));var h;n?(h=Dp(Mr(n,e,!0)),h.classes=["tag"],i.push(h)):s&&i.push(s);var m=xl(["katex-html"],i);if(m.setAttribute("aria-hidden","true"),h){var p=h.children[0];p.style.height=Be(m.height+m.depth),m.depth&&(p.style.verticalAlign=Be(-m.depth))}return m}function vR(t){return new w0(t)}class ti{constructor(e,n,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=n||[],this.classes=r||[]}setAttribute(e,n){this.attributes[e]=n}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&e.setAttribute(n,this.attributes[n]);this.classes.length>0&&(e.className=vo(this.classes));for(var r=0;r0&&(e+=' class ="'+tn.escape(vo(this.classes))+'"'),e+=">";for(var r=0;r",e}toText(){return this.children.map(e=>e.toText()).join("")}}class pa{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return tn.escape(this.toText())}toText(){return this.text}}class Oce{constructor(e){this.width=void 0,this.character=void 0,this.width=e,e>=.05555&&e<=.05556?this.character=" ":e>=.1666&&e<=.1667?this.character=" ":e>=.2222&&e<=.2223?this.character=" ":e>=.2777&&e<=.2778?this.character="  ":e>=-.05556&&e<=-.05555?this.character=" ⁣":e>=-.1667&&e<=-.1666?this.character=" ⁣":e>=-.2223&&e<=-.2222?this.character=" ⁣":e>=-.2778&&e<=-.2777?this.character=" ⁣":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",Be(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}}var _e={MathNode:ti,TextNode:pa,SpaceNode:Oce,newDocumentFragment:vR},Mi=function(e,n,r){return Ln[n][e]&&Ln[n][e].replace&&e.charCodeAt(0)!==55349&&!(dR.hasOwnProperty(e)&&r&&(r.fontFamily&&r.fontFamily.slice(4,6)==="tt"||r.font&&r.font.slice(4,6)==="tt"))&&(e=Ln[n][e].replace),new _e.TextNode(e)},_5=function(e){return e.length===1?e[0]:new _e.MathNode("mrow",e)},D5=function(e,n){if(n.fontFamily==="texttt")return"monospace";if(n.fontFamily==="textsf")return n.fontShape==="textit"&&n.fontWeight==="textbf"?"sans-serif-bold-italic":n.fontShape==="textit"?"sans-serif-italic":n.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(n.fontShape==="textit"&&n.fontWeight==="textbf")return"bold-italic";if(n.fontShape==="textit")return"italic";if(n.fontWeight==="textbf")return"bold";var r=n.font;if(!r||r==="mathnormal")return null;var s=e.mode;if(r==="mathit")return"italic";if(r==="boldsymbol")return e.type==="textord"?"bold":"bold-italic";if(r==="mathbf")return"bold";if(r==="mathbb")return"double-struck";if(r==="mathsfit")return"sans-serif-italic";if(r==="mathfrak")return"fraktur";if(r==="mathscr"||r==="mathcal")return"script";if(r==="mathsf")return"sans-serif";if(r==="mathtt")return"monospace";var i=e.text;if(["\\imath","\\jmath"].includes(i))return null;Ln[s][i]&&Ln[s][i].replace&&(i=Ln[s][i].replace);var l=ge.fontMap[r].fontName;return M5(i,l,s)?ge.fontMap[r].variant:null};function Rb(t){if(!t)return!1;if(t.type==="mi"&&t.children.length===1){var e=t.children[0];return e instanceof pa&&e.text==="."}else if(t.type==="mo"&&t.children.length===1&&t.getAttribute("separator")==="true"&&t.getAttribute("lspace")==="0em"&&t.getAttribute("rspace")==="0em"){var n=t.children[0];return n instanceof pa&&n.text===","}else return!1}var qs=function(e,n,r){if(e.length===1){var s=Rn(e[0],n);return r&&s instanceof ti&&s.type==="mo"&&(s.setAttribute("lspace","0em"),s.setAttribute("rspace","0em")),[s]}for(var i=[],l,c=0;c=1&&(l.type==="mn"||Rb(l))){var h=d.children[0];h instanceof ti&&h.type==="mn"&&(h.children=[...l.children,...h.children],i.pop())}else if(l.type==="mi"&&l.children.length===1){var m=l.children[0];if(m instanceof pa&&m.text==="̸"&&(d.type==="mo"||d.type==="mi"||d.type==="mn")){var p=d.children[0];p instanceof pa&&p.text.length>0&&(p.text=p.text.slice(0,1)+"̸"+p.text.slice(1),i.pop())}}}i.push(d),l=d}return i},bo=function(e,n,r){return _5(qs(e,n,r))},Rn=function(e,n){if(!e)return new _e.MathNode("mrow");if(Kg[e.type]){var r=Kg[e.type](e,n);return r}else throw new De("Got group of unknown type: '"+e.type+"'")};function fN(t,e,n,r,s){var i=qs(t,n),l;i.length===1&&i[0]instanceof ti&&["mrow","mtable"].includes(i[0].type)?l=i[0]:l=new _e.MathNode("mrow",i);var c=new _e.MathNode("annotation",[new _e.TextNode(e)]);c.setAttribute("encoding","application/x-tex");var d=new _e.MathNode("semantics",[l,c]),h=new _e.MathNode("math",[d]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),r&&h.setAttribute("display","block");var m=s?"katex":"katex-mathml";return ge.makeSpan([m],[h])}var yR=function(e){return new rl({style:e.displayMode?at.DISPLAY:at.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},bR=function(e,n){if(n.displayMode){var r=["katex-display"];n.leqno&&r.push("leqno"),n.fleqn&&r.push("fleqn"),e=ge.makeSpan(r,[e])}return e},jce=function(e,n,r){var s=yR(r),i;if(r.output==="mathml")return fN(e,n,s,r.displayMode,!0);if(r.output==="html"){var l=C4(e,s);i=ge.makeSpan(["katex"],[l])}else{var c=fN(e,n,s,r.displayMode,!1),d=C4(e,s);i=ge.makeSpan(["katex"],[c,d])}return bR(i,r)},Nce=function(e,n,r){var s=yR(r),i=C4(e,s),l=ge.makeSpan(["katex"],[i]);return bR(l,r)},Cce={widehat:"^",widecheck:"ˇ",widetilde:"~",utilde:"~",overleftarrow:"←",underleftarrow:"←",xleftarrow:"←",overrightarrow:"→",underrightarrow:"→",xrightarrow:"→",underbrace:"⏟",overbrace:"⏞",overgroup:"⏠",undergroup:"⏡",overleftrightarrow:"↔",underleftrightarrow:"↔",xleftrightarrow:"↔",Overrightarrow:"⇒",xRightarrow:"⇒",overleftharpoon:"↼",xleftharpoonup:"↼",overrightharpoon:"⇀",xrightharpoonup:"⇀",xLeftarrow:"⇐",xLeftrightarrow:"⇔",xhookleftarrow:"↩",xhookrightarrow:"↪",xmapsto:"↦",xrightharpoondown:"⇁",xleftharpoondown:"↽",xrightleftharpoons:"⇌",xleftrightharpoons:"⇋",xtwoheadleftarrow:"↞",xtwoheadrightarrow:"↠",xlongequal:"=",xtofrom:"⇄",xrightleftarrows:"⇄",xrightequilibrium:"⇌",xleftequilibrium:"⇋","\\cdrightarrow":"→","\\cdleftarrow":"←","\\cdlongequal":"="},Tce=function(e){var n=new _e.MathNode("mo",[new _e.TextNode(Cce[e.replace(/^\\/,"")])]);return n.setAttribute("stretchy","true"),n},Mce={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Ace=function(e){return e.type==="ordgroup"?e.body.length:1},Ece=function(e,n){function r(){var c=4e5,d=e.label.slice(1);if(["widehat","widecheck","widetilde","utilde"].includes(d)){var h=e,m=Ace(h.base),p,x,v;if(m>5)d==="widehat"||d==="widecheck"?(p=420,c=2364,v=.42,x=d+"4"):(p=312,c=2340,v=.34,x="tilde4");else{var b=[1,1,2,2,3,3][m];d==="widehat"||d==="widecheck"?(c=[0,1062,2364,2364,2364][b],p=[0,239,300,360,420][b],v=[0,.24,.3,.3,.36,.42][b],x=d+b):(c=[0,600,1033,2339,2340][b],p=[0,260,286,306,312][b],v=[0,.26,.286,.3,.306,.34][b],x="tilde"+b)}var k=new yo(x),O=new gl([k],{width:"100%",height:Be(v),viewBox:"0 0 "+c+" "+p,preserveAspectRatio:"none"});return{span:ge.makeSvgSpan([],[O],n),minWidth:0,height:v}}else{var j=[],T=Mce[d],[M,_,D]=T,E=D/1e3,z=M.length,Q,F;if(z===1){var B=T[3];Q=["hide-tail"],F=[B]}else if(z===2)Q=["halfarrow-left","halfarrow-right"],F=["xMinYMin","xMaxYMin"];else if(z===3)Q=["brace-left","brace-center","brace-right"],F=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support - `+z+" children.");for(var U=0;U0&&(s.style.minWidth=Be(i)),s},_ce=function(e,n,r,s,i){var l,c=e.height+e.depth+r+s;if(/fbox|color|angl/.test(n)){if(l=ge.makeSpan(["stretchy",n],[],i),n==="fbox"){var d=i.color&&i.getColor();d&&(l.style.borderColor=d)}}else{var h=[];/^[bx]cancel$/.test(n)&&h.push(new O4({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(n)&&h.push(new O4({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var m=new gl(h,{width:"100%",height:Be(c)});l=ge.makeSvgSpan([],[m],i)}return l.height=c,l.style.height=Be(c),l},vl={encloseSpan:_ce,mathMLnode:Tce,svgSpan:Ece};function Nt(t,e){if(!t||t.type!==e)throw new Error("Expected node of type "+e+", but got "+(t?"node of type "+t.type:String(t)));return t}function R5(t){var e=Ux(t);if(!e)throw new Error("Expected node of symbol group type, but got "+(t?"node of type "+t.type:String(t)));return e}function Ux(t){return t&&(t.type==="atom"||rce.hasOwnProperty(t.type))?t:null}var z5=(t,e)=>{var n,r,s;t&&t.type==="supsub"?(r=Nt(t.base,"accent"),n=r.base,t.base=n,s=tce(Xt(t,e)),t.base=r):(r=Nt(t,"accent"),n=r.base);var i=Xt(n,e.havingCrampedStyle()),l=r.isShifty&&tn.isCharacterBox(n),c=0;if(l){var d=tn.getBaseElem(n),h=Xt(d,e.havingCrampedStyle());c=aN(h).skew}var m=r.label==="\\c",p=m?i.height+i.depth:Math.min(i.height,e.fontMetrics().xHeight),x;if(r.isStretchy)x=vl.svgSpan(r,e),x=ge.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:x,wrapperClasses:["svg-align"],wrapperStyle:c>0?{width:"calc(100% - "+Be(2*c)+")",marginLeft:Be(2*c)}:void 0}]},e);else{var v,b;r.label==="\\vec"?(v=ge.staticSvg("vec",e),b=ge.svgData.vec[1]):(v=ge.makeOrd({mode:r.mode,text:r.label},e,"textord"),v=aN(v),v.italic=0,b=v.width,m&&(p+=v.depth)),x=ge.makeSpan(["accent-body"],[v]);var k=r.label==="\\textcircled";k&&(x.classes.push("accent-full"),p=i.height);var O=c;k||(O-=b/2),x.style.left=Be(O),r.label==="\\textcircled"&&(x.style.top=".2em"),x=ge.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-p},{type:"elem",elem:x}]},e)}var j=ge.makeSpan(["mord","accent"],[x],e);return s?(s.children[0]=j,s.height=Math.max(j.height,s.height),s.classes[0]="mord",s):j},wR=(t,e)=>{var n=t.isStretchy?vl.mathMLnode(t.label):new _e.MathNode("mo",[Mi(t.label,t.mode)]),r=new _e.MathNode("mover",[Rn(t.base,e),n]);return r.setAttribute("accent","true"),r},Dce=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(t=>"\\"+t).join("|"));Qe({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(t,e)=>{var n=Zg(e[0]),r=!Dce.test(t.funcName),s=!r||t.funcName==="\\widehat"||t.funcName==="\\widetilde"||t.funcName==="\\widecheck";return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:r,isShifty:s,base:n}},htmlBuilder:z5,mathmlBuilder:wR});Qe({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(t,e)=>{var n=e[0],r=t.parser.mode;return r==="math"&&(t.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+t.funcName+" works only in text mode"),r="text"),{type:"accent",mode:r,label:t.funcName,isStretchy:!1,isShifty:!0,base:n}},htmlBuilder:z5,mathmlBuilder:wR});Qe({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=e[0];return{type:"accentUnder",mode:n.mode,label:r,base:s}},htmlBuilder:(t,e)=>{var n=Xt(t.base,e),r=vl.svgSpan(t,e),s=t.label==="\\utilde"?.12:0,i=ge.makeVList({positionType:"top",positionData:n.height,children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:s},{type:"elem",elem:n}]},e);return ge.makeSpan(["mord","accentunder"],[i],e)},mathmlBuilder:(t,e)=>{var n=vl.mathMLnode(t.label),r=new _e.MathNode("munder",[Rn(t.base,e),n]);return r.setAttribute("accentunder","true"),r}});var Rp=t=>{var e=new _e.MathNode("mpadded",t?[t]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e};Qe({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,n){var{parser:r,funcName:s}=t;return{type:"xArrow",mode:r.mode,label:s,body:e[0],below:n[0]}},htmlBuilder(t,e){var n=e.style,r=e.havingStyle(n.sup()),s=ge.wrapFragment(Xt(t.body,r,e),e),i=t.label.slice(0,2)==="\\x"?"x":"cd";s.classes.push(i+"-arrow-pad");var l;t.below&&(r=e.havingStyle(n.sub()),l=ge.wrapFragment(Xt(t.below,r,e),e),l.classes.push(i+"-arrow-pad"));var c=vl.svgSpan(t,e),d=-e.fontMetrics().axisHeight+.5*c.height,h=-e.fontMetrics().axisHeight-.5*c.height-.111;(s.depth>.25||t.label==="\\xleftequilibrium")&&(h-=s.depth);var m;if(l){var p=-e.fontMetrics().axisHeight+l.height+.5*c.height+.111;m=ge.makeVList({positionType:"individualShift",children:[{type:"elem",elem:s,shift:h},{type:"elem",elem:c,shift:d},{type:"elem",elem:l,shift:p}]},e)}else m=ge.makeVList({positionType:"individualShift",children:[{type:"elem",elem:s,shift:h},{type:"elem",elem:c,shift:d}]},e);return m.children[0].children[0].children[1].classes.push("svg-align"),ge.makeSpan(["mrel","x-arrow"],[m],e)},mathmlBuilder(t,e){var n=vl.mathMLnode(t.label);n.setAttribute("minsize",t.label.charAt(0)==="x"?"1.75em":"3.0em");var r;if(t.body){var s=Rp(Rn(t.body,e));if(t.below){var i=Rp(Rn(t.below,e));r=new _e.MathNode("munderover",[n,i,s])}else r=new _e.MathNode("mover",[n,s])}else if(t.below){var l=Rp(Rn(t.below,e));r=new _e.MathNode("munder",[n,l])}else r=Rp(),r=new _e.MathNode("mover",[n,r]);return r}});var Rce=ge.makeSpan;function SR(t,e){var n=Mr(t.body,e,!0);return Rce([t.mclass],n,e)}function kR(t,e){var n,r=qs(t.body,e);return t.mclass==="minner"?n=new _e.MathNode("mpadded",r):t.mclass==="mord"?t.isCharacterBox?(n=r[0],n.type="mi"):n=new _e.MathNode("mi",r):(t.isCharacterBox?(n=r[0],n.type="mo"):n=new _e.MathNode("mo",r),t.mclass==="mbin"?(n.attributes.lspace="0.22em",n.attributes.rspace="0.22em"):t.mclass==="mpunct"?(n.attributes.lspace="0em",n.attributes.rspace="0.17em"):t.mclass==="mopen"||t.mclass==="mclose"?(n.attributes.lspace="0em",n.attributes.rspace="0em"):t.mclass==="minner"&&(n.attributes.lspace="0.0556em",n.attributes.width="+0.1111em")),n}Qe({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(t,e){var{parser:n,funcName:r}=t,s=e[0];return{type:"mclass",mode:n.mode,mclass:"m"+r.slice(5),body:ar(s),isCharacterBox:tn.isCharacterBox(s)}},htmlBuilder:SR,mathmlBuilder:kR});var Vx=t=>{var e=t.type==="ordgroup"&&t.body.length?t.body[0]:t;return e.type==="atom"&&(e.family==="bin"||e.family==="rel")?"m"+e.family:"mord"};Qe({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(t,e){var{parser:n}=t;return{type:"mclass",mode:n.mode,mclass:Vx(e[0]),body:ar(e[1]),isCharacterBox:tn.isCharacterBox(e[1])}}});Qe({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(t,e){var{parser:n,funcName:r}=t,s=e[1],i=e[0],l;r!=="\\stackrel"?l=Vx(s):l="mrel";var c={type:"op",mode:s.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:r!=="\\stackrel",body:ar(s)},d={type:"supsub",mode:i.mode,base:c,sup:r==="\\underset"?null:i,sub:r==="\\underset"?i:null};return{type:"mclass",mode:n.mode,mclass:l,body:[d],isCharacterBox:tn.isCharacterBox(d)}},htmlBuilder:SR,mathmlBuilder:kR});Qe({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:n}=t;return{type:"pmb",mode:n.mode,mclass:Vx(e[0]),body:ar(e[0])}},htmlBuilder(t,e){var n=Mr(t.body,e,!0),r=ge.makeSpan([t.mclass],n,e);return r.style.textShadow="0.02em 0.01em 0.04px",r},mathmlBuilder(t,e){var n=qs(t.body,e),r=new _e.MathNode("mstyle",n);return r.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),r}});var zce={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},mN=()=>({type:"styling",body:[],mode:"math",style:"display"}),pN=t=>t.type==="textord"&&t.text==="@",Pce=(t,e)=>(t.type==="mathord"||t.type==="atom")&&t.text===e;function Lce(t,e,n){var r=zce[t];switch(r){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return n.callFunction(r,[e[0]],[e[1]]);case"\\uparrow":case"\\downarrow":{var s=n.callFunction("\\\\cdleft",[e[0]],[]),i={type:"atom",text:r,mode:"math",family:"rel"},l=n.callFunction("\\Big",[i],[]),c=n.callFunction("\\\\cdright",[e[1]],[]),d={type:"ordgroup",mode:"math",body:[s,l,c]};return n.callFunction("\\\\cdparent",[d],[])}case"\\\\cdlongequal":return n.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var h={type:"textord",text:"\\Vert",mode:"math"};return n.callFunction("\\Big",[h],[])}default:return{type:"textord",text:" ",mode:"math"}}}function Bce(t){var e=[];for(t.gullet.beginGroup(),t.gullet.macros.set("\\cr","\\\\\\relax"),t.gullet.beginGroup();;){e.push(t.parseExpression(!1,"\\\\")),t.gullet.endGroup(),t.gullet.beginGroup();var n=t.fetch().text;if(n==="&"||n==="\\\\")t.consume();else if(n==="\\end"){e[e.length-1].length===0&&e.pop();break}else throw new De("Expected \\\\ or \\cr or \\end",t.nextToken)}for(var r=[],s=[r],i=0;i-1))if("<>AV".indexOf(h)>-1)for(var p=0;p<2;p++){for(var x=!0,v=d+1;vAV=|." after @',l[d]);var b=Lce(h,m,t),k={type:"styling",body:[b],mode:"math",style:"display"};r.push(k),c=mN()}i%2===0?r.push(c):r.shift(),r=[],s.push(r)}t.gullet.endGroup(),t.gullet.endGroup();var O=new Array(s[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:s,arraystretch:1,addJot:!0,rowGaps:[null],cols:O,colSeparationType:"CD",hLinesBeforeRow:new Array(s.length+1).fill([])}}Qe({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(t,e){var{parser:n,funcName:r}=t;return{type:"cdlabel",mode:n.mode,side:r.slice(4),label:e[0]}},htmlBuilder(t,e){var n=e.havingStyle(e.style.sup()),r=ge.wrapFragment(Xt(t.label,n,e),e);return r.classes.push("cd-label-"+t.side),r.style.bottom=Be(.8-r.depth),r.height=0,r.depth=0,r},mathmlBuilder(t,e){var n=new _e.MathNode("mrow",[Rn(t.label,e)]);return n=new _e.MathNode("mpadded",[n]),n.setAttribute("width","0"),t.side==="left"&&n.setAttribute("lspace","-1width"),n.setAttribute("voffset","0.7em"),n=new _e.MathNode("mstyle",[n]),n.setAttribute("displaystyle","false"),n.setAttribute("scriptlevel","1"),n}});Qe({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(t,e){var{parser:n}=t;return{type:"cdlabelparent",mode:n.mode,fragment:e[0]}},htmlBuilder(t,e){var n=ge.wrapFragment(Xt(t.fragment,e),e);return n.classes.push("cd-vert-arrow"),n},mathmlBuilder(t,e){return new _e.MathNode("mrow",[Rn(t.fragment,e)])}});Qe({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(t,e){for(var{parser:n}=t,r=Nt(e[0],"ordgroup"),s=r.body,i="",l=0;l=1114111)throw new De("\\@char with invalid code point "+i);return d<=65535?h=String.fromCharCode(d):(d-=65536,h=String.fromCharCode((d>>10)+55296,(d&1023)+56320)),{type:"textord",mode:n.mode,text:h}}});var OR=(t,e)=>{var n=Mr(t.body,e.withColor(t.color),!1);return ge.makeFragment(n)},jR=(t,e)=>{var n=qs(t.body,e.withColor(t.color)),r=new _e.MathNode("mstyle",n);return r.setAttribute("mathcolor",t.color),r};Qe({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(t,e){var{parser:n}=t,r=Nt(e[0],"color-token").color,s=e[1];return{type:"color",mode:n.mode,color:r,body:ar(s)}},htmlBuilder:OR,mathmlBuilder:jR});Qe({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(t,e){var{parser:n,breakOnTokenText:r}=t,s=Nt(e[0],"color-token").color;n.gullet.macros.set("\\current@color",s);var i=n.parseExpression(!0,r);return{type:"color",mode:n.mode,color:s,body:i}},htmlBuilder:OR,mathmlBuilder:jR});Qe({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(t,e,n){var{parser:r}=t,s=r.gullet.future().text==="["?r.parseSizeGroup(!0):null,i=!r.settings.displayMode||!r.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:r.mode,newLine:i,size:s&&Nt(s,"size").value}},htmlBuilder(t,e){var n=ge.makeSpan(["mspace"],[],e);return t.newLine&&(n.classes.push("newline"),t.size&&(n.style.marginTop=Be(Kn(t.size,e)))),n},mathmlBuilder(t,e){var n=new _e.MathNode("mspace");return t.newLine&&(n.setAttribute("linebreak","newline"),t.size&&n.setAttribute("height",Be(Kn(t.size,e)))),n}});var T4={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},NR=t=>{var e=t.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new De("Expected a control sequence",t);return e},Ice=t=>{var e=t.gullet.popToken();return e.text==="="&&(e=t.gullet.popToken(),e.text===" "&&(e=t.gullet.popToken())),e},CR=(t,e,n,r)=>{var s=t.gullet.macros.get(n.text);s==null&&(n.noexpand=!0,s={tokens:[n],numArgs:0,unexpandable:!t.gullet.isExpandable(n.text)}),t.gullet.macros.set(e,s,r)};Qe({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(t){var{parser:e,funcName:n}=t;e.consumeSpaces();var r=e.fetch();if(T4[r.text])return(n==="\\global"||n==="\\\\globallong")&&(r.text=T4[r.text]),Nt(e.parseFunction(),"internal");throw new De("Invalid token after macro prefix",r)}});Qe({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:n}=t,r=e.gullet.popToken(),s=r.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(s))throw new De("Expected a control sequence",r);for(var i=0,l,c=[[]];e.gullet.future().text!=="{";)if(r=e.gullet.popToken(),r.text==="#"){if(e.gullet.future().text==="{"){l=e.gullet.future(),c[i].push("{");break}if(r=e.gullet.popToken(),!/^[1-9]$/.test(r.text))throw new De('Invalid argument number "'+r.text+'"');if(parseInt(r.text)!==i+1)throw new De('Argument number "'+r.text+'" out of order');i++,c.push([])}else{if(r.text==="EOF")throw new De("Expected a macro definition");c[i].push(r.text)}var{tokens:d}=e.gullet.consumeArg();return l&&d.unshift(l),(n==="\\edef"||n==="\\xdef")&&(d=e.gullet.expandTokens(d),d.reverse()),e.gullet.macros.set(s,{tokens:d,numArgs:i,delimiters:c},n===T4[n]),{type:"internal",mode:e.mode}}});Qe({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:n}=t,r=NR(e.gullet.popToken());e.gullet.consumeSpaces();var s=Ice(e);return CR(e,r,s,n==="\\\\globallet"),{type:"internal",mode:e.mode}}});Qe({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:n}=t,r=NR(e.gullet.popToken()),s=e.gullet.popToken(),i=e.gullet.popToken();return CR(e,r,i,n==="\\\\globalfuture"),e.gullet.pushToken(i),e.gullet.pushToken(s),{type:"internal",mode:e.mode}}});var Vh=function(e,n,r){var s=Ln.math[e]&&Ln.math[e].replace,i=M5(s||e,n,r);if(!i)throw new Error("Unsupported symbol "+e+" and font size "+n+".");return i},P5=function(e,n,r,s){var i=r.havingBaseStyle(n),l=ge.makeSpan(s.concat(i.sizingClasses(r)),[e],r),c=i.sizeMultiplier/r.sizeMultiplier;return l.height*=c,l.depth*=c,l.maxFontSize=i.sizeMultiplier,l},TR=function(e,n,r){var s=n.havingBaseStyle(r),i=(1-n.sizeMultiplier/s.sizeMultiplier)*n.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=Be(i),e.height-=i,e.depth+=i},qce=function(e,n,r,s,i,l){var c=ge.makeSymbol(e,"Main-Regular",i,s),d=P5(c,n,s,l);return r&&TR(d,s,n),d},Fce=function(e,n,r,s){return ge.makeSymbol(e,"Size"+n+"-Regular",r,s)},MR=function(e,n,r,s,i,l){var c=Fce(e,n,i,s),d=P5(ge.makeSpan(["delimsizing","size"+n],[c],s),at.TEXT,s,l);return r&&TR(d,s,at.TEXT),d},zb=function(e,n,r){var s;n==="Size1-Regular"?s="delim-size1":s="delim-size4";var i=ge.makeSpan(["delimsizinginner",s],[ge.makeSpan([],[ge.makeSymbol(e,n,r)])]);return{type:"elem",elem:i}},Pb=function(e,n,r){var s=ma["Size4-Regular"][e.charCodeAt(0)]?ma["Size4-Regular"][e.charCodeAt(0)][4]:ma["Size1-Regular"][e.charCodeAt(0)][4],i=new yo("inner",Voe(e,Math.round(1e3*n))),l=new gl([i],{width:Be(s),height:Be(n),style:"width:"+Be(s),viewBox:"0 0 "+1e3*s+" "+Math.round(1e3*n),preserveAspectRatio:"xMinYMin"}),c=ge.makeSvgSpan([],[l],r);return c.height=n,c.style.height=Be(n),c.style.width=Be(s),{type:"elem",elem:c}},M4=.008,zp={type:"kern",size:-1*M4},Qce=["|","\\lvert","\\rvert","\\vert"],$ce=["\\|","\\lVert","\\rVert","\\Vert"],AR=function(e,n,r,s,i,l){var c,d,h,m,p="",x=0;c=h=m=e,d=null;var v="Size1-Regular";e==="\\uparrow"?h=m="⏐":e==="\\Uparrow"?h=m="‖":e==="\\downarrow"?c=h="⏐":e==="\\Downarrow"?c=h="‖":e==="\\updownarrow"?(c="\\uparrow",h="⏐",m="\\downarrow"):e==="\\Updownarrow"?(c="\\Uparrow",h="‖",m="\\Downarrow"):Qce.includes(e)?(h="∣",p="vert",x=333):$ce.includes(e)?(h="∥",p="doublevert",x=556):e==="["||e==="\\lbrack"?(c="⎡",h="⎢",m="⎣",v="Size4-Regular",p="lbrack",x=667):e==="]"||e==="\\rbrack"?(c="⎤",h="⎥",m="⎦",v="Size4-Regular",p="rbrack",x=667):e==="\\lfloor"||e==="⌊"?(h=c="⎢",m="⎣",v="Size4-Regular",p="lfloor",x=667):e==="\\lceil"||e==="⌈"?(c="⎡",h=m="⎢",v="Size4-Regular",p="lceil",x=667):e==="\\rfloor"||e==="⌋"?(h=c="⎥",m="⎦",v="Size4-Regular",p="rfloor",x=667):e==="\\rceil"||e==="⌉"?(c="⎤",h=m="⎥",v="Size4-Regular",p="rceil",x=667):e==="("||e==="\\lparen"?(c="⎛",h="⎜",m="⎝",v="Size4-Regular",p="lparen",x=875):e===")"||e==="\\rparen"?(c="⎞",h="⎟",m="⎠",v="Size4-Regular",p="rparen",x=875):e==="\\{"||e==="\\lbrace"?(c="⎧",d="⎨",m="⎩",h="⎪",v="Size4-Regular"):e==="\\}"||e==="\\rbrace"?(c="⎫",d="⎬",m="⎭",h="⎪",v="Size4-Regular"):e==="\\lgroup"||e==="⟮"?(c="⎧",m="⎩",h="⎪",v="Size4-Regular"):e==="\\rgroup"||e==="⟯"?(c="⎫",m="⎭",h="⎪",v="Size4-Regular"):e==="\\lmoustache"||e==="⎰"?(c="⎧",m="⎭",h="⎪",v="Size4-Regular"):(e==="\\rmoustache"||e==="⎱")&&(c="⎫",m="⎩",h="⎪",v="Size4-Regular");var b=Vh(c,v,i),k=b.height+b.depth,O=Vh(h,v,i),j=O.height+O.depth,T=Vh(m,v,i),M=T.height+T.depth,_=0,D=1;if(d!==null){var E=Vh(d,v,i);_=E.height+E.depth,D=2}var z=k+M+_,Q=Math.max(0,Math.ceil((n-z)/(D*j))),F=z+Q*D*j,B=s.fontMetrics().axisHeight;r&&(B*=s.sizeMultiplier);var U=F/2-B,V=[];if(p.length>0){var ce=F-k-M,W=Math.round(F*1e3),J=Woe(p,Math.round(ce*1e3)),H=new yo(p,J),ae=(x/1e3).toFixed(3)+"em",ne=(W/1e3).toFixed(3)+"em",ue=new gl([H],{width:ae,height:ne,viewBox:"0 0 "+x+" "+W}),R=ge.makeSvgSpan([],[ue],s);R.height=W/1e3,R.style.width=ae,R.style.height=ne,V.push({type:"elem",elem:R})}else{if(V.push(zb(m,v,i)),V.push(zp),d===null){var me=F-k-M+2*M4;V.push(Pb(h,me,s))}else{var Y=(F-k-M-_)/2+2*M4;V.push(Pb(h,Y,s)),V.push(zp),V.push(zb(d,v,i)),V.push(zp),V.push(Pb(h,Y,s))}V.push(zp),V.push(zb(c,v,i))}var P=s.havingBaseStyle(at.TEXT),K=ge.makeVList({positionType:"bottom",positionData:U,children:V},P);return P5(ge.makeSpan(["delimsizing","mult"],[K],P),at.TEXT,s,l)},Lb=80,Bb=.08,Ib=function(e,n,r,s,i){var l=Uoe(e,s,r),c=new yo(e,l),d=new gl([c],{width:"400em",height:Be(n),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return ge.makeSvgSpan(["hide-tail"],[d],i)},Hce=function(e,n){var r=n.havingBaseSizing(),s=RR("\\surd",e*r.sizeMultiplier,DR,r),i=r.sizeMultiplier,l=Math.max(0,n.minRuleThickness-n.fontMetrics().sqrtRuleThickness),c,d=0,h=0,m=0,p;return s.type==="small"?(m=1e3+1e3*l+Lb,e<1?i=1:e<1.4&&(i=.7),d=(1+l+Bb)/i,h=(1+l)/i,c=Ib("sqrtMain",d,m,l,n),c.style.minWidth="0.853em",p=.833/i):s.type==="large"?(m=(1e3+Lb)*cf[s.size],h=(cf[s.size]+l)/i,d=(cf[s.size]+l+Bb)/i,c=Ib("sqrtSize"+s.size,d,m,l,n),c.style.minWidth="1.02em",p=1/i):(d=e+l+Bb,h=e+l,m=Math.floor(1e3*e+l)+Lb,c=Ib("sqrtTall",d,m,l,n),c.style.minWidth="0.742em",p=1.056),c.height=h,c.style.height=Be(d),{span:c,advanceWidth:p,ruleWidth:(n.fontMetrics().sqrtRuleThickness+l)*i}},ER=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","\\surd"],Uce=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱"],_R=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],cf=[0,1.2,1.8,2.4,3],Vce=function(e,n,r,s,i){if(e==="<"||e==="\\lt"||e==="⟨"?e="\\langle":(e===">"||e==="\\gt"||e==="⟩")&&(e="\\rangle"),ER.includes(e)||_R.includes(e))return MR(e,n,!1,r,s,i);if(Uce.includes(e))return AR(e,cf[n],!1,r,s,i);throw new De("Illegal delimiter: '"+e+"'")},Wce=[{type:"small",style:at.SCRIPTSCRIPT},{type:"small",style:at.SCRIPT},{type:"small",style:at.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],Gce=[{type:"small",style:at.SCRIPTSCRIPT},{type:"small",style:at.SCRIPT},{type:"small",style:at.TEXT},{type:"stack"}],DR=[{type:"small",style:at.SCRIPTSCRIPT},{type:"small",style:at.SCRIPT},{type:"small",style:at.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Xce=function(e){if(e.type==="small")return"Main-Regular";if(e.type==="large")return"Size"+e.size+"-Regular";if(e.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},RR=function(e,n,r,s){for(var i=Math.min(2,3-s.style.size),l=i;ln)return r[l]}return r[r.length-1]},zR=function(e,n,r,s,i,l){e==="<"||e==="\\lt"||e==="⟨"?e="\\langle":(e===">"||e==="\\gt"||e==="⟩")&&(e="\\rangle");var c;_R.includes(e)?c=Wce:ER.includes(e)?c=DR:c=Gce;var d=RR(e,n,c,s);return d.type==="small"?qce(e,d.style,r,s,i,l):d.type==="large"?MR(e,d.size,r,s,i,l):AR(e,n,r,s,i,l)},Yce=function(e,n,r,s,i,l){var c=s.fontMetrics().axisHeight*s.sizeMultiplier,d=901,h=5/s.fontMetrics().ptPerEm,m=Math.max(n-c,r+c),p=Math.max(m/500*d,2*m-h);return zR(e,p,!0,s,i,l)},ul={sqrtImage:Hce,sizedDelim:Vce,sizeToMaxHeight:cf,customSizedDelim:zR,leftRightDelim:Yce},gN={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Kce=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","<",">","\\langle","⟨","\\rangle","⟩","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Wx(t,e){var n=Ux(t);if(n&&Kce.includes(n.text))return n;throw n?new De("Invalid delimiter '"+n.text+"' after '"+e.funcName+"'",t):new De("Invalid delimiter type '"+t.type+"'",t)}Qe({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(t,e)=>{var n=Wx(e[0],t);return{type:"delimsizing",mode:t.parser.mode,size:gN[t.funcName].size,mclass:gN[t.funcName].mclass,delim:n.text}},htmlBuilder:(t,e)=>t.delim==="."?ge.makeSpan([t.mclass]):ul.sizedDelim(t.delim,t.size,e,t.mode,[t.mclass]),mathmlBuilder:t=>{var e=[];t.delim!=="."&&e.push(Mi(t.delim,t.mode));var n=new _e.MathNode("mo",e);t.mclass==="mopen"||t.mclass==="mclose"?n.setAttribute("fence","true"):n.setAttribute("fence","false"),n.setAttribute("stretchy","true");var r=Be(ul.sizeToMaxHeight[t.size]);return n.setAttribute("minsize",r),n.setAttribute("maxsize",r),n}});function xN(t){if(!t.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}Qe({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(t,e)=>{var n=t.parser.gullet.macros.get("\\current@color");if(n&&typeof n!="string")throw new De("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:t.parser.mode,delim:Wx(e[0],t).text,color:n}}});Qe({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(t,e)=>{var n=Wx(e[0],t),r=t.parser;++r.leftrightDepth;var s=r.parseExpression(!1);--r.leftrightDepth,r.expect("\\right",!1);var i=Nt(r.parseFunction(),"leftright-right");return{type:"leftright",mode:r.mode,body:s,left:n.text,right:i.delim,rightColor:i.color}},htmlBuilder:(t,e)=>{xN(t);for(var n=Mr(t.body,e,!0,["mopen","mclose"]),r=0,s=0,i=!1,l=0;l{xN(t);var n=qs(t.body,e);if(t.left!=="."){var r=new _e.MathNode("mo",[Mi(t.left,t.mode)]);r.setAttribute("fence","true"),n.unshift(r)}if(t.right!=="."){var s=new _e.MathNode("mo",[Mi(t.right,t.mode)]);s.setAttribute("fence","true"),t.rightColor&&s.setAttribute("mathcolor",t.rightColor),n.push(s)}return _5(n)}});Qe({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(t,e)=>{var n=Wx(e[0],t);if(!t.parser.leftrightDepth)throw new De("\\middle without preceding \\left",n);return{type:"middle",mode:t.parser.mode,delim:n.text}},htmlBuilder:(t,e)=>{var n;if(t.delim===".")n=qf(e,[]);else{n=ul.sizedDelim(t.delim,1,e,t.mode,[]);var r={delim:t.delim,options:e};n.isMiddle=r}return n},mathmlBuilder:(t,e)=>{var n=t.delim==="\\vert"||t.delim==="|"?Mi("|","text"):Mi(t.delim,t.mode),r=new _e.MathNode("mo",[n]);return r.setAttribute("fence","true"),r.setAttribute("lspace","0.05em"),r.setAttribute("rspace","0.05em"),r}});var L5=(t,e)=>{var n=ge.wrapFragment(Xt(t.body,e),e),r=t.label.slice(1),s=e.sizeMultiplier,i,l=0,c=tn.isCharacterBox(t.body);if(r==="sout")i=ge.makeSpan(["stretchy","sout"]),i.height=e.fontMetrics().defaultRuleThickness/s,l=-.5*e.fontMetrics().xHeight;else if(r==="phase"){var d=Kn({number:.6,unit:"pt"},e),h=Kn({number:.35,unit:"ex"},e),m=e.havingBaseSizing();s=s/m.sizeMultiplier;var p=n.height+n.depth+d+h;n.style.paddingLeft=Be(p/2+d);var x=Math.floor(1e3*p*s),v=$oe(x),b=new gl([new yo("phase",v)],{width:"400em",height:Be(x/1e3),viewBox:"0 0 400000 "+x,preserveAspectRatio:"xMinYMin slice"});i=ge.makeSvgSpan(["hide-tail"],[b],e),i.style.height=Be(p),l=n.depth+d+h}else{/cancel/.test(r)?c||n.classes.push("cancel-pad"):r==="angl"?n.classes.push("anglpad"):n.classes.push("boxpad");var k=0,O=0,j=0;/box/.test(r)?(j=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),k=e.fontMetrics().fboxsep+(r==="colorbox"?0:j),O=k):r==="angl"?(j=Math.max(e.fontMetrics().defaultRuleThickness,e.minRuleThickness),k=4*j,O=Math.max(0,.25-n.depth)):(k=c?.2:0,O=k),i=vl.encloseSpan(n,r,k,O,e),/fbox|boxed|fcolorbox/.test(r)?(i.style.borderStyle="solid",i.style.borderWidth=Be(j)):r==="angl"&&j!==.049&&(i.style.borderTopWidth=Be(j),i.style.borderRightWidth=Be(j)),l=n.depth+O,t.backgroundColor&&(i.style.backgroundColor=t.backgroundColor,t.borderColor&&(i.style.borderColor=t.borderColor))}var T;if(t.backgroundColor)T=ge.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:l},{type:"elem",elem:n,shift:0}]},e);else{var M=/cancel|phase/.test(r)?["svg-align"]:[];T=ge.makeVList({positionType:"individualShift",children:[{type:"elem",elem:n,shift:0},{type:"elem",elem:i,shift:l,wrapperClasses:M}]},e)}return/cancel/.test(r)&&(T.height=n.height,T.depth=n.depth),/cancel/.test(r)&&!c?ge.makeSpan(["mord","cancel-lap"],[T],e):ge.makeSpan(["mord"],[T],e)},B5=(t,e)=>{var n=0,r=new _e.MathNode(t.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Rn(t.body,e)]);switch(t.label){case"\\cancel":r.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":r.setAttribute("notation","downdiagonalstrike");break;case"\\phase":r.setAttribute("notation","phasorangle");break;case"\\sout":r.setAttribute("notation","horizontalstrike");break;case"\\fbox":r.setAttribute("notation","box");break;case"\\angl":r.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(n=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,r.setAttribute("width","+"+2*n+"pt"),r.setAttribute("height","+"+2*n+"pt"),r.setAttribute("lspace",n+"pt"),r.setAttribute("voffset",n+"pt"),t.label==="\\fcolorbox"){var s=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);r.setAttribute("style","border: "+s+"em solid "+String(t.borderColor))}break;case"\\xcancel":r.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return t.backgroundColor&&r.setAttribute("mathbackground",t.backgroundColor),r};Qe({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(t,e,n){var{parser:r,funcName:s}=t,i=Nt(e[0],"color-token").color,l=e[1];return{type:"enclose",mode:r.mode,label:s,backgroundColor:i,body:l}},htmlBuilder:L5,mathmlBuilder:B5});Qe({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(t,e,n){var{parser:r,funcName:s}=t,i=Nt(e[0],"color-token").color,l=Nt(e[1],"color-token").color,c=e[2];return{type:"enclose",mode:r.mode,label:s,backgroundColor:l,borderColor:i,body:c}},htmlBuilder:L5,mathmlBuilder:B5});Qe({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(t,e){var{parser:n}=t;return{type:"enclose",mode:n.mode,label:"\\fbox",body:e[0]}}});Qe({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(t,e){var{parser:n,funcName:r}=t,s=e[0];return{type:"enclose",mode:n.mode,label:r,body:s}},htmlBuilder:L5,mathmlBuilder:B5});Qe({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(t,e){var{parser:n}=t;return{type:"enclose",mode:n.mode,label:"\\angl",body:e[0]}}});var PR={};function Na(t){for(var{type:e,names:n,props:r,handler:s,htmlBuilder:i,mathmlBuilder:l}=t,c={type:e,numArgs:r.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:s},d=0;d{var e=t.parser.settings;if(!e.displayMode)throw new De("{"+t.envName+"} can be used only in display mode.")};function I5(t){if(t.indexOf("ed")===-1)return t.indexOf("*")===-1}function Mo(t,e,n){var{hskipBeforeAndAfter:r,addJot:s,cols:i,arraystretch:l,colSeparationType:c,autoTag:d,singleRow:h,emptySingleRow:m,maxNumCols:p,leqno:x}=e;if(t.gullet.beginGroup(),h||t.gullet.macros.set("\\cr","\\\\\\relax"),!l){var v=t.gullet.expandMacroAsText("\\arraystretch");if(v==null)l=1;else if(l=parseFloat(v),!l||l<0)throw new De("Invalid \\arraystretch: "+v)}t.gullet.beginGroup();var b=[],k=[b],O=[],j=[],T=d!=null?[]:void 0;function M(){d&&t.gullet.macros.set("\\@eqnsw","1",!0)}function _(){T&&(t.gullet.macros.get("\\df@tag")?(T.push(t.subparse([new si("\\df@tag")])),t.gullet.macros.set("\\df@tag",void 0,!0)):T.push(!!d&&t.gullet.macros.get("\\@eqnsw")==="1"))}for(M(),j.push(vN(t));;){var D=t.parseExpression(!1,h?"\\end":"\\\\");t.gullet.endGroup(),t.gullet.beginGroup(),D={type:"ordgroup",mode:t.mode,body:D},n&&(D={type:"styling",mode:t.mode,style:n,body:[D]}),b.push(D);var E=t.fetch().text;if(E==="&"){if(p&&b.length===p){if(h||c)throw new De("Too many tab characters: &",t.nextToken);t.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}t.consume()}else if(E==="\\end"){_(),b.length===1&&D.type==="styling"&&D.body[0].body.length===0&&(k.length>1||!m)&&k.pop(),j.length0&&(M+=.25),h.push({pos:M,isDashed:Jn[nn]})}for(_(l[0]),r=0;r0&&(U+=T,zJn))for(r=0;r=c)){var ve=void 0;(s>0||e.hskipBeforeAndAfter)&&(ve=tn.deflt(Y.pregap,x),ve!==0&&(J=ge.makeSpan(["arraycolsep"],[]),J.style.width=Be(ve),W.push(J)));var Re=[];for(r=0;r0){for(var Oe=ge.makeLineSpan("hline",n,m),nt=ge.makeLineSpan("hdashline",n,m),ut=[{type:"elem",elem:d,shift:0}];h.length>0;){var Ct=h.pop(),Bn=Ct.pos-V;Ct.isDashed?ut.push({type:"elem",elem:nt,shift:Bn}):ut.push({type:"elem",elem:Oe,shift:Bn})}d=ge.makeVList({positionType:"individualShift",children:ut},n)}if(ae.length===0)return ge.makeSpan(["mord"],[d],n);var Tn=ge.makeVList({positionType:"individualShift",children:ae},n);return Tn=ge.makeSpan(["tag"],[Tn],n),ge.makeFragment([d,Tn])},Zce={c:"center ",l:"left ",r:"right "},Ta=function(e,n){for(var r=[],s=new _e.MathNode("mtd",[],["mtr-glue"]),i=new _e.MathNode("mtd",[],["mml-eqn-num"]),l=0;l0){var b=e.cols,k="",O=!1,j=0,T=b.length;b[0].type==="separator"&&(x+="top ",j=1),b[b.length-1].type==="separator"&&(x+="bottom ",T-=1);for(var M=j;M0?"left ":"",x+=Q[Q.length-1].length>0?"right ":"";for(var F=1;F-1?"alignat":"align",i=e.envName==="split",l=Mo(e.parser,{cols:r,addJot:!0,autoTag:i?void 0:I5(e.envName),emptySingleRow:!0,colSeparationType:s,maxNumCols:i?2:void 0,leqno:e.parser.settings.leqno},"display"),c,d=0,h={type:"ordgroup",mode:e.mode,body:[]};if(n[0]&&n[0].type==="ordgroup"){for(var m="",p=0;p0&&v&&(O=1),r[b]={type:"align",align:k,pregap:O,postgap:0}}return l.colSeparationType=v?"align":"alignat",l};Na({type:"array",names:["array","darray"],props:{numArgs:1},handler(t,e){var n=Ux(e[0]),r=n?[e[0]]:Nt(e[0],"ordgroup").body,s=r.map(function(l){var c=R5(l),d=c.text;if("lcr".indexOf(d)!==-1)return{type:"align",align:d};if(d==="|")return{type:"separator",separator:"|"};if(d===":")return{type:"separator",separator:":"};throw new De("Unknown column alignment: "+d,l)}),i={cols:s,hskipBeforeAndAfter:!0,maxNumCols:s.length};return Mo(t.parser,i,q5(t.envName))},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(t){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[t.envName.replace("*","")],n="c",r={hskipBeforeAndAfter:!1,cols:[{type:"align",align:n}]};if(t.envName.charAt(t.envName.length-1)==="*"){var s=t.parser;if(s.consumeSpaces(),s.fetch().text==="["){if(s.consume(),s.consumeSpaces(),n=s.fetch().text,"lcr".indexOf(n)===-1)throw new De("Expected l or c or r",s.nextToken);s.consume(),s.consumeSpaces(),s.expect("]"),s.consume(),r.cols=[{type:"align",align:n}]}}var i=Mo(t.parser,r,q5(t.envName)),l=Math.max(0,...i.body.map(c=>c.length));return i.cols=new Array(l).fill({type:"align",align:n}),e?{type:"leftright",mode:t.mode,body:[i],left:e[0],right:e[1],rightColor:void 0}:i},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(t){var e={arraystretch:.5},n=Mo(t.parser,e,"script");return n.colSeparationType="small",n},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["subarray"],props:{numArgs:1},handler(t,e){var n=Ux(e[0]),r=n?[e[0]]:Nt(e[0],"ordgroup").body,s=r.map(function(l){var c=R5(l),d=c.text;if("lc".indexOf(d)!==-1)return{type:"align",align:d};throw new De("Unknown column alignment: "+d,l)});if(s.length>1)throw new De("{subarray} can contain only one column");var i={cols:s,hskipBeforeAndAfter:!1,arraystretch:.5};if(i=Mo(t.parser,i,"script"),i.body.length>0&&i.body[0].length>1)throw new De("{subarray} can contain only one column");return i},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(t){var e={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},n=Mo(t.parser,e,q5(t.envName));return{type:"leftright",mode:t.mode,body:[n],left:t.envName.indexOf("r")>-1?".":"\\{",right:t.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:BR,htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(t){["gather","gather*"].includes(t.envName)&&Gx(t);var e={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:I5(t.envName),emptySingleRow:!0,leqno:t.parser.settings.leqno};return Mo(t.parser,e,"display")},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:BR,htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(t){Gx(t);var e={autoTag:I5(t.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:t.parser.settings.leqno};return Mo(t.parser,e,"display")},htmlBuilder:Ca,mathmlBuilder:Ta});Na({type:"array",names:["CD"],props:{numArgs:0},handler(t){return Gx(t),Bce(t.parser)},htmlBuilder:Ca,mathmlBuilder:Ta});q("\\nonumber","\\gdef\\@eqnsw{0}");q("\\notag","\\nonumber");Qe({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(t,e){throw new De(t.funcName+" valid only within array environment")}});var yN=PR;Qe({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(t,e){var{parser:n,funcName:r}=t,s=e[0];if(s.type!=="ordgroup")throw new De("Invalid environment name",s);for(var i="",l=0;l{var n=t.font,r=e.withFont(n);return Xt(t.body,r)},qR=(t,e)=>{var n=t.font,r=e.withFont(n);return Rn(t.body,r)},bN={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Qe({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=Zg(e[0]),i=r;return i in bN&&(i=bN[i]),{type:"font",mode:n.mode,font:i.slice(1),body:s}},htmlBuilder:IR,mathmlBuilder:qR});Qe({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(t,e)=>{var{parser:n}=t,r=e[0],s=tn.isCharacterBox(r);return{type:"mclass",mode:n.mode,mclass:Vx(r),body:[{type:"font",mode:n.mode,font:"boldsymbol",body:r}],isCharacterBox:s}}});Qe({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(t,e)=>{var{parser:n,funcName:r,breakOnTokenText:s}=t,{mode:i}=n,l=n.parseExpression(!0,s),c="math"+r.slice(1);return{type:"font",mode:i,font:c,body:{type:"ordgroup",mode:n.mode,body:l}}},htmlBuilder:IR,mathmlBuilder:qR});var FR=(t,e)=>{var n=e;return t==="display"?n=n.id>=at.SCRIPT.id?n.text():at.DISPLAY:t==="text"&&n.size===at.DISPLAY.size?n=at.TEXT:t==="script"?n=at.SCRIPT:t==="scriptscript"&&(n=at.SCRIPTSCRIPT),n},F5=(t,e)=>{var n=FR(t.size,e.style),r=n.fracNum(),s=n.fracDen(),i;i=e.havingStyle(r);var l=Xt(t.numer,i,e);if(t.continued){var c=8.5/e.fontMetrics().ptPerEm,d=3.5/e.fontMetrics().ptPerEm;l.height=l.height0?b=3*x:b=7*x,k=e.fontMetrics().denom1):(p>0?(v=e.fontMetrics().num2,b=x):(v=e.fontMetrics().num3,b=3*x),k=e.fontMetrics().denom2);var O;if(m){var T=e.fontMetrics().axisHeight;v-l.depth-(T+.5*p){var n=new _e.MathNode("mfrac",[Rn(t.numer,e),Rn(t.denom,e)]);if(!t.hasBarLine)n.setAttribute("linethickness","0px");else if(t.barSize){var r=Kn(t.barSize,e);n.setAttribute("linethickness",Be(r))}var s=FR(t.size,e.style);if(s.size!==e.style.size){n=new _e.MathNode("mstyle",[n]);var i=s.size===at.DISPLAY.size?"true":"false";n.setAttribute("displaystyle",i),n.setAttribute("scriptlevel","0")}if(t.leftDelim!=null||t.rightDelim!=null){var l=[];if(t.leftDelim!=null){var c=new _e.MathNode("mo",[new _e.TextNode(t.leftDelim.replace("\\",""))]);c.setAttribute("fence","true"),l.push(c)}if(l.push(n),t.rightDelim!=null){var d=new _e.MathNode("mo",[new _e.TextNode(t.rightDelim.replace("\\",""))]);d.setAttribute("fence","true"),l.push(d)}return _5(l)}return n};Qe({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=e[0],i=e[1],l,c=null,d=null,h="auto";switch(r){case"\\dfrac":case"\\frac":case"\\tfrac":l=!0;break;case"\\\\atopfrac":l=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":l=!1,c="(",d=")";break;case"\\\\bracefrac":l=!1,c="\\{",d="\\}";break;case"\\\\brackfrac":l=!1,c="[",d="]";break;default:throw new Error("Unrecognized genfrac command")}switch(r){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text";break}return{type:"genfrac",mode:n.mode,continued:!1,numer:s,denom:i,hasBarLine:l,leftDelim:c,rightDelim:d,size:h,barSize:null}},htmlBuilder:F5,mathmlBuilder:Q5});Qe({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=e[0],i=e[1];return{type:"genfrac",mode:n.mode,continued:!0,numer:s,denom:i,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}});Qe({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(t){var{parser:e,funcName:n,token:r}=t,s;switch(n){case"\\over":s="\\frac";break;case"\\choose":s="\\binom";break;case"\\atop":s="\\\\atopfrac";break;case"\\brace":s="\\\\bracefrac";break;case"\\brack":s="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:e.mode,replaceWith:s,token:r}}});var wN=["display","text","script","scriptscript"],SN=function(e){var n=null;return e.length>0&&(n=e,n=n==="."?null:n),n};Qe({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(t,e){var{parser:n}=t,r=e[4],s=e[5],i=Zg(e[0]),l=i.type==="atom"&&i.family==="open"?SN(i.text):null,c=Zg(e[1]),d=c.type==="atom"&&c.family==="close"?SN(c.text):null,h=Nt(e[2],"size"),m,p=null;h.isBlank?m=!0:(p=h.value,m=p.number>0);var x="auto",v=e[3];if(v.type==="ordgroup"){if(v.body.length>0){var b=Nt(v.body[0],"textord");x=wN[Number(b.text)]}}else v=Nt(v,"textord"),x=wN[Number(v.text)];return{type:"genfrac",mode:n.mode,numer:r,denom:s,continued:!1,hasBarLine:m,barSize:p,leftDelim:l,rightDelim:d,size:x}},htmlBuilder:F5,mathmlBuilder:Q5});Qe({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(t,e){var{parser:n,funcName:r,token:s}=t;return{type:"infix",mode:n.mode,replaceWith:"\\\\abovefrac",size:Nt(e[0],"size").value,token:s}}});Qe({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=e[0],i=Toe(Nt(e[1],"infix").size),l=e[2],c=i.number>0;return{type:"genfrac",mode:n.mode,numer:s,denom:l,continued:!1,hasBarLine:c,barSize:i,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:F5,mathmlBuilder:Q5});var QR=(t,e)=>{var n=e.style,r,s;t.type==="supsub"?(r=t.sup?Xt(t.sup,e.havingStyle(n.sup()),e):Xt(t.sub,e.havingStyle(n.sub()),e),s=Nt(t.base,"horizBrace")):s=Nt(t,"horizBrace");var i=Xt(s.base,e.havingBaseStyle(at.DISPLAY)),l=vl.svgSpan(s,e),c;if(s.isOver?(c=ge.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:.1},{type:"elem",elem:l}]},e),c.children[0].children[0].children[1].classes.push("svg-align")):(c=ge.makeVList({positionType:"bottom",positionData:i.depth+.1+l.height,children:[{type:"elem",elem:l},{type:"kern",size:.1},{type:"elem",elem:i}]},e),c.children[0].children[0].children[0].classes.push("svg-align")),r){var d=ge.makeSpan(["mord",s.isOver?"mover":"munder"],[c],e);s.isOver?c=ge.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:d},{type:"kern",size:.2},{type:"elem",elem:r}]},e):c=ge.makeVList({positionType:"bottom",positionData:d.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:d}]},e)}return ge.makeSpan(["mord",s.isOver?"mover":"munder"],[c],e)},Jce=(t,e)=>{var n=vl.mathMLnode(t.label);return new _e.MathNode(t.isOver?"mover":"munder",[Rn(t.base,e),n])};Qe({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(t,e){var{parser:n,funcName:r}=t;return{type:"horizBrace",mode:n.mode,label:r,isOver:/^\\over/.test(r),base:e[0]}},htmlBuilder:QR,mathmlBuilder:Jce});Qe({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(t,e)=>{var{parser:n}=t,r=e[1],s=Nt(e[0],"url").url;return n.settings.isTrusted({command:"\\href",url:s})?{type:"href",mode:n.mode,href:s,body:ar(r)}:n.formatUnsupportedCmd("\\href")},htmlBuilder:(t,e)=>{var n=Mr(t.body,e,!1);return ge.makeAnchor(t.href,[],n,e)},mathmlBuilder:(t,e)=>{var n=bo(t.body,e);return n instanceof ti||(n=new ti("mrow",[n])),n.setAttribute("href",t.href),n}});Qe({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(t,e)=>{var{parser:n}=t,r=Nt(e[0],"url").url;if(!n.settings.isTrusted({command:"\\url",url:r}))return n.formatUnsupportedCmd("\\url");for(var s=[],i=0;i{var{parser:n,funcName:r,token:s}=t,i=Nt(e[0],"raw").string,l=e[1];n.settings.strict&&n.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var c,d={};switch(r){case"\\htmlClass":d.class=i,c={command:"\\htmlClass",class:i};break;case"\\htmlId":d.id=i,c={command:"\\htmlId",id:i};break;case"\\htmlStyle":d.style=i,c={command:"\\htmlStyle",style:i};break;case"\\htmlData":{for(var h=i.split(","),m=0;m{var n=Mr(t.body,e,!1),r=["enclosing"];t.attributes.class&&r.push(...t.attributes.class.trim().split(/\s+/));var s=ge.makeSpan(r,n,e);for(var i in t.attributes)i!=="class"&&t.attributes.hasOwnProperty(i)&&s.setAttribute(i,t.attributes[i]);return s},mathmlBuilder:(t,e)=>bo(t.body,e)});Qe({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(t,e)=>{var{parser:n}=t;return{type:"htmlmathml",mode:n.mode,html:ar(e[0]),mathml:ar(e[1])}},htmlBuilder:(t,e)=>{var n=Mr(t.html,e,!1);return ge.makeFragment(n)},mathmlBuilder:(t,e)=>bo(t.mathml,e)});var qb=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var n=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!n)throw new De("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(n[1]+n[2]),unit:n[3]};if(!lR(r))throw new De("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};Qe({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(t,e,n)=>{var{parser:r}=t,s={number:0,unit:"em"},i={number:.9,unit:"em"},l={number:0,unit:"em"},c="";if(n[0])for(var d=Nt(n[0],"raw").string,h=d.split(","),m=0;m{var n=Kn(t.height,e),r=0;t.totalheight.number>0&&(r=Kn(t.totalheight,e)-n);var s=0;t.width.number>0&&(s=Kn(t.width,e));var i={height:Be(n+r)};s>0&&(i.width=Be(s)),r>0&&(i.verticalAlign=Be(-r));var l=new Joe(t.src,t.alt,i);return l.height=n,l.depth=r,l},mathmlBuilder:(t,e)=>{var n=new _e.MathNode("mglyph",[]);n.setAttribute("alt",t.alt);var r=Kn(t.height,e),s=0;if(t.totalheight.number>0&&(s=Kn(t.totalheight,e)-r,n.setAttribute("valign",Be(-s))),n.setAttribute("height",Be(r+s)),t.width.number>0){var i=Kn(t.width,e);n.setAttribute("width",Be(i))}return n.setAttribute("src",t.src),n}});Qe({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(t,e){var{parser:n,funcName:r}=t,s=Nt(e[0],"size");if(n.settings.strict){var i=r[1]==="m",l=s.value.unit==="mu";i?(l||n.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" supports only mu units, "+("not "+s.value.unit+" units")),n.mode!=="math"&&n.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" works only in math mode")):l&&n.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" doesn't support mu units")}return{type:"kern",mode:n.mode,dimension:s.value}},htmlBuilder(t,e){return ge.makeGlue(t.dimension,e)},mathmlBuilder(t,e){var n=Kn(t.dimension,e);return new _e.SpaceNode(n)}});Qe({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=e[0];return{type:"lap",mode:n.mode,alignment:r.slice(5),body:s}},htmlBuilder:(t,e)=>{var n;t.alignment==="clap"?(n=ge.makeSpan([],[Xt(t.body,e)]),n=ge.makeSpan(["inner"],[n],e)):n=ge.makeSpan(["inner"],[Xt(t.body,e)]);var r=ge.makeSpan(["fix"],[]),s=ge.makeSpan([t.alignment],[n,r],e),i=ge.makeSpan(["strut"]);return i.style.height=Be(s.height+s.depth),s.depth&&(i.style.verticalAlign=Be(-s.depth)),s.children.unshift(i),s=ge.makeSpan(["thinbox"],[s],e),ge.makeSpan(["mord","vbox"],[s],e)},mathmlBuilder:(t,e)=>{var n=new _e.MathNode("mpadded",[Rn(t.body,e)]);if(t.alignment!=="rlap"){var r=t.alignment==="llap"?"-1":"-0.5";n.setAttribute("lspace",r+"width")}return n.setAttribute("width","0px"),n}});Qe({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){var{funcName:n,parser:r}=t,s=r.mode;r.switchMode("math");var i=n==="\\("?"\\)":"$",l=r.parseExpression(!1,i);return r.expect(i),r.switchMode(s),{type:"styling",mode:r.mode,style:"text",body:l}}});Qe({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){throw new De("Mismatched "+t.funcName)}});var kN=(t,e)=>{switch(e.style.size){case at.DISPLAY.size:return t.display;case at.TEXT.size:return t.text;case at.SCRIPT.size:return t.script;case at.SCRIPTSCRIPT.size:return t.scriptscript;default:return t.text}};Qe({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(t,e)=>{var{parser:n}=t;return{type:"mathchoice",mode:n.mode,display:ar(e[0]),text:ar(e[1]),script:ar(e[2]),scriptscript:ar(e[3])}},htmlBuilder:(t,e)=>{var n=kN(t,e),r=Mr(n,e,!1);return ge.makeFragment(r)},mathmlBuilder:(t,e)=>{var n=kN(t,e);return bo(n,e)}});var $R=(t,e,n,r,s,i,l)=>{t=ge.makeSpan([],[t]);var c=n&&tn.isCharacterBox(n),d,h;if(e){var m=Xt(e,r.havingStyle(s.sup()),r);h={elem:m,kern:Math.max(r.fontMetrics().bigOpSpacing1,r.fontMetrics().bigOpSpacing3-m.depth)}}if(n){var p=Xt(n,r.havingStyle(s.sub()),r);d={elem:p,kern:Math.max(r.fontMetrics().bigOpSpacing2,r.fontMetrics().bigOpSpacing4-p.height)}}var x;if(h&&d){var v=r.fontMetrics().bigOpSpacing5+d.elem.height+d.elem.depth+d.kern+t.depth+l;x=ge.makeVList({positionType:"bottom",positionData:v,children:[{type:"kern",size:r.fontMetrics().bigOpSpacing5},{type:"elem",elem:d.elem,marginLeft:Be(-i)},{type:"kern",size:d.kern},{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:Be(i)},{type:"kern",size:r.fontMetrics().bigOpSpacing5}]},r)}else if(d){var b=t.height-l;x=ge.makeVList({positionType:"top",positionData:b,children:[{type:"kern",size:r.fontMetrics().bigOpSpacing5},{type:"elem",elem:d.elem,marginLeft:Be(-i)},{type:"kern",size:d.kern},{type:"elem",elem:t}]},r)}else if(h){var k=t.depth+l;x=ge.makeVList({positionType:"bottom",positionData:k,children:[{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:Be(i)},{type:"kern",size:r.fontMetrics().bigOpSpacing5}]},r)}else return t;var O=[x];if(d&&i!==0&&!c){var j=ge.makeSpan(["mspace"],[],r);j.style.marginRight=Be(i),O.unshift(j)}return ge.makeSpan(["mop","op-limits"],O,r)},HR=["\\smallint"],zd=(t,e)=>{var n,r,s=!1,i;t.type==="supsub"?(n=t.sup,r=t.sub,i=Nt(t.base,"op"),s=!0):i=Nt(t,"op");var l=e.style,c=!1;l.size===at.DISPLAY.size&&i.symbol&&!HR.includes(i.name)&&(c=!0);var d;if(i.symbol){var h=c?"Size2-Regular":"Size1-Regular",m="";if((i.name==="\\oiint"||i.name==="\\oiiint")&&(m=i.name.slice(1),i.name=m==="oiint"?"\\iint":"\\iiint"),d=ge.makeSymbol(i.name,h,"math",e,["mop","op-symbol",c?"large-op":"small-op"]),m.length>0){var p=d.italic,x=ge.staticSvg(m+"Size"+(c?"2":"1"),e);d=ge.makeVList({positionType:"individualShift",children:[{type:"elem",elem:d,shift:0},{type:"elem",elem:x,shift:c?.08:0}]},e),i.name="\\"+m,d.classes.unshift("mop"),d.italic=p}}else if(i.body){var v=Mr(i.body,e,!0);v.length===1&&v[0]instanceof Ti?(d=v[0],d.classes[0]="mop"):d=ge.makeSpan(["mop"],v,e)}else{for(var b=[],k=1;k{var n;if(t.symbol)n=new ti("mo",[Mi(t.name,t.mode)]),HR.includes(t.name)&&n.setAttribute("largeop","false");else if(t.body)n=new ti("mo",qs(t.body,e));else{n=new ti("mi",[new pa(t.name.slice(1))]);var r=new ti("mo",[Mi("⁡","text")]);t.parentIsSupSub?n=new ti("mrow",[n,r]):n=vR([n,r])}return n},eue={"∏":"\\prod","∐":"\\coprod","∑":"\\sum","⋀":"\\bigwedge","⋁":"\\bigvee","⋂":"\\bigcap","⋃":"\\bigcup","⨀":"\\bigodot","⨁":"\\bigoplus","⨂":"\\bigotimes","⨄":"\\biguplus","⨆":"\\bigsqcup"};Qe({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","∏","∐","∑","⋀","⋁","⋂","⋃","⨀","⨁","⨂","⨄","⨆"],props:{numArgs:0},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=r;return s.length===1&&(s=eue[s]),{type:"op",mode:n.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:s}},htmlBuilder:zd,mathmlBuilder:k0});Qe({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(t,e)=>{var{parser:n}=t,r=e[0];return{type:"op",mode:n.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:ar(r)}},htmlBuilder:zd,mathmlBuilder:k0});var tue={"∫":"\\int","∬":"\\iint","∭":"\\iiint","∮":"\\oint","∯":"\\oiint","∰":"\\oiiint"};Qe({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(t){var{parser:e,funcName:n}=t;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:n}},htmlBuilder:zd,mathmlBuilder:k0});Qe({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(t){var{parser:e,funcName:n}=t;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:n}},htmlBuilder:zd,mathmlBuilder:k0});Qe({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","∫","∬","∭","∮","∯","∰"],props:{numArgs:0},handler(t){var{parser:e,funcName:n}=t,r=n;return r.length===1&&(r=tue[r]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:r}},htmlBuilder:zd,mathmlBuilder:k0});var UR=(t,e)=>{var n,r,s=!1,i;t.type==="supsub"?(n=t.sup,r=t.sub,i=Nt(t.base,"operatorname"),s=!0):i=Nt(t,"operatorname");var l;if(i.body.length>0){for(var c=i.body.map(p=>{var x=p.text;return typeof x=="string"?{type:"textord",mode:p.mode,text:x}:p}),d=Mr(c,e.withFont("mathrm"),!0),h=0;h{for(var n=qs(t.body,e.withFont("mathrm")),r=!0,s=0;sm.toText()).join("");n=[new _e.TextNode(c)]}var d=new _e.MathNode("mi",n);d.setAttribute("mathvariant","normal");var h=new _e.MathNode("mo",[Mi("⁡","text")]);return t.parentIsSupSub?new _e.MathNode("mrow",[d,h]):_e.newDocumentFragment([d,h])};Qe({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:(t,e)=>{var{parser:n,funcName:r}=t,s=e[0];return{type:"operatorname",mode:n.mode,body:ar(s),alwaysHandleSupSub:r==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},htmlBuilder:UR,mathmlBuilder:nue});q("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");Rc({type:"ordgroup",htmlBuilder(t,e){return t.semisimple?ge.makeFragment(Mr(t.body,e,!1)):ge.makeSpan(["mord"],Mr(t.body,e,!0),e)},mathmlBuilder(t,e){return bo(t.body,e,!0)}});Qe({type:"overline",names:["\\overline"],props:{numArgs:1},handler(t,e){var{parser:n}=t,r=e[0];return{type:"overline",mode:n.mode,body:r}},htmlBuilder(t,e){var n=Xt(t.body,e.havingCrampedStyle()),r=ge.makeLineSpan("overline-line",e),s=e.fontMetrics().defaultRuleThickness,i=ge.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:n},{type:"kern",size:3*s},{type:"elem",elem:r},{type:"kern",size:s}]},e);return ge.makeSpan(["mord","overline"],[i],e)},mathmlBuilder(t,e){var n=new _e.MathNode("mo",[new _e.TextNode("‾")]);n.setAttribute("stretchy","true");var r=new _e.MathNode("mover",[Rn(t.body,e),n]);return r.setAttribute("accent","true"),r}});Qe({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(t,e)=>{var{parser:n}=t,r=e[0];return{type:"phantom",mode:n.mode,body:ar(r)}},htmlBuilder:(t,e)=>{var n=Mr(t.body,e.withPhantom(),!1);return ge.makeFragment(n)},mathmlBuilder:(t,e)=>{var n=qs(t.body,e);return new _e.MathNode("mphantom",n)}});Qe({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(t,e)=>{var{parser:n}=t,r=e[0];return{type:"hphantom",mode:n.mode,body:r}},htmlBuilder:(t,e)=>{var n=ge.makeSpan([],[Xt(t.body,e.withPhantom())]);if(n.height=0,n.depth=0,n.children)for(var r=0;r{var n=qs(ar(t.body),e),r=new _e.MathNode("mphantom",n),s=new _e.MathNode("mpadded",[r]);return s.setAttribute("height","0px"),s.setAttribute("depth","0px"),s}});Qe({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(t,e)=>{var{parser:n}=t,r=e[0];return{type:"vphantom",mode:n.mode,body:r}},htmlBuilder:(t,e)=>{var n=ge.makeSpan(["inner"],[Xt(t.body,e.withPhantom())]),r=ge.makeSpan(["fix"],[]);return ge.makeSpan(["mord","rlap"],[n,r],e)},mathmlBuilder:(t,e)=>{var n=qs(ar(t.body),e),r=new _e.MathNode("mphantom",n),s=new _e.MathNode("mpadded",[r]);return s.setAttribute("width","0px"),s}});Qe({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(t,e){var{parser:n}=t,r=Nt(e[0],"size").value,s=e[1];return{type:"raisebox",mode:n.mode,dy:r,body:s}},htmlBuilder(t,e){var n=Xt(t.body,e),r=Kn(t.dy,e);return ge.makeVList({positionType:"shift",positionData:-r,children:[{type:"elem",elem:n}]},e)},mathmlBuilder(t,e){var n=new _e.MathNode("mpadded",[Rn(t.body,e)]),r=t.dy.number+t.dy.unit;return n.setAttribute("voffset",r),n}});Qe({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(t){var{parser:e}=t;return{type:"internal",mode:e.mode}}});Qe({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(t,e,n){var{parser:r}=t,s=n[0],i=Nt(e[0],"size"),l=Nt(e[1],"size");return{type:"rule",mode:r.mode,shift:s&&Nt(s,"size").value,width:i.value,height:l.value}},htmlBuilder(t,e){var n=ge.makeSpan(["mord","rule"],[],e),r=Kn(t.width,e),s=Kn(t.height,e),i=t.shift?Kn(t.shift,e):0;return n.style.borderRightWidth=Be(r),n.style.borderTopWidth=Be(s),n.style.bottom=Be(i),n.width=r,n.height=s+i,n.depth=-i,n.maxFontSize=s*1.125*e.sizeMultiplier,n},mathmlBuilder(t,e){var n=Kn(t.width,e),r=Kn(t.height,e),s=t.shift?Kn(t.shift,e):0,i=e.color&&e.getColor()||"black",l=new _e.MathNode("mspace");l.setAttribute("mathbackground",i),l.setAttribute("width",Be(n)),l.setAttribute("height",Be(r));var c=new _e.MathNode("mpadded",[l]);return s>=0?c.setAttribute("height",Be(s)):(c.setAttribute("height",Be(s)),c.setAttribute("depth",Be(-s))),c.setAttribute("voffset",Be(s)),c}});function VR(t,e,n){for(var r=Mr(t,e,!1),s=e.sizeMultiplier/n.sizeMultiplier,i=0;i{var n=e.havingSize(t.size);return VR(t.body,n,e)};Qe({type:"sizing",names:ON,props:{numArgs:0,allowedInText:!0},handler:(t,e)=>{var{breakOnTokenText:n,funcName:r,parser:s}=t,i=s.parseExpression(!1,n);return{type:"sizing",mode:s.mode,size:ON.indexOf(r)+1,body:i}},htmlBuilder:rue,mathmlBuilder:(t,e)=>{var n=e.havingSize(t.size),r=qs(t.body,n),s=new _e.MathNode("mstyle",r);return s.setAttribute("mathsize",Be(n.sizeMultiplier)),s}});Qe({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(t,e,n)=>{var{parser:r}=t,s=!1,i=!1,l=n[0]&&Nt(n[0],"ordgroup");if(l)for(var c="",d=0;d{var n=ge.makeSpan([],[Xt(t.body,e)]);if(!t.smashHeight&&!t.smashDepth)return n;if(t.smashHeight&&(n.height=0,n.children))for(var r=0;r{var n=new _e.MathNode("mpadded",[Rn(t.body,e)]);return t.smashHeight&&n.setAttribute("height","0px"),t.smashDepth&&n.setAttribute("depth","0px"),n}});Qe({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,n){var{parser:r}=t,s=n[0],i=e[0];return{type:"sqrt",mode:r.mode,body:i,index:s}},htmlBuilder(t,e){var n=Xt(t.body,e.havingCrampedStyle());n.height===0&&(n.height=e.fontMetrics().xHeight),n=ge.wrapFragment(n,e);var r=e.fontMetrics(),s=r.defaultRuleThickness,i=s;e.style.idn.height+n.depth+l&&(l=(l+p-n.height-n.depth)/2);var x=d.height-n.height-l-h;n.style.paddingLeft=Be(m);var v=ge.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:-(n.height+x)},{type:"elem",elem:d},{type:"kern",size:h}]},e);if(t.index){var b=e.havingStyle(at.SCRIPTSCRIPT),k=Xt(t.index,b,e),O=.6*(v.height-v.depth),j=ge.makeVList({positionType:"shift",positionData:-O,children:[{type:"elem",elem:k}]},e),T=ge.makeSpan(["root"],[j]);return ge.makeSpan(["mord","sqrt"],[T,v],e)}else return ge.makeSpan(["mord","sqrt"],[v],e)},mathmlBuilder(t,e){var{body:n,index:r}=t;return r?new _e.MathNode("mroot",[Rn(n,e),Rn(r,e)]):new _e.MathNode("msqrt",[Rn(n,e)])}});var jN={display:at.DISPLAY,text:at.TEXT,script:at.SCRIPT,scriptscript:at.SCRIPTSCRIPT};Qe({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t,e){var{breakOnTokenText:n,funcName:r,parser:s}=t,i=s.parseExpression(!0,n),l=r.slice(1,r.length-5);return{type:"styling",mode:s.mode,style:l,body:i}},htmlBuilder(t,e){var n=jN[t.style],r=e.havingStyle(n).withFont("");return VR(t.body,r,e)},mathmlBuilder(t,e){var n=jN[t.style],r=e.havingStyle(n),s=qs(t.body,r),i=new _e.MathNode("mstyle",s),l={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},c=l[t.style];return i.setAttribute("scriptlevel",c[0]),i.setAttribute("displaystyle",c[1]),i}});var sue=function(e,n){var r=e.base;if(r)if(r.type==="op"){var s=r.limits&&(n.style.size===at.DISPLAY.size||r.alwaysHandleSupSub);return s?zd:null}else if(r.type==="operatorname"){var i=r.alwaysHandleSupSub&&(n.style.size===at.DISPLAY.size||r.limits);return i?UR:null}else{if(r.type==="accent")return tn.isCharacterBox(r.base)?z5:null;if(r.type==="horizBrace"){var l=!e.sub;return l===r.isOver?QR:null}else return null}else return null};Rc({type:"supsub",htmlBuilder(t,e){var n=sue(t,e);if(n)return n(t,e);var{base:r,sup:s,sub:i}=t,l=Xt(r,e),c,d,h=e.fontMetrics(),m=0,p=0,x=r&&tn.isCharacterBox(r);if(s){var v=e.havingStyle(e.style.sup());c=Xt(s,v,e),x||(m=l.height-v.fontMetrics().supDrop*v.sizeMultiplier/e.sizeMultiplier)}if(i){var b=e.havingStyle(e.style.sub());d=Xt(i,b,e),x||(p=l.depth+b.fontMetrics().subDrop*b.sizeMultiplier/e.sizeMultiplier)}var k;e.style===at.DISPLAY?k=h.sup1:e.style.cramped?k=h.sup3:k=h.sup2;var O=e.sizeMultiplier,j=Be(.5/h.ptPerEm/O),T=null;if(d){var M=t.base&&t.base.type==="op"&&t.base.name&&(t.base.name==="\\oiint"||t.base.name==="\\oiiint");(l instanceof Ti||M)&&(T=Be(-l.italic))}var _;if(c&&d){m=Math.max(m,k,c.depth+.25*h.xHeight),p=Math.max(p,h.sub2);var D=h.defaultRuleThickness,E=4*D;if(m-c.depth-(d.height-p)0&&(m+=z,p-=z)}var Q=[{type:"elem",elem:d,shift:p,marginRight:j,marginLeft:T},{type:"elem",elem:c,shift:-m,marginRight:j}];_=ge.makeVList({positionType:"individualShift",children:Q},e)}else if(d){p=Math.max(p,h.sub1,d.height-.8*h.xHeight);var F=[{type:"elem",elem:d,marginLeft:T,marginRight:j}];_=ge.makeVList({positionType:"shift",positionData:p,children:F},e)}else if(c)m=Math.max(m,k,c.depth+.25*h.xHeight),_=ge.makeVList({positionType:"shift",positionData:-m,children:[{type:"elem",elem:c,marginRight:j}]},e);else throw new Error("supsub must have either sup or sub.");var B=N4(l,"right")||"mord";return ge.makeSpan([B],[l,ge.makeSpan(["msupsub"],[_])],e)},mathmlBuilder(t,e){var n=!1,r,s;t.base&&t.base.type==="horizBrace"&&(s=!!t.sup,s===t.base.isOver&&(n=!0,r=t.base.isOver)),t.base&&(t.base.type==="op"||t.base.type==="operatorname")&&(t.base.parentIsSupSub=!0);var i=[Rn(t.base,e)];t.sub&&i.push(Rn(t.sub,e)),t.sup&&i.push(Rn(t.sup,e));var l;if(n)l=r?"mover":"munder";else if(t.sub)if(t.sup){var h=t.base;h&&h.type==="op"&&h.limits&&e.style===at.DISPLAY||h&&h.type==="operatorname"&&h.alwaysHandleSupSub&&(e.style===at.DISPLAY||h.limits)?l="munderover":l="msubsup"}else{var d=t.base;d&&d.type==="op"&&d.limits&&(e.style===at.DISPLAY||d.alwaysHandleSupSub)||d&&d.type==="operatorname"&&d.alwaysHandleSupSub&&(d.limits||e.style===at.DISPLAY)?l="munder":l="msub"}else{var c=t.base;c&&c.type==="op"&&c.limits&&(e.style===at.DISPLAY||c.alwaysHandleSupSub)||c&&c.type==="operatorname"&&c.alwaysHandleSupSub&&(c.limits||e.style===at.DISPLAY)?l="mover":l="msup"}return new _e.MathNode(l,i)}});Rc({type:"atom",htmlBuilder(t,e){return ge.mathsym(t.text,t.mode,e,["m"+t.family])},mathmlBuilder(t,e){var n=new _e.MathNode("mo",[Mi(t.text,t.mode)]);if(t.family==="bin"){var r=D5(t,e);r==="bold-italic"&&n.setAttribute("mathvariant",r)}else t.family==="punct"?n.setAttribute("separator","true"):(t.family==="open"||t.family==="close")&&n.setAttribute("stretchy","false");return n}});var WR={mi:"italic",mn:"normal",mtext:"normal"};Rc({type:"mathord",htmlBuilder(t,e){return ge.makeOrd(t,e,"mathord")},mathmlBuilder(t,e){var n=new _e.MathNode("mi",[Mi(t.text,t.mode,e)]),r=D5(t,e)||"italic";return r!==WR[n.type]&&n.setAttribute("mathvariant",r),n}});Rc({type:"textord",htmlBuilder(t,e){return ge.makeOrd(t,e,"textord")},mathmlBuilder(t,e){var n=Mi(t.text,t.mode,e),r=D5(t,e)||"normal",s;return t.mode==="text"?s=new _e.MathNode("mtext",[n]):/[0-9]/.test(t.text)?s=new _e.MathNode("mn",[n]):t.text==="\\prime"?s=new _e.MathNode("mo",[n]):s=new _e.MathNode("mi",[n]),r!==WR[s.type]&&s.setAttribute("mathvariant",r),s}});var Fb={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Qb={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};Rc({type:"spacing",htmlBuilder(t,e){if(Qb.hasOwnProperty(t.text)){var n=Qb[t.text].className||"";if(t.mode==="text"){var r=ge.makeOrd(t,e,"textord");return r.classes.push(n),r}else return ge.makeSpan(["mspace",n],[ge.mathsym(t.text,t.mode,e)],e)}else{if(Fb.hasOwnProperty(t.text))return ge.makeSpan(["mspace",Fb[t.text]],[],e);throw new De('Unknown type of space "'+t.text+'"')}},mathmlBuilder(t,e){var n;if(Qb.hasOwnProperty(t.text))n=new _e.MathNode("mtext",[new _e.TextNode(" ")]);else{if(Fb.hasOwnProperty(t.text))return new _e.MathNode("mspace");throw new De('Unknown type of space "'+t.text+'"')}return n}});var NN=()=>{var t=new _e.MathNode("mtd",[]);return t.setAttribute("width","50%"),t};Rc({type:"tag",mathmlBuilder(t,e){var n=new _e.MathNode("mtable",[new _e.MathNode("mtr",[NN(),new _e.MathNode("mtd",[bo(t.body,e)]),NN(),new _e.MathNode("mtd",[bo(t.tag,e)])])]);return n.setAttribute("width","100%"),n}});var CN={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},TN={"\\textbf":"textbf","\\textmd":"textmd"},iue={"\\textit":"textit","\\textup":"textup"},MN=(t,e)=>{var n=t.font;if(n){if(CN[n])return e.withTextFontFamily(CN[n]);if(TN[n])return e.withTextFontWeight(TN[n]);if(n==="\\emph")return e.fontShape==="textit"?e.withTextFontShape("textup"):e.withTextFontShape("textit")}else return e;return e.withTextFontShape(iue[n])};Qe({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(t,e){var{parser:n,funcName:r}=t,s=e[0];return{type:"text",mode:n.mode,body:ar(s),font:r}},htmlBuilder(t,e){var n=MN(t,e),r=Mr(t.body,n,!0);return ge.makeSpan(["mord","text"],r,n)},mathmlBuilder(t,e){var n=MN(t,e);return bo(t.body,n)}});Qe({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:n}=t;return{type:"underline",mode:n.mode,body:e[0]}},htmlBuilder(t,e){var n=Xt(t.body,e),r=ge.makeLineSpan("underline-line",e),s=e.fontMetrics().defaultRuleThickness,i=ge.makeVList({positionType:"top",positionData:n.height,children:[{type:"kern",size:s},{type:"elem",elem:r},{type:"kern",size:3*s},{type:"elem",elem:n}]},e);return ge.makeSpan(["mord","underline"],[i],e)},mathmlBuilder(t,e){var n=new _e.MathNode("mo",[new _e.TextNode("‾")]);n.setAttribute("stretchy","true");var r=new _e.MathNode("munder",[Rn(t.body,e),n]);return r.setAttribute("accentunder","true"),r}});Qe({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(t,e){var{parser:n}=t;return{type:"vcenter",mode:n.mode,body:e[0]}},htmlBuilder(t,e){var n=Xt(t.body,e),r=e.fontMetrics().axisHeight,s=.5*(n.height-r-(n.depth+r));return ge.makeVList({positionType:"shift",positionData:s,children:[{type:"elem",elem:n}]},e)},mathmlBuilder(t,e){return new _e.MathNode("mpadded",[Rn(t.body,e)],["vcenter"])}});Qe({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(t,e,n){throw new De("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(t,e){for(var n=AN(t),r=[],s=e.havingStyle(e.style.text()),i=0;it.body.replace(/ /g,t.star?"␣":" "),so=gR,GR=`[ \r - ]`,aue="\\\\[a-zA-Z@]+",lue="\\\\[^\uD800-\uDFFF]",oue="("+aue+")"+GR+"*",cue=`\\\\( -|[ \r ]+ -?)[ \r ]*`,A4="[̀-ͯ]",uue=new RegExp(A4+"+$"),due="("+GR+"+)|"+(cue+"|")+"([!-\\[\\]-‧‪-퟿豈-￿]"+(A4+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(A4+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+oue)+("|"+lue+")");class EN{constructor(e,n){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=n,this.tokenRegex=new RegExp(due,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,n){this.catcodes[e]=n}lex(){var e=this.input,n=this.tokenRegex.lastIndex;if(n===e.length)return new si("EOF",new Ts(this,n,n));var r=this.tokenRegex.exec(e);if(r===null||r.index!==n)throw new De("Unexpected character: '"+e[n]+"'",new si(e[n],new Ts(this,n,n+1)));var s=r[6]||r[3]||(r[2]?"\\ ":" ");if(this.catcodes[s]===14){var i=e.indexOf(` -`,this.tokenRegex.lastIndex);return i===-1?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=i+1,this.lex()}return new si(s,new Ts(this,n,this.tokenRegex.lastIndex))}}class hue{constructor(e,n){e===void 0&&(e={}),n===void 0&&(n={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=n,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new De("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var n in e)e.hasOwnProperty(n)&&(e[n]==null?delete this.current[n]:this.current[n]=e[n])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,n,r){if(r===void 0&&(r=!1),r){for(var s=0;s0&&(this.undefStack[this.undefStack.length-1][e]=n)}else{var i=this.undefStack[this.undefStack.length-1];i&&!i.hasOwnProperty(e)&&(i[e]=this.current[e])}n==null?delete this.current[e]:this.current[e]=n}}var fue=LR;q("\\noexpand",function(t){var e=t.popToken();return t.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}});q("\\expandafter",function(t){var e=t.popToken();return t.expandOnce(!0),{tokens:[e],numArgs:0}});q("\\@firstoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[0],numArgs:0}});q("\\@secondoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[1],numArgs:0}});q("\\@ifnextchar",function(t){var e=t.consumeArgs(3);t.consumeSpaces();var n=t.future();return e[0].length===1&&e[0][0].text===n.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}});q("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");q("\\TextOrMath",function(t){var e=t.consumeArgs(2);return t.mode==="text"?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});var _N={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};q("\\char",function(t){var e=t.popToken(),n,r="";if(e.text==="'")n=8,e=t.popToken();else if(e.text==='"')n=16,e=t.popToken();else if(e.text==="`")if(e=t.popToken(),e.text[0]==="\\")r=e.text.charCodeAt(1);else{if(e.text==="EOF")throw new De("\\char` missing argument");r=e.text.charCodeAt(0)}else n=10;if(n){if(r=_N[e.text],r==null||r>=n)throw new De("Invalid base-"+n+" digit "+e.text);for(var s;(s=_N[t.future().text])!=null&&s{var s=t.consumeArg().tokens;if(s.length!==1)throw new De("\\newcommand's first argument must be a macro name");var i=s[0].text,l=t.isDefined(i);if(l&&!e)throw new De("\\newcommand{"+i+"} attempting to redefine "+(i+"; use \\renewcommand"));if(!l&&!n)throw new De("\\renewcommand{"+i+"} when command "+i+" does not yet exist; use \\newcommand");var c=0;if(s=t.consumeArg().tokens,s.length===1&&s[0].text==="["){for(var d="",h=t.expandNextToken();h.text!=="]"&&h.text!=="EOF";)d+=h.text,h=t.expandNextToken();if(!d.match(/^\s*[0-9]+\s*$/))throw new De("Invalid number of arguments: "+d);c=parseInt(d),s=t.consumeArg().tokens}return l&&r||t.macros.set(i,{tokens:s,numArgs:c}),""};q("\\newcommand",t=>$5(t,!1,!0,!1));q("\\renewcommand",t=>$5(t,!0,!1,!1));q("\\providecommand",t=>$5(t,!0,!0,!0));q("\\message",t=>{var e=t.consumeArgs(1)[0];return console.log(e.reverse().map(n=>n.text).join("")),""});q("\\errmessage",t=>{var e=t.consumeArgs(1)[0];return console.error(e.reverse().map(n=>n.text).join("")),""});q("\\show",t=>{var e=t.popToken(),n=e.text;return console.log(e,t.macros.get(n),so[n],Ln.math[n],Ln.text[n]),""});q("\\bgroup","{");q("\\egroup","}");q("~","\\nobreakspace");q("\\lq","`");q("\\rq","'");q("\\aa","\\r a");q("\\AA","\\r A");q("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`©}");q("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");q("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}");q("ℬ","\\mathscr{B}");q("ℰ","\\mathscr{E}");q("ℱ","\\mathscr{F}");q("ℋ","\\mathscr{H}");q("ℐ","\\mathscr{I}");q("ℒ","\\mathscr{L}");q("ℳ","\\mathscr{M}");q("ℛ","\\mathscr{R}");q("ℭ","\\mathfrak{C}");q("ℌ","\\mathfrak{H}");q("ℨ","\\mathfrak{Z}");q("\\Bbbk","\\Bbb{k}");q("·","\\cdotp");q("\\llap","\\mathllap{\\textrm{#1}}");q("\\rlap","\\mathrlap{\\textrm{#1}}");q("\\clap","\\mathclap{\\textrm{#1}}");q("\\mathstrut","\\vphantom{(}");q("\\underbar","\\underline{\\text{#1}}");q("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');q("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`≠}}");q("\\ne","\\neq");q("≠","\\neq");q("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`∉}}");q("∉","\\notin");q("≘","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`≘}}");q("≙","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`≘}}");q("≚","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`≚}}");q("≛","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`≛}}");q("≝","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`≝}}");q("≞","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`≞}}");q("≟","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`≟}}");q("⟂","\\perp");q("‼","\\mathclose{!\\mkern-0.8mu!}");q("∌","\\notni");q("⌜","\\ulcorner");q("⌝","\\urcorner");q("⌞","\\llcorner");q("⌟","\\lrcorner");q("©","\\copyright");q("®","\\textregistered");q("️","\\textregistered");q("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');q("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');q("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');q("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');q("\\vdots","{\\varvdots\\rule{0pt}{15pt}}");q("⋮","\\vdots");q("\\varGamma","\\mathit{\\Gamma}");q("\\varDelta","\\mathit{\\Delta}");q("\\varTheta","\\mathit{\\Theta}");q("\\varLambda","\\mathit{\\Lambda}");q("\\varXi","\\mathit{\\Xi}");q("\\varPi","\\mathit{\\Pi}");q("\\varSigma","\\mathit{\\Sigma}");q("\\varUpsilon","\\mathit{\\Upsilon}");q("\\varPhi","\\mathit{\\Phi}");q("\\varPsi","\\mathit{\\Psi}");q("\\varOmega","\\mathit{\\Omega}");q("\\substack","\\begin{subarray}{c}#1\\end{subarray}");q("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");q("\\boxed","\\fbox{$\\displaystyle{#1}$}");q("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");q("\\implies","\\DOTSB\\;\\Longrightarrow\\;");q("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");q("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");q("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");var DN={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};q("\\dots",function(t){var e="\\dotso",n=t.expandAfterFuture().text;return n in DN?e=DN[n]:(n.slice(0,4)==="\\not"||n in Ln.math&&["bin","rel"].includes(Ln.math[n].group))&&(e="\\dotsb"),e});var H5={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};q("\\dotso",function(t){var e=t.future().text;return e in H5?"\\ldots\\,":"\\ldots"});q("\\dotsc",function(t){var e=t.future().text;return e in H5&&e!==","?"\\ldots\\,":"\\ldots"});q("\\cdots",function(t){var e=t.future().text;return e in H5?"\\@cdots\\,":"\\@cdots"});q("\\dotsb","\\cdots");q("\\dotsm","\\cdots");q("\\dotsi","\\!\\cdots");q("\\dotsx","\\ldots\\,");q("\\DOTSI","\\relax");q("\\DOTSB","\\relax");q("\\DOTSX","\\relax");q("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");q("\\,","\\tmspace+{3mu}{.1667em}");q("\\thinspace","\\,");q("\\>","\\mskip{4mu}");q("\\:","\\tmspace+{4mu}{.2222em}");q("\\medspace","\\:");q("\\;","\\tmspace+{5mu}{.2777em}");q("\\thickspace","\\;");q("\\!","\\tmspace-{3mu}{.1667em}");q("\\negthinspace","\\!");q("\\negmedspace","\\tmspace-{4mu}{.2222em}");q("\\negthickspace","\\tmspace-{5mu}{.277em}");q("\\enspace","\\kern.5em ");q("\\enskip","\\hskip.5em\\relax");q("\\quad","\\hskip1em\\relax");q("\\qquad","\\hskip2em\\relax");q("\\tag","\\@ifstar\\tag@literal\\tag@paren");q("\\tag@paren","\\tag@literal{({#1})}");q("\\tag@literal",t=>{if(t.macros.get("\\df@tag"))throw new De("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});q("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");q("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");q("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");q("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");q("\\newline","\\\\\\relax");q("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var XR=Be(ma["Main-Regular"][84][1]-.7*ma["Main-Regular"][65][1]);q("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+XR+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");q("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+XR+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");q("\\hspace","\\@ifstar\\@hspacer\\@hspace");q("\\@hspace","\\hskip #1\\relax");q("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");q("\\ordinarycolon",":");q("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");q("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');q("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');q("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');q("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');q("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');q("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');q("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');q("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');q("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');q("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');q("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');q("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');q("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');q("∷","\\dblcolon");q("∹","\\eqcolon");q("≔","\\coloneqq");q("≕","\\eqqcolon");q("⩴","\\Coloneqq");q("\\ratio","\\vcentcolon");q("\\coloncolon","\\dblcolon");q("\\colonequals","\\coloneqq");q("\\coloncolonequals","\\Coloneqq");q("\\equalscolon","\\eqqcolon");q("\\equalscoloncolon","\\Eqqcolon");q("\\colonminus","\\coloneq");q("\\coloncolonminus","\\Coloneq");q("\\minuscolon","\\eqcolon");q("\\minuscoloncolon","\\Eqcolon");q("\\coloncolonapprox","\\Colonapprox");q("\\coloncolonsim","\\Colonsim");q("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");q("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");q("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");q("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");q("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`∌}}");q("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");q("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");q("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");q("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");q("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");q("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");q("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");q("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");q("\\gvertneqq","\\html@mathml{\\@gvertneqq}{≩}");q("\\lvertneqq","\\html@mathml{\\@lvertneqq}{≨}");q("\\ngeqq","\\html@mathml{\\@ngeqq}{≱}");q("\\ngeqslant","\\html@mathml{\\@ngeqslant}{≱}");q("\\nleqq","\\html@mathml{\\@nleqq}{≰}");q("\\nleqslant","\\html@mathml{\\@nleqslant}{≰}");q("\\nshortmid","\\html@mathml{\\@nshortmid}{∤}");q("\\nshortparallel","\\html@mathml{\\@nshortparallel}{∦}");q("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{⊈}");q("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{⊉}");q("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{⊊}");q("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{⫋}");q("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{⊋}");q("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{⫌}");q("\\imath","\\html@mathml{\\@imath}{ı}");q("\\jmath","\\html@mathml{\\@jmath}{ȷ}");q("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`⟦}}");q("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`⟧}}");q("⟦","\\llbracket");q("⟧","\\rrbracket");q("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`⦃}}");q("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`⦄}}");q("⦃","\\lBrace");q("⦄","\\rBrace");q("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`⦵}}");q("⦵","\\minuso");q("\\darr","\\downarrow");q("\\dArr","\\Downarrow");q("\\Darr","\\Downarrow");q("\\lang","\\langle");q("\\rang","\\rangle");q("\\uarr","\\uparrow");q("\\uArr","\\Uparrow");q("\\Uarr","\\Uparrow");q("\\N","\\mathbb{N}");q("\\R","\\mathbb{R}");q("\\Z","\\mathbb{Z}");q("\\alef","\\aleph");q("\\alefsym","\\aleph");q("\\Alpha","\\mathrm{A}");q("\\Beta","\\mathrm{B}");q("\\bull","\\bullet");q("\\Chi","\\mathrm{X}");q("\\clubs","\\clubsuit");q("\\cnums","\\mathbb{C}");q("\\Complex","\\mathbb{C}");q("\\Dagger","\\ddagger");q("\\diamonds","\\diamondsuit");q("\\empty","\\emptyset");q("\\Epsilon","\\mathrm{E}");q("\\Eta","\\mathrm{H}");q("\\exist","\\exists");q("\\harr","\\leftrightarrow");q("\\hArr","\\Leftrightarrow");q("\\Harr","\\Leftrightarrow");q("\\hearts","\\heartsuit");q("\\image","\\Im");q("\\infin","\\infty");q("\\Iota","\\mathrm{I}");q("\\isin","\\in");q("\\Kappa","\\mathrm{K}");q("\\larr","\\leftarrow");q("\\lArr","\\Leftarrow");q("\\Larr","\\Leftarrow");q("\\lrarr","\\leftrightarrow");q("\\lrArr","\\Leftrightarrow");q("\\Lrarr","\\Leftrightarrow");q("\\Mu","\\mathrm{M}");q("\\natnums","\\mathbb{N}");q("\\Nu","\\mathrm{N}");q("\\Omicron","\\mathrm{O}");q("\\plusmn","\\pm");q("\\rarr","\\rightarrow");q("\\rArr","\\Rightarrow");q("\\Rarr","\\Rightarrow");q("\\real","\\Re");q("\\reals","\\mathbb{R}");q("\\Reals","\\mathbb{R}");q("\\Rho","\\mathrm{P}");q("\\sdot","\\cdot");q("\\sect","\\S");q("\\spades","\\spadesuit");q("\\sub","\\subset");q("\\sube","\\subseteq");q("\\supe","\\supseteq");q("\\Tau","\\mathrm{T}");q("\\thetasym","\\vartheta");q("\\weierp","\\wp");q("\\Zeta","\\mathrm{Z}");q("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");q("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");q("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");q("\\bra","\\mathinner{\\langle{#1}|}");q("\\ket","\\mathinner{|{#1}\\rangle}");q("\\braket","\\mathinner{\\langle{#1}\\rangle}");q("\\Bra","\\left\\langle#1\\right|");q("\\Ket","\\left|#1\\right\\rangle");var YR=t=>e=>{var n=e.consumeArg().tokens,r=e.consumeArg().tokens,s=e.consumeArg().tokens,i=e.consumeArg().tokens,l=e.macros.get("|"),c=e.macros.get("\\|");e.macros.beginGroup();var d=p=>x=>{t&&(x.macros.set("|",l),s.length&&x.macros.set("\\|",c));var v=p;if(!p&&s.length){var b=x.future();b.text==="|"&&(x.popToken(),v=!0)}return{tokens:v?s:r,numArgs:0}};e.macros.set("|",d(!1)),s.length&&e.macros.set("\\|",d(!0));var h=e.consumeArg().tokens,m=e.expandTokens([...i,...h,...n]);return e.macros.endGroup(),{tokens:m.reverse(),numArgs:0}};q("\\bra@ket",YR(!1));q("\\bra@set",YR(!0));q("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");q("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");q("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");q("\\angln","{\\angl n}");q("\\blue","\\textcolor{##6495ed}{#1}");q("\\orange","\\textcolor{##ffa500}{#1}");q("\\pink","\\textcolor{##ff00af}{#1}");q("\\red","\\textcolor{##df0030}{#1}");q("\\green","\\textcolor{##28ae7b}{#1}");q("\\gray","\\textcolor{gray}{#1}");q("\\purple","\\textcolor{##9d38bd}{#1}");q("\\blueA","\\textcolor{##ccfaff}{#1}");q("\\blueB","\\textcolor{##80f6ff}{#1}");q("\\blueC","\\textcolor{##63d9ea}{#1}");q("\\blueD","\\textcolor{##11accd}{#1}");q("\\blueE","\\textcolor{##0c7f99}{#1}");q("\\tealA","\\textcolor{##94fff5}{#1}");q("\\tealB","\\textcolor{##26edd5}{#1}");q("\\tealC","\\textcolor{##01d1c1}{#1}");q("\\tealD","\\textcolor{##01a995}{#1}");q("\\tealE","\\textcolor{##208170}{#1}");q("\\greenA","\\textcolor{##b6ffb0}{#1}");q("\\greenB","\\textcolor{##8af281}{#1}");q("\\greenC","\\textcolor{##74cf70}{#1}");q("\\greenD","\\textcolor{##1fab54}{#1}");q("\\greenE","\\textcolor{##0d923f}{#1}");q("\\goldA","\\textcolor{##ffd0a9}{#1}");q("\\goldB","\\textcolor{##ffbb71}{#1}");q("\\goldC","\\textcolor{##ff9c39}{#1}");q("\\goldD","\\textcolor{##e07d10}{#1}");q("\\goldE","\\textcolor{##a75a05}{#1}");q("\\redA","\\textcolor{##fca9a9}{#1}");q("\\redB","\\textcolor{##ff8482}{#1}");q("\\redC","\\textcolor{##f9685d}{#1}");q("\\redD","\\textcolor{##e84d39}{#1}");q("\\redE","\\textcolor{##bc2612}{#1}");q("\\maroonA","\\textcolor{##ffbde0}{#1}");q("\\maroonB","\\textcolor{##ff92c6}{#1}");q("\\maroonC","\\textcolor{##ed5fa6}{#1}");q("\\maroonD","\\textcolor{##ca337c}{#1}");q("\\maroonE","\\textcolor{##9e034e}{#1}");q("\\purpleA","\\textcolor{##ddd7ff}{#1}");q("\\purpleB","\\textcolor{##c6b9fc}{#1}");q("\\purpleC","\\textcolor{##aa87ff}{#1}");q("\\purpleD","\\textcolor{##7854ab}{#1}");q("\\purpleE","\\textcolor{##543b78}{#1}");q("\\mintA","\\textcolor{##f5f9e8}{#1}");q("\\mintB","\\textcolor{##edf2df}{#1}");q("\\mintC","\\textcolor{##e0e5cc}{#1}");q("\\grayA","\\textcolor{##f6f7f7}{#1}");q("\\grayB","\\textcolor{##f0f1f2}{#1}");q("\\grayC","\\textcolor{##e3e5e6}{#1}");q("\\grayD","\\textcolor{##d6d8da}{#1}");q("\\grayE","\\textcolor{##babec2}{#1}");q("\\grayF","\\textcolor{##888d93}{#1}");q("\\grayG","\\textcolor{##626569}{#1}");q("\\grayH","\\textcolor{##3b3e40}{#1}");q("\\grayI","\\textcolor{##21242c}{#1}");q("\\kaBlue","\\textcolor{##314453}{#1}");q("\\kaGreen","\\textcolor{##71B307}{#1}");var KR={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class mue{constructor(e,n,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=n,this.expansionCount=0,this.feed(e),this.macros=new hue(fue,n.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new EN(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var n,r,s;if(e){if(this.consumeSpaces(),this.future().text!=="[")return null;n=this.popToken(),{tokens:s,end:r}=this.consumeArg(["]"])}else({tokens:s,start:n,end:r}=this.consumeArg());return this.pushToken(new si("EOF",r.loc)),this.pushTokens(s),new si("",Ts.range(n,r))}consumeSpaces(){for(;;){var e=this.future();if(e.text===" ")this.stack.pop();else break}}consumeArg(e){var n=[],r=e&&e.length>0;r||this.consumeSpaces();var s=this.future(),i,l=0,c=0;do{if(i=this.popToken(),n.push(i),i.text==="{")++l;else if(i.text==="}"){if(--l,l===-1)throw new De("Extra }",i)}else if(i.text==="EOF")throw new De("Unexpected end of input in a macro argument, expected '"+(e&&r?e[c]:"}")+"'",i);if(e&&r)if((l===0||l===1&&e[c]==="{")&&i.text===e[c]){if(++c,c===e.length){n.splice(-c,c);break}}else c=0}while(l!==0||r);return s.text==="{"&&n[n.length-1].text==="}"&&(n.pop(),n.shift()),n.reverse(),{tokens:n,start:s,end:i}}consumeArgs(e,n){if(n){if(n.length!==e+1)throw new De("The length of delimiters doesn't match the number of args!");for(var r=n[0],s=0;sthis.settings.maxExpand)throw new De("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var n=this.popToken(),r=n.text,s=n.noexpand?null:this._getExpansion(r);if(s==null||e&&s.unexpandable){if(e&&s==null&&r[0]==="\\"&&!this.isDefined(r))throw new De("Undefined control sequence: "+r);return this.pushToken(n),!1}this.countExpansion(1);var i=s.tokens,l=this.consumeArgs(s.numArgs,s.delimiters);if(s.numArgs){i=i.slice();for(var c=i.length-1;c>=0;--c){var d=i[c];if(d.text==="#"){if(c===0)throw new De("Incomplete placeholder at end of macro body",d);if(d=i[--c],d.text==="#")i.splice(c+1,1);else if(/^[1-9]$/.test(d.text))i.splice(c,2,...l[+d.text-1]);else throw new De("Not a valid argument number",d)}}}return this.pushTokens(i),i.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new si(e)]):void 0}expandTokens(e){var n=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(this.expandOnce(!0)===!1){var s=this.stack.pop();s.treatAsRelax&&(s.noexpand=!1,s.treatAsRelax=!1),n.push(s)}return this.countExpansion(n.length),n}expandMacroAsText(e){var n=this.expandMacro(e);return n&&n.map(r=>r.text).join("")}_getExpansion(e){var n=this.macros.get(e);if(n==null)return n;if(e.length===1){var r=this.lexer.catcodes[e];if(r!=null&&r!==13)return}var s=typeof n=="function"?n(this):n;if(typeof s=="string"){var i=0;if(s.indexOf("#")!==-1)for(var l=s.replace(/##/g,"");l.indexOf("#"+(i+1))!==-1;)++i;for(var c=new EN(s,this.settings),d=[],h=c.lex();h.text!=="EOF";)d.push(h),h=c.lex();d.reverse();var m={tokens:d,numArgs:i};return m}return s}isDefined(e){return this.macros.has(e)||so.hasOwnProperty(e)||Ln.math.hasOwnProperty(e)||Ln.text.hasOwnProperty(e)||KR.hasOwnProperty(e)}isExpandable(e){var n=this.macros.get(e);return n!=null?typeof n=="string"||typeof n=="function"||!n.unexpandable:so.hasOwnProperty(e)&&!so[e].primitive}}var RN=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,Pp=Object.freeze({"₊":"+","₋":"-","₌":"=","₍":"(","₎":")","₀":"0","₁":"1","₂":"2","₃":"3","₄":"4","₅":"5","₆":"6","₇":"7","₈":"8","₉":"9","ₐ":"a","ₑ":"e","ₕ":"h","ᵢ":"i","ⱼ":"j","ₖ":"k","ₗ":"l","ₘ":"m","ₙ":"n","ₒ":"o","ₚ":"p","ᵣ":"r","ₛ":"s","ₜ":"t","ᵤ":"u","ᵥ":"v","ₓ":"x","ᵦ":"β","ᵧ":"γ","ᵨ":"ρ","ᵩ":"ϕ","ᵪ":"χ","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")","⁰":"0","¹":"1","²":"2","³":"3","⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᴬ":"A","ᴮ":"B","ᴰ":"D","ᴱ":"E","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","ᴿ":"R","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g",ʰ:"h","ⁱ":"i",ʲ:"j","ᵏ":"k",ˡ:"l","ᵐ":"m",ⁿ:"n","ᵒ":"o","ᵖ":"p",ʳ:"r",ˢ:"s","ᵗ":"t","ᵘ":"u","ᵛ":"v",ʷ:"w",ˣ:"x",ʸ:"y","ᶻ":"z","ᵝ":"β","ᵞ":"γ","ᵟ":"δ","ᵠ":"ϕ","ᵡ":"χ","ᶿ":"θ"}),$b={"́":{text:"\\'",math:"\\acute"},"̀":{text:"\\`",math:"\\grave"},"̈":{text:'\\"',math:"\\ddot"},"̃":{text:"\\~",math:"\\tilde"},"̄":{text:"\\=",math:"\\bar"},"̆":{text:"\\u",math:"\\breve"},"̌":{text:"\\v",math:"\\check"},"̂":{text:"\\^",math:"\\hat"},"̇":{text:"\\.",math:"\\dot"},"̊":{text:"\\r",math:"\\mathring"},"̋":{text:"\\H"},"̧":{text:"\\c"}},zN={á:"á",à:"à",ä:"ä",ǟ:"ǟ",ã:"ã",ā:"ā",ă:"ă",ắ:"ắ",ằ:"ằ",ẵ:"ẵ",ǎ:"ǎ",â:"â",ấ:"ấ",ầ:"ầ",ẫ:"ẫ",ȧ:"ȧ",ǡ:"ǡ",å:"å",ǻ:"ǻ",ḃ:"ḃ",ć:"ć",ḉ:"ḉ",č:"č",ĉ:"ĉ",ċ:"ċ",ç:"ç",ď:"ď",ḋ:"ḋ",ḑ:"ḑ",é:"é",è:"è",ë:"ë",ẽ:"ẽ",ē:"ē",ḗ:"ḗ",ḕ:"ḕ",ĕ:"ĕ",ḝ:"ḝ",ě:"ě",ê:"ê",ế:"ế",ề:"ề",ễ:"ễ",ė:"ė",ȩ:"ȩ",ḟ:"ḟ",ǵ:"ǵ",ḡ:"ḡ",ğ:"ğ",ǧ:"ǧ",ĝ:"ĝ",ġ:"ġ",ģ:"ģ",ḧ:"ḧ",ȟ:"ȟ",ĥ:"ĥ",ḣ:"ḣ",ḩ:"ḩ",í:"í",ì:"ì",ï:"ï",ḯ:"ḯ",ĩ:"ĩ",ī:"ī",ĭ:"ĭ",ǐ:"ǐ",î:"î",ǰ:"ǰ",ĵ:"ĵ",ḱ:"ḱ",ǩ:"ǩ",ķ:"ķ",ĺ:"ĺ",ľ:"ľ",ļ:"ļ",ḿ:"ḿ",ṁ:"ṁ",ń:"ń",ǹ:"ǹ",ñ:"ñ",ň:"ň",ṅ:"ṅ",ņ:"ņ",ó:"ó",ò:"ò",ö:"ö",ȫ:"ȫ",õ:"õ",ṍ:"ṍ",ṏ:"ṏ",ȭ:"ȭ",ō:"ō",ṓ:"ṓ",ṑ:"ṑ",ŏ:"ŏ",ǒ:"ǒ",ô:"ô",ố:"ố",ồ:"ồ",ỗ:"ỗ",ȯ:"ȯ",ȱ:"ȱ",ő:"ő",ṕ:"ṕ",ṗ:"ṗ",ŕ:"ŕ",ř:"ř",ṙ:"ṙ",ŗ:"ŗ",ś:"ś",ṥ:"ṥ",š:"š",ṧ:"ṧ",ŝ:"ŝ",ṡ:"ṡ",ş:"ş",ẗ:"ẗ",ť:"ť",ṫ:"ṫ",ţ:"ţ",ú:"ú",ù:"ù",ü:"ü",ǘ:"ǘ",ǜ:"ǜ",ǖ:"ǖ",ǚ:"ǚ",ũ:"ũ",ṹ:"ṹ",ū:"ū",ṻ:"ṻ",ŭ:"ŭ",ǔ:"ǔ",û:"û",ů:"ů",ű:"ű",ṽ:"ṽ",ẃ:"ẃ",ẁ:"ẁ",ẅ:"ẅ",ŵ:"ŵ",ẇ:"ẇ",ẘ:"ẘ",ẍ:"ẍ",ẋ:"ẋ",ý:"ý",ỳ:"ỳ",ÿ:"ÿ",ỹ:"ỹ",ȳ:"ȳ",ŷ:"ŷ",ẏ:"ẏ",ẙ:"ẙ",ź:"ź",ž:"ž",ẑ:"ẑ",ż:"ż",Á:"Á",À:"À",Ä:"Ä",Ǟ:"Ǟ",Ã:"Ã",Ā:"Ā",Ă:"Ă",Ắ:"Ắ",Ằ:"Ằ",Ẵ:"Ẵ",Ǎ:"Ǎ",Â:"Â",Ấ:"Ấ",Ầ:"Ầ",Ẫ:"Ẫ",Ȧ:"Ȧ",Ǡ:"Ǡ",Å:"Å",Ǻ:"Ǻ",Ḃ:"Ḃ",Ć:"Ć",Ḉ:"Ḉ",Č:"Č",Ĉ:"Ĉ",Ċ:"Ċ",Ç:"Ç",Ď:"Ď",Ḋ:"Ḋ",Ḑ:"Ḑ",É:"É",È:"È",Ë:"Ë",Ẽ:"Ẽ",Ē:"Ē",Ḗ:"Ḗ",Ḕ:"Ḕ",Ĕ:"Ĕ",Ḝ:"Ḝ",Ě:"Ě",Ê:"Ê",Ế:"Ế",Ề:"Ề",Ễ:"Ễ",Ė:"Ė",Ȩ:"Ȩ",Ḟ:"Ḟ",Ǵ:"Ǵ",Ḡ:"Ḡ",Ğ:"Ğ",Ǧ:"Ǧ",Ĝ:"Ĝ",Ġ:"Ġ",Ģ:"Ģ",Ḧ:"Ḧ",Ȟ:"Ȟ",Ĥ:"Ĥ",Ḣ:"Ḣ",Ḩ:"Ḩ",Í:"Í",Ì:"Ì",Ï:"Ï",Ḯ:"Ḯ",Ĩ:"Ĩ",Ī:"Ī",Ĭ:"Ĭ",Ǐ:"Ǐ",Î:"Î",İ:"İ",Ĵ:"Ĵ",Ḱ:"Ḱ",Ǩ:"Ǩ",Ķ:"Ķ",Ĺ:"Ĺ",Ľ:"Ľ",Ļ:"Ļ",Ḿ:"Ḿ",Ṁ:"Ṁ",Ń:"Ń",Ǹ:"Ǹ",Ñ:"Ñ",Ň:"Ň",Ṅ:"Ṅ",Ņ:"Ņ",Ó:"Ó",Ò:"Ò",Ö:"Ö",Ȫ:"Ȫ",Õ:"Õ",Ṍ:"Ṍ",Ṏ:"Ṏ",Ȭ:"Ȭ",Ō:"Ō",Ṓ:"Ṓ",Ṑ:"Ṑ",Ŏ:"Ŏ",Ǒ:"Ǒ",Ô:"Ô",Ố:"Ố",Ồ:"Ồ",Ỗ:"Ỗ",Ȯ:"Ȯ",Ȱ:"Ȱ",Ő:"Ő",Ṕ:"Ṕ",Ṗ:"Ṗ",Ŕ:"Ŕ",Ř:"Ř",Ṙ:"Ṙ",Ŗ:"Ŗ",Ś:"Ś",Ṥ:"Ṥ",Š:"Š",Ṧ:"Ṧ",Ŝ:"Ŝ",Ṡ:"Ṡ",Ş:"Ş",Ť:"Ť",Ṫ:"Ṫ",Ţ:"Ţ",Ú:"Ú",Ù:"Ù",Ü:"Ü",Ǘ:"Ǘ",Ǜ:"Ǜ",Ǖ:"Ǖ",Ǚ:"Ǚ",Ũ:"Ũ",Ṹ:"Ṹ",Ū:"Ū",Ṻ:"Ṻ",Ŭ:"Ŭ",Ǔ:"Ǔ",Û:"Û",Ů:"Ů",Ű:"Ű",Ṽ:"Ṽ",Ẃ:"Ẃ",Ẁ:"Ẁ",Ẅ:"Ẅ",Ŵ:"Ŵ",Ẇ:"Ẇ",Ẍ:"Ẍ",Ẋ:"Ẋ",Ý:"Ý",Ỳ:"Ỳ",Ÿ:"Ÿ",Ỹ:"Ỹ",Ȳ:"Ȳ",Ŷ:"Ŷ",Ẏ:"Ẏ",Ź:"Ź",Ž:"Ž",Ẑ:"Ẑ",Ż:"Ż",ά:"ά",ὰ:"ὰ",ᾱ:"ᾱ",ᾰ:"ᾰ",έ:"έ",ὲ:"ὲ",ή:"ή",ὴ:"ὴ",ί:"ί",ὶ:"ὶ",ϊ:"ϊ",ΐ:"ΐ",ῒ:"ῒ",ῑ:"ῑ",ῐ:"ῐ",ό:"ό",ὸ:"ὸ",ύ:"ύ",ὺ:"ὺ",ϋ:"ϋ",ΰ:"ΰ",ῢ:"ῢ",ῡ:"ῡ",ῠ:"ῠ",ώ:"ώ",ὼ:"ὼ",Ύ:"Ύ",Ὺ:"Ὺ",Ϋ:"Ϋ",Ῡ:"Ῡ",Ῠ:"Ῠ",Ώ:"Ώ",Ὼ:"Ὼ"};class Xx{constructor(e,n){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new mue(e,n,this.mode),this.settings=n,this.leftrightDepth=0}expect(e,n){if(n===void 0&&(n=!0),this.fetch().text!==e)throw new De("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());n&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var n=this.nextToken;this.consume(),this.gullet.pushToken(new si("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=n,r}parseExpression(e,n){for(var r=[];;){this.mode==="math"&&this.consumeSpaces();var s=this.fetch();if(Xx.endOfExpression.indexOf(s.text)!==-1||n&&s.text===n||e&&so[s.text]&&so[s.text].infix)break;var i=this.parseAtom(n);if(i){if(i.type==="internal")continue}else break;r.push(i)}return this.mode==="text"&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var n=-1,r,s=0;s=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+n[0]+'" used in math mode',e);var c=Ln[this.mode][n].group,d=Ts.range(e),h;if(nce.hasOwnProperty(c)){var m=c;h={type:"atom",mode:this.mode,family:m,loc:d,text:n}}else h={type:c,mode:this.mode,loc:d,text:n};l=h}else if(n.charCodeAt(0)>=128)this.settings.strict&&(aR(n.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+n[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+n[0]+'"'+(" ("+n.charCodeAt(0)+")"),e)),l={type:"textord",mode:"text",loc:Ts.range(e),text:n};else return null;if(this.consume(),i)for(var p=0;ph&&(h=m):m&&(h!==void 0&&h>-1&&d.push(` -`.repeat(h)||" "),h=-1,d.push(m))}return d.join("")}function sz(t,e,n){return t.type==="element"?Uue(t,e,n):t.type==="text"?n.whitespace==="normal"?iz(t,n):Vue(t):[]}function Uue(t,e,n){const r=az(t,n),s=t.children||[];let i=-1,l=[];if($ue(t))return l;let c,d;for(_4(t)||HN(t)&&qN(e,t,HN)?d=` -`:Que(t)?(c=2,d=2):rz(t)&&(c=1,d=1);++i{try{i(!0);const Oe=await nde({page:l,page_size:m,search:x||void 0,is_registered:b==="all"?void 0:b==="registered",is_banned:O==="all"?void 0:O==="banned",format:T==="all"?void 0:T,sort_by:"usage_count",sort_order:"desc"});e(Oe.data),h(Oe.total)}catch(Oe){const nt=Oe instanceof Error?Oe.message:"加载表情包列表失败";ne({title:"错误",description:nt,variant:"destructive"})}finally{i(!1)}},[l,m,x,b,O,T,ne]),R=async()=>{try{const Oe=await ade();r(Oe.data)}catch(Oe){console.error("加载统计数据失败:",Oe)}};S.useEffect(()=>{ue()},[ue]),S.useEffect(()=>{R()},[]);const me=async Oe=>{try{const nt=await rde(Oe.id);D(nt.data),z(!0)}catch(nt){const ut=nt instanceof Error?nt.message:"加载详情失败";ne({title:"错误",description:ut,variant:"destructive"})}},Y=Oe=>{D(Oe),F(!0)},P=Oe=>{D(Oe),U(!0)},K=async()=>{if(_)try{await ide(_.id),ne({title:"成功",description:"表情包已删除"}),U(!1),D(null),ue(),R()}catch(Oe){const nt=Oe instanceof Error?Oe.message:"删除失败";ne({title:"错误",description:nt,variant:"destructive"})}},$=async Oe=>{try{await lde(Oe.id),ne({title:"成功",description:"表情包已注册"}),ue(),R()}catch(nt){const ut=nt instanceof Error?nt.message:"注册失败";ne({title:"错误",description:ut,variant:"destructive"})}},fe=async Oe=>{try{await ode(Oe.id),ne({title:"成功",description:"表情包已封禁"}),ue(),R()}catch(nt){const ut=nt instanceof Error?nt.message:"封禁失败";ne({title:"错误",description:ut,variant:"destructive"})}},ve=Oe=>{const nt=new Set(V);nt.has(Oe)?nt.delete(Oe):nt.add(Oe),ce(nt)},Re=()=>{V.size===t.length&&t.length>0?ce(new Set):ce(new Set(t.map(Oe=>Oe.id)))},de=async()=>{try{const Oe=await cde(Array.from(V));ne({title:"批量删除完成",description:Oe.message}),ce(new Set),J(!1),ue(),R()}catch(Oe){ne({title:"批量删除失败",description:Oe instanceof Error?Oe.message:"批量删除失败",variant:"destructive"})}},We=()=>{const Oe=parseInt(H),nt=Math.ceil(d/m);Oe>=1&&Oe<=nt?(c(Oe),ae("")):ne({title:"无效的页码",description:`请输入1-${nt}之间的页码`,variant:"destructive"})},ct=n?.formats?Object.keys(n.formats):[];return a.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[a.jsxs("div",{className:"mb-4 sm:mb-6",children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"表情包管理"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"管理麦麦的表情包资源"})]}),a.jsx(fn,{className:"flex-1",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[n&&a.jsxs("div",{className:"grid gap-4 grid-cols-2 lg:grid-cols-4",children:[a.jsx(yt,{children:a.jsxs(Jt,{className:"pb-2",children:[a.jsx(Sr,{children:"总数"}),a.jsx(en,{className:"text-2xl",children:n.total})]})}),a.jsx(yt,{children:a.jsxs(Jt,{className:"pb-2",children:[a.jsx(Sr,{children:"已注册"}),a.jsx(en,{className:"text-2xl text-green-600",children:n.registered})]})}),a.jsx(yt,{children:a.jsxs(Jt,{className:"pb-2",children:[a.jsx(Sr,{children:"已封禁"}),a.jsx(en,{className:"text-2xl text-red-600",children:n.banned})]})}),a.jsx(yt,{children:a.jsxs(Jt,{className:"pb-2",children:[a.jsx(Sr,{children:"未注册"}),a.jsx(en,{className:"text-2xl text-gray-600",children:n.unregistered})]})})]}),a.jsxs(yt,{children:[a.jsx(Jt,{children:a.jsxs(en,{className:"flex items-center gap-2",children:[a.jsx(t2,{className:"h-5 w-5"}),"搜索和筛选"]})}),a.jsxs(vn,{className:"space-y-4",children:[a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{children:"搜索"}),a.jsxs("div",{className:"relative",children:[a.jsx(Ps,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{placeholder:"描述或哈希值...",value:x,onChange:Oe=>{v(Oe.target.value),c(1)},className:"pl-8"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{children:"注册状态"}),a.jsxs(Bt,{value:b,onValueChange:Oe=>{k(Oe),c(1)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部"}),a.jsx(Pe,{value:"registered",children:"已注册"}),a.jsx(Pe,{value:"unregistered",children:"未注册"})]})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{children:"封禁状态"}),a.jsxs(Bt,{value:O,onValueChange:Oe=>{j(Oe),c(1)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部"}),a.jsx(Pe,{value:"banned",children:"已封禁"}),a.jsx(Pe,{value:"unbanned",children:"未封禁"})]})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{children:"格式"}),a.jsxs(Bt,{value:T,onValueChange:Oe=>{M(Oe),c(1)},children:[a.jsx(Dt,{children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部"}),ct.map(Oe=>a.jsxs(Pe,{value:Oe,children:[Oe.toUpperCase()," (",n?.formats[Oe],")"]},Oe))]})]})]})]}),a.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 pt-4 border-t",children:[a.jsx("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:V.size>0&&a.jsxs("span",{children:["已选择 ",V.size," 个表情包"]})}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(te,{htmlFor:"emoji-page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),a.jsxs(Bt,{value:m.toString(),onValueChange:Oe=>{p(parseInt(Oe)),c(1),ce(new Set)},children:[a.jsx(Dt,{id:"emoji-page-size",className:"w-20",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"10",children:"10"}),a.jsx(Pe,{value:"20",children:"20"}),a.jsx(Pe,{value:"50",children:"50"}),a.jsx(Pe,{value:"100",children:"100"})]})]}),V.size>0&&a.jsxs(a.Fragment,{children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>ce(new Set),children:"取消选择"}),a.jsxs(ie,{variant:"destructive",size:"sm",onClick:()=>J(!0),children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]})]}),a.jsx("div",{className:"flex justify-end pt-4 border-t",children:a.jsxs(ie,{variant:"outline",size:"sm",onClick:ue,disabled:s,children:[a.jsx(Ii,{className:`h-4 w-4 mr-2 ${s?"animate-spin":""}`}),"刷新"]})})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"表情包列表"}),a.jsxs(Sr,{children:["共 ",d," 个表情包,当前第 ",l," 页"]})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"hidden md:block rounded-md border overflow-hidden",children:a.jsxs(Ac,{children:[a.jsx(Ec,{children:a.jsxs(xr,{children:[a.jsx(gt,{className:"w-12",children:a.jsx(ss,{checked:t.length>0&&V.size===t.length,onCheckedChange:Re,"aria-label":"全选"})}),a.jsx(gt,{className:"w-16",children:"预览"}),a.jsx(gt,{children:"描述"}),a.jsx(gt,{children:"格式"}),a.jsx(gt,{children:"情绪"}),a.jsx(gt,{className:"text-center",children:"状态"}),a.jsx(gt,{className:"text-right",children:"使用次数"}),a.jsx(gt,{className:"text-right",children:"操作"})]})}),a.jsx(_c,{children:t.length===0?a.jsx(xr,{children:a.jsx(it,{colSpan:8,className:"text-center py-8 text-muted-foreground",children:"暂无数据"})}):t.map(Oe=>a.jsxs(xr,{children:[a.jsx(it,{children:a.jsx(ss,{checked:V.has(Oe.id),onCheckedChange:()=>ve(Oe.id),"aria-label":`选择 ${Oe.description}`})}),a.jsx(it,{children:a.jsx("div",{className:"w-20 h-20 bg-muted rounded flex items-center justify-center overflow-hidden",children:a.jsx("img",{src:D4(Oe.id),alt:Oe.description||"表情包",className:"w-full h-full object-cover",onError:nt=>{const ut=nt.target;ut.style.display="none";const Ct=ut.parentElement;Ct&&(Ct.innerHTML='')}})})}),a.jsx(it,{children:a.jsxs("div",{className:"space-y-1 max-w-xs",children:[a.jsx("div",{className:"font-medium truncate",title:Oe.description||"无描述",children:Oe.description||"无描述"}),a.jsxs("div",{className:"text-xs text-muted-foreground font-mono",children:[Oe.emoji_hash.slice(0,16),"..."]})]})}),a.jsx(it,{children:a.jsx($n,{variant:"outline",children:Oe.format.toUpperCase()})}),a.jsx(it,{children:a.jsx(UN,{emotions:Oe.emotion})}),a.jsx(it,{className:"align-middle",children:a.jsxs("div",{className:"flex gap-2 justify-center",children:[Oe.is_registered&&a.jsxs($n,{variant:"default",className:"bg-green-600",children:[a.jsx(ua,{className:"h-3 w-3 mr-1"}),"已注册"]}),Oe.is_banned&&a.jsxs($n,{variant:"destructive",children:[a.jsx(Kb,{className:"h-3 w-3 mr-1"}),"已封禁"]})]})}),a.jsx(it,{className:"text-right font-mono",children:Oe.usage_count}),a.jsx(it,{children:a.jsxs("div",{className:"flex items-center justify-end gap-1 flex-wrap",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>me(Oe),children:[a.jsx(oo,{className:"h-4 w-4 mr-1"}),"详情"]}),a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>Y(Oe),children:[a.jsx(rd,{className:"h-4 w-4 mr-1"}),"编辑"]}),!Oe.is_registered&&a.jsxs(ie,{size:"sm",onClick:()=>$(Oe),className:"bg-green-600 hover:bg-green-700 text-white",children:[a.jsx(ua,{className:"h-4 w-4 mr-1"}),"注册"]}),!Oe.is_banned&&a.jsxs(ie,{size:"sm",onClick:()=>fe(Oe),className:"bg-orange-600 hover:bg-orange-700 text-white",children:[a.jsx(cO,{className:"h-4 w-4 mr-1"}),"封禁"]}),a.jsxs(ie,{size:"sm",onClick:()=>P(Oe),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"删除"]})]})})]},Oe.id))})]})}),a.jsx("div",{className:"md:hidden space-y-3",children:t.length===0?a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"暂无数据"}):t.map(Oe=>a.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3 overflow-hidden",children:[a.jsxs("div",{className:"flex gap-3",children:[a.jsx("div",{className:"flex-shrink-0",children:a.jsx("div",{className:"w-16 h-16 bg-muted rounded flex items-center justify-center overflow-hidden",children:a.jsx("img",{src:D4(Oe.id),alt:Oe.description||"表情包",className:"w-full h-full object-cover",onError:nt=>{const ut=nt.target;ut.style.display="none";const Ct=ut.parentElement;Ct&&(Ct.innerHTML='')}})})}),a.jsxs("div",{className:"flex-1 min-w-0 space-y-2",children:[a.jsxs("div",{className:"min-w-0 w-full overflow-hidden",children:[a.jsx("h3",{className:"font-semibold text-sm line-clamp-1 w-full break-all",title:Oe.description||"无描述",children:Oe.description||"无描述"}),a.jsxs("p",{className:"text-xs text-muted-foreground font-mono line-clamp-1 w-full break-all",children:[Oe.emoji_hash.slice(0,16),"..."]})]}),a.jsxs("div",{className:"flex flex-wrap gap-1 items-center min-w-0",children:[a.jsx($n,{variant:"outline",className:"text-xs flex-shrink-0",children:Oe.format.toUpperCase()}),Oe.is_registered&&a.jsxs($n,{variant:"default",className:"bg-green-600 text-xs flex-shrink-0",children:[a.jsx(ua,{className:"h-3 w-3 mr-1"}),"已注册"]}),Oe.is_banned&&a.jsxs($n,{variant:"destructive",className:"text-xs flex-shrink-0",children:[a.jsx(Kb,{className:"h-3 w-3 mr-1"}),"已封禁"]}),a.jsxs("span",{className:"text-xs text-muted-foreground flex-shrink-0",children:["使用: ",Oe.usage_count]})]}),Oe.emotion&&Oe.emotion.trim()&&a.jsx("div",{className:"min-w-0 overflow-hidden",children:a.jsx(UN,{emotions:Oe.emotion})})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-1 pt-2 border-t overflow-hidden",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>me(Oe),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[a.jsx(oo,{className:"h-3 w-3 mr-1"}),"详情"]}),a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>Y(Oe),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[a.jsx(rd,{className:"h-3 w-3 mr-1"}),"编辑"]}),!Oe.is_registered&&a.jsxs(ie,{size:"sm",onClick:()=>$(Oe),className:"text-xs px-2 py-1 h-auto flex-shrink-0 bg-green-600 hover:bg-green-700 text-white",children:[a.jsx(ua,{className:"h-3 w-3 mr-1"}),"注册"]}),!Oe.is_banned&&a.jsxs(ie,{size:"sm",onClick:()=>fe(Oe),className:"text-xs px-2 py-1 h-auto flex-shrink-0 bg-orange-600 hover:bg-orange-700 text-white",children:[a.jsx(cO,{className:"h-3 w-3 mr-1"}),"封禁"]}),a.jsxs(ie,{size:"sm",onClick:()=>P(Oe),className:"text-xs px-2 py-1 h-auto flex-shrink-0 bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-3 w-3 mr-1"}),"删除"]})]})]},Oe.id))}),d>0&&a.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[a.jsxs("div",{className:"text-sm text-muted-foreground",children:["显示 ",(l-1)*m+1," 到"," ",Math.min(l*m,d)," 条,共 ",d," 条"]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>c(1),disabled:l===1,className:"hidden sm:flex",children:a.jsx(Xf,{className:"h-4 w-4"})}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>c(Oe=>Math.max(1,Oe-1)),disabled:l===1,children:[a.jsx(Tc,{className:"h-4 w-4 sm:mr-1"}),a.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(Ae,{type:"number",value:H,onChange:Oe=>ae(Oe.target.value),onKeyDown:Oe=>Oe.key==="Enter"&&We(),placeholder:l.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(d/m)}),a.jsx(ie,{variant:"outline",size:"sm",onClick:We,disabled:!H,className:"h-8",children:"跳转"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>c(Oe=>Oe+1),disabled:l>=Math.ceil(d/m),children:[a.jsx("span",{className:"hidden sm:inline",children:"下一页"}),a.jsx(Mc,{className:"h-4 w-4 sm:ml-1"})]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>c(Math.ceil(d/m)),disabled:l>=Math.ceil(d/m),className:"hidden sm:flex",children:a.jsx(Yf,{className:"h-4 w-4"})})]})]})]})]}),a.jsx(dde,{emoji:_,open:E,onOpenChange:z}),a.jsx(hde,{emoji:_,open:Q,onOpenChange:F,onSuccess:()=>{ue(),R()}})]})}),a.jsx(mn,{open:W,onOpenChange:J,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认批量删除"}),a.jsxs(un,{children:["你确定要删除选中的 ",V.size," 个表情包吗?此操作不可撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:de,children:"确认删除"})]})]})}),a.jsx(Rr,{open:B,onOpenChange:U,children:a.jsxs(Nr,{children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"确认删除"}),a.jsx(Gr,{children:"确定要删除这个表情包吗?此操作无法撤销。"})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>U(!1),children:"取消"}),a.jsx(ie,{variant:"destructive",onClick:K,children:"删除"})]})]})})]})}function dde({emoji:t,open:e,onOpenChange:n}){if(!t)return null;const r=s=>s?new Date(s*1e3).toLocaleString("zh-CN"):"-";return a.jsx(Rr,{open:e,onOpenChange:n,children:a.jsxs(Nr,{className:"max-w-2xl max-h-[90vh]",children:[a.jsx(Cr,{children:a.jsx(Tr,{children:"表情包详情"})}),a.jsx(fn,{className:"max-h-[calc(90vh-8rem)] pr-4",children:a.jsxs("div",{className:"space-y-4",children:[a.jsx("div",{className:"flex justify-center",children:a.jsx("div",{className:"w-32 h-32 bg-muted rounded-lg flex items-center justify-center overflow-hidden",children:a.jsx("img",{src:D4(t.id),alt:t.description||"表情包",className:"w-full h-full object-cover",onError:s=>{const i=s.target;i.style.display="none";const l=i.parentElement;l&&(l.innerHTML='')}})})}),a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"ID"}),a.jsx("div",{className:"mt-1 font-mono",children:t.id})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"格式"}),a.jsx("div",{className:"mt-1",children:a.jsx($n,{variant:"outline",children:t.format.toUpperCase()})})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"文件路径"}),a.jsx("div",{className:"mt-1 font-mono text-sm break-all bg-muted p-2 rounded",children:t.full_path})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"哈希值"}),a.jsx("div",{className:"mt-1 font-mono text-sm break-all bg-muted p-2 rounded",children:t.emoji_hash})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"描述"}),t.description?a.jsx("div",{className:"mt-1 rounded-lg border bg-muted/50 p-3",children:a.jsx(tde,{className:"prose-sm",children:t.description})}):a.jsx("div",{className:"mt-1 text-sm text-muted-foreground",children:"-"})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"情绪"}),a.jsx("div",{className:"mt-1",children:t.emotion?a.jsx("span",{className:"text-sm",children:t.emotion}):a.jsx("span",{className:"text-sm text-muted-foreground",children:"-"})})]}),a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"状态"}),a.jsxs("div",{className:"mt-2 flex gap-2",children:[t.is_registered&&a.jsx($n,{variant:"default",className:"bg-green-600",children:"已注册"}),t.is_banned&&a.jsx($n,{variant:"destructive",children:"已封禁"}),!t.is_registered&&!t.is_banned&&a.jsx($n,{variant:"outline",children:"未注册"})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"使用次数"}),a.jsx("div",{className:"mt-1 font-mono text-lg",children:t.usage_count})]})]}),a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"记录时间"}),a.jsx("div",{className:"mt-1 text-sm",children:r(t.record_time)})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"注册时间"}),a.jsx("div",{className:"mt-1 text-sm",children:r(t.register_time)})]})]}),a.jsxs("div",{children:[a.jsx(te,{className:"text-muted-foreground",children:"最后使用"}),a.jsx("div",{className:"mt-1 text-sm",children:r(t.last_used_time)})]})]})})]})})}function hde({emoji:t,open:e,onOpenChange:n,onSuccess:r}){const[s,i]=S.useState(""),[l,c]=S.useState(""),[d,h]=S.useState(!1),[m,p]=S.useState(!1),[x,v]=S.useState(!1),{toast:b}=Pr();S.useEffect(()=>{t&&(i(t.description||""),c(t.emotion||""),h(t.is_registered),p(t.is_banned))},[t]);const k=async()=>{if(t)try{v(!0);const O=l.split(/[,,]/).map(j=>j.trim()).filter(Boolean).join(",");await sde(t.id,{description:s||void 0,emotion:O||void 0,is_registered:d,is_banned:m}),b({title:"成功",description:"表情包信息已更新"}),n(!1),r()}catch(O){const j=O instanceof Error?O.message:"保存失败";b({title:"错误",description:j,variant:"destructive"})}finally{v(!1)}};return t?a.jsx(Rr,{open:e,onOpenChange:n,children:a.jsxs(Nr,{className:"max-w-2xl",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"编辑表情包"}),a.jsx(Gr,{children:"修改表情包的描述和标签信息"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{children:[a.jsx(te,{children:"描述"}),a.jsx(On,{value:s,onChange:O=>i(O.target.value),placeholder:"输入表情包描述...",rows:3,className:"mt-1"})]}),a.jsxs("div",{children:[a.jsx(te,{children:"情绪"}),a.jsx(On,{value:l,onChange:O=>c(O.target.value),placeholder:"输入情绪描述...",rows:2,className:"mt-1"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"输入情绪相关的文本描述"})]}),a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(ss,{id:"is_registered",checked:d,onCheckedChange:O=>h(O===!0)}),a.jsx(te,{htmlFor:"is_registered",className:"cursor-pointer",children:"已注册"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(ss,{id:"is_banned",checked:m,onCheckedChange:O=>p(O===!0)}),a.jsx(te,{htmlFor:"is_banned",className:"cursor-pointer",children:"已封禁"})]})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>n(!1),children:"取消"}),a.jsx(ie,{onClick:k,disabled:x,children:x?"保存中...":"保存"})]})]})}):null}function UN({emotions:t}){if(!t||t.trim()==="")return a.jsx("span",{className:"text-xs text-muted-foreground",children:"-"});const e=20,n=t.length>e?t.slice(0,e)+"...":t;return a.jsx("div",{className:"text-sm break-words max-w-xs",title:t,children:n})}const Pc="/api/webui/expression";async function fde(t){const e=new URLSearchParams;t.page&&e.append("page",t.page.toString()),t.page_size&&e.append("page_size",t.page_size.toString()),t.search&&e.append("search",t.search),t.chat_id&&e.append("chat_id",t.chat_id);const n=await ot(`${Pc}/list?${e}`,{headers:bt()});if(!n.ok){const r=await n.json();throw new Error(r.detail||"获取表达方式列表失败")}return n.json()}async function mde(t){const e=await ot(`${Pc}/${t}`,{headers:bt()});if(!e.ok){const n=await e.json();throw new Error(n.detail||"获取表达方式详情失败")}return e.json()}async function pde(t){const e=await ot(`${Pc}/`,{method:"POST",headers:bt(),body:JSON.stringify(t)});if(!e.ok){const n=await e.json();throw new Error(n.detail||"创建表达方式失败")}return e.json()}async function gde(t,e){const n=await ot(`${Pc}/${t}`,{method:"PATCH",headers:bt(),body:JSON.stringify(e)});if(!n.ok){const r=await n.json();throw new Error(r.detail||"更新表达方式失败")}return n.json()}async function xde(t){const e=await ot(`${Pc}/${t}`,{method:"DELETE",headers:bt()});if(!e.ok){const n=await e.json();throw new Error(n.detail||"删除表达方式失败")}return e.json()}async function vde(t){const e=await ot(`${Pc}/batch/delete`,{method:"POST",headers:bt(),body:JSON.stringify({ids:t})});if(!e.ok){const n=await e.json();throw new Error(n.detail||"批量删除表达方式失败")}return e.json()}async function yde(){const t=await ot(`${Pc}/stats/summary`,{headers:bt()});if(!t.ok){const e=await t.json();throw new Error(e.detail||"获取统计数据失败")}return t.json()}function bde(){const[t,e]=S.useState([]),[n,r]=S.useState(!0),[s,i]=S.useState(0),[l,c]=S.useState(1),[d,h]=S.useState(20),[m,p]=S.useState(""),[x,v]=S.useState(null),[b,k]=S.useState(!1),[O,j]=S.useState(!1),[T,M]=S.useState(!1),[_,D]=S.useState(null),[E,z]=S.useState(new Set),[Q,F]=S.useState(!1),[B,U]=S.useState(""),[V,ce]=S.useState({total:0,recent_7days:0,chat_count:0,top_chats:{}}),{toast:W}=Pr(),J=async()=>{try{r(!0);const $=await fde({page:l,page_size:d,search:m||void 0});e($.data),i($.total)}catch($){W({title:"加载失败",description:$ instanceof Error?$.message:"无法加载表达方式",variant:"destructive"})}finally{r(!1)}},H=async()=>{try{const $=await yde();$?.data&&ce($.data)}catch($){console.error("加载统计数据失败:",$)}};S.useEffect(()=>{J(),H()},[l,d,m]);const ae=async $=>{try{const fe=await mde($.id);v(fe.data),k(!0)}catch(fe){W({title:"加载详情失败",description:fe instanceof Error?fe.message:"无法加载表达方式详情",variant:"destructive"})}},ne=$=>{v($),j(!0)},ue=async $=>{try{await xde($.id),W({title:"删除成功",description:`已删除表达方式: ${$.situation}`}),D(null),J(),H()}catch(fe){W({title:"删除失败",description:fe instanceof Error?fe.message:"无法删除表达方式",variant:"destructive"})}},R=$=>{const fe=new Set(E);fe.has($)?fe.delete($):fe.add($),z(fe)},me=()=>{E.size===t.length&&t.length>0?z(new Set):z(new Set(t.map($=>$.id)))},Y=async()=>{try{await vde(Array.from(E)),W({title:"批量删除成功",description:`已删除 ${E.size} 个表达方式`}),z(new Set),F(!1),J(),H()}catch($){W({title:"批量删除失败",description:$ instanceof Error?$.message:"无法批量删除表达方式",variant:"destructive"})}},P=()=>{const $=parseInt(B),fe=Math.ceil(s/d);$>=1&&$<=fe?(c($),U("")):W({title:"无效的页码",description:`请输入1-${fe}之间的页码`,variant:"destructive"})},K=$=>$?new Date($*1e3).toLocaleString("zh-CN"):"-";return a.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[a.jsx("div",{className:"mb-4 sm:mb-6",children:a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[a.jsxs("div",{children:[a.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[a.jsx(Wf,{className:"h-8 w-8",strokeWidth:2}),"表达方式管理"]}),a.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"管理麦麦的表达方式和话术模板"})]}),a.jsxs(ie,{onClick:()=>M(!0),className:"gap-2",children:[a.jsx(Wr,{className:"h-4 w-4"}),"新增表达方式"]})]})}),a.jsx(fn,{className:"flex-1",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx("div",{className:"text-sm text-muted-foreground",children:"总数量"}),a.jsx("div",{className:"text-2xl font-bold mt-1",children:V.total})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx("div",{className:"text-sm text-muted-foreground",children:"近7天新增"}),a.jsx("div",{className:"text-2xl font-bold mt-1 text-green-600",children:V.recent_7days})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx("div",{className:"text-sm text-muted-foreground",children:"关联聊天数"}),a.jsx("div",{className:"text-2xl font-bold mt-1 text-blue-600",children:V.chat_count})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx(te,{htmlFor:"search",children:"搜索"}),a.jsx("div",{className:"flex flex-col sm:flex-row gap-2 mt-1.5",children:a.jsxs("div",{className:"flex-1 relative",children:[a.jsx(Ps,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{id:"search",placeholder:"搜索情境、风格或上下文...",value:m,onChange:$=>p($.target.value),className:"pl-9"})]})}),a.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mt-4 pt-4 border-t",children:[a.jsx("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:E.size>0&&a.jsxs("span",{children:["已选择 ",E.size," 个表达方式"]})}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(te,{htmlFor:"page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),a.jsxs(Bt,{value:d.toString(),onValueChange:$=>{h(parseInt($)),c(1),z(new Set)},children:[a.jsx(Dt,{id:"page-size",className:"w-20",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"10",children:"10"}),a.jsx(Pe,{value:"20",children:"20"}),a.jsx(Pe,{value:"50",children:"50"}),a.jsx(Pe,{value:"100",children:"100"})]})]}),E.size>0&&a.jsxs(a.Fragment,{children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>z(new Set),children:"取消选择"}),a.jsxs(ie,{variant:"destructive",size:"sm",onClick:()=>F(!0),children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card",children:[a.jsx("div",{className:"hidden md:block",children:a.jsxs(Ac,{children:[a.jsx(Ec,{children:a.jsxs(xr,{children:[a.jsx(gt,{className:"w-12",children:a.jsx(ss,{checked:E.size===t.length&&t.length>0,onCheckedChange:me})}),a.jsx(gt,{children:"情境"}),a.jsx(gt,{children:"风格"}),a.jsx(gt,{children:"聊天ID"}),a.jsx(gt,{children:"最后活跃"}),a.jsx(gt,{className:"text-right",children:"操作"})]})}),a.jsx(_c,{children:n?a.jsx(xr,{children:a.jsx(it,{colSpan:6,className:"text-center py-8 text-muted-foreground",children:"加载中..."})}):t.length===0?a.jsx(xr,{children:a.jsx(it,{colSpan:6,className:"text-center py-8 text-muted-foreground",children:"暂无数据"})}):t.map($=>a.jsxs(xr,{children:[a.jsx(it,{children:a.jsx(ss,{checked:E.has($.id),onCheckedChange:()=>R($.id)})}),a.jsx(it,{className:"font-medium max-w-xs truncate",children:$.situation}),a.jsx(it,{className:"max-w-xs truncate",children:$.style}),a.jsx(it,{className:"font-mono text-sm",children:$.chat_id}),a.jsx(it,{className:"text-sm text-muted-foreground",children:K($.last_active_time)}),a.jsx(it,{className:"text-right",children:a.jsxs("div",{className:"flex justify-end gap-2",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>ae($),children:[a.jsx(Fi,{className:"h-4 w-4 mr-1"}),"详情"]}),a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>ne($),children:[a.jsx(rd,{className:"h-4 w-4 mr-1"}),"编辑"]}),a.jsxs(ie,{size:"sm",onClick:()=>D($),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"删除"]})]})})]},$.id))})]})}),a.jsx("div",{className:"md:hidden space-y-3 p-4",children:n?a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):t.length===0?a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"暂无数据"}):t.map($=>a.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3 overflow-hidden",children:[a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx(ss,{checked:E.has($.id),onCheckedChange:()=>R($.id),className:"mt-1"}),a.jsxs("div",{className:"min-w-0 flex-1 overflow-hidden space-y-2",children:[a.jsxs("div",{children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"情境"}),a.jsx("h3",{className:"font-semibold text-sm line-clamp-2 w-full break-all",title:$.situation,children:$.situation})]}),a.jsxs("div",{children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"风格"}),a.jsx("p",{className:"text-sm line-clamp-2 w-full break-all",title:$.style,children:$.style})]})]})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[a.jsxs("div",{children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"聊天ID"}),a.jsx("p",{className:"font-mono text-xs truncate",children:$.chat_id})]}),a.jsxs("div",{children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"最后活跃"}),a.jsx("p",{className:"text-xs",children:K($.last_active_time)})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-1 pt-2 border-t overflow-hidden",children:[a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>ae($),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[a.jsx(Fi,{className:"h-3 w-3 mr-1"}),"查看"]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>ne($),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[a.jsx(rd,{className:"h-3 w-3 mr-1"}),"编辑"]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>D($),className:"text-xs px-2 py-1 h-auto flex-shrink-0 text-destructive hover:text-destructive",children:[a.jsx(Ht,{className:"h-3 w-3 mr-1"}),"删除"]})]})]},$.id))}),s>0&&a.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 px-4 py-3 border-t",children:[a.jsxs("div",{className:"text-sm text-muted-foreground",children:["共 ",s," 条记录,第 ",l," / ",Math.ceil(s/d)," 页"]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>c(1),disabled:l===1,className:"hidden sm:flex",children:a.jsx(Xf,{className:"h-4 w-4"})}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>c(l-1),disabled:l===1,children:[a.jsx(Tc,{className:"h-4 w-4 sm:mr-1"}),a.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(Ae,{type:"number",value:B,onChange:$=>U($.target.value),onKeyDown:$=>$.key==="Enter"&&P(),placeholder:l.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(s/d)}),a.jsx(ie,{variant:"outline",size:"sm",onClick:P,disabled:!B,className:"h-8",children:"跳转"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>c(l+1),disabled:l>=Math.ceil(s/d),children:[a.jsx("span",{className:"hidden sm:inline",children:"下一页"}),a.jsx(Mc,{className:"h-4 w-4 sm:ml-1"})]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>c(Math.ceil(s/d)),disabled:l>=Math.ceil(s/d),className:"hidden sm:flex",children:a.jsx(Yf,{className:"h-4 w-4"})})]})]})]})]})}),a.jsx(wde,{expression:x,open:b,onOpenChange:k}),a.jsx(Sde,{open:T,onOpenChange:M,onSuccess:()=>{J(),H(),M(!1)}}),a.jsx(kde,{expression:x,open:O,onOpenChange:j,onSuccess:()=>{J(),H(),j(!1)}}),a.jsx(mn,{open:!!_,onOpenChange:()=>D(null),children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除表达方式 "',_?.situation,'" 吗? 此操作不可撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>_&&ue(_),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"删除"})]})]})}),a.jsx(Ode,{open:Q,onOpenChange:F,onConfirm:Y,count:E.size})]})}function wde({expression:t,open:e,onOpenChange:n}){if(!t)return null;const r=s=>s?new Date(s*1e3).toLocaleString("zh-CN"):"-";return a.jsx(Rr,{open:e,onOpenChange:n,children:a.jsxs(Nr,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"表达方式详情"}),a.jsx(Gr,{children:"查看表达方式的完整信息"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[a.jsx(Mu,{label:"情境",value:t.situation}),a.jsx(Mu,{label:"风格",value:t.style}),a.jsx(Mu,{icon:mg,label:"聊天ID",value:t.chat_id,mono:!0}),a.jsx(Mu,{icon:mg,label:"记录ID",value:t.id.toString(),mono:!0})]}),t.context&&a.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[a.jsx(te,{className:"text-xs text-muted-foreground",children:"上下文"}),a.jsx("p",{className:"mt-1 text-sm whitespace-pre-wrap",children:t.context})]}),t.up_content&&a.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[a.jsx(te,{className:"text-xs text-muted-foreground",children:"上文内容"}),a.jsx("p",{className:"mt-1 text-sm whitespace-pre-wrap",children:t.up_content})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[a.jsx(Mu,{icon:uc,label:"最后活跃",value:r(t.last_active_time)}),a.jsx(Mu,{icon:uc,label:"创建时间",value:r(t.create_date)})]})]}),a.jsx(ps,{children:a.jsx(ie,{onClick:()=>n(!1),children:"关闭"})})]})})}function Mu({icon:t,label:e,value:n,mono:r=!1}){return a.jsxs("div",{className:"space-y-1",children:[a.jsxs(te,{className:"text-xs text-muted-foreground flex items-center gap-1",children:[t&&a.jsx(t,{className:"h-3 w-3"}),e]}),a.jsx("div",{className:ye("text-sm",r&&"font-mono",!n&&"text-muted-foreground"),children:n||"-"})]})}function Sde({open:t,onOpenChange:e,onSuccess:n}){const[r,s]=S.useState({situation:"",style:"",context:"",up_content:"",chat_id:""}),[i,l]=S.useState(!1),{toast:c}=Pr(),d=async()=>{if(!r.situation||!r.style||!r.chat_id){c({title:"验证失败",description:"请填写必填字段:情境、风格和聊天ID",variant:"destructive"});return}try{l(!0),await pde(r),c({title:"创建成功",description:"表达方式已创建"}),s({situation:"",style:"",context:"",up_content:"",chat_id:""}),n()}catch(h){c({title:"创建失败",description:h instanceof Error?h.message:"无法创建表达方式",variant:"destructive"})}finally{l(!1)}};return a.jsx(Rr,{open:t,onOpenChange:e,children:a.jsxs(Nr,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"新增表达方式"}),a.jsx(Gr,{children:"创建新的表达方式记录"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsxs(te,{htmlFor:"situation",children:["情境 ",a.jsx("span",{className:"text-destructive",children:"*"})]}),a.jsx(Ae,{id:"situation",value:r.situation,onChange:h=>s({...r,situation:h.target.value}),placeholder:"描述使用场景"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs(te,{htmlFor:"style",children:["风格 ",a.jsx("span",{className:"text-destructive",children:"*"})]}),a.jsx(Ae,{id:"style",value:r.style,onChange:h=>s({...r,style:h.target.value}),placeholder:"描述表达风格"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs(te,{htmlFor:"chat_id",children:["聊天ID ",a.jsx("span",{className:"text-destructive",children:"*"})]}),a.jsx(Ae,{id:"chat_id",value:r.chat_id,onChange:h=>s({...r,chat_id:h.target.value}),placeholder:"关联的聊天ID"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"context",children:"上下文"}),a.jsx(On,{id:"context",value:r.context,onChange:h=>s({...r,context:h.target.value}),placeholder:"上下文信息(可选)",rows:3})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"up_content",children:"上文内容"}),a.jsx(On,{id:"up_content",value:r.up_content,onChange:h=>s({...r,up_content:h.target.value}),placeholder:"上文内容(可选)",rows:3})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>e(!1),children:"取消"}),a.jsx(ie,{onClick:d,disabled:i,children:i?"创建中...":"创建"})]})]})})}function kde({expression:t,open:e,onOpenChange:n,onSuccess:r}){const[s,i]=S.useState({}),[l,c]=S.useState(!1),{toast:d}=Pr();S.useEffect(()=>{t&&i({situation:t.situation,style:t.style,context:t.context||"",up_content:t.up_content||"",chat_id:t.chat_id})},[t]);const h=async()=>{if(t)try{c(!0),await gde(t.id,s),d({title:"保存成功",description:"表达方式已更新"}),r()}catch(m){d({title:"保存失败",description:m instanceof Error?m.message:"无法更新表达方式",variant:"destructive"})}finally{c(!1)}};return t?a.jsx(Rr,{open:e,onOpenChange:n,children:a.jsxs(Nr,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"编辑表达方式"}),a.jsx(Gr,{children:"修改表达方式的信息"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit_situation",children:"情境"}),a.jsx(Ae,{id:"edit_situation",value:s.situation||"",onChange:m=>i({...s,situation:m.target.value}),placeholder:"描述使用场景"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit_style",children:"风格"}),a.jsx(Ae,{id:"edit_style",value:s.style||"",onChange:m=>i({...s,style:m.target.value}),placeholder:"描述表达风格"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit_chat_id",children:"聊天ID"}),a.jsx(Ae,{id:"edit_chat_id",value:s.chat_id||"",onChange:m=>i({...s,chat_id:m.target.value}),placeholder:"关联的聊天ID"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit_context",children:"上下文"}),a.jsx(On,{id:"edit_context",value:s.context||"",onChange:m=>i({...s,context:m.target.value}),placeholder:"上下文信息",rows:3})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit_up_content",children:"上文内容"}),a.jsx(On,{id:"edit_up_content",value:s.up_content||"",onChange:m=>i({...s,up_content:m.target.value}),placeholder:"上文内容",rows:3})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>n(!1),children:"取消"}),a.jsx(ie,{onClick:h,disabled:l,children:l?"保存中...":"保存"})]})]})}):null}function Ode({open:t,onOpenChange:e,onConfirm:n,count:r}){return a.jsx(mn,{open:t,onOpenChange:e,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认批量删除"}),a.jsxs(un,{children:["您即将删除 ",r," 个表达方式,此操作无法撤销。确定要继续吗?"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:n,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认删除"})]})]})})}const Pd="/api/webui/person";async function jde(t){const e=new URLSearchParams;t.page&&e.append("page",t.page.toString()),t.page_size&&e.append("page_size",t.page_size.toString()),t.search&&e.append("search",t.search),t.is_known!==void 0&&e.append("is_known",t.is_known.toString()),t.platform&&e.append("platform",t.platform);const n=await ot(`${Pd}/list?${e}`,{headers:bt()});if(!n.ok){const r=await n.json();throw new Error(r.detail||"获取人物列表失败")}return n.json()}async function Nde(t){const e=await ot(`${Pd}/${t}`,{headers:bt()});if(!e.ok){const n=await e.json();throw new Error(n.detail||"获取人物详情失败")}return e.json()}async function Cde(t,e){const n=await ot(`${Pd}/${t}`,{method:"PATCH",headers:bt(),body:JSON.stringify(e)});if(!n.ok){const r=await n.json();throw new Error(r.detail||"更新人物信息失败")}return n.json()}async function Tde(t){const e=await ot(`${Pd}/${t}`,{method:"DELETE",headers:bt()});if(!e.ok){const n=await e.json();throw new Error(n.detail||"删除人物信息失败")}return e.json()}async function Mde(){const t=await ot(`${Pd}/stats/summary`,{headers:bt()});if(!t.ok){const e=await t.json();throw new Error(e.detail||"获取统计数据失败")}return t.json()}async function Ade(t){const e=await ot(`${Pd}/batch/delete`,{method:"POST",headers:bt(),body:JSON.stringify({person_ids:t})});if(!e.ok){const n=await e.json();throw new Error(n.detail||"批量删除失败")}return e.json()}function Ede(){const[t,e]=S.useState([]),[n,r]=S.useState(!0),[s,i]=S.useState(0),[l,c]=S.useState(1),[d,h]=S.useState(20),[m,p]=S.useState(""),[x,v]=S.useState(void 0),[b,k]=S.useState(void 0),[O,j]=S.useState(null),[T,M]=S.useState(!1),[_,D]=S.useState(!1),[E,z]=S.useState(null),[Q,F]=S.useState({total:0,known:0,unknown:0,platforms:{}}),[B,U]=S.useState(new Set),[V,ce]=S.useState(!1),[W,J]=S.useState(""),{toast:H}=Pr(),ae=async()=>{try{r(!0);const de=await jde({page:l,page_size:d,search:m||void 0,is_known:x,platform:b});e(de.data),i(de.total)}catch(de){H({title:"加载失败",description:de instanceof Error?de.message:"无法加载人物信息",variant:"destructive"})}finally{r(!1)}},ne=async()=>{try{const de=await Mde();de?.data&&F(de.data)}catch(de){console.error("加载统计数据失败:",de)}};S.useEffect(()=>{ae(),ne()},[l,d,m,x,b]);const ue=async de=>{try{const We=await Nde(de.person_id);j(We.data),M(!0)}catch(We){H({title:"加载详情失败",description:We instanceof Error?We.message:"无法加载人物详情",variant:"destructive"})}},R=de=>{j(de),D(!0)},me=async de=>{try{await Tde(de.person_id),H({title:"删除成功",description:`已删除人物信息: ${de.person_name||de.nickname||de.user_id}`}),z(null),ae(),ne()}catch(We){H({title:"删除失败",description:We instanceof Error?We.message:"无法删除人物信息",variant:"destructive"})}},Y=S.useMemo(()=>Object.keys(Q.platforms),[Q.platforms]),P=de=>{const We=new Set(B);We.has(de)?We.delete(de):We.add(de),U(We)},K=()=>{B.size===t.length&&t.length>0?U(new Set):U(new Set(t.map(de=>de.person_id)))},$=()=>{if(B.size===0){H({title:"未选择任何人物",description:"请先选择要删除的人物",variant:"destructive"});return}ce(!0)},fe=async()=>{try{const de=await Ade(Array.from(B));H({title:"批量删除完成",description:de.message}),U(new Set),ce(!1),ae(),ne()}catch(de){H({title:"批量删除失败",description:de instanceof Error?de.message:"批量删除失败",variant:"destructive"})}},ve=()=>{const de=parseInt(W),We=Math.ceil(s/d);de>=1&&de<=We?(c(de),J("")):H({title:"无效的页码",description:`请输入1-${We}之间的页码`,variant:"destructive"})},Re=de=>de?new Date(de*1e3).toLocaleString("zh-CN"):"-";return a.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[a.jsx("div",{className:"mb-4 sm:mb-6",children:a.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:a.jsxs("div",{children:[a.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[a.jsx(Oq,{className:"h-8 w-8",strokeWidth:2}),"人物信息管理"]}),a.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"管理麦麦认识的所有人物信息"})]})})}),a.jsx(fn,{className:"flex-1",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx("div",{className:"text-sm text-muted-foreground",children:"总人数"}),a.jsx("div",{className:"text-2xl font-bold mt-1",children:Q.total})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx("div",{className:"text-sm text-muted-foreground",children:"已认识"}),a.jsx("div",{className:"text-2xl font-bold mt-1 text-green-600",children:Q.known})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsx("div",{className:"text-sm text-muted-foreground",children:"未认识"}),a.jsx("div",{className:"text-2xl font-bold mt-1 text-muted-foreground",children:Q.unknown})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-4 gap-4",children:[a.jsxs("div",{className:"sm:col-span-2",children:[a.jsx(te,{htmlFor:"search",children:"搜索"}),a.jsxs("div",{className:"relative mt-1.5",children:[a.jsx(Ps,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{id:"search",placeholder:"搜索名称、昵称或用户ID...",value:m,onChange:de=>p(de.target.value),className:"pl-9"})]})]}),a.jsxs("div",{children:[a.jsx(te,{htmlFor:"filter-known",children:"认识状态"}),a.jsxs(Bt,{value:x===void 0?"all":x.toString(),onValueChange:de=>{v(de==="all"?void 0:de==="true"),c(1)},children:[a.jsx(Dt,{id:"filter-known",className:"mt-1.5",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部"}),a.jsx(Pe,{value:"true",children:"已认识"}),a.jsx(Pe,{value:"false",children:"未认识"})]})]})]}),a.jsxs("div",{children:[a.jsx(te,{htmlFor:"filter-platform",children:"平台"}),a.jsxs(Bt,{value:b||"all",onValueChange:de=>{k(de==="all"?void 0:de),c(1)},children:[a.jsx(Dt,{id:"filter-platform",className:"mt-1.5",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部平台"}),Y.map(de=>a.jsxs(Pe,{value:de,children:[de," (",Q.platforms[de],")"]},de))]})]})]})]}),a.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mt-4 pt-4 border-t",children:[a.jsx("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:B.size>0&&a.jsxs("span",{children:["已选择 ",B.size," 个人物"]})}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(te,{htmlFor:"page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),a.jsxs(Bt,{value:d.toString(),onValueChange:de=>{h(parseInt(de)),c(1),U(new Set)},children:[a.jsx(Dt,{id:"page-size",className:"w-20",children:a.jsx(It,{})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"10",children:"10"}),a.jsx(Pe,{value:"20",children:"20"}),a.jsx(Pe,{value:"50",children:"50"}),a.jsx(Pe,{value:"100",children:"100"})]})]}),B.size>0&&a.jsxs(a.Fragment,{children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>U(new Set),children:"取消选择"}),a.jsxs(ie,{variant:"destructive",size:"sm",onClick:$,children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]})]})]}),a.jsxs("div",{className:"rounded-lg border bg-card",children:[a.jsx("div",{className:"hidden md:block",children:a.jsxs(Ac,{children:[a.jsx(Ec,{children:a.jsxs(xr,{children:[a.jsx(gt,{className:"w-12",children:a.jsx(ss,{checked:t.length>0&&B.size===t.length,onCheckedChange:K,"aria-label":"全选"})}),a.jsx(gt,{children:"状态"}),a.jsx(gt,{children:"名称"}),a.jsx(gt,{children:"昵称"}),a.jsx(gt,{children:"平台"}),a.jsx(gt,{children:"用户ID"}),a.jsx(gt,{children:"最后更新"}),a.jsx(gt,{className:"text-right",children:"操作"})]})}),a.jsx(_c,{children:n?a.jsx(xr,{children:a.jsx(it,{colSpan:8,className:"text-center py-8 text-muted-foreground",children:"加载中..."})}):t.length===0?a.jsx(xr,{children:a.jsx(it,{colSpan:8,className:"text-center py-8 text-muted-foreground",children:"暂无数据"})}):t.map(de=>a.jsxs(xr,{children:[a.jsx(it,{children:a.jsx(ss,{checked:B.has(de.person_id),onCheckedChange:()=>P(de.person_id),"aria-label":`选择 ${de.person_name||de.nickname||de.user_id}`})}),a.jsx(it,{children:a.jsx("div",{className:ye("inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium",de.is_known?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400"),children:de.is_known?"已认识":"未认识"})}),a.jsx(it,{className:"font-medium",children:de.person_name||a.jsx("span",{className:"text-muted-foreground",children:"-"})}),a.jsx(it,{children:de.nickname||"-"}),a.jsx(it,{children:de.platform}),a.jsx(it,{className:"font-mono text-sm",children:de.user_id}),a.jsx(it,{className:"text-sm text-muted-foreground",children:Re(de.last_know)}),a.jsx(it,{className:"text-right",children:a.jsxs("div",{className:"flex justify-end gap-2",children:[a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>ue(de),children:[a.jsx(Fi,{className:"h-4 w-4 mr-1"}),"详情"]}),a.jsxs(ie,{variant:"default",size:"sm",onClick:()=>R(de),children:[a.jsx(rd,{className:"h-4 w-4 mr-1"}),"编辑"]}),a.jsxs(ie,{size:"sm",onClick:()=>z(de),className:"bg-red-600 hover:bg-red-700 text-white",children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"删除"]})]})})]},de.id))})]})}),a.jsx("div",{className:"md:hidden space-y-3 p-4",children:n?a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):t.length===0?a.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"暂无数据"}):t.map(de=>a.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3 overflow-hidden",children:[a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx(ss,{checked:B.has(de.person_id),onCheckedChange:()=>P(de.person_id),className:"mt-1"}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:ye("inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium mb-2",de.is_known?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400"),children:de.is_known?"已认识":"未认识"}),a.jsx("h3",{className:"font-semibold text-sm line-clamp-1 w-full break-all",children:de.person_name||a.jsx("span",{className:"text-muted-foreground",children:"未命名"})}),de.nickname&&a.jsxs("p",{className:"text-xs text-muted-foreground mt-1 line-clamp-1 w-full break-all",children:["昵称: ",de.nickname]})]})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[a.jsxs("div",{children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"平台"}),a.jsx("p",{className:"font-medium text-xs",children:de.platform})]}),a.jsxs("div",{children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"用户ID"}),a.jsx("p",{className:"font-mono text-xs truncate",title:de.user_id,children:de.user_id})]}),a.jsxs("div",{className:"col-span-2",children:[a.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"最后更新"}),a.jsx("p",{className:"text-xs",children:Re(de.last_know)})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-1 pt-2 border-t overflow-hidden",children:[a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>ue(de),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[a.jsx(Fi,{className:"h-3 w-3 mr-1"}),"查看"]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>R(de),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[a.jsx(rd,{className:"h-3 w-3 mr-1"}),"编辑"]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>z(de),className:"text-xs px-2 py-1 h-auto flex-shrink-0 text-destructive hover:text-destructive",children:[a.jsx(Ht,{className:"h-3 w-3 mr-1"}),"删除"]})]})]},de.id))}),s>0&&a.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 px-4 py-3 border-t",children:[a.jsxs("div",{className:"text-sm text-muted-foreground",children:["共 ",s," 条记录,第 ",l," / ",Math.ceil(s/d)," 页"]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>c(1),disabled:l===1,className:"hidden sm:flex",children:a.jsx(Xf,{className:"h-4 w-4"})}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>c(l-1),disabled:l===1,children:[a.jsx(Tc,{className:"h-4 w-4 sm:mr-1"}),a.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(Ae,{type:"number",value:W,onChange:de=>J(de.target.value),onKeyDown:de=>de.key==="Enter"&&ve(),placeholder:l.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(s/d)}),a.jsx(ie,{variant:"outline",size:"sm",onClick:ve,disabled:!W,className:"h-8",children:"跳转"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:()=>c(l+1),disabled:l>=Math.ceil(s/d),children:[a.jsx("span",{className:"hidden sm:inline",children:"下一页"}),a.jsx(Mc,{className:"h-4 w-4 sm:ml-1"})]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>c(Math.ceil(s/d)),disabled:l>=Math.ceil(s/d),className:"hidden sm:flex",children:a.jsx(Yf,{className:"h-4 w-4"})})]})]})]})]})}),a.jsx(_de,{person:O,open:T,onOpenChange:M}),a.jsx(Dde,{person:O,open:_,onOpenChange:D,onSuccess:()=>{ae(),ne(),D(!1)}}),a.jsx(mn,{open:!!E,onOpenChange:()=>z(null),children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认删除"}),a.jsxs(un,{children:['确定要删除人物信息 "',E?.person_name||E?.nickname||E?.user_id,'" 吗? 此操作不可撤销。']})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:()=>E&&me(E),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"删除"})]})]})}),a.jsx(mn,{open:V,onOpenChange:ce,children:a.jsxs(an,{children:[a.jsxs(ln,{children:[a.jsx(cn,{children:"确认批量删除"}),a.jsxs(un,{children:["确定要删除选中的 ",B.size," 个人物信息吗? 此操作不可撤销。"]})]}),a.jsxs(on,{children:[a.jsx(hn,{children:"取消"}),a.jsx(dn,{onClick:fe,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"批量删除"})]})]})})]})}function _de({person:t,open:e,onOpenChange:n}){if(!t)return null;const r=s=>s?new Date(s*1e3).toLocaleString("zh-CN"):"-";return a.jsx(Rr,{open:e,onOpenChange:n,children:a.jsxs(Nr,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"人物详情"}),a.jsxs(Gr,{children:["查看 ",t.person_name||t.nickname||t.user_id," 的完整信息"]})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[a.jsx(Ka,{icon:D9,label:"人物名称",value:t.person_name}),a.jsx(Ka,{icon:Wf,label:"昵称",value:t.nickname}),a.jsx(Ka,{icon:mg,label:"用户ID",value:t.user_id,mono:!0}),a.jsx(Ka,{icon:mg,label:"人物ID",value:t.person_id,mono:!0}),a.jsx(Ka,{label:"平台",value:t.platform}),a.jsx(Ka,{label:"状态",value:t.is_known?"已认识":"未认识"})]}),t.name_reason&&a.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[a.jsx(te,{className:"text-xs text-muted-foreground",children:"名称设定原因"}),a.jsx("p",{className:"mt-1 text-sm",children:t.name_reason})]}),t.memory_points&&a.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[a.jsx(te,{className:"text-xs text-muted-foreground",children:"个人印象"}),a.jsx("p",{className:"mt-1 text-sm whitespace-pre-wrap",children:t.memory_points})]}),t.group_nick_name&&t.group_nick_name.length>0&&a.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[a.jsx(te,{className:"text-xs text-muted-foreground",children:"群昵称"}),a.jsx("div",{className:"mt-2 space-y-1",children:t.group_nick_name.map((s,i)=>a.jsxs("div",{className:"text-sm flex items-center gap-2",children:[a.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:s.group_id}),a.jsx("span",{children:"→"}),a.jsx("span",{children:s.group_nick_name})]},i))})]}),a.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[a.jsx(Ka,{icon:uc,label:"认识时间",value:r(t.know_times)}),a.jsx(Ka,{icon:uc,label:"首次记录",value:r(t.know_since)}),a.jsx(Ka,{icon:uc,label:"最后更新",value:r(t.last_know)})]})]}),a.jsx(ps,{children:a.jsx(ie,{onClick:()=>n(!1),children:"关闭"})})]})})}function Ka({icon:t,label:e,value:n,mono:r=!1}){return a.jsxs("div",{className:"space-y-1",children:[a.jsxs(te,{className:"text-xs text-muted-foreground flex items-center gap-1",children:[t&&a.jsx(t,{className:"h-3 w-3"}),e]}),a.jsx("div",{className:ye("text-sm",r&&"font-mono",!n&&"text-muted-foreground"),children:n||"-"})]})}function Dde({person:t,open:e,onOpenChange:n,onSuccess:r}){const[s,i]=S.useState({}),[l,c]=S.useState(!1),{toast:d}=Pr();S.useEffect(()=>{t&&i({person_name:t.person_name||"",name_reason:t.name_reason||"",nickname:t.nickname||"",memory_points:t.memory_points||"",is_known:t.is_known})},[t]);const h=async()=>{if(t)try{c(!0),await Cde(t.person_id,s),d({title:"保存成功",description:"人物信息已更新"}),r()}catch(m){d({title:"保存失败",description:m instanceof Error?m.message:"无法更新人物信息",variant:"destructive"})}finally{c(!1)}};return t?a.jsx(Rr,{open:e,onOpenChange:n,children:a.jsxs(Nr,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"编辑人物信息"}),a.jsxs(Gr,{children:["修改 ",t.person_name||t.nickname||t.user_id," 的信息"]})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"person_name",children:"人物名称"}),a.jsx(Ae,{id:"person_name",value:s.person_name||"",onChange:m=>i({...s,person_name:m.target.value}),placeholder:"为这个人设置一个名称"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"nickname",children:"昵称"}),a.jsx(Ae,{id:"nickname",value:s.nickname||"",onChange:m=>i({...s,nickname:m.target.value}),placeholder:"昵称"})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"name_reason",children:"名称设定原因"}),a.jsx(On,{id:"name_reason",value:s.name_reason||"",onChange:m=>i({...s,name_reason:m.target.value}),placeholder:"为什么这样称呼这个人?",rows:2})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"memory_points",children:"个人印象"}),a.jsx(On,{id:"memory_points",value:s.memory_points||"",onChange:m=>i({...s,memory_points:m.target.value}),placeholder:"对这个人的印象和记忆点...",rows:4})]}),a.jsxs("div",{className:"flex items-center justify-between rounded-lg border p-3",children:[a.jsxs("div",{children:[a.jsx(te,{htmlFor:"is_known",className:"text-base font-medium",children:"已认识"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"标记是否已经认识这个人"})]}),a.jsx(jt,{id:"is_known",checked:s.is_known,onCheckedChange:m=>i({...s,is_known:m})})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>n(!1),children:"取消"}),a.jsx(ie,{onClick:h,disabled:l,children:l?"保存中...":"保存"})]})]})}):null}function Rde(t,e,n="long"){return new Intl.DateTimeFormat("en-US",{hour:"numeric",timeZone:t,timeZoneName:n}).format(e).split(/\s/g).slice(2).join(" ")}const zde={},Wh={};function cc(t,e){try{const r=(zde[t]||=new Intl.DateTimeFormat("en-US",{timeZone:t,timeZoneName:"longOffset"}).format)(e).split("GMT")[1];return r in Wh?Wh[r]:VN(r,r.split(":"))}catch{if(t in Wh)return Wh[t];const n=t?.match(Pde);return n?VN(t,n.slice(1)):NaN}}const Pde=/([+-]\d\d):?(\d\d)?/;function VN(t,e){const n=+(e[0]||0),r=+(e[1]||0),s=+(e[2]||0)/60;return Wh[t]=n*60+r>0?n*60+r+s:n*60-r-s}class ga extends Date{constructor(...e){super(),e.length>1&&typeof e[e.length-1]=="string"&&(this.timeZone=e.pop()),this.internal=new Date,isNaN(cc(this.timeZone,this))?this.setTime(NaN):e.length?typeof e[0]=="number"&&(e.length===1||e.length===2&&typeof e[1]!="number")?this.setTime(e[0]):typeof e[0]=="string"?this.setTime(+new Date(e[0])):e[0]instanceof Date?this.setTime(+e[0]):(this.setTime(+new Date(...e)),lz(this),R4(this)):this.setTime(Date.now())}static tz(e,...n){return n.length?new ga(...n,e):new ga(Date.now(),e)}withTimeZone(e){return new ga(+this,e)}getTimezoneOffset(){const e=-cc(this.timeZone,this);return e>0?Math.floor(e):Math.ceil(e)}setTime(e){return Date.prototype.setTime.apply(this,arguments),R4(this),+this}[Symbol.for("constructDateFrom")](e){return new ga(+new Date(e),this.timeZone)}}const WN=/^(get|set)(?!UTC)/;Object.getOwnPropertyNames(Date.prototype).forEach(t=>{if(!WN.test(t))return;const e=t.replace(WN,"$1UTC");ga.prototype[e]&&(t.startsWith("get")?ga.prototype[t]=function(){return this.internal[e]()}:(ga.prototype[t]=function(){return Date.prototype[e].apply(this.internal,arguments),Lde(this),+this},ga.prototype[e]=function(){return Date.prototype[e].apply(this,arguments),R4(this),+this}))});function R4(t){t.internal.setTime(+t),t.internal.setUTCSeconds(t.internal.getUTCSeconds()-Math.round(-cc(t.timeZone,t)*60))}function Lde(t){Date.prototype.setFullYear.call(t,t.internal.getUTCFullYear(),t.internal.getUTCMonth(),t.internal.getUTCDate()),Date.prototype.setHours.call(t,t.internal.getUTCHours(),t.internal.getUTCMinutes(),t.internal.getUTCSeconds(),t.internal.getUTCMilliseconds()),lz(t)}function lz(t){const e=cc(t.timeZone,t),n=e>0?Math.floor(e):Math.ceil(e),r=new Date(+t);r.setUTCHours(r.getUTCHours()-1);const s=-new Date(+t).getTimezoneOffset(),i=-new Date(+r).getTimezoneOffset(),l=s-i,c=Date.prototype.getHours.apply(t)!==t.internal.getUTCHours();l&&c&&t.internal.setUTCMinutes(t.internal.getUTCMinutes()+l);const d=s-n;d&&Date.prototype.setUTCMinutes.call(t,Date.prototype.getUTCMinutes.call(t)+d);const h=new Date(+t);h.setUTCSeconds(0);const m=s>0?h.getSeconds():(h.getSeconds()-60)%60,p=Math.round(-(cc(t.timeZone,t)*60))%60;(p||m)&&(t.internal.setUTCSeconds(t.internal.getUTCSeconds()+p),Date.prototype.setUTCSeconds.call(t,Date.prototype.getUTCSeconds.call(t)+p+m));const x=cc(t.timeZone,t),v=x>0?Math.floor(x):Math.ceil(x),k=-new Date(+t).getTimezoneOffset()-v,O=v!==n,j=k-d;if(O&&j){Date.prototype.setUTCMinutes.call(t,Date.prototype.getUTCMinutes.call(t)+j);const T=cc(t.timeZone,t),M=T>0?Math.floor(T):Math.ceil(T),_=v-M;_&&(t.internal.setUTCMinutes(t.internal.getUTCMinutes()+_),Date.prototype.setUTCMinutes.call(t,Date.prototype.getUTCMinutes.call(t)+_))}}class Zr extends ga{static tz(e,...n){return n.length?new Zr(...n,e):new Zr(Date.now(),e)}toISOString(){const[e,n,r]=this.tzComponents(),s=`${e}${n}:${r}`;return this.internal.toISOString().slice(0,-1)+s}toString(){return`${this.toDateString()} ${this.toTimeString()}`}toDateString(){const[e,n,r,s]=this.internal.toUTCString().split(" ");return`${e?.slice(0,-1)} ${r} ${n} ${s}`}toTimeString(){const e=this.internal.toUTCString().split(" ")[4],[n,r,s]=this.tzComponents();return`${e} GMT${n}${r}${s} (${Rde(this.timeZone,this)})`}toLocaleString(e,n){return Date.prototype.toLocaleString.call(this,e,{...n,timeZone:n?.timeZone||this.timeZone})}toLocaleDateString(e,n){return Date.prototype.toLocaleDateString.call(this,e,{...n,timeZone:n?.timeZone||this.timeZone})}toLocaleTimeString(e,n){return Date.prototype.toLocaleTimeString.call(this,e,{...n,timeZone:n?.timeZone||this.timeZone})}tzComponents(){const e=this.getTimezoneOffset(),n=e>0?"-":"+",r=String(Math.floor(Math.abs(e)/60)).padStart(2,"0"),s=String(Math.abs(e)%60).padStart(2,"0");return[n,r,s]}withTimeZone(e){return new Zr(+this,e)}[Symbol.for("constructDateFrom")](e){return new Zr(+new Date(e),this.timeZone)}}const oz=6048e5,Bde=864e5,GN=Symbol.for("constructDateFrom");function vr(t,e){return typeof t=="function"?t(e):t&&typeof t=="object"&&GN in t?t[GN](e):t instanceof Date?new t.constructor(e):new Date(e)}function Nn(t,e){return vr(e||t,t)}function cz(t,e,n){const r=Nn(t,n?.in);return isNaN(e)?vr(t,NaN):(e&&r.setDate(r.getDate()+e),r)}function uz(t,e,n){const r=Nn(t,n?.in);if(isNaN(e))return vr(t,NaN);if(!e)return r;const s=r.getDate(),i=vr(t,r.getTime());i.setMonth(r.getMonth()+e+1,0);const l=i.getDate();return s>=l?i:(r.setFullYear(i.getFullYear(),i.getMonth(),s),r)}let Ide={};function O0(){return Ide}function wo(t,e){const n=O0(),r=e?.weekStartsOn??e?.locale?.options?.weekStartsOn??n.weekStartsOn??n.locale?.options?.weekStartsOn??0,s=Nn(t,e?.in),i=s.getDay(),l=(i=i.getTime()?r+1:n.getTime()>=c.getTime()?r:r-1}function XN(t){const e=Nn(t),n=new Date(Date.UTC(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()));return n.setUTCFullYear(e.getFullYear()),+t-+n}function Lc(t,...e){const n=vr.bind(null,t||e.find(r=>typeof r=="object"));return e.map(n)}function Qf(t,e){const n=Nn(t,e?.in);return n.setHours(0,0,0,0),n}function hz(t,e,n){const[r,s]=Lc(n?.in,t,e),i=Qf(r),l=Qf(s),c=+i-XN(i),d=+l-XN(l);return Math.round((c-d)/Bde)}function qde(t,e){const n=dz(t,e),r=vr(t,0);return r.setFullYear(n,0,4),r.setHours(0,0,0,0),Ff(r)}function Fde(t,e,n){return cz(t,e*7,n)}function Qde(t,e,n){return uz(t,e*12,n)}function $de(t,e){let n,r=e?.in;return t.forEach(s=>{!r&&typeof s=="object"&&(r=vr.bind(null,s));const i=Nn(s,r);(!n||n{!r&&typeof s=="object"&&(r=vr.bind(null,s));const i=Nn(s,r);(!n||n>i||isNaN(+i))&&(n=i)}),vr(r,n||NaN)}function Ude(t,e,n){const[r,s]=Lc(n?.in,t,e);return+Qf(r)==+Qf(s)}function fz(t){return t instanceof Date||typeof t=="object"&&Object.prototype.toString.call(t)==="[object Date]"}function Vde(t){return!(!fz(t)&&typeof t!="number"||isNaN(+Nn(t)))}function Wde(t,e,n){const[r,s]=Lc(n?.in,t,e),i=r.getFullYear()-s.getFullYear(),l=r.getMonth()-s.getMonth();return i*12+l}function Gde(t,e){const n=Nn(t,e?.in),r=n.getMonth();return n.setFullYear(n.getFullYear(),r+1,0),n.setHours(23,59,59,999),n}function mz(t,e){const[n,r]=Lc(t,e.start,e.end);return{start:n,end:r}}function Xde(t,e){const{start:n,end:r}=mz(e?.in,t);let s=+n>+r;const i=s?+n:+r,l=s?r:n;l.setHours(0,0,0,0),l.setDate(1);let c=1;const d=[];for(;+l<=i;)d.push(vr(n,l)),l.setMonth(l.getMonth()+c);return s?d.reverse():d}function Yde(t,e){const n=Nn(t,e?.in);return n.setDate(1),n.setHours(0,0,0,0),n}function Kde(t,e){const n=Nn(t,e?.in),r=n.getFullYear();return n.setFullYear(r+1,0,0),n.setHours(23,59,59,999),n}function pz(t,e){const n=Nn(t,e?.in);return n.setFullYear(n.getFullYear(),0,1),n.setHours(0,0,0,0),n}function Zde(t,e){const{start:n,end:r}=mz(e?.in,t);let s=+n>+r;const i=s?+n:+r,l=s?r:n;l.setHours(0,0,0,0),l.setMonth(0,1);let c=1;const d=[];for(;+l<=i;)d.push(vr(n,l)),l.setFullYear(l.getFullYear()+c);return s?d.reverse():d}function gz(t,e){const n=O0(),r=e?.weekStartsOn??e?.locale?.options?.weekStartsOn??n.weekStartsOn??n.locale?.options?.weekStartsOn??0,s=Nn(t,e?.in),i=s.getDay(),l=(i{let r;const s=ehe[t];return typeof s=="string"?r=s:e===1?r=s.one:r=s.other.replace("{{count}}",e.toString()),n?.addSuffix?n.comparison&&n.comparison>0?"in "+r:r+" ago":r};function td(t){return(e={})=>{const n=e.width?String(e.width):t.defaultWidth;return t.formats[n]||t.formats[t.defaultWidth]}}const nhe={full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},rhe={full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},she={full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},ihe={date:td({formats:nhe,defaultWidth:"full"}),time:td({formats:rhe,defaultWidth:"full"}),dateTime:td({formats:she,defaultWidth:"full"})},ahe={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"},lhe=(t,e,n,r)=>ahe[t];function oa(t){return(e,n)=>{const r=n?.context?String(n.context):"standalone";let s;if(r==="formatting"&&t.formattingValues){const l=t.defaultFormattingWidth||t.defaultWidth,c=n?.width?String(n.width):l;s=t.formattingValues[c]||t.formattingValues[l]}else{const l=t.defaultWidth,c=n?.width?String(n.width):t.defaultWidth;s=t.values[c]||t.values[l]}const i=t.argumentCallback?t.argumentCallback(e):e;return s[i]}}const ohe={narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},che={narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},uhe={narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},dhe={narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},hhe={narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},fhe={narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},mhe=(t,e)=>{const n=Number(t),r=n%100;if(r>20||r<10)switch(r%10){case 1:return n+"st";case 2:return n+"nd";case 3:return n+"rd"}return n+"th"},phe={ordinalNumber:mhe,era:oa({values:ohe,defaultWidth:"wide"}),quarter:oa({values:che,defaultWidth:"wide",argumentCallback:t=>t-1}),month:oa({values:uhe,defaultWidth:"wide"}),day:oa({values:dhe,defaultWidth:"wide"}),dayPeriod:oa({values:hhe,defaultWidth:"wide",formattingValues:fhe,defaultFormattingWidth:"wide"})};function ca(t){return(e,n={})=>{const r=n.width,s=r&&t.matchPatterns[r]||t.matchPatterns[t.defaultMatchWidth],i=e.match(s);if(!i)return null;const l=i[0],c=r&&t.parsePatterns[r]||t.parsePatterns[t.defaultParseWidth],d=Array.isArray(c)?xhe(c,p=>p.test(l)):ghe(c,p=>p.test(l));let h;h=t.valueCallback?t.valueCallback(d):d,h=n.valueCallback?n.valueCallback(h):h;const m=e.slice(l.length);return{value:h,rest:m}}}function ghe(t,e){for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&e(t[n]))return n}function xhe(t,e){for(let n=0;n{const r=e.match(t.matchPattern);if(!r)return null;const s=r[0],i=e.match(t.parsePattern);if(!i)return null;let l=t.valueCallback?t.valueCallback(i[0]):i[0];l=n.valueCallback?n.valueCallback(l):l;const c=e.slice(s.length);return{value:l,rest:c}}}const vhe=/^(\d+)(th|st|nd|rd)?/i,yhe=/\d+/i,bhe={narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},whe={any:[/^b/i,/^(a|c)/i]},She={narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},khe={any:[/1/i,/2/i,/3/i,/4/i]},Ohe={narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},jhe={narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},Nhe={narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},Che={narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},The={narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},Mhe={any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},Ahe={ordinalNumber:xz({matchPattern:vhe,parsePattern:yhe,valueCallback:t=>parseInt(t,10)}),era:ca({matchPatterns:bhe,defaultMatchWidth:"wide",parsePatterns:whe,defaultParseWidth:"any"}),quarter:ca({matchPatterns:She,defaultMatchWidth:"wide",parsePatterns:khe,defaultParseWidth:"any",valueCallback:t=>t+1}),month:ca({matchPatterns:Ohe,defaultMatchWidth:"wide",parsePatterns:jhe,defaultParseWidth:"any"}),day:ca({matchPatterns:Nhe,defaultMatchWidth:"wide",parsePatterns:Che,defaultParseWidth:"any"}),dayPeriod:ca({matchPatterns:The,defaultMatchWidth:"any",parsePatterns:Mhe,defaultParseWidth:"any"})},G5={code:"en-US",formatDistance:the,formatLong:ihe,formatRelative:lhe,localize:phe,match:Ahe,options:{weekStartsOn:0,firstWeekContainsDate:1}};function Ehe(t,e){const n=Nn(t,e?.in);return hz(n,pz(n))+1}function vz(t,e){const n=Nn(t,e?.in),r=+Ff(n)-+qde(n);return Math.round(r/oz)+1}function yz(t,e){const n=Nn(t,e?.in),r=n.getFullYear(),s=O0(),i=e?.firstWeekContainsDate??e?.locale?.options?.firstWeekContainsDate??s.firstWeekContainsDate??s.locale?.options?.firstWeekContainsDate??1,l=vr(e?.in||t,0);l.setFullYear(r+1,0,i),l.setHours(0,0,0,0);const c=wo(l,e),d=vr(e?.in||t,0);d.setFullYear(r,0,i),d.setHours(0,0,0,0);const h=wo(d,e);return+n>=+c?r+1:+n>=+h?r:r-1}function _he(t,e){const n=O0(),r=e?.firstWeekContainsDate??e?.locale?.options?.firstWeekContainsDate??n.firstWeekContainsDate??n.locale?.options?.firstWeekContainsDate??1,s=yz(t,e),i=vr(e?.in||t,0);return i.setFullYear(s,0,r),i.setHours(0,0,0,0),wo(i,e)}function bz(t,e){const n=Nn(t,e?.in),r=+wo(n,e)-+_he(n,e);return Math.round(r/oz)+1}function xn(t,e){const n=t<0?"-":"",r=Math.abs(t).toString().padStart(e,"0");return n+r}const Kl={y(t,e){const n=t.getFullYear(),r=n>0?n:1-n;return xn(e==="yy"?r%100:r,e.length)},M(t,e){const n=t.getMonth();return e==="M"?String(n+1):xn(n+1,2)},d(t,e){return xn(t.getDate(),e.length)},a(t,e){const n=t.getHours()/12>=1?"pm":"am";switch(e){case"a":case"aa":return n.toUpperCase();case"aaa":return n;case"aaaaa":return n[0];case"aaaa":default:return n==="am"?"a.m.":"p.m."}},h(t,e){return xn(t.getHours()%12||12,e.length)},H(t,e){return xn(t.getHours(),e.length)},m(t,e){return xn(t.getMinutes(),e.length)},s(t,e){return xn(t.getSeconds(),e.length)},S(t,e){const n=e.length,r=t.getMilliseconds(),s=Math.trunc(r*Math.pow(10,n-3));return xn(s,e.length)}},Au={midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},YN={G:function(t,e,n){const r=t.getFullYear()>0?1:0;switch(e){case"G":case"GG":case"GGG":return n.era(r,{width:"abbreviated"});case"GGGGG":return n.era(r,{width:"narrow"});case"GGGG":default:return n.era(r,{width:"wide"})}},y:function(t,e,n){if(e==="yo"){const r=t.getFullYear(),s=r>0?r:1-r;return n.ordinalNumber(s,{unit:"year"})}return Kl.y(t,e)},Y:function(t,e,n,r){const s=yz(t,r),i=s>0?s:1-s;if(e==="YY"){const l=i%100;return xn(l,2)}return e==="Yo"?n.ordinalNumber(i,{unit:"year"}):xn(i,e.length)},R:function(t,e){const n=dz(t);return xn(n,e.length)},u:function(t,e){const n=t.getFullYear();return xn(n,e.length)},Q:function(t,e,n){const r=Math.ceil((t.getMonth()+1)/3);switch(e){case"Q":return String(r);case"QQ":return xn(r,2);case"Qo":return n.ordinalNumber(r,{unit:"quarter"});case"QQQ":return n.quarter(r,{width:"abbreviated",context:"formatting"});case"QQQQQ":return n.quarter(r,{width:"narrow",context:"formatting"});case"QQQQ":default:return n.quarter(r,{width:"wide",context:"formatting"})}},q:function(t,e,n){const r=Math.ceil((t.getMonth()+1)/3);switch(e){case"q":return String(r);case"qq":return xn(r,2);case"qo":return n.ordinalNumber(r,{unit:"quarter"});case"qqq":return n.quarter(r,{width:"abbreviated",context:"standalone"});case"qqqqq":return n.quarter(r,{width:"narrow",context:"standalone"});case"qqqq":default:return n.quarter(r,{width:"wide",context:"standalone"})}},M:function(t,e,n){const r=t.getMonth();switch(e){case"M":case"MM":return Kl.M(t,e);case"Mo":return n.ordinalNumber(r+1,{unit:"month"});case"MMM":return n.month(r,{width:"abbreviated",context:"formatting"});case"MMMMM":return n.month(r,{width:"narrow",context:"formatting"});case"MMMM":default:return n.month(r,{width:"wide",context:"formatting"})}},L:function(t,e,n){const r=t.getMonth();switch(e){case"L":return String(r+1);case"LL":return xn(r+1,2);case"Lo":return n.ordinalNumber(r+1,{unit:"month"});case"LLL":return n.month(r,{width:"abbreviated",context:"standalone"});case"LLLLL":return n.month(r,{width:"narrow",context:"standalone"});case"LLLL":default:return n.month(r,{width:"wide",context:"standalone"})}},w:function(t,e,n,r){const s=bz(t,r);return e==="wo"?n.ordinalNumber(s,{unit:"week"}):xn(s,e.length)},I:function(t,e,n){const r=vz(t);return e==="Io"?n.ordinalNumber(r,{unit:"week"}):xn(r,e.length)},d:function(t,e,n){return e==="do"?n.ordinalNumber(t.getDate(),{unit:"date"}):Kl.d(t,e)},D:function(t,e,n){const r=Ehe(t);return e==="Do"?n.ordinalNumber(r,{unit:"dayOfYear"}):xn(r,e.length)},E:function(t,e,n){const r=t.getDay();switch(e){case"E":case"EE":case"EEE":return n.day(r,{width:"abbreviated",context:"formatting"});case"EEEEE":return n.day(r,{width:"narrow",context:"formatting"});case"EEEEEE":return n.day(r,{width:"short",context:"formatting"});case"EEEE":default:return n.day(r,{width:"wide",context:"formatting"})}},e:function(t,e,n,r){const s=t.getDay(),i=(s-r.weekStartsOn+8)%7||7;switch(e){case"e":return String(i);case"ee":return xn(i,2);case"eo":return n.ordinalNumber(i,{unit:"day"});case"eee":return n.day(s,{width:"abbreviated",context:"formatting"});case"eeeee":return n.day(s,{width:"narrow",context:"formatting"});case"eeeeee":return n.day(s,{width:"short",context:"formatting"});case"eeee":default:return n.day(s,{width:"wide",context:"formatting"})}},c:function(t,e,n,r){const s=t.getDay(),i=(s-r.weekStartsOn+8)%7||7;switch(e){case"c":return String(i);case"cc":return xn(i,e.length);case"co":return n.ordinalNumber(i,{unit:"day"});case"ccc":return n.day(s,{width:"abbreviated",context:"standalone"});case"ccccc":return n.day(s,{width:"narrow",context:"standalone"});case"cccccc":return n.day(s,{width:"short",context:"standalone"});case"cccc":default:return n.day(s,{width:"wide",context:"standalone"})}},i:function(t,e,n){const r=t.getDay(),s=r===0?7:r;switch(e){case"i":return String(s);case"ii":return xn(s,e.length);case"io":return n.ordinalNumber(s,{unit:"day"});case"iii":return n.day(r,{width:"abbreviated",context:"formatting"});case"iiiii":return n.day(r,{width:"narrow",context:"formatting"});case"iiiiii":return n.day(r,{width:"short",context:"formatting"});case"iiii":default:return n.day(r,{width:"wide",context:"formatting"})}},a:function(t,e,n){const s=t.getHours()/12>=1?"pm":"am";switch(e){case"a":case"aa":return n.dayPeriod(s,{width:"abbreviated",context:"formatting"});case"aaa":return n.dayPeriod(s,{width:"abbreviated",context:"formatting"}).toLowerCase();case"aaaaa":return n.dayPeriod(s,{width:"narrow",context:"formatting"});case"aaaa":default:return n.dayPeriod(s,{width:"wide",context:"formatting"})}},b:function(t,e,n){const r=t.getHours();let s;switch(r===12?s=Au.noon:r===0?s=Au.midnight:s=r/12>=1?"pm":"am",e){case"b":case"bb":return n.dayPeriod(s,{width:"abbreviated",context:"formatting"});case"bbb":return n.dayPeriod(s,{width:"abbreviated",context:"formatting"}).toLowerCase();case"bbbbb":return n.dayPeriod(s,{width:"narrow",context:"formatting"});case"bbbb":default:return n.dayPeriod(s,{width:"wide",context:"formatting"})}},B:function(t,e,n){const r=t.getHours();let s;switch(r>=17?s=Au.evening:r>=12?s=Au.afternoon:r>=4?s=Au.morning:s=Au.night,e){case"B":case"BB":case"BBB":return n.dayPeriod(s,{width:"abbreviated",context:"formatting"});case"BBBBB":return n.dayPeriod(s,{width:"narrow",context:"formatting"});case"BBBB":default:return n.dayPeriod(s,{width:"wide",context:"formatting"})}},h:function(t,e,n){if(e==="ho"){let r=t.getHours()%12;return r===0&&(r=12),n.ordinalNumber(r,{unit:"hour"})}return Kl.h(t,e)},H:function(t,e,n){return e==="Ho"?n.ordinalNumber(t.getHours(),{unit:"hour"}):Kl.H(t,e)},K:function(t,e,n){const r=t.getHours()%12;return e==="Ko"?n.ordinalNumber(r,{unit:"hour"}):xn(r,e.length)},k:function(t,e,n){let r=t.getHours();return r===0&&(r=24),e==="ko"?n.ordinalNumber(r,{unit:"hour"}):xn(r,e.length)},m:function(t,e,n){return e==="mo"?n.ordinalNumber(t.getMinutes(),{unit:"minute"}):Kl.m(t,e)},s:function(t,e,n){return e==="so"?n.ordinalNumber(t.getSeconds(),{unit:"second"}):Kl.s(t,e)},S:function(t,e){return Kl.S(t,e)},X:function(t,e,n){const r=t.getTimezoneOffset();if(r===0)return"Z";switch(e){case"X":return ZN(r);case"XXXX":case"XX":return nc(r);case"XXXXX":case"XXX":default:return nc(r,":")}},x:function(t,e,n){const r=t.getTimezoneOffset();switch(e){case"x":return ZN(r);case"xxxx":case"xx":return nc(r);case"xxxxx":case"xxx":default:return nc(r,":")}},O:function(t,e,n){const r=t.getTimezoneOffset();switch(e){case"O":case"OO":case"OOO":return"GMT"+KN(r,":");case"OOOO":default:return"GMT"+nc(r,":")}},z:function(t,e,n){const r=t.getTimezoneOffset();switch(e){case"z":case"zz":case"zzz":return"GMT"+KN(r,":");case"zzzz":default:return"GMT"+nc(r,":")}},t:function(t,e,n){const r=Math.trunc(+t/1e3);return xn(r,e.length)},T:function(t,e,n){return xn(+t,e.length)}};function KN(t,e=""){const n=t>0?"-":"+",r=Math.abs(t),s=Math.trunc(r/60),i=r%60;return i===0?n+String(s):n+String(s)+e+xn(i,2)}function ZN(t,e){return t%60===0?(t>0?"-":"+")+xn(Math.abs(t)/60,2):nc(t,e)}function nc(t,e=""){const n=t>0?"-":"+",r=Math.abs(t),s=xn(Math.trunc(r/60),2),i=xn(r%60,2);return n+s+e+i}const JN=(t,e)=>{switch(t){case"P":return e.date({width:"short"});case"PP":return e.date({width:"medium"});case"PPP":return e.date({width:"long"});case"PPPP":default:return e.date({width:"full"})}},wz=(t,e)=>{switch(t){case"p":return e.time({width:"short"});case"pp":return e.time({width:"medium"});case"ppp":return e.time({width:"long"});case"pppp":default:return e.time({width:"full"})}},Dhe=(t,e)=>{const n=t.match(/(P+)(p+)?/)||[],r=n[1],s=n[2];if(!s)return JN(t,e);let i;switch(r){case"P":i=e.dateTime({width:"short"});break;case"PP":i=e.dateTime({width:"medium"});break;case"PPP":i=e.dateTime({width:"long"});break;case"PPPP":default:i=e.dateTime({width:"full"});break}return i.replace("{{date}}",JN(r,e)).replace("{{time}}",wz(s,e))},Rhe={p:wz,P:Dhe},zhe=/^D+$/,Phe=/^Y+$/,Lhe=["D","DD","YY","YYYY"];function Bhe(t){return zhe.test(t)}function Ihe(t){return Phe.test(t)}function qhe(t,e,n){const r=Fhe(t,e,n);if(console.warn(r),Lhe.includes(t))throw new RangeError(r)}function Fhe(t,e,n){const r=t[0]==="Y"?"years":"days of the month";return`Use \`${t.toLowerCase()}\` instead of \`${t}\` (in \`${e}\`) for formatting ${r} to the input \`${n}\`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md`}const Qhe=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,$he=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,Hhe=/^'([^]*?)'?$/,Uhe=/''/g,Vhe=/[a-zA-Z]/;function dg(t,e,n){const r=O0(),s=n?.locale??r.locale??G5,i=n?.firstWeekContainsDate??n?.locale?.options?.firstWeekContainsDate??r.firstWeekContainsDate??r.locale?.options?.firstWeekContainsDate??1,l=n?.weekStartsOn??n?.locale?.options?.weekStartsOn??r.weekStartsOn??r.locale?.options?.weekStartsOn??0,c=Nn(t,n?.in);if(!Vde(c))throw new RangeError("Invalid time value");let d=e.match($he).map(m=>{const p=m[0];if(p==="p"||p==="P"){const x=Rhe[p];return x(m,s.formatLong)}return m}).join("").match(Qhe).map(m=>{if(m==="''")return{isToken:!1,value:"'"};const p=m[0];if(p==="'")return{isToken:!1,value:Whe(m)};if(YN[p])return{isToken:!0,value:m};if(p.match(Vhe))throw new RangeError("Format string contains an unescaped latin alphabet character `"+p+"`");return{isToken:!1,value:m}});s.localize.preprocessor&&(d=s.localize.preprocessor(c,d));const h={firstWeekContainsDate:i,weekStartsOn:l,locale:s};return d.map(m=>{if(!m.isToken)return m.value;const p=m.value;(!n?.useAdditionalWeekYearTokens&&Ihe(p)||!n?.useAdditionalDayOfYearTokens&&Bhe(p))&&qhe(p,e,String(t));const x=YN[p[0]];return x(c,p,s.localize,h)}).join("")}function Whe(t){const e=t.match(Hhe);return e?e[1].replace(Uhe,"'"):t}function Ghe(t,e){const n=Nn(t,e?.in),r=n.getFullYear(),s=n.getMonth(),i=vr(n,0);return i.setFullYear(r,s+1,0),i.setHours(0,0,0,0),i.getDate()}function Xhe(t,e){return Nn(t,e?.in).getMonth()}function Yhe(t,e){return Nn(t,e?.in).getFullYear()}function Khe(t,e){return+Nn(t)>+Nn(e)}function Zhe(t,e){return+Nn(t)<+Nn(e)}function Jhe(t,e,n){const[r,s]=Lc(n?.in,t,e);return+wo(r,n)==+wo(s,n)}function efe(t,e,n){const[r,s]=Lc(n?.in,t,e);return r.getFullYear()===s.getFullYear()&&r.getMonth()===s.getMonth()}function tfe(t,e,n){const[r,s]=Lc(n?.in,t,e);return r.getFullYear()===s.getFullYear()}function nfe(t,e,n){const r=Nn(t,n?.in),s=r.getFullYear(),i=r.getDate(),l=vr(t,0);l.setFullYear(s,e,15),l.setHours(0,0,0,0);const c=Ghe(l);return r.setMonth(e,Math.min(i,c)),r}function rfe(t,e,n){const r=Nn(t,n?.in);return isNaN(+r)?vr(t,NaN):(r.setFullYear(e),r)}const e9=5,sfe=4;function ife(t,e){const n=e.startOfMonth(t),r=n.getDay()>0?n.getDay():7,s=e.addDays(t,-r+1),i=e.addDays(s,e9*7-1);return e.getMonth(t)===e.getMonth(i)?e9:sfe}function Sz(t,e){const n=e.startOfMonth(t),r=n.getDay();return r===1?n:r===0?e.addDays(n,-6):e.addDays(n,-1*(r-1))}function afe(t,e){const n=Sz(t,e),r=ife(t,e);return e.addDays(n,r*7-1)}class ii{constructor(e,n){this.Date=Date,this.today=()=>this.overrides?.today?this.overrides.today():this.options.timeZone?Zr.tz(this.options.timeZone):new this.Date,this.newDate=(r,s,i)=>this.overrides?.newDate?this.overrides.newDate(r,s,i):this.options.timeZone?new Zr(r,s,i,this.options.timeZone):new Date(r,s,i),this.addDays=(r,s)=>this.overrides?.addDays?this.overrides.addDays(r,s):cz(r,s),this.addMonths=(r,s)=>this.overrides?.addMonths?this.overrides.addMonths(r,s):uz(r,s),this.addWeeks=(r,s)=>this.overrides?.addWeeks?this.overrides.addWeeks(r,s):Fde(r,s),this.addYears=(r,s)=>this.overrides?.addYears?this.overrides.addYears(r,s):Qde(r,s),this.differenceInCalendarDays=(r,s)=>this.overrides?.differenceInCalendarDays?this.overrides.differenceInCalendarDays(r,s):hz(r,s),this.differenceInCalendarMonths=(r,s)=>this.overrides?.differenceInCalendarMonths?this.overrides.differenceInCalendarMonths(r,s):Wde(r,s),this.eachMonthOfInterval=r=>this.overrides?.eachMonthOfInterval?this.overrides.eachMonthOfInterval(r):Xde(r),this.eachYearOfInterval=r=>{const s=this.overrides?.eachYearOfInterval?this.overrides.eachYearOfInterval(r):Zde(r),i=new Set(s.map(c=>this.getYear(c)));if(i.size===s.length)return s;const l=[];return i.forEach(c=>{l.push(new Date(c,0,1))}),l},this.endOfBroadcastWeek=r=>this.overrides?.endOfBroadcastWeek?this.overrides.endOfBroadcastWeek(r):afe(r,this),this.endOfISOWeek=r=>this.overrides?.endOfISOWeek?this.overrides.endOfISOWeek(r):Jde(r),this.endOfMonth=r=>this.overrides?.endOfMonth?this.overrides.endOfMonth(r):Gde(r),this.endOfWeek=(r,s)=>this.overrides?.endOfWeek?this.overrides.endOfWeek(r,s):gz(r,this.options),this.endOfYear=r=>this.overrides?.endOfYear?this.overrides.endOfYear(r):Kde(r),this.format=(r,s,i)=>{const l=this.overrides?.format?this.overrides.format(r,s,this.options):dg(r,s,this.options);return this.options.numerals&&this.options.numerals!=="latn"?this.replaceDigits(l):l},this.getISOWeek=r=>this.overrides?.getISOWeek?this.overrides.getISOWeek(r):vz(r),this.getMonth=(r,s)=>this.overrides?.getMonth?this.overrides.getMonth(r,this.options):Xhe(r,this.options),this.getYear=(r,s)=>this.overrides?.getYear?this.overrides.getYear(r,this.options):Yhe(r,this.options),this.getWeek=(r,s)=>this.overrides?.getWeek?this.overrides.getWeek(r,this.options):bz(r,this.options),this.isAfter=(r,s)=>this.overrides?.isAfter?this.overrides.isAfter(r,s):Khe(r,s),this.isBefore=(r,s)=>this.overrides?.isBefore?this.overrides.isBefore(r,s):Zhe(r,s),this.isDate=r=>this.overrides?.isDate?this.overrides.isDate(r):fz(r),this.isSameDay=(r,s)=>this.overrides?.isSameDay?this.overrides.isSameDay(r,s):Ude(r,s),this.isSameMonth=(r,s)=>this.overrides?.isSameMonth?this.overrides.isSameMonth(r,s):efe(r,s),this.isSameYear=(r,s)=>this.overrides?.isSameYear?this.overrides.isSameYear(r,s):tfe(r,s),this.max=r=>this.overrides?.max?this.overrides.max(r):$de(r),this.min=r=>this.overrides?.min?this.overrides.min(r):Hde(r),this.setMonth=(r,s)=>this.overrides?.setMonth?this.overrides.setMonth(r,s):nfe(r,s),this.setYear=(r,s)=>this.overrides?.setYear?this.overrides.setYear(r,s):rfe(r,s),this.startOfBroadcastWeek=(r,s)=>this.overrides?.startOfBroadcastWeek?this.overrides.startOfBroadcastWeek(r,this):Sz(r,this),this.startOfDay=r=>this.overrides?.startOfDay?this.overrides.startOfDay(r):Qf(r),this.startOfISOWeek=r=>this.overrides?.startOfISOWeek?this.overrides.startOfISOWeek(r):Ff(r),this.startOfMonth=r=>this.overrides?.startOfMonth?this.overrides.startOfMonth(r):Yde(r),this.startOfWeek=(r,s)=>this.overrides?.startOfWeek?this.overrides.startOfWeek(r,this.options):wo(r,this.options),this.startOfYear=r=>this.overrides?.startOfYear?this.overrides.startOfYear(r):pz(r),this.options={locale:G5,...e},this.overrides=n}getDigitMap(){const{numerals:e="latn"}=this.options,n=new Intl.NumberFormat("en-US",{numberingSystem:e}),r={};for(let s=0;s<10;s++)r[s.toString()]=n.format(s);return r}replaceDigits(e){const n=this.getDigitMap();return e.replace(/\d/g,r=>n[r]||r)}formatNumber(e){return this.replaceDigits(e.toString())}getMonthYearOrder(){const e=this.options.locale?.code;return e&&ii.yearFirstLocales.has(e)?"year-first":"month-first"}formatMonthYear(e){const{locale:n,timeZone:r,numerals:s}=this.options,i=n?.code;if(i&&ii.yearFirstLocales.has(i))try{return new Intl.DateTimeFormat(i,{month:"long",year:"numeric",timeZone:r,numberingSystem:s}).format(e)}catch{}const l=this.getMonthYearOrder()==="year-first"?"y LLLL":"LLLL y";return this.format(e,l)}}ii.yearFirstLocales=new Set(["eu","hu","ja","ja-Hira","ja-JP","ko","ko-KR","lt","lt-LT","lv","lv-LV","mn","mn-MN","zh","zh-CN","zh-HK","zh-TW"]);const Ma=new ii;class kz{constructor(e,n,r=Ma){this.date=e,this.displayMonth=n,this.outside=!!(n&&!r.isSameMonth(e,n)),this.dateLib=r}isEqualTo(e){return this.dateLib.isSameDay(e.date,this.date)&&this.dateLib.isSameMonth(e.displayMonth,this.displayMonth)}}class lfe{constructor(e,n){this.date=e,this.weeks=n}}class ofe{constructor(e,n){this.days=n,this.weekNumber=e}}function cfe(t){return Ue.createElement("button",{...t})}function ufe(t){return Ue.createElement("span",{...t})}function dfe(t){const{size:e=24,orientation:n="left",className:r}=t;return Ue.createElement("svg",{className:r,width:e,height:e,viewBox:"0 0 24 24"},n==="up"&&Ue.createElement("polygon",{points:"6.77 17 12.5 11.43 18.24 17 20 15.28 12.5 8 5 15.28"}),n==="down"&&Ue.createElement("polygon",{points:"6.77 8 12.5 13.57 18.24 8 20 9.72 12.5 17 5 9.72"}),n==="left"&&Ue.createElement("polygon",{points:"16 18.112 9.81111111 12 16 5.87733333 14.0888889 4 6 12 14.0888889 20"}),n==="right"&&Ue.createElement("polygon",{points:"8 18.112 14.18888889 12 8 5.87733333 9.91111111 4 18 12 9.91111111 20"}))}function hfe(t){const{day:e,modifiers:n,...r}=t;return Ue.createElement("td",{...r})}function ffe(t){const{day:e,modifiers:n,...r}=t,s=Ue.useRef(null);return Ue.useEffect(()=>{n.focused&&s.current?.focus()},[n.focused]),Ue.createElement("button",{ref:s,...r})}var et;(function(t){t.Root="root",t.Chevron="chevron",t.Day="day",t.DayButton="day_button",t.CaptionLabel="caption_label",t.Dropdowns="dropdowns",t.Dropdown="dropdown",t.DropdownRoot="dropdown_root",t.Footer="footer",t.MonthGrid="month_grid",t.MonthCaption="month_caption",t.MonthsDropdown="months_dropdown",t.Month="month",t.Months="months",t.Nav="nav",t.NextMonthButton="button_next",t.PreviousMonthButton="button_previous",t.Week="week",t.Weeks="weeks",t.Weekday="weekday",t.Weekdays="weekdays",t.WeekNumber="week_number",t.WeekNumberHeader="week_number_header",t.YearsDropdown="years_dropdown"})(et||(et={}));var Yn;(function(t){t.disabled="disabled",t.hidden="hidden",t.outside="outside",t.focused="focused",t.today="today"})(Yn||(Yn={}));var Bi;(function(t){t.range_end="range_end",t.range_middle="range_middle",t.range_start="range_start",t.selected="selected"})(Bi||(Bi={}));var ei;(function(t){t.weeks_before_enter="weeks_before_enter",t.weeks_before_exit="weeks_before_exit",t.weeks_after_enter="weeks_after_enter",t.weeks_after_exit="weeks_after_exit",t.caption_after_enter="caption_after_enter",t.caption_after_exit="caption_after_exit",t.caption_before_enter="caption_before_enter",t.caption_before_exit="caption_before_exit"})(ei||(ei={}));function mfe(t){const{options:e,className:n,components:r,classNames:s,...i}=t,l=[s[et.Dropdown],n].join(" "),c=e?.find(({value:d})=>d===i.value);return Ue.createElement("span",{"data-disabled":i.disabled,className:s[et.DropdownRoot]},Ue.createElement(r.Select,{className:l,...i},e?.map(({value:d,label:h,disabled:m})=>Ue.createElement(r.Option,{key:d,value:d,disabled:m},h))),Ue.createElement("span",{className:s[et.CaptionLabel],"aria-hidden":!0},c?.label,Ue.createElement(r.Chevron,{orientation:"down",size:18,className:s[et.Chevron]})))}function pfe(t){return Ue.createElement("div",{...t})}function gfe(t){return Ue.createElement("div",{...t})}function xfe(t){const{calendarMonth:e,displayIndex:n,...r}=t;return Ue.createElement("div",{...r},t.children)}function vfe(t){const{calendarMonth:e,displayIndex:n,...r}=t;return Ue.createElement("div",{...r})}function yfe(t){return Ue.createElement("table",{...t})}function bfe(t){return Ue.createElement("div",{...t})}const Oz=S.createContext(void 0);function j0(){const t=S.useContext(Oz);if(t===void 0)throw new Error("useDayPicker() must be used within a custom component.");return t}function wfe(t){const{components:e}=j0();return Ue.createElement(e.Dropdown,{...t})}function Sfe(t){const{onPreviousClick:e,onNextClick:n,previousMonth:r,nextMonth:s,...i}=t,{components:l,classNames:c,labels:{labelPrevious:d,labelNext:h}}=j0(),m=S.useCallback(x=>{s&&n?.(x)},[s,n]),p=S.useCallback(x=>{r&&e?.(x)},[r,e]);return Ue.createElement("nav",{...i},Ue.createElement(l.PreviousMonthButton,{type:"button",className:c[et.PreviousMonthButton],tabIndex:r?void 0:-1,"aria-disabled":r?void 0:!0,"aria-label":d(r),onClick:p},Ue.createElement(l.Chevron,{disabled:r?void 0:!0,className:c[et.Chevron],orientation:"left"})),Ue.createElement(l.NextMonthButton,{type:"button",className:c[et.NextMonthButton],tabIndex:s?void 0:-1,"aria-disabled":s?void 0:!0,"aria-label":h(s),onClick:m},Ue.createElement(l.Chevron,{disabled:s?void 0:!0,orientation:"right",className:c[et.Chevron]})))}function kfe(t){const{components:e}=j0();return Ue.createElement(e.Button,{...t})}function Ofe(t){return Ue.createElement("option",{...t})}function jfe(t){const{components:e}=j0();return Ue.createElement(e.Button,{...t})}function Nfe(t){const{rootRef:e,...n}=t;return Ue.createElement("div",{...n,ref:e})}function Cfe(t){return Ue.createElement("select",{...t})}function Tfe(t){const{week:e,...n}=t;return Ue.createElement("tr",{...n})}function Mfe(t){return Ue.createElement("th",{...t})}function Afe(t){return Ue.createElement("thead",{"aria-hidden":!0},Ue.createElement("tr",{...t}))}function Efe(t){const{week:e,...n}=t;return Ue.createElement("th",{...n})}function _fe(t){return Ue.createElement("th",{...t})}function Dfe(t){return Ue.createElement("tbody",{...t})}function Rfe(t){const{components:e}=j0();return Ue.createElement(e.Dropdown,{...t})}const zfe=Object.freeze(Object.defineProperty({__proto__:null,Button:cfe,CaptionLabel:ufe,Chevron:dfe,Day:hfe,DayButton:ffe,Dropdown:mfe,DropdownNav:pfe,Footer:gfe,Month:xfe,MonthCaption:vfe,MonthGrid:yfe,Months:bfe,MonthsDropdown:wfe,Nav:Sfe,NextMonthButton:kfe,Option:Ofe,PreviousMonthButton:jfe,Root:Nfe,Select:Cfe,Week:Tfe,WeekNumber:Efe,WeekNumberHeader:_fe,Weekday:Mfe,Weekdays:Afe,Weeks:Dfe,YearsDropdown:Rfe},Symbol.toStringTag,{value:"Module"}));function al(t,e,n=!1,r=Ma){let{from:s,to:i}=t;const{differenceInCalendarDays:l,isSameDay:c}=r;return s&&i?(l(i,s)<0&&([s,i]=[i,s]),l(e,s)>=(n?1:0)&&l(i,e)>=(n?1:0)):!n&&i?c(i,e):!n&&s?c(s,e):!1}function jz(t){return!!(t&&typeof t=="object"&&"before"in t&&"after"in t)}function X5(t){return!!(t&&typeof t=="object"&&"from"in t)}function Nz(t){return!!(t&&typeof t=="object"&&"after"in t)}function Cz(t){return!!(t&&typeof t=="object"&&"before"in t)}function Tz(t){return!!(t&&typeof t=="object"&&"dayOfWeek"in t)}function Mz(t,e){return Array.isArray(t)&&t.every(e.isDate)}function ll(t,e,n=Ma){const r=Array.isArray(e)?e:[e],{isSameDay:s,differenceInCalendarDays:i,isAfter:l}=n;return r.some(c=>{if(typeof c=="boolean")return c;if(n.isDate(c))return s(t,c);if(Mz(c,n))return c.includes(t);if(X5(c))return al(c,t,!1,n);if(Tz(c))return Array.isArray(c.dayOfWeek)?c.dayOfWeek.includes(t.getDay()):c.dayOfWeek===t.getDay();if(jz(c)){const d=i(c.before,t),h=i(c.after,t),m=d>0,p=h<0;return l(c.before,c.after)?p&&m:m||p}return Nz(c)?i(t,c.after)>0:Cz(c)?i(c.before,t)>0:typeof c=="function"?c(t):!1})}function Pfe(t,e,n,r,s){const{disabled:i,hidden:l,modifiers:c,showOutsideDays:d,broadcastCalendar:h,today:m}=e,{isSameDay:p,isSameMonth:x,startOfMonth:v,isBefore:b,endOfMonth:k,isAfter:O}=s,j=n&&v(n),T=r&&k(r),M={[Yn.focused]:[],[Yn.outside]:[],[Yn.disabled]:[],[Yn.hidden]:[],[Yn.today]:[]},_={};for(const D of t){const{date:E,displayMonth:z}=D,Q=!!(z&&!x(E,z)),F=!!(j&&b(E,j)),B=!!(T&&O(E,T)),U=!!(i&&ll(E,i,s)),V=!!(l&&ll(E,l,s))||F||B||!h&&!d&&Q||h&&d===!1&&Q,ce=p(E,m??s.today());Q&&M.outside.push(D),U&&M.disabled.push(D),V&&M.hidden.push(D),ce&&M.today.push(D),c&&Object.keys(c).forEach(W=>{const J=c?.[W];J&&ll(E,J,s)&&(_[W]?_[W].push(D):_[W]=[D])})}return D=>{const E={[Yn.focused]:!1,[Yn.disabled]:!1,[Yn.hidden]:!1,[Yn.outside]:!1,[Yn.today]:!1},z={};for(const Q in M){const F=M[Q];E[Q]=F.some(B=>B===D)}for(const Q in _)z[Q]=_[Q].some(F=>F===D);return{...E,...z}}}function Lfe(t,e,n={}){return Object.entries(t).filter(([,s])=>s===!0).reduce((s,[i])=>(n[i]?s.push(n[i]):e[Yn[i]]?s.push(e[Yn[i]]):e[Bi[i]]&&s.push(e[Bi[i]]),s),[e[et.Day]])}function Bfe(t){return{...zfe,...t}}function Ife(t){const e={"data-mode":t.mode??void 0,"data-required":"required"in t?t.required:void 0,"data-multiple-months":t.numberOfMonths&&t.numberOfMonths>1||void 0,"data-week-numbers":t.showWeekNumber||void 0,"data-broadcast-calendar":t.broadcastCalendar||void 0,"data-nav-layout":t.navLayout||void 0};return Object.entries(t).forEach(([n,r])=>{n.startsWith("data-")&&(e[n]=r)}),e}function Y5(){const t={};for(const e in et)t[et[e]]=`rdp-${et[e]}`;for(const e in Yn)t[Yn[e]]=`rdp-${Yn[e]}`;for(const e in Bi)t[Bi[e]]=`rdp-${Bi[e]}`;for(const e in ei)t[ei[e]]=`rdp-${ei[e]}`;return t}function Az(t,e,n){return(n??new ii(e)).formatMonthYear(t)}const qfe=Az;function Ffe(t,e,n){return(n??new ii(e)).format(t,"d")}function Qfe(t,e=Ma){return e.format(t,"LLLL")}function $fe(t,e,n){return(n??new ii(e)).format(t,"cccccc")}function Hfe(t,e=Ma){return t<10?e.formatNumber(`0${t.toLocaleString()}`):e.formatNumber(`${t.toLocaleString()}`)}function Ufe(){return""}function Ez(t,e=Ma){return e.format(t,"yyyy")}const Vfe=Ez,Wfe=Object.freeze(Object.defineProperty({__proto__:null,formatCaption:Az,formatDay:Ffe,formatMonthCaption:qfe,formatMonthDropdown:Qfe,formatWeekNumber:Hfe,formatWeekNumberHeader:Ufe,formatWeekdayName:$fe,formatYearCaption:Vfe,formatYearDropdown:Ez},Symbol.toStringTag,{value:"Module"}));function Gfe(t){return t?.formatMonthCaption&&!t.formatCaption&&(t.formatCaption=t.formatMonthCaption),t?.formatYearCaption&&!t.formatYearDropdown&&(t.formatYearDropdown=t.formatYearCaption),{...Wfe,...t}}function Xfe(t,e,n,r,s){const{startOfMonth:i,startOfYear:l,endOfYear:c,eachMonthOfInterval:d,getMonth:h}=s;return d({start:l(t),end:c(t)}).map(x=>{const v=r.formatMonthDropdown(x,s),b=h(x),k=e&&xi(n)||!1;return{value:b,label:v,disabled:k}})}function Yfe(t,e={},n={}){let r={...e?.[et.Day]};return Object.entries(t).filter(([,s])=>s===!0).forEach(([s])=>{r={...r,...n?.[s]}}),r}function Kfe(t,e,n){const r=t.today(),s=e?t.startOfISOWeek(r):t.startOfWeek(r),i=[];for(let l=0;l<7;l++){const c=t.addDays(s,l);i.push(c)}return i}function Zfe(t,e,n,r,s=!1){if(!t||!e)return;const{startOfYear:i,endOfYear:l,eachYearOfInterval:c,getYear:d}=r,h=i(t),m=l(e),p=c({start:h,end:m});return s&&p.reverse(),p.map(x=>{const v=n.formatYearDropdown(x,r);return{value:d(x),label:v,disabled:!1}})}function _z(t,e,n,r){let s=(r??new ii(n)).format(t,"PPPP");return e.today&&(s=`Today, ${s}`),e.selected&&(s=`${s}, selected`),s}const Jfe=_z;function Dz(t,e,n){return(n??new ii(e)).formatMonthYear(t)}const e0e=Dz;function t0e(t,e,n,r){let s=(r??new ii(n)).format(t,"PPPP");return e?.today&&(s=`Today, ${s}`),s}function n0e(t){return"Choose the Month"}function r0e(){return""}function s0e(t){return"Go to the Next Month"}function i0e(t){return"Go to the Previous Month"}function a0e(t,e,n){return(n??new ii(e)).format(t,"cccc")}function l0e(t,e){return`Week ${t}`}function o0e(t){return"Week Number"}function c0e(t){return"Choose the Year"}const u0e=Object.freeze(Object.defineProperty({__proto__:null,labelCaption:e0e,labelDay:Jfe,labelDayButton:_z,labelGrid:Dz,labelGridcell:t0e,labelMonthDropdown:n0e,labelNav:r0e,labelNext:s0e,labelPrevious:i0e,labelWeekNumber:l0e,labelWeekNumberHeader:o0e,labelWeekday:a0e,labelYearDropdown:c0e},Symbol.toStringTag,{value:"Module"})),N0=t=>t instanceof HTMLElement?t:null,Ub=t=>[...t.querySelectorAll("[data-animated-month]")??[]],d0e=t=>N0(t.querySelector("[data-animated-month]")),Vb=t=>N0(t.querySelector("[data-animated-caption]")),Wb=t=>N0(t.querySelector("[data-animated-weeks]")),h0e=t=>N0(t.querySelector("[data-animated-nav]")),f0e=t=>N0(t.querySelector("[data-animated-weekdays]"));function m0e(t,e,{classNames:n,months:r,focused:s,dateLib:i}){const l=S.useRef(null),c=S.useRef(r),d=S.useRef(!1);S.useLayoutEffect(()=>{const h=c.current;if(c.current=r,!e||!t.current||!(t.current instanceof HTMLElement)||r.length===0||h.length===0||r.length!==h.length)return;const m=i.isSameMonth(r[0].date,h[0].date),p=i.isAfter(r[0].date,h[0].date),x=p?n[ei.caption_after_enter]:n[ei.caption_before_enter],v=p?n[ei.weeks_after_enter]:n[ei.weeks_before_enter],b=l.current,k=t.current.cloneNode(!0);if(k instanceof HTMLElement?(Ub(k).forEach(M=>{if(!(M instanceof HTMLElement))return;const _=d0e(M);_&&M.contains(_)&&M.removeChild(_);const D=Vb(M);D&&D.classList.remove(x);const E=Wb(M);E&&E.classList.remove(v)}),l.current=k):l.current=null,d.current||m||s)return;const O=b instanceof HTMLElement?Ub(b):[],j=Ub(t.current);if(j?.every(T=>T instanceof HTMLElement)&&O&&O.every(T=>T instanceof HTMLElement)){d.current=!0,t.current.style.isolation="isolate";const T=h0e(t.current);T&&(T.style.zIndex="1"),j.forEach((M,_)=>{const D=O[_];if(!D)return;M.style.position="relative",M.style.overflow="hidden";const E=Vb(M);E&&E.classList.add(x);const z=Wb(M);z&&z.classList.add(v);const Q=()=>{d.current=!1,t.current&&(t.current.style.isolation=""),T&&(T.style.zIndex=""),E&&E.classList.remove(x),z&&z.classList.remove(v),M.style.position="",M.style.overflow="",M.contains(D)&&M.removeChild(D)};D.style.pointerEvents="none",D.style.position="absolute",D.style.overflow="hidden",D.setAttribute("aria-hidden","true");const F=f0e(D);F&&(F.style.opacity="0");const B=Vb(D);B&&(B.classList.add(p?n[ei.caption_before_exit]:n[ei.caption_after_exit]),B.addEventListener("animationend",Q));const U=Wb(D);U&&U.classList.add(p?n[ei.weeks_before_exit]:n[ei.weeks_after_exit]),M.insertBefore(D,M.firstChild)})}})}function p0e(t,e,n,r){const s=t[0],i=t[t.length-1],{ISOWeek:l,fixedWeeks:c,broadcastCalendar:d}=n??{},{addDays:h,differenceInCalendarDays:m,differenceInCalendarMonths:p,endOfBroadcastWeek:x,endOfISOWeek:v,endOfMonth:b,endOfWeek:k,isAfter:O,startOfBroadcastWeek:j,startOfISOWeek:T,startOfWeek:M}=r,_=d?j(s,r):l?T(s):M(s),D=d?x(i):l?v(b(i)):k(b(i)),E=m(D,_),z=p(i,s)+1,Q=[];for(let U=0;U<=E;U++){const V=h(_,U);if(e&&O(V,e))break;Q.push(V)}const B=(d?35:42)*z;if(c&&Q.length{const s=r.weeks.reduce((i,l)=>i.concat(l.days.slice()),e.slice());return n.concat(s.slice())},e.slice())}function x0e(t,e,n,r){const{numberOfMonths:s=1}=n,i=[];for(let l=0;le)break;i.push(c)}return i}function t9(t,e,n,r){const{month:s,defaultMonth:i,today:l=r.today(),numberOfMonths:c=1}=t;let d=s||i||l;const{differenceInCalendarMonths:h,addMonths:m,startOfMonth:p}=r;if(n&&h(n,d){const j=n.broadcastCalendar?p(O,r):n.ISOWeek?x(O):v(O),T=n.broadcastCalendar?i(O):n.ISOWeek?l(c(O)):d(c(O)),M=e.filter(z=>z>=j&&z<=T),_=n.broadcastCalendar?35:42;if(n.fixedWeeks&&M.length<_){const z=e.filter(Q=>{const F=_-M.length;return Q>T&&Q<=s(T,F)});M.push(...z)}const D=M.reduce((z,Q)=>{const F=n.ISOWeek?h(Q):m(Q),B=z.find(V=>V.weekNumber===F),U=new kz(Q,O,r);return B?B.days.push(U):z.push(new ofe(F,[U])),z},[]),E=new lfe(O,D);return k.push(E),k},[]);return n.reverseMonths?b.reverse():b}function y0e(t,e){let{startMonth:n,endMonth:r}=t;const{startOfYear:s,startOfDay:i,startOfMonth:l,endOfMonth:c,addYears:d,endOfYear:h,newDate:m,today:p}=e,{fromYear:x,toYear:v,fromMonth:b,toMonth:k}=t;!n&&b&&(n=b),!n&&x&&(n=e.newDate(x,0,1)),!r&&k&&(r=k),!r&&v&&(r=m(v,11,31));const O=t.captionLayout==="dropdown"||t.captionLayout==="dropdown-years";return n?n=l(n):x?n=m(x,0,1):!n&&O&&(n=s(d(t.today??p(),-100))),r?r=c(r):v?r=m(v,11,31):!r&&O&&(r=h(t.today??p())),[n&&i(n),r&&i(r)]}function b0e(t,e,n,r){if(n.disableNavigation)return;const{pagedNavigation:s,numberOfMonths:i=1}=n,{startOfMonth:l,addMonths:c,differenceInCalendarMonths:d}=r,h=s?i:1,m=l(t);if(!e)return c(m,h);if(!(d(e,t)n.concat(r.weeks.slice()),e.slice())}function Yx(t,e){const[n,r]=S.useState(t);return[e===void 0?n:e,r]}function k0e(t,e){const[n,r]=y0e(t,e),{startOfMonth:s,endOfMonth:i}=e,l=t9(t,n,r,e),[c,d]=Yx(l,t.month?l:void 0);S.useEffect(()=>{const E=t9(t,n,r,e);d(E)},[t.timeZone]);const h=x0e(c,r,t,e),m=p0e(h,t.endMonth?i(t.endMonth):void 0,t,e),p=v0e(h,m,t,e),x=S0e(p),v=g0e(p),b=w0e(c,n,t,e),k=b0e(c,r,t,e),{disableNavigation:O,onMonthChange:j}=t,T=E=>x.some(z=>z.days.some(Q=>Q.isEqualTo(E))),M=E=>{if(O)return;let z=s(E);n&&zs(r)&&(z=s(r)),d(z),j?.(z)};return{months:p,weeks:x,days:v,navStart:n,navEnd:r,previousMonth:b,nextMonth:k,goToMonth:M,goToDay:E=>{T(E)||M(E.date)}}}var sa;(function(t){t[t.Today=0]="Today",t[t.Selected=1]="Selected",t[t.LastFocused=2]="LastFocused",t[t.FocusedModifier=3]="FocusedModifier"})(sa||(sa={}));function n9(t){return!t[Yn.disabled]&&!t[Yn.hidden]&&!t[Yn.outside]}function O0e(t,e,n,r){let s,i=-1;for(const l of t){const c=e(l);n9(c)&&(c[Yn.focused]&&in9(e(l)))),s}function j0e(t,e,n,r,s,i,l){const{ISOWeek:c,broadcastCalendar:d}=i,{addDays:h,addMonths:m,addWeeks:p,addYears:x,endOfBroadcastWeek:v,endOfISOWeek:b,endOfWeek:k,max:O,min:j,startOfBroadcastWeek:T,startOfISOWeek:M,startOfWeek:_}=l;let E={day:h,week:p,month:m,year:x,startOfWeek:z=>d?T(z,l):c?M(z):_(z),endOfWeek:z=>d?v(z):c?b(z):k(z)}[t](n,e==="after"?1:-1);return e==="before"&&r?E=O([r,E]):e==="after"&&s&&(E=j([s,E])),E}function Rz(t,e,n,r,s,i,l,c=0){if(c>365)return;const d=j0e(t,e,n.date,r,s,i,l),h=!!(i.disabled&&ll(d,i.disabled,l)),m=!!(i.hidden&&ll(d,i.hidden,l)),p=d,x=new kz(d,p,l);return!h&&!m?x:Rz(t,e,x,r,s,i,l,c+1)}function N0e(t,e,n,r,s){const{autoFocus:i}=t,[l,c]=S.useState(),d=O0e(e.days,n,r||(()=>!1),l),[h,m]=S.useState(i?d:void 0);return{isFocusTarget:k=>!!d?.isEqualTo(k),setFocused:m,focused:h,blur:()=>{c(h),m(void 0)},moveFocus:(k,O)=>{if(!h)return;const j=Rz(k,O,h,e.navStart,e.navEnd,t,s);j&&(t.disableNavigation&&!e.days.some(M=>M.isEqualTo(j))||(e.goToDay(j),m(j)))}}}function C0e(t,e){const{selected:n,required:r,onSelect:s}=t,[i,l]=Yx(n,s?n:void 0),c=s?n:i,{isSameDay:d}=e,h=v=>c?.some(b=>d(b,v))??!1,{min:m,max:p}=t;return{selected:c,select:(v,b,k)=>{let O=[...c??[]];if(h(v)){if(c?.length===m||r&&c?.length===1)return;O=c?.filter(j=>!d(j,v))}else c?.length===p?O=[v]:O=[...O,v];return s||l(O),s?.(O,v,b,k),O},isSelected:h}}function T0e(t,e,n=0,r=0,s=!1,i=Ma){const{from:l,to:c}=e||{},{isSameDay:d,isAfter:h,isBefore:m}=i;let p;if(!l&&!c)p={from:t,to:n>0?void 0:t};else if(l&&!c)d(l,t)?n===0?p={from:l,to:t}:s?p={from:l,to:void 0}:p=void 0:m(t,l)?p={from:t,to:l}:p={from:l,to:t};else if(l&&c)if(d(l,t)&&d(c,t))s?p={from:l,to:c}:p=void 0;else if(d(l,t))p={from:l,to:n>0?void 0:t};else if(d(c,t))p={from:t,to:n>0?void 0:t};else if(m(t,l))p={from:t,to:c};else if(h(t,l))p={from:l,to:t};else if(h(t,c))p={from:l,to:t};else throw new Error("Invalid range");if(p?.from&&p?.to){const x=i.differenceInCalendarDays(p.to,p.from);r>0&&x>r?p={from:t,to:void 0}:n>1&&xtypeof c!="function").some(c=>typeof c=="boolean"?c:n.isDate(c)?al(t,c,!1,n):Mz(c,n)?c.some(d=>al(t,d,!1,n)):X5(c)?c.from&&c.to?r9(t,{from:c.from,to:c.to},n):!1:Tz(c)?M0e(t,c.dayOfWeek,n):jz(c)?n.isAfter(c.before,c.after)?r9(t,{from:n.addDays(c.after,1),to:n.addDays(c.before,-1)},n):ll(t.from,c,n)||ll(t.to,c,n):Nz(c)||Cz(c)?ll(t.from,c,n)||ll(t.to,c,n):!1))return!0;const l=r.filter(c=>typeof c=="function");if(l.length){let c=t.from;const d=n.differenceInCalendarDays(t.to,t.from);for(let h=0;h<=d;h++){if(l.some(m=>m(c)))return!0;c=n.addDays(c,1)}}return!1}function E0e(t,e){const{disabled:n,excludeDisabled:r,selected:s,required:i,onSelect:l}=t,[c,d]=Yx(s,l?s:void 0),h=l?s:c;return{selected:h,select:(x,v,b)=>{const{min:k,max:O}=t,j=x?T0e(x,h,k,O,i,e):void 0;return r&&n&&j?.from&&j.to&&A0e({from:j.from,to:j.to},n,e)&&(j.from=x,j.to=void 0),l||d(j),l?.(j,x,v,b),j},isSelected:x=>h&&al(h,x,!1,e)}}function _0e(t,e){const{selected:n,required:r,onSelect:s}=t,[i,l]=Yx(n,s?n:void 0),c=s?n:i,{isSameDay:d}=e;return{selected:c,select:(p,x,v)=>{let b=p;return!r&&c&&c&&d(p,c)&&(b=void 0),s||l(b),s?.(b,p,x,v),b},isSelected:p=>c?d(c,p):!1}}function D0e(t,e){const n=_0e(t,e),r=C0e(t,e),s=E0e(t,e);switch(t.mode){case"single":return n;case"multiple":return r;case"range":return s;default:return}}function R0e(t){let e=t;e.timeZone&&(e={...t},e.today&&(e.today=new Zr(e.today,e.timeZone)),e.month&&(e.month=new Zr(e.month,e.timeZone)),e.defaultMonth&&(e.defaultMonth=new Zr(e.defaultMonth,e.timeZone)),e.startMonth&&(e.startMonth=new Zr(e.startMonth,e.timeZone)),e.endMonth&&(e.endMonth=new Zr(e.endMonth,e.timeZone)),e.mode==="single"&&e.selected?e.selected=new Zr(e.selected,e.timeZone):e.mode==="multiple"&&e.selected?e.selected=e.selected?.map(dt=>new Zr(dt,e.timeZone)):e.mode==="range"&&e.selected&&(e.selected={from:e.selected.from?new Zr(e.selected.from,e.timeZone):void 0,to:e.selected.to?new Zr(e.selected.to,e.timeZone):void 0}));const{components:n,formatters:r,labels:s,dateLib:i,locale:l,classNames:c}=S.useMemo(()=>{const dt={...G5,...e.locale};return{dateLib:new ii({locale:dt,weekStartsOn:e.broadcastCalendar?1:e.weekStartsOn,firstWeekContainsDate:e.firstWeekContainsDate,useAdditionalWeekYearTokens:e.useAdditionalWeekYearTokens,useAdditionalDayOfYearTokens:e.useAdditionalDayOfYearTokens,timeZone:e.timeZone,numerals:e.numerals},e.dateLib),components:Bfe(e.components),formatters:Gfe(e.formatters),labels:{...u0e,...e.labels},locale:dt,classNames:{...Y5(),...e.classNames}}},[e.locale,e.broadcastCalendar,e.weekStartsOn,e.firstWeekContainsDate,e.useAdditionalWeekYearTokens,e.useAdditionalDayOfYearTokens,e.timeZone,e.numerals,e.dateLib,e.components,e.formatters,e.labels,e.classNames]),{captionLayout:d,mode:h,navLayout:m,numberOfMonths:p=1,onDayBlur:x,onDayClick:v,onDayFocus:b,onDayKeyDown:k,onDayMouseEnter:O,onDayMouseLeave:j,onNextClick:T,onPrevClick:M,showWeekNumber:_,styles:D}=e,{formatCaption:E,formatDay:z,formatMonthDropdown:Q,formatWeekNumber:F,formatWeekNumberHeader:B,formatWeekdayName:U,formatYearDropdown:V}=r,ce=k0e(e,i),{days:W,months:J,navStart:H,navEnd:ae,previousMonth:ne,nextMonth:ue,goToMonth:R}=ce,me=Pfe(W,e,H,ae,i),{isSelected:Y,select:P,selected:K}=D0e(e,i)??{},{blur:$,focused:fe,isFocusTarget:ve,moveFocus:Re,setFocused:de}=N0e(e,ce,me,Y??(()=>!1),i),{labelDayButton:We,labelGridcell:ct,labelGrid:Oe,labelMonthDropdown:nt,labelNav:ut,labelPrevious:Ct,labelNext:Bn,labelWeekday:Tn,labelWeekNumber:Jn,labelWeekNumberHeader:nn,labelYearDropdown:_t}=s,Yr=S.useMemo(()=>Kfe(i,e.ISOWeek),[i,e.ISOWeek]),In=h!==void 0||v!==void 0,or=S.useCallback(()=>{ne&&(R(ne),M?.(ne))},[ne,R,M]),yn=S.useCallback(()=>{ue&&(R(ue),T?.(ue))},[R,ue,T]),ft=S.useCallback((dt,zn)=>mt=>{mt.preventDefault(),mt.stopPropagation(),de(dt),P?.(dt.date,zn,mt),v?.(dt.date,zn,mt)},[P,v,de]),ee=S.useCallback((dt,zn)=>mt=>{de(dt),b?.(dt.date,zn,mt)},[b,de]),Se=S.useCallback((dt,zn)=>mt=>{$(),x?.(dt.date,zn,mt)},[$,x]),Le=S.useCallback((dt,zn)=>mt=>{const rn={ArrowLeft:[mt.shiftKey?"month":"day",e.dir==="rtl"?"after":"before"],ArrowRight:[mt.shiftKey?"month":"day",e.dir==="rtl"?"before":"after"],ArrowDown:[mt.shiftKey?"year":"week","after"],ArrowUp:[mt.shiftKey?"year":"week","before"],PageUp:[mt.shiftKey?"year":"month","before"],PageDown:[mt.shiftKey?"year":"month","after"],Home:["startOfWeek","before"],End:["endOfWeek","after"]};if(rn[mt.key]){mt.preventDefault(),mt.stopPropagation();const[Ar,Mt]=rn[mt.key];Re(Ar,Mt)}k?.(dt.date,zn,mt)},[Re,k,e.dir]),rt=S.useCallback((dt,zn)=>mt=>{O?.(dt.date,zn,mt)},[O]),Tt=S.useCallback((dt,zn)=>mt=>{j?.(dt.date,zn,mt)},[j]),cr=S.useCallback(dt=>zn=>{const mt=Number(zn.target.value),rn=i.setMonth(i.startOfMonth(dt),mt);R(rn)},[i,R]),Kr=S.useCallback(dt=>zn=>{const mt=Number(zn.target.value),rn=i.setYear(i.startOfMonth(dt),mt);R(rn)},[i,R]),{className:re,style:Me}=S.useMemo(()=>({className:[c[et.Root],e.className].filter(Boolean).join(" "),style:{...D?.[et.Root],...e.style}}),[c,e.className,e.style,D]),pt=Ife(e),vt=S.useRef(null);m0e(vt,!!e.animate,{classNames:c,months:J,focused:fe,dateLib:i});const vs={dayPickerProps:e,selected:K,select:P,isSelected:Y,months:J,nextMonth:ue,previousMonth:ne,goToMonth:R,getModifiers:me,components:n,classNames:c,styles:D,labels:s,formatters:r};return Ue.createElement(Oz.Provider,{value:vs},Ue.createElement(n.Root,{rootRef:e.animate?vt:void 0,className:re,style:Me,dir:e.dir,id:e.id,lang:e.lang,nonce:e.nonce,title:e.title,role:e.role,"aria-label":e["aria-label"],"aria-labelledby":e["aria-labelledby"],...pt},Ue.createElement(n.Months,{className:c[et.Months],style:D?.[et.Months]},!e.hideNavigation&&!m&&Ue.createElement(n.Nav,{"data-animated-nav":e.animate?"true":void 0,className:c[et.Nav],style:D?.[et.Nav],"aria-label":ut(),onPreviousClick:or,onNextClick:yn,previousMonth:ne,nextMonth:ue}),J.map((dt,zn)=>Ue.createElement(n.Month,{"data-animated-month":e.animate?"true":void 0,className:c[et.Month],style:D?.[et.Month],key:zn,displayIndex:zn,calendarMonth:dt},m==="around"&&!e.hideNavigation&&zn===0&&Ue.createElement(n.PreviousMonthButton,{type:"button",className:c[et.PreviousMonthButton],tabIndex:ne?void 0:-1,"aria-disabled":ne?void 0:!0,"aria-label":Ct(ne),onClick:or,"data-animated-button":e.animate?"true":void 0},Ue.createElement(n.Chevron,{disabled:ne?void 0:!0,className:c[et.Chevron],orientation:e.dir==="rtl"?"right":"left"})),Ue.createElement(n.MonthCaption,{"data-animated-caption":e.animate?"true":void 0,className:c[et.MonthCaption],style:D?.[et.MonthCaption],calendarMonth:dt,displayIndex:zn},d?.startsWith("dropdown")?Ue.createElement(n.DropdownNav,{className:c[et.Dropdowns],style:D?.[et.Dropdowns]},(()=>{const mt=d==="dropdown"||d==="dropdown-months"?Ue.createElement(n.MonthsDropdown,{key:"month",className:c[et.MonthsDropdown],"aria-label":nt(),classNames:c,components:n,disabled:!!e.disableNavigation,onChange:cr(dt.date),options:Xfe(dt.date,H,ae,r,i),style:D?.[et.Dropdown],value:i.getMonth(dt.date)}):Ue.createElement("span",{key:"month"},Q(dt.date,i)),rn=d==="dropdown"||d==="dropdown-years"?Ue.createElement(n.YearsDropdown,{key:"year",className:c[et.YearsDropdown],"aria-label":_t(i.options),classNames:c,components:n,disabled:!!e.disableNavigation,onChange:Kr(dt.date),options:Zfe(H,ae,r,i,!!e.reverseYears),style:D?.[et.Dropdown],value:i.getYear(dt.date)}):Ue.createElement("span",{key:"year"},V(dt.date,i));return i.getMonthYearOrder()==="year-first"?[rn,mt]:[mt,rn]})(),Ue.createElement("span",{role:"status","aria-live":"polite",style:{border:0,clip:"rect(0 0 0 0)",height:"1px",margin:"-1px",overflow:"hidden",padding:0,position:"absolute",width:"1px",whiteSpace:"nowrap",wordWrap:"normal"}},E(dt.date,i.options,i))):Ue.createElement(n.CaptionLabel,{className:c[et.CaptionLabel],role:"status","aria-live":"polite"},E(dt.date,i.options,i))),m==="around"&&!e.hideNavigation&&zn===p-1&&Ue.createElement(n.NextMonthButton,{type:"button",className:c[et.NextMonthButton],tabIndex:ue?void 0:-1,"aria-disabled":ue?void 0:!0,"aria-label":Bn(ue),onClick:yn,"data-animated-button":e.animate?"true":void 0},Ue.createElement(n.Chevron,{disabled:ue?void 0:!0,className:c[et.Chevron],orientation:e.dir==="rtl"?"left":"right"})),zn===p-1&&m==="after"&&!e.hideNavigation&&Ue.createElement(n.Nav,{"data-animated-nav":e.animate?"true":void 0,className:c[et.Nav],style:D?.[et.Nav],"aria-label":ut(),onPreviousClick:or,onNextClick:yn,previousMonth:ne,nextMonth:ue}),Ue.createElement(n.MonthGrid,{role:"grid","aria-multiselectable":h==="multiple"||h==="range","aria-label":Oe(dt.date,i.options,i)||void 0,className:c[et.MonthGrid],style:D?.[et.MonthGrid]},!e.hideWeekdays&&Ue.createElement(n.Weekdays,{"data-animated-weekdays":e.animate?"true":void 0,className:c[et.Weekdays],style:D?.[et.Weekdays]},_&&Ue.createElement(n.WeekNumberHeader,{"aria-label":nn(i.options),className:c[et.WeekNumberHeader],style:D?.[et.WeekNumberHeader],scope:"col"},B()),Yr.map(mt=>Ue.createElement(n.Weekday,{"aria-label":Tn(mt,i.options,i),className:c[et.Weekday],key:String(mt),style:D?.[et.Weekday],scope:"col"},U(mt,i.options,i)))),Ue.createElement(n.Weeks,{"data-animated-weeks":e.animate?"true":void 0,className:c[et.Weeks],style:D?.[et.Weeks]},dt.weeks.map(mt=>Ue.createElement(n.Week,{className:c[et.Week],key:mt.weekNumber,style:D?.[et.Week],week:mt},_&&Ue.createElement(n.WeekNumber,{week:mt,style:D?.[et.WeekNumber],"aria-label":Jn(mt.weekNumber,{locale:l}),className:c[et.WeekNumber],scope:"row",role:"rowheader"},F(mt.weekNumber,i)),mt.days.map(rn=>{const{date:Ar}=rn,Mt=me(rn);if(Mt[Yn.focused]=!Mt.hidden&&!!fe?.isEqualTo(rn),Mt[Bi.selected]=Y?.(Ar)||Mt.selected,X5(K)){const{from:qc,to:_o}=K;Mt[Bi.range_start]=!!(qc&&_o&&i.isSameDay(Ar,qc)),Mt[Bi.range_end]=!!(qc&&_o&&i.isSameDay(Ar,_o)),Mt[Bi.range_middle]=al(K,Ar,!0,i)}const Ic=Yfe(Mt,D,e.modifiersStyles),Eo=Lfe(Mt,c,e.modifiersClassNames),t1=!In&&!Mt.hidden?ct(Ar,Mt,i.options,i):void 0;return Ue.createElement(n.Day,{key:`${i.format(Ar,"yyyy-MM-dd")}_${i.format(rn.displayMonth,"yyyy-MM")}`,day:rn,modifiers:Mt,className:Eo.join(" "),style:Ic,role:"gridcell","aria-selected":Mt.selected||void 0,"aria-label":t1,"data-day":i.format(Ar,"yyyy-MM-dd"),"data-month":rn.outside?i.format(Ar,"yyyy-MM"):void 0,"data-selected":Mt.selected||void 0,"data-disabled":Mt.disabled||void 0,"data-hidden":Mt.hidden||void 0,"data-outside":rn.outside||void 0,"data-focused":Mt.focused||void 0,"data-today":Mt.today||void 0},!Mt.hidden&&In?Ue.createElement(n.DayButton,{className:c[et.DayButton],style:D?.[et.DayButton],type:"button",day:rn,modifiers:Mt,disabled:Mt.disabled||void 0,tabIndex:ve(rn)?0:-1,"aria-label":We(Ar,Mt,i.options,i),onClick:ft(rn,Mt),onBlur:Se(rn,Mt),onFocus:ee(rn,Mt),onKeyDown:Le(rn,Mt),onMouseEnter:rt(rn,Mt),onMouseLeave:Tt(rn,Mt)},z(Ar,i.options,i)):!Mt.hidden&&z(rn.date,i.options,i))})))))))),e.footer&&Ue.createElement(n.Footer,{className:c[et.Footer],style:D?.[et.Footer],role:"status","aria-live":"polite"},e.footer)))}function s9({className:t,classNames:e,showOutsideDays:n=!0,captionLayout:r="label",buttonVariant:s="ghost",formatters:i,components:l,...c}){const d=Y5();return a.jsx(R0e,{showOutsideDays:n,className:ye("bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,t),captionLayout:r,formatters:{formatMonthDropdown:h=>h.toLocaleString("default",{month:"short"}),...i},classNames:{root:ye("w-fit",d.root),months:ye("relative flex flex-col gap-4 md:flex-row",d.months),month:ye("flex w-full flex-col gap-4",d.month),nav:ye("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",d.nav),button_previous:ye(ff({variant:s}),"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",d.button_previous),button_next:ye(ff({variant:s}),"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",d.button_next),month_caption:ye("flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",d.month_caption),dropdowns:ye("flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",d.dropdowns),dropdown_root:ye("has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",d.dropdown_root),dropdown:ye("bg-popover absolute inset-0 opacity-0",d.dropdown),caption_label:ye("select-none font-medium",r==="label"?"text-sm":"[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",d.caption_label),table:"w-full border-collapse",weekdays:ye("flex",d.weekdays),weekday:ye("text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",d.weekday),week:ye("mt-2 flex w-full",d.week),week_number_header:ye("w-[--cell-size] select-none",d.week_number_header),week_number:ye("text-muted-foreground select-none text-[0.8rem]",d.week_number),day:ye("group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",d.day),range_start:ye("bg-accent rounded-l-md",d.range_start),range_middle:ye("rounded-none",d.range_middle),range_end:ye("bg-accent rounded-r-md",d.range_end),today:ye("bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",d.today),outside:ye("text-muted-foreground aria-selected:text-muted-foreground",d.outside),disabled:ye("text-muted-foreground opacity-50",d.disabled),hidden:ye("invisible",d.hidden),...e},components:{Root:({className:h,rootRef:m,...p})=>a.jsx("div",{"data-slot":"calendar",ref:m,className:ye(h),...p}),Chevron:({className:h,orientation:m,...p})=>m==="left"?a.jsx(Tc,{className:ye("size-4",h),...p}):m==="right"?a.jsx(Mc,{className:ye("size-4",h),...p}):a.jsx(df,{className:ye("size-4",h),...p}),DayButton:z0e,WeekNumber:({children:h,...m})=>a.jsx("td",{...m,children:a.jsx("div",{className:"flex size-[--cell-size] items-center justify-center text-center",children:h})}),...l},...c})}function z0e({className:t,day:e,modifiers:n,...r}){const s=Y5(),i=S.useRef(null);return S.useEffect(()=>{n.focused&&i.current?.focus()},[n.focused]),a.jsx(ie,{ref:i,variant:"ghost",size:"icon","data-day":e.date.toLocaleDateString(),"data-selected-single":n.selected&&!n.range_start&&!n.range_end&&!n.range_middle,"data-range-start":n.range_start,"data-range-end":n.range_end,"data-range-middle":n.range_middle,className:ye("data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",s.day,t),...r})}class P0e{ws=null;reconnectTimeout=null;reconnectAttempts=0;maxReconnectAttempts=10;heartbeatInterval=null;logCallbacks=new Set;connectionCallbacks=new Set;isConnected=!1;logCache=[];maxCacheSize=1e3;getWebSocketUrl(){{const e=window.location.protocol==="https:"?"wss:":"ws:",n=window.location.host;return`${e}//${n}/ws/logs`}}connect(){if(this.ws?.readyState===WebSocket.OPEN||this.ws?.readyState===WebSocket.CONNECTING)return;const e=this.getWebSocketUrl();try{this.ws=new WebSocket(e),this.ws.onopen=()=>{this.isConnected=!0,this.reconnectAttempts=0,this.notifyConnection(!0),this.startHeartbeat()},this.ws.onmessage=n=>{try{if(n.data==="pong")return;const r=JSON.parse(n.data);this.notifyLog(r)}catch(r){console.error("解析日志消息失败:",r)}},this.ws.onerror=n=>{console.error("❌ WebSocket 错误:",n),this.isConnected=!1,this.notifyConnection(!1)},this.ws.onclose=()=>{this.isConnected=!1,this.notifyConnection(!1),this.stopHeartbeat(),this.attemptReconnect()}}catch(n){console.error("创建 WebSocket 连接失败:",n),this.attemptReconnect()}}attemptReconnect(){if(this.reconnectAttempts>=this.maxReconnectAttempts)return;this.reconnectAttempts+=1;const e=Math.min(1e3*this.reconnectAttempts,1e4);this.reconnectTimeout=window.setTimeout(()=>{this.connect()},e)}startHeartbeat(){this.heartbeatInterval=window.setInterval(()=>{this.ws?.readyState===WebSocket.OPEN&&this.ws.send("ping")},3e4)}stopHeartbeat(){this.heartbeatInterval!==null&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null)}disconnect(){this.reconnectTimeout!==null&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.stopHeartbeat(),this.ws&&(this.ws.close(),this.ws=null),this.isConnected=!1,this.reconnectAttempts=0}onLog(e){return this.logCallbacks.add(e),()=>this.logCallbacks.delete(e)}onConnectionChange(e){return this.connectionCallbacks.add(e),e(this.isConnected),()=>this.connectionCallbacks.delete(e)}notifyLog(e){this.logCache.some(r=>r.id===e.id)||(this.logCache.push(e),this.logCache.length>this.maxCacheSize&&(this.logCache=this.logCache.slice(-this.maxCacheSize)),this.logCallbacks.forEach(r=>{try{r(e)}catch(s){console.error("日志回调执行失败:",s)}}))}notifyConnection(e){this.connectionCallbacks.forEach(n=>{try{n(e)}catch(r){console.error("连接状态回调执行失败:",r)}})}getAllLogs(){return[...this.logCache]}clearLogs(){this.logCache=[]}getConnectionStatus(){return this.isConnected}}const Iu=new P0e;typeof window<"u"&&Iu.connect();const L0e={lessThanXSeconds:{one:"不到 1 秒",other:"不到 {{count}} 秒"},xSeconds:{one:"1 秒",other:"{{count}} 秒"},halfAMinute:"半分钟",lessThanXMinutes:{one:"不到 1 分钟",other:"不到 {{count}} 分钟"},xMinutes:{one:"1 分钟",other:"{{count}} 分钟"},xHours:{one:"1 小时",other:"{{count}} 小时"},aboutXHours:{one:"大约 1 小时",other:"大约 {{count}} 小时"},xDays:{one:"1 天",other:"{{count}} 天"},aboutXWeeks:{one:"大约 1 个星期",other:"大约 {{count}} 个星期"},xWeeks:{one:"1 个星期",other:"{{count}} 个星期"},aboutXMonths:{one:"大约 1 个月",other:"大约 {{count}} 个月"},xMonths:{one:"1 个月",other:"{{count}} 个月"},aboutXYears:{one:"大约 1 年",other:"大约 {{count}} 年"},xYears:{one:"1 年",other:"{{count}} 年"},overXYears:{one:"超过 1 年",other:"超过 {{count}} 年"},almostXYears:{one:"将近 1 年",other:"将近 {{count}} 年"}},B0e=(t,e,n)=>{let r;const s=L0e[t];return typeof s=="string"?r=s:e===1?r=s.one:r=s.other.replace("{{count}}",String(e)),n?.addSuffix?n.comparison&&n.comparison>0?r+"内":r+"前":r},I0e={full:"y'年'M'月'd'日' EEEE",long:"y'年'M'月'd'日'",medium:"yyyy-MM-dd",short:"yy-MM-dd"},q0e={full:"zzzz a h:mm:ss",long:"z a h:mm:ss",medium:"a h:mm:ss",short:"a h:mm"},F0e={full:"{{date}} {{time}}",long:"{{date}} {{time}}",medium:"{{date}} {{time}}",short:"{{date}} {{time}}"},Q0e={date:td({formats:I0e,defaultWidth:"full"}),time:td({formats:q0e,defaultWidth:"full"}),dateTime:td({formats:F0e,defaultWidth:"full"})};function i9(t,e,n){const r="eeee p";return Jhe(t,e,n)?r:t.getTime()>e.getTime()?"'下个'"+r:"'上个'"+r}const $0e={lastWeek:i9,yesterday:"'昨天' p",today:"'今天' p",tomorrow:"'明天' p",nextWeek:i9,other:"PP p"},H0e=(t,e,n,r)=>{const s=$0e[t];return typeof s=="function"?s(e,n,r):s},U0e={narrow:["前","公元"],abbreviated:["前","公元"],wide:["公元前","公元"]},V0e={narrow:["1","2","3","4"],abbreviated:["第一季","第二季","第三季","第四季"],wide:["第一季度","第二季度","第三季度","第四季度"]},W0e={narrow:["一","二","三","四","五","六","七","八","九","十","十一","十二"],abbreviated:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],wide:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]},G0e={narrow:["日","一","二","三","四","五","六"],short:["日","一","二","三","四","五","六"],abbreviated:["周日","周一","周二","周三","周四","周五","周六"],wide:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]},X0e={narrow:{am:"上",pm:"下",midnight:"凌晨",noon:"午",morning:"早",afternoon:"下午",evening:"晚",night:"夜"},abbreviated:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"},wide:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"}},Y0e={narrow:{am:"上",pm:"下",midnight:"凌晨",noon:"午",morning:"早",afternoon:"下午",evening:"晚",night:"夜"},abbreviated:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"},wide:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"}},K0e=(t,e)=>{const n=Number(t);switch(e?.unit){case"date":return n.toString()+"日";case"hour":return n.toString()+"时";case"minute":return n.toString()+"分";case"second":return n.toString()+"秒";default:return"第 "+n.toString()}},Z0e={ordinalNumber:K0e,era:oa({values:U0e,defaultWidth:"wide"}),quarter:oa({values:V0e,defaultWidth:"wide",argumentCallback:t=>t-1}),month:oa({values:W0e,defaultWidth:"wide"}),day:oa({values:G0e,defaultWidth:"wide"}),dayPeriod:oa({values:X0e,defaultWidth:"wide",formattingValues:Y0e,defaultFormattingWidth:"wide"})},J0e=/^(第\s*)?\d+(日|时|分|秒)?/i,eme=/\d+/i,tme={narrow:/^(前)/i,abbreviated:/^(前)/i,wide:/^(公元前|公元)/i},nme={any:[/^(前)/i,/^(公元)/i]},rme={narrow:/^[1234]/i,abbreviated:/^第[一二三四]刻/i,wide:/^第[一二三四]刻钟/i},sme={any:[/(1|一)/i,/(2|二)/i,/(3|三)/i,/(4|四)/i]},ime={narrow:/^(一|二|三|四|五|六|七|八|九|十[二一])/i,abbreviated:/^(一|二|三|四|五|六|七|八|九|十[二一]|\d|1[12])月/i,wide:/^(一|二|三|四|五|六|七|八|九|十[二一])月/i},ame={narrow:[/^一/i,/^二/i,/^三/i,/^四/i,/^五/i,/^六/i,/^七/i,/^八/i,/^九/i,/^十(?!(一|二))/i,/^十一/i,/^十二/i],any:[/^一|1/i,/^二|2/i,/^三|3/i,/^四|4/i,/^五|5/i,/^六|6/i,/^七|7/i,/^八|8/i,/^九|9/i,/^十(?!(一|二))|10/i,/^十一|11/i,/^十二|12/i]},lme={narrow:/^[一二三四五六日]/i,short:/^[一二三四五六日]/i,abbreviated:/^周[一二三四五六日]/i,wide:/^星期[一二三四五六日]/i},ome={any:[/日/i,/一/i,/二/i,/三/i,/四/i,/五/i,/六/i]},cme={any:/^(上午?|下午?|午夜|[中正]午|早上?|下午|晚上?|凌晨|)/i},ume={any:{am:/^上午?/i,pm:/^下午?/i,midnight:/^午夜/i,noon:/^[中正]午/i,morning:/^早上/i,afternoon:/^下午/i,evening:/^晚上?/i,night:/^凌晨/i}},dme={ordinalNumber:xz({matchPattern:J0e,parsePattern:eme,valueCallback:t=>parseInt(t,10)}),era:ca({matchPatterns:tme,defaultMatchWidth:"wide",parsePatterns:nme,defaultParseWidth:"any"}),quarter:ca({matchPatterns:rme,defaultMatchWidth:"wide",parsePatterns:sme,defaultParseWidth:"any",valueCallback:t=>t+1}),month:ca({matchPatterns:ime,defaultMatchWidth:"wide",parsePatterns:ame,defaultParseWidth:"any"}),day:ca({matchPatterns:lme,defaultMatchWidth:"wide",parsePatterns:ome,defaultParseWidth:"any"}),dayPeriod:ca({matchPatterns:cme,defaultMatchWidth:"any",parsePatterns:ume,defaultParseWidth:"any"})},Lp={code:"zh-CN",formatDistance:B0e,formatLong:Q0e,formatRelative:H0e,localize:Z0e,match:dme,options:{weekStartsOn:1,firstWeekContainsDate:4}};function hme(){const[t,e]=S.useState([]),[n,r]=S.useState(""),[s,i]=S.useState("all"),[l,c]=S.useState("all"),[d,h]=S.useState(void 0),[m,p]=S.useState(void 0),[x,v]=S.useState(!0),[b,k]=S.useState(!1),O=S.useRef(null),j=S.useRef(null);S.useEffect(()=>{const U=Iu.getAllLogs();e(U);const V=Iu.onLog(()=>{e(Iu.getAllLogs())}),ce=Iu.onConnectionChange(W=>{k(W)});return()=>{V(),ce()}},[]),S.useEffect(()=>{x&&j.current&&j.current.scrollIntoView({behavior:"smooth",block:"end"})},[t,x]);const T=S.useMemo(()=>{const U=new Set(t.map(V=>V.module));return Array.from(U).sort()},[t]),M=U=>{switch(U){case"DEBUG":return"text-muted-foreground";case"INFO":return"text-blue-500 dark:text-blue-400";case"WARNING":return"text-yellow-600 dark:text-yellow-500";case"ERROR":return"text-red-600 dark:text-red-500";case"CRITICAL":return"text-red-700 dark:text-red-400 font-bold";default:return"text-foreground"}},_=U=>{switch(U){case"DEBUG":return"bg-gray-800/30 dark:bg-gray-800/50";case"INFO":return"bg-blue-900/20 dark:bg-blue-500/20";case"WARNING":return"bg-yellow-900/20 dark:bg-yellow-500/20";case"ERROR":return"bg-red-900/20 dark:bg-red-500/20";case"CRITICAL":return"bg-red-900/30 dark:bg-red-600/30";default:return"bg-gray-800/20 dark:bg-gray-800/30"}},D=()=>{window.location.reload()},E=()=>{Iu.clearLogs(),e([])},z=()=>{const U=B.map(J=>`${J.timestamp} [${J.level.padEnd(8)}] [${J.module}] ${J.message}`).join(` -`),V=new Blob([U],{type:"text/plain;charset=utf-8"}),ce=URL.createObjectURL(V),W=document.createElement("a");W.href=ce,W.download=`logs-${dg(new Date,"yyyy-MM-dd-HHmmss")}.txt`,W.click(),URL.revokeObjectURL(ce)},Q=()=>{v(!x)},F=()=>{h(void 0),p(void 0)},B=S.useMemo(()=>t.filter(U=>{const V=n===""||U.message.toLowerCase().includes(n.toLowerCase())||U.module.toLowerCase().includes(n.toLowerCase()),ce=s==="all"||U.level===s,W=l==="all"||U.module===l;let J=!0;if(d||m){const H=new Date(U.timestamp);if(d){const ae=new Date(d);ae.setHours(0,0,0,0),J=J&&H>=ae}if(m){const ae=new Date(m);ae.setHours(23,59,59,999),J=J&&H<=ae}}return V&&ce&&W&&J}),[t,n,s,l,d,m]);return a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-4 p-3 sm:p-4 lg:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-xl sm:text-2xl lg:text-3xl font-bold",children:"日志查看器"}),a.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground mt-1",children:"实时查看和分析麦麦运行日志"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:ye("h-2.5 w-2.5 sm:h-3 sm:w-3 rounded-full",b?"bg-green-500 animate-pulse":"bg-red-500")}),a.jsx("span",{className:"text-xs sm:text-sm text-muted-foreground",children:b?"已连接":"未连接"})]})]}),a.jsx(yt,{className:"p-3 sm:p-4",children:a.jsxs("div",{className:"flex flex-col gap-3 sm:gap-4",children:[a.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:gap-4",children:[a.jsxs("div",{className:"flex-1 relative",children:[a.jsx(Ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{placeholder:"搜索日志...",value:n,onChange:U=>r(U.target.value),className:"pl-9 h-9 text-sm"})]}),a.jsxs(Bt,{value:s,onValueChange:i,children:[a.jsxs(Dt,{className:"w-full sm:w-[140px] lg:w-[180px] h-9 text-sm",children:[a.jsx(t2,{className:"h-4 w-4 mr-2"}),a.jsx(It,{placeholder:"级别"})]}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部级别"}),a.jsx(Pe,{value:"DEBUG",children:"DEBUG"}),a.jsx(Pe,{value:"INFO",children:"INFO"}),a.jsx(Pe,{value:"WARNING",children:"WARNING"}),a.jsx(Pe,{value:"ERROR",children:"ERROR"}),a.jsx(Pe,{value:"CRITICAL",children:"CRITICAL"})]})]}),a.jsxs(Bt,{value:l,onValueChange:c,children:[a.jsxs(Dt,{className:"w-full sm:w-[160px] lg:w-[200px] h-9 text-sm",children:[a.jsx(t2,{className:"h-4 w-4 mr-2"}),a.jsx(It,{placeholder:"模块"})]}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部模块"}),T.map(U=>a.jsx(Pe,{value:U,children:U},U))]})]})]}),a.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:gap-4",children:[a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",className:ye("w-full sm:w-[200px] lg:w-[240px] justify-start text-left font-normal h-9",!d&&"text-muted-foreground"),children:[a.jsx(uO,{className:"mr-2 h-4 w-4"}),a.jsx("span",{className:"text-xs sm:text-sm",children:d?dg(d,"PPP",{locale:Lp}):"开始日期"})]})}),a.jsx(hl,{className:"w-auto p-0",align:"start",children:a.jsx(s9,{mode:"single",selected:d,onSelect:h,initialFocus:!0,locale:Lp})})]}),a.jsxs(co,{children:[a.jsx(uo,{asChild:!0,children:a.jsxs(ie,{variant:"outline",size:"sm",className:ye("w-full sm:w-[200px] lg:w-[240px] justify-start text-left font-normal h-9",!m&&"text-muted-foreground"),children:[a.jsx(uO,{className:"mr-2 h-4 w-4"}),a.jsx("span",{className:"text-xs sm:text-sm",children:m?dg(m,"PPP",{locale:Lp}):"结束日期"})]})}),a.jsx(hl,{className:"w-auto p-0",align:"start",children:a.jsx(s9,{mode:"single",selected:m,onSelect:p,initialFocus:!0,locale:Lp})})]}),(d||m)&&a.jsxs(ie,{variant:"outline",size:"sm",onClick:F,className:"w-full sm:w-auto h-9",children:[a.jsx(Gf,{className:"h-4 w-4 sm:mr-2"}),a.jsx("span",{className:"hidden sm:inline text-sm",children:"清除时间筛选"}),a.jsx("span",{className:"sm:hidden text-sm",children:"清除"})]})]}),a.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center",children:[a.jsxs("div",{className:"flex gap-2 flex-wrap",children:[a.jsxs(ie,{variant:x?"default":"outline",size:"sm",onClick:Q,className:"flex-1 sm:flex-none h-9",children:[x?a.jsx(jq,{className:"h-4 w-4"}):a.jsx(Nq,{className:"h-4 w-4"}),a.jsx("span",{className:"ml-2 text-sm",children:x?"自动滚动":"已暂停"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:D,className:"flex-1 sm:flex-none h-9",children:[a.jsx(Ii,{className:"h-4 w-4"}),a.jsx("span",{className:"ml-2 text-sm",children:"刷新"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:E,className:"flex-1 sm:flex-none h-9",children:[a.jsx(Ht,{className:"h-4 w-4"}),a.jsx("span",{className:"ml-2 text-sm",children:"清空"})]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:z,className:"flex-1 sm:flex-none h-9",children:[a.jsx(fc,{className:"h-4 w-4"}),a.jsx("span",{className:"ml-2 text-sm",children:"导出"})]})]}),a.jsx("div",{className:"flex-1 hidden sm:block"}),a.jsxs("div",{className:"text-xs sm:text-sm text-muted-foreground flex items-center justify-center sm:justify-end",children:[a.jsxs("span",{className:"font-mono",children:[B.length," / ",t.length]}),a.jsx("span",{className:"ml-1",children:"条日志"})]})]})]})}),a.jsx(yt,{className:"bg-black dark:bg-gray-950 border-gray-800 dark:border-gray-900",children:a.jsx(fn,{className:"h-[calc(100vh-280px)] sm:h-[calc(100vh-320px)] lg:h-[calc(100vh-400px)]",children:a.jsxs("div",{ref:O,className:"p-2 sm:p-3 lg:p-4 font-mono text-xs sm:text-sm space-y-1",children:[B.length===0?a.jsx("div",{className:"text-gray-500 dark:text-gray-600 text-center py-8 text-sm",children:"暂无日志数据"}):B.map(U=>a.jsxs("div",{className:ye("py-2 px-2 sm:px-3 rounded hover:bg-white/5 transition-colors group",_(U.level)),children:[a.jsxs("div",{className:"flex flex-col gap-1 sm:hidden",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"text-gray-500 dark:text-gray-600 text-xs",children:U.timestamp}),a.jsxs("span",{className:ye("text-xs font-semibold",M(U.level)),children:["[",U.level,"]"]})]}),a.jsx("div",{className:"text-cyan-400 dark:text-cyan-500 text-xs truncate",children:U.module}),a.jsx("div",{className:"text-gray-300 dark:text-gray-400 text-xs whitespace-pre-wrap break-words",children:U.message})]}),a.jsxs("div",{className:"hidden sm:flex gap-3 items-start",children:[a.jsx("span",{className:"text-gray-500 dark:text-gray-600 flex-shrink-0 w-[140px] lg:w-[180px] text-xs lg:text-sm",children:U.timestamp}),a.jsxs("span",{className:ye("flex-shrink-0 w-[70px] lg:w-[80px] font-semibold text-xs lg:text-sm",M(U.level)),children:["[",U.level,"]"]}),a.jsx("span",{className:"text-cyan-400 dark:text-cyan-500 flex-shrink-0 w-[120px] lg:w-[150px] truncate text-xs lg:text-sm",children:U.module}),a.jsx("span",{className:"text-gray-300 dark:text-gray-400 flex-1 whitespace-pre-wrap break-words text-xs lg:text-sm",children:U.message})]})]},U.id)),a.jsx("div",{ref:j,className:"h-4"})]})})})]})})}const fme="Mai-with-u",mme="plugin-repo",pme="main",gme="plugin_details.json";async function xme(){try{const t=await ot("/api/webui/plugins/fetch-raw",{method:"POST",headers:bt(),body:JSON.stringify({owner:fme,repo:mme,branch:pme,file_path:gme})});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const e=await t.json();if(!e.success||!e.data)throw new Error(e.error||"获取插件列表失败");return JSON.parse(e.data).filter(s=>!s?.id||!s?.manifest?(console.warn("跳过无效插件数据:",s),!1):!s.manifest.name||!s.manifest.version?(console.warn("跳过缺少必需字段的插件:",s.id),!1):!0).map(s=>({id:s.id,manifest:{manifest_version:s.manifest.manifest_version||1,name:s.manifest.name,version:s.manifest.version,description:s.manifest.description||"",author:s.manifest.author||{name:"Unknown"},license:s.manifest.license||"Unknown",host_application:s.manifest.host_application||{min_version:"0.0.0"},homepage_url:s.manifest.homepage_url,repository_url:s.manifest.repository_url,keywords:s.manifest.keywords||[],categories:s.manifest.categories||[],default_locale:s.manifest.default_locale||"zh-CN",locales_path:s.manifest.locales_path},downloads:0,rating:0,review_count:0,installed:!1,published_at:new Date().toISOString(),updated_at:new Date().toISOString()}))}catch(t){throw console.error("Failed to fetch plugin list:",t),t}}async function vme(){try{const t=await ot("/api/webui/plugins/git-status");if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);return await t.json()}catch(t){return console.error("Failed to check Git status:",t),{installed:!1,error:"无法检测 Git 安装状态"}}}async function yme(){try{const t=await ot("/api/webui/plugins/version");if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);return await t.json()}catch(t){return console.error("Failed to get Maimai version:",t),{version:"0.0.0",version_major:0,version_minor:0,version_patch:0}}}function bme(t,e,n){const r=t.split(".").map(c=>parseInt(c)||0),s=r[0]||0,i=r[1]||0,l=r[2]||0;if(n.version_majorparseInt(p)||0),d=c[0]||0,h=c[1]||0,m=c[2]||0;if(n.version_major>d||n.version_major===d&&n.version_minor>h||n.version_major===d&&n.version_minor===h&&n.version_patch>m)return!1}return!0}function wme(t,e){const n=window.location.protocol==="https:"?"wss:":"ws:",r=window.location.host,s=new WebSocket(`${n}//${r}/api/webui/ws/plugin-progress`);return s.onopen=()=>{console.log("Plugin progress WebSocket connected");const i=setInterval(()=>{s.readyState===WebSocket.OPEN?s.send("ping"):clearInterval(i)},3e4)},s.onmessage=i=>{try{if(i.data==="pong")return;const l=JSON.parse(i.data);t(l)}catch(l){console.error("Failed to parse progress data:",l)}},s.onerror=i=>{console.error("Plugin progress WebSocket error:",i),e?.(i)},s.onclose=()=>{console.log("Plugin progress WebSocket disconnected")},s}async function Bp(){try{const t=await ot("/api/webui/plugins/installed",{headers:bt()});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const e=await t.json();if(!e.success)throw new Error(e.message||"获取已安装插件列表失败");return e.plugins||[]}catch(t){return console.error("Failed to get installed plugins:",t),[]}}function Ip(t,e){return e.some(n=>n.id===t)}function qp(t,e){const n=e.find(r=>r.id===t);if(n)return n.manifest?.version||n.version}async function Sme(t,e,n="main"){const r=await ot("/api/webui/plugins/install",{method:"POST",headers:bt(),body:JSON.stringify({plugin_id:t,repository_url:e,branch:n})});if(!r.ok){const s=await r.json();throw new Error(s.detail||"安装失败")}return await r.json()}async function kme(t){const e=await ot("/api/webui/plugins/uninstall",{method:"POST",headers:bt(),body:JSON.stringify({plugin_id:t})});if(!e.ok){const n=await e.json();throw new Error(n.detail||"卸载失败")}return await e.json()}async function Ome(t,e,n="main"){const r=await ot("/api/webui/plugins/update",{method:"POST",headers:bt(),body:JSON.stringify({plugin_id:t,repository_url:e,branch:n})});if(!r.ok){const s=await r.json();throw new Error(s.detail||"更新失败")}return await r.json()}const C0="https://maibot-plugin-stats.maibot-webui.workers.dev";async function zz(t){try{const e=await fetch(`${C0}/stats/${t}`);return e.ok?await e.json():(console.error("Failed to fetch plugin stats:",e.statusText),null)}catch(e){return console.error("Error fetching plugin stats:",e),null}}async function jme(t,e){try{const n=e||K5(),r=await fetch(`${C0}/stats/like`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:t,user_id:n})}),s=await r.json();return r.status===429?{success:!1,error:"操作过于频繁,请稍后再试"}:r.ok?{success:!0,...s}:{success:!1,error:s.error||"点赞失败"}}catch(n){return console.error("Error liking plugin:",n),{success:!1,error:"网络错误"}}}async function Nme(t,e){try{const n=e||K5(),r=await fetch(`${C0}/stats/dislike`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:t,user_id:n})}),s=await r.json();return r.status===429?{success:!1,error:"操作过于频繁,请稍后再试"}:r.ok?{success:!0,...s}:{success:!1,error:s.error||"点踩失败"}}catch(n){return console.error("Error disliking plugin:",n),{success:!1,error:"网络错误"}}}async function Cme(t,e,n,r){if(e<1||e>5)return{success:!1,error:"评分必须在 1-5 之间"};try{const s=r||K5(),i=await fetch(`${C0}/stats/rate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:t,rating:e,comment:n,user_id:s})}),l=await i.json();return i.status===429?{success:!1,error:"每天最多评分 3 次"}:i.ok?{success:!0,...l}:{success:!1,error:l.error||"评分失败"}}catch(s){return console.error("Error rating plugin:",s),{success:!1,error:"网络错误"}}}async function Tme(t){try{const e=await fetch(`${C0}/stats/download`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:t})}),n=await e.json();return e.status===429?(console.warn("Download recording rate limited"),{success:!0}):e.ok?{success:!0,...n}:(console.error("Failed to record download:",n.error),{success:!1,error:n.error})}catch(e){return console.error("Error recording download:",e),{success:!1,error:"网络错误"}}}function Mme(){const t=navigator,e=[navigator.userAgent,navigator.language,navigator.languages?.join(",")||"",navigator.platform,navigator.hardwareConcurrency||0,screen.width,screen.height,screen.colorDepth,screen.pixelDepth,new Date().getTimezoneOffset(),Intl.DateTimeFormat().resolvedOptions().timeZone,navigator.maxTouchPoints||0,t.deviceMemory||0].join("|");let n=0;for(let r=0;r{i(!0);const j=await zz(t);j&&r(j),i(!1)};S.useEffect(()=>{v()},[t]);const b=async()=>{const j=await jme(t);j.success?(x({title:"已点赞",description:"感谢你的支持!"}),v()):x({title:"点赞失败",description:j.error||"未知错误",variant:"destructive"})},k=async()=>{const j=await Nme(t);j.success?(x({title:"已反馈",description:"感谢你的反馈!"}),v()):x({title:"操作失败",description:j.error||"未知错误",variant:"destructive"})},O=async()=>{if(l===0){x({title:"请选择评分",description:"至少选择 1 颗星",variant:"destructive"});return}const j=await Cme(t,l,d||void 0);j.success?(x({title:"评分成功",description:"感谢你的评价!"}),p(!1),c(0),h(""),v()):x({title:"评分失败",description:j.error||"未知错误",variant:"destructive"})};return s?a.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx(fc,{className:"h-4 w-4"}),a.jsx("span",{children:"-"})]}),a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx(Zl,{className:"h-4 w-4"}),a.jsx("span",{children:"-"})]})]}):n?e?a.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[a.jsxs("div",{className:"flex items-center gap-1",title:`下载量: ${n.downloads.toLocaleString()}`,children:[a.jsx(fc,{className:"h-4 w-4"}),a.jsx("span",{children:n.downloads.toLocaleString()})]}),a.jsxs("div",{className:"flex items-center gap-1",title:`评分: ${n.rating.toFixed(1)} (${n.rating_count} 条评价)`,children:[a.jsx(Zl,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),a.jsx("span",{children:n.rating.toFixed(1)})]}),a.jsxs("div",{className:"flex items-center gap-1",title:`点赞数: ${n.likes}`,children:[a.jsx(my,{className:"h-4 w-4"}),a.jsx("span",{children:n.likes})]})]}):a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:[a.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[a.jsx(fc,{className:"h-5 w-5 text-muted-foreground mb-1"}),a.jsx("span",{className:"text-2xl font-bold",children:n.downloads.toLocaleString()}),a.jsx("span",{className:"text-xs text-muted-foreground",children:"下载量"})]}),a.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[a.jsx(Zl,{className:"h-5 w-5 text-yellow-400 mb-1 fill-yellow-400"}),a.jsx("span",{className:"text-2xl font-bold",children:n.rating.toFixed(1)}),a.jsxs("span",{className:"text-xs text-muted-foreground",children:[n.rating_count," 条评价"]})]}),a.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[a.jsx(my,{className:"h-5 w-5 text-green-500 mb-1"}),a.jsx("span",{className:"text-2xl font-bold",children:n.likes}),a.jsx("span",{className:"text-xs text-muted-foreground",children:"点赞"})]}),a.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[a.jsx(dO,{className:"h-5 w-5 text-red-500 mb-1"}),a.jsx("span",{className:"text-2xl font-bold",children:n.dislikes}),a.jsx("span",{className:"text-xs text-muted-foreground",children:"点踩"})]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsxs(ie,{variant:"outline",size:"sm",onClick:b,children:[a.jsx(my,{className:"h-4 w-4 mr-1"}),"点赞"]}),a.jsxs(ie,{variant:"outline",size:"sm",onClick:k,children:[a.jsx(dO,{className:"h-4 w-4 mr-1"}),"点踩"]}),a.jsxs(Rr,{open:m,onOpenChange:p,children:[a.jsx(mw,{asChild:!0,children:a.jsxs(ie,{variant:"default",size:"sm",children:[a.jsx(Zl,{className:"h-4 w-4 mr-1"}),"评分"]})}),a.jsxs(Nr,{children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"为插件评分"}),a.jsx(Gr,{children:"分享你的使用体验,帮助其他用户"})]}),a.jsxs("div",{className:"space-y-4 py-4",children:[a.jsxs("div",{className:"flex flex-col items-center gap-2",children:[a.jsx("div",{className:"flex gap-2",children:[1,2,3,4,5].map(j=>a.jsx("button",{onClick:()=>c(j),className:"focus:outline-none",children:a.jsx(Zl,{className:`h-8 w-8 transition-colors ${j<=l?"fill-yellow-400 text-yellow-400":"text-muted-foreground hover:text-yellow-300"}`})},j))}),a.jsxs("span",{className:"text-sm text-muted-foreground",children:[l===0&&"点击星星进行评分",l===1&&"很差",l===2&&"一般",l===3&&"还行",l===4&&"不错",l===5&&"非常好"]})]}),a.jsxs("div",{children:[a.jsx("label",{className:"text-sm font-medium mb-2 block",children:"评论(可选)"}),a.jsx(On,{value:d,onChange:j=>h(j.target.value),placeholder:"分享你的使用体验...",rows:4,maxLength:500}),a.jsxs("div",{className:"text-xs text-muted-foreground mt-1 text-right",children:[d.length," / 500"]})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>p(!1),children:"取消"}),a.jsx(ie,{onClick:O,disabled:l===0,children:"提交评分"})]})]})]})]}),n.recent_ratings&&n.recent_ratings.length>0&&a.jsxs("div",{className:"space-y-2",children:[a.jsx("h4",{className:"text-sm font-semibold",children:"最近评价"}),a.jsx("div",{className:"space-y-3",children:n.recent_ratings.map((j,T)=>a.jsxs("div",{className:"p-3 rounded-lg border bg-muted/50",children:[a.jsxs("div",{className:"flex items-center justify-between mb-2",children:[a.jsx("div",{className:"flex gap-1",children:[1,2,3,4,5].map(M=>a.jsx(Zl,{className:`h-3 w-3 ${M<=j.rating?"fill-yellow-400 text-yellow-400":"text-muted-foreground"}`},M))}),a.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(j.created_at).toLocaleDateString()})]}),j.comment&&a.jsx("p",{className:"text-sm text-muted-foreground",children:j.comment})]},T))})]})]}):null}const a9={"Group Management":"群组管理","Entertainment & Interaction":"娱乐互动","Utility Tools":"实用工具","Content Generation":"内容生成",Multimedia:"多媒体","External Integration":"外部集成","Data Analysis & Insights":"数据分析与洞察",Other:"其他"};function Eme(){const t=ba(),[e,n]=S.useState(null),[r,s]=S.useState(""),[i,l]=S.useState("all"),[c,d]=S.useState("all"),[h,m]=S.useState(!0),[p,x]=S.useState([]),[v,b]=S.useState(!0),[k,O]=S.useState(null),[j,T]=S.useState(null),[M,_]=S.useState(null),[D,E]=S.useState(null),[,z]=S.useState([]),[Q,F]=S.useState({}),{toast:B}=Pr(),U=async R=>{const me=R.map(async K=>{try{const $=await zz(K.id);return{id:K.id,stats:$}}catch($){return console.warn(`Failed to load stats for ${K.id}:`,$),{id:K.id,stats:null}}}),Y=await Promise.all(me),P={};Y.forEach(({id:K,stats:$})=>{$&&(P[K]=$)}),F(P)};S.useEffect(()=>{let R=null,me=!1;return(async()=>{if(R=wme(P=>{me||(_(P),P.stage==="success"?setTimeout(()=>{me||_(null)},2e3):P.stage==="error"&&(b(!1),O(P.error||"加载失败")))},P=>{console.error("WebSocket error:",P),me||B({title:"WebSocket 连接失败",description:"无法实时显示加载进度",variant:"destructive"})}),await new Promise(P=>{if(!R){P();return}const K=()=>{R&&R.readyState===WebSocket.OPEN?(console.log("WebSocket connected, starting to load plugins"),P()):R&&R.readyState===WebSocket.CLOSED?(console.warn("WebSocket closed before loading plugins"),P()):setTimeout(K,100)};K()}),!me){const P=await vme();T(P),P.installed||B({title:"Git 未安装",description:P.error||"请先安装 Git 才能使用插件安装功能",variant:"destructive"})}if(!me){const P=await yme();E(P)}if(!me)try{b(!0),O(null);const P=await xme();if(!me){const K=await Bp();z(K);const $=P.map(fe=>{const ve=Ip(fe.id,K),Re=qp(fe.id,K);return{...fe,installed:ve,installed_version:Re}});for(const fe of K)!$.some(Re=>Re.id===fe.id)&&fe.manifest&&$.push({id:fe.id,manifest:{manifest_version:fe.manifest.manifest_version||1,name:fe.manifest.name,version:fe.manifest.version,description:fe.manifest.description||"",author:fe.manifest.author,license:fe.manifest.license||"Unknown",host_application:fe.manifest.host_application,homepage_url:fe.manifest.homepage_url,repository_url:fe.manifest.repository_url,keywords:fe.manifest.keywords||[],categories:fe.manifest.categories||[],default_locale:fe.manifest.default_locale||"zh-CN",locales_path:fe.manifest.locales_path},downloads:0,rating:0,review_count:0,installed:!0,installed_version:fe.manifest.version,published_at:new Date().toISOString(),updated_at:new Date().toISOString()});x($),U($)}}catch(P){if(!me){const K=P instanceof Error?P.message:"加载插件列表失败";O(K),B({title:"加载失败",description:K,variant:"destructive"})}}finally{me||b(!1)}})(),()=>{me=!0,R&&R.close()}},[B]);const V=R=>{if(!R.installed&&D&&!ce(R))return a.jsxs($n,{variant:"destructive",className:"gap-1",children:[a.jsx(xc,{className:"h-3 w-3"}),"不兼容"]});if(R.installed){const me=R.installed_version?.trim(),Y=R.manifest.version?.trim();if(me!==Y){const P=me?.split(".").map(Number)||[0,0,0],K=Y?.split(".").map(Number)||[0,0,0];for(let $=0;$<3;$++){if((K[$]||0)>(P[$]||0))return a.jsxs($n,{variant:"outline",className:"gap-1 text-orange-600 border-orange-600",children:[a.jsx(xc,{className:"h-3 w-3"}),"可更新"]});if((K[$]||0)<(P[$]||0))break}}return a.jsxs($n,{variant:"default",className:"gap-1",children:[a.jsx(ua,{className:"h-3 w-3"}),"已安装"]})}return null},ce=R=>!D||!R.manifest?.host_application?!0:bme(R.manifest.host_application.min_version,R.manifest.host_application.max_version,D),W=R=>{if(!R.installed||!R.installed_version||!R.manifest?.version)return!1;const me=R.installed_version.trim(),Y=R.manifest.version.trim();if(me===Y)return!1;const P=me.split(".").map(Number),K=Y.split(".").map(Number);for(let $=0;$<3;$++){if((K[$]||0)>(P[$]||0))return!0;if((K[$]||0)<(P[$]||0))return!1}return!1},J=p.filter(R=>{if(!R.manifest)return console.warn("[过滤] 跳过无 manifest 的插件:",R.id),!1;const me=r===""||R.manifest.name?.toLowerCase().includes(r.toLowerCase())||R.manifest.description?.toLowerCase().includes(r.toLowerCase())||R.manifest.keywords&&R.manifest.keywords.some($=>$.toLowerCase().includes(r.toLowerCase())),Y=i==="all"||R.manifest.categories&&R.manifest.categories.includes(i);let P=!0;c==="installed"?P=R.installed===!0:c==="updates"&&(P=R.installed===!0&&W(R));const K=!h||!D||ce(R);return me&&Y&&P&&K}),H=()=>{n(null)},ae=async R=>{if(!j?.installed){B({title:"无法安装",description:"Git 未安装",variant:"destructive"});return}if(D&&!ce(R)){B({title:"无法安装",description:"插件与当前麦麦版本不兼容",variant:"destructive"});return}try{await Sme(R.id,R.manifest.repository_url||"","main"),Tme(R.id).catch(Y=>{console.warn("Failed to record download:",Y)}),B({title:"安装成功",description:`${R.manifest.name} 已成功安装`});const me=await Bp();z(me),x(Y=>Y.map(P=>{if(P.id===R.id){const K=Ip(P.id,me),$=qp(P.id,me);return{...P,installed:K,installed_version:$}}return P}))}catch(me){B({title:"安装失败",description:me instanceof Error?me.message:"未知错误",variant:"destructive"})}},ne=async R=>{try{await kme(R.id),B({title:"卸载成功",description:`${R.manifest.name} 已成功卸载`});const me=await Bp();z(me),x(Y=>Y.map(P=>{if(P.id===R.id){const K=Ip(P.id,me),$=qp(P.id,me);return{...P,installed:K,installed_version:$}}return P}))}catch(me){B({title:"卸载失败",description:me instanceof Error?me.message:"未知错误",variant:"destructive"})}},ue=async R=>{if(!j?.installed){B({title:"无法更新",description:"Git 未安装",variant:"destructive"});return}try{const me=await Ome(R.id,R.manifest.repository_url||"","main");B({title:"更新成功",description:`${R.manifest.name} 已从 ${me.old_version} 更新到 ${me.new_version}`});const Y=await Bp();z(Y),x(P=>P.map(K=>{if(K.id===R.id){const $=Ip(K.id,Y),fe=qp(K.id,Y);return{...K,installed:$,installed_version:fe}}return K}))}catch(me){B({title:"更新失败",description:me instanceof Error?me.message:"未知错误",variant:"destructive"})}};return a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件市场"}),a.jsx("p",{className:"text-muted-foreground mt-2",children:"浏览和管理麦麦的插件"})]}),a.jsxs(ie,{onClick:()=>t({to:"/plugin-mirrors"}),children:[a.jsx(Cq,{className:"h-4 w-4 mr-2"}),"配置镜像源"]})]}),j&&!j.installed&&a.jsxs(yt,{className:"border-orange-600 bg-orange-50 dark:bg-orange-950/20",children:[a.jsx(Jt,{children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(Hu,{className:"h-5 w-5 text-orange-600"}),a.jsxs("div",{children:[a.jsx(en,{className:"text-lg text-orange-900 dark:text-orange-100",children:"Git 未安装"}),a.jsx(Sr,{className:"text-orange-800 dark:text-orange-200",children:j.error||"请先安装 Git 才能使用插件安装功能"})]})]})}),a.jsx(vn,{children:a.jsxs("p",{className:"text-sm text-orange-800 dark:text-orange-200",children:["您可以从 ",a.jsx("a",{href:"https://git-scm.com/downloads",target:"_blank",rel:"noopener noreferrer",className:"underline font-medium",children:"git-scm.com"})," 下载并安装 Git。 安装完成后,请重启麦麦应用。"]})})]}),a.jsx(yt,{className:"p-4",children:a.jsxs("div",{className:"flex flex-col gap-4",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[a.jsxs("div",{className:"flex-1 relative",children:[a.jsx(Ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),a.jsx(Ae,{placeholder:"搜索插件...",value:r,onChange:R=>s(R.target.value),className:"pl-9"})]}),a.jsxs(Bt,{value:i,onValueChange:l,children:[a.jsx(Dt,{className:"w-full sm:w-[200px]",children:a.jsx(It,{placeholder:"选择分类"})}),a.jsxs(Rt,{children:[a.jsx(Pe,{value:"all",children:"全部分类"}),a.jsx(Pe,{value:"Group Management",children:"群组管理"}),a.jsx(Pe,{value:"Entertainment & Interaction",children:"娱乐互动"}),a.jsx(Pe,{value:"Utility Tools",children:"实用工具"}),a.jsx(Pe,{value:"Content Generation",children:"内容生成"}),a.jsx(Pe,{value:"Multimedia",children:"多媒体"}),a.jsx(Pe,{value:"External Integration",children:"外部集成"}),a.jsx(Pe,{value:"Data Analysis & Insights",children:"数据分析与洞察"}),a.jsx(Pe,{value:"Other",children:"其他"})]})]})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(ss,{id:"compatible-only",checked:h,onCheckedChange:R=>m(R===!0)}),a.jsx("label",{htmlFor:"compatible-only",className:"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer",children:"只显示兼容当前版本的插件"})]})]})}),a.jsx(dl,{value:c,onValueChange:d,className:"w-full",children:a.jsxs(va,{className:"grid w-full grid-cols-3",children:[a.jsxs($t,{value:"all",children:["全部插件 (",p.filter(R=>{if(!R.manifest)return!1;const me=r===""||R.manifest.name?.toLowerCase().includes(r.toLowerCase())||R.manifest.description?.toLowerCase().includes(r.toLowerCase())||R.manifest.keywords&&R.manifest.keywords.some(K=>K.toLowerCase().includes(r.toLowerCase())),Y=i==="all"||R.manifest.categories&&R.manifest.categories.includes(i),P=!h||!D||ce(R);return me&&Y&&P}).length,")"]}),a.jsxs($t,{value:"installed",children:["已安装 (",p.filter(R=>{if(!R.manifest)return!1;const me=r===""||R.manifest.name?.toLowerCase().includes(r.toLowerCase())||R.manifest.description?.toLowerCase().includes(r.toLowerCase())||R.manifest.keywords&&R.manifest.keywords.some(K=>K.toLowerCase().includes(r.toLowerCase())),Y=i==="all"||R.manifest.categories&&R.manifest.categories.includes(i),P=!h||!D||ce(R);return R.installed&&me&&Y&&P}).length,")"]}),a.jsxs($t,{value:"updates",children:["可更新 (",p.filter(R=>{if(!R.manifest)return!1;const me=r===""||R.manifest.name?.toLowerCase().includes(r.toLowerCase())||R.manifest.description?.toLowerCase().includes(r.toLowerCase())||R.manifest.keywords&&R.manifest.keywords.some(K=>K.toLowerCase().includes(r.toLowerCase())),Y=i==="all"||R.manifest.categories&&R.manifest.categories.includes(i),P=!h||!D||ce(R);return R.installed&&W(R)&&me&&Y&&P}).length,")"]})]})}),M&&M.stage==="loading"&&a.jsx(yt,{className:"p-4",children:a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx(hf,{className:"h-4 w-4 animate-spin"}),a.jsxs("span",{className:"text-sm font-medium",children:[M.operation==="fetch"&&"加载插件列表",M.operation==="install"&&`安装插件${M.plugin_id?`: ${M.plugin_id}`:""}`,M.operation==="uninstall"&&`卸载插件${M.plugin_id?`: ${M.plugin_id}`:""}`,M.operation==="update"&&`更新插件${M.plugin_id?`: ${M.plugin_id}`:""}`]})]}),a.jsxs("span",{className:"text-sm font-medium",children:[M.progress,"%"]})]}),a.jsx(n0,{value:M.progress,className:"h-2"}),a.jsx("div",{className:"text-xs text-muted-foreground",children:M.message}),M.operation==="fetch"&&M.total_plugins>0&&a.jsxs("div",{className:"text-xs text-muted-foreground text-center",children:["已加载 ",M.loaded_plugins," / ",M.total_plugins," 个插件"]})]})}),M&&M.stage==="error"&&M.error&&a.jsx(yt,{className:"border-destructive bg-destructive/10",children:a.jsx(Jt,{children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(Hu,{className:"h-5 w-5 text-destructive"}),a.jsxs("div",{children:[a.jsx(en,{className:"text-lg text-destructive",children:"加载失败"}),a.jsx(Sr,{className:"text-destructive/80",children:M.error})]})]})})}),v?a.jsxs("div",{className:"flex items-center justify-center py-12",children:[a.jsx(hf,{className:"h-8 w-8 animate-spin text-muted-foreground"}),a.jsx("span",{className:"ml-3 text-muted-foreground",children:"加载插件列表中..."})]}):k?a.jsx(yt,{className:"p-6",children:a.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[a.jsx(Hu,{className:"h-12 w-12 text-destructive mb-4"}),a.jsx("h3",{className:"text-lg font-semibold mb-2",children:"加载失败"}),a.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:k}),a.jsx(ie,{onClick:()=>window.location.reload(),children:"重新加载"})]})}):J.length===0?a.jsx(yt,{className:"p-6",children:a.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[a.jsx(Ps,{className:"h-12 w-12 text-muted-foreground mb-4"}),a.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未找到插件"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:r||i!=="all"?"尝试调整搜索条件或筛选器":"暂无可用插件"})]})}):a.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:J.map(R=>a.jsxs(yt,{className:"flex flex-col hover:shadow-lg transition-shadow h-full",children:[a.jsxs(Jt,{children:[a.jsxs("div",{className:"flex items-start justify-between gap-2",children:[a.jsx(en,{className:"text-xl",children:R.manifest?.name||R.id}),a.jsxs("div",{className:"flex flex-col gap-1",children:[R.manifest?.categories&&R.manifest.categories[0]&&a.jsx($n,{variant:"secondary",className:"text-xs whitespace-nowrap",children:a9[R.manifest.categories[0]]||R.manifest.categories[0]}),V(R)]})]}),a.jsx(Sr,{className:"line-clamp-2",children:R.manifest?.description||"无描述"})]}),a.jsx(vn,{className:"flex-1",children:a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx(fc,{className:"h-4 w-4"}),a.jsx("span",{children:(Q[R.id]?.downloads??R.downloads??0).toLocaleString()})]}),a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx(Zl,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),a.jsx("span",{children:(Q[R.id]?.rating??R.rating??0).toFixed(1)})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-2",children:[R.manifest?.keywords&&R.manifest.keywords.slice(0,3).map(me=>a.jsx($n,{variant:"outline",className:"text-xs",children:me},me)),R.manifest?.keywords&&R.manifest.keywords.length>3&&a.jsxs($n,{variant:"outline",className:"text-xs",children:["+",R.manifest.keywords.length-3]})]}),a.jsxs("div",{className:"text-xs text-muted-foreground pt-2 border-t space-y-1",children:[a.jsxs("div",{children:["v",R.manifest?.version||"unknown"," · ",R.manifest?.author?.name||"Unknown"]}),R.manifest?.host_application&&a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx("span",{children:"支持:"}),a.jsxs("span",{className:"font-medium",children:[R.manifest.host_application.min_version,R.manifest.host_application.max_version?` - ${R.manifest.host_application.max_version}`:" - 最新版本"]})]})]})]})}),a.jsx(bC,{className:"pt-4",children:a.jsxs("div",{className:"flex items-center justify-end gap-2 w-full",children:[a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>n(R),children:"查看详情"}),R.installed?W(R)?a.jsxs(ie,{size:"sm",disabled:!j?.installed,title:j?.installed?void 0:"Git 未安装",onClick:()=>ue(R),children:[a.jsx(Ii,{className:"h-4 w-4 mr-1"}),"更新"]}):a.jsxs(ie,{variant:"destructive",size:"sm",disabled:!j?.installed,title:j?.installed?void 0:"Git 未安装",onClick:()=>ne(R),children:[a.jsx(Ht,{className:"h-4 w-4 mr-1"}),"卸载"]}):a.jsxs(ie,{size:"sm",disabled:!j?.installed||M?.operation==="install"||D!==null&&!ce(R),title:j?.installed?D!==null&&!ce(R)?`不兼容当前版本 (需要 ${R.manifest?.host_application?.min_version||"未知"}${R.manifest?.host_application?.max_version?` - ${R.manifest.host_application.max_version}`:"+"},当前 ${D?.version})`:void 0:"Git 未安装",onClick:()=>ae(R),children:[a.jsx(fc,{className:"h-4 w-4 mr-1"}),M?.operation==="install"&&M?.plugin_id===R.id?"安装中...":"安装"]})]})})]},R.id))}),a.jsx(Rr,{open:e!==null,onOpenChange:H,children:e&&e.manifest&&a.jsxs(Nr,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[a.jsx(Cr,{children:a.jsxs("div",{className:"flex items-start justify-between gap-4",children:[a.jsxs("div",{className:"space-y-2 flex-1",children:[a.jsx(Tr,{className:"text-2xl",children:e.manifest.name}),a.jsxs(Gr,{children:["作者: ",e.manifest.author?.name||"Unknown",e.manifest.author?.url&&a.jsx("a",{href:e.manifest.author.url,target:"_blank",rel:"noopener noreferrer",className:"ml-2 text-primary hover:underline",children:a.jsx(Yh,{className:"h-3 w-3 inline"})})]})]}),a.jsxs("div",{className:"flex flex-col gap-2",children:[e.manifest.categories&&e.manifest.categories[0]&&a.jsx($n,{variant:"secondary",children:a9[e.manifest.categories[0]]||e.manifest.categories[0]}),V(e)]})]})}),a.jsxs("div",{className:"space-y-6",children:[a.jsx(Ame,{pluginId:e.id}),a.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium",children:"版本"}),a.jsxs("p",{className:"text-sm text-muted-foreground",children:["v",e.manifest?.version||"unknown"]}),e.installed&&e.installed_version&&a.jsxs("p",{className:"text-xs text-muted-foreground",children:["已安装: v",e.installed_version]})]}),a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium",children:"下载量"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:(Q[e.id]?.downloads??e.downloads??0).toLocaleString()})]}),a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium",children:"评分"}),a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx(Zl,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),a.jsxs("span",{className:"text-sm text-muted-foreground",children:[(Q[e.id]?.rating??e.rating??0).toFixed(1)," (",Q[e.id]?.rating_count??e.review_count??0,")"]})]})]}),a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium",children:"许可证"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:e.manifest.license||"Unknown"})]}),a.jsxs("div",{className:"col-span-2",children:[a.jsx("p",{className:"text-sm font-medium",children:"支持版本"}),a.jsxs("p",{className:"text-sm text-muted-foreground",children:[e.manifest.host_application?.min_version||"未知",e.manifest.host_application?.max_version?` - ${e.manifest.host_application.max_version}`:" - 最新版本"]})]})]}),a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium mb-2",children:"关键词"}),a.jsx("div",{className:"flex flex-wrap gap-2",children:e.manifest.keywords&&e.manifest.keywords.map(R=>a.jsx($n,{variant:"outline",children:R},R))})]}),e.detailed_description&&a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium mb-2",children:"详细说明"}),a.jsx("p",{className:"text-sm text-muted-foreground whitespace-pre-line",children:e.detailed_description})]}),!e.detailed_description&&a.jsxs("div",{children:[a.jsx("p",{className:"text-sm font-medium mb-2",children:"说明"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:e.manifest.description||"无描述"})]}),a.jsxs("div",{className:"space-y-2",children:[e.manifest.homepage_url&&a.jsxs("div",{className:"text-sm",children:[a.jsx("span",{className:"font-medium",children:"主页: "}),a.jsx("a",{href:e.manifest.homepage_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:e.manifest.homepage_url})]}),e.manifest.repository_url&&a.jsxs("div",{className:"text-sm",children:[a.jsx("span",{className:"font-medium",children:"仓库: "}),a.jsx("a",{href:e.manifest.repository_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:e.manifest.repository_url})]})]})]}),a.jsxs(ps,{children:[e.manifest.homepage_url&&a.jsxs(ie,{onClick:()=>window.open(e.manifest.homepage_url,"_blank"),children:[a.jsx(Yh,{className:"h-4 w-4 mr-2"}),"访问主页"]}),e.manifest.repository_url&&a.jsxs(ie,{variant:"outline",onClick:()=>window.open(e.manifest.repository_url,"_blank"),children:[a.jsx(Yh,{className:"h-4 w-4 mr-2"}),"查看仓库"]})]})]})})]})})}function _me(){return a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件配置"}),a.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理和配置已安装的插件"})]}),a.jsxs("div",{className:"flex gap-2",children:[a.jsxs(ie,{variant:"outline",size:"sm",children:[a.jsx(Ii,{className:"h-4 w-4 mr-2"}),"刷新"]}),a.jsxs(ie,{size:"sm",children:[a.jsx(dc,{className:"h-4 w-4 mr-2"}),"全局设置"]})]})]}),a.jsxs("div",{className:"grid gap-4 grid-cols-1 xs:grid-cols-2 lg:grid-cols-4",children:[a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"已安装插件"}),a.jsx(pg,{className:"h-4 w-4 text-muted-foreground"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-2xl font-bold",children:"0"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"正在加载..."})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"已启用"}),a.jsx(ua,{className:"h-4 w-4 text-green-600"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-2xl font-bold",children:"0"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"运行中的插件"})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"已禁用"}),a.jsx(xc,{className:"h-4 w-4 text-orange-600"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-2xl font-bold",children:"0"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"未激活的插件"})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[a.jsx(en,{className:"text-sm font-medium",children:"可更新"}),a.jsx(Ii,{className:"h-4 w-4 text-blue-600"})]}),a.jsxs(vn,{children:[a.jsx("div",{className:"text-2xl font-bold",children:"0"}),a.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"有新版本可用"})]})]})]}),a.jsxs(yt,{children:[a.jsxs(Jt,{children:[a.jsx(en,{children:"已安装的插件"}),a.jsx(Sr,{children:"查看和管理已安装插件的配置"})]}),a.jsx(vn,{children:a.jsxs("div",{className:"flex flex-col items-center justify-center py-12 space-y-4",children:[a.jsx(pg,{className:"h-16 w-16 text-muted-foreground/50"}),a.jsxs("div",{className:"text-center space-y-2",children:[a.jsx("p",{className:"text-lg font-medium text-muted-foreground",children:"插件配置功能开发中"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"即将支持插件的启用/禁用、参数配置等功能"})]}),a.jsx("div",{className:"flex gap-2",children:a.jsx(ie,{variant:"outline",asChild:!0,children:a.jsxs("a",{href:"/plugins",children:[a.jsx(Yh,{className:"h-4 w-4 mr-2"}),"前往插件市场"]})})})]})})]}),a.jsx(yt,{className:"border-blue-200 bg-blue-50 dark:bg-blue-950/20 dark:border-blue-900",children:a.jsx(vn,{className:"pt-6",children:a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx(xc,{className:"h-5 w-5 text-blue-600 mt-0.5 flex-shrink-0"}),a.jsxs("div",{className:"space-y-1",children:[a.jsx("p",{className:"text-sm font-medium text-blue-900 dark:text-blue-100",children:"开发进行中"}),a.jsxs("p",{className:"text-sm text-blue-800 dark:text-blue-200",children:["插件配置功能正在积极开发中。目前您可以通过",a.jsx("strong",{children:"插件市场"}),"安装和卸载插件,完整的配置管理功能即将推出。"]})]})]})})})]})})}function Dme(){const t=ba(),{toast:e}=Pr(),[n,r]=S.useState([]),[s,i]=S.useState(!0),[l,c]=S.useState(null),[d,h]=S.useState(null),[m,p]=S.useState(!1),[x,v]=S.useState(!1),[b,k]=S.useState({id:"",name:"",raw_prefix:"",clone_prefix:"",enabled:!0,priority:1}),O=S.useCallback(async()=>{try{i(!0),c(null);const z=localStorage.getItem("access-token"),Q=await fetch("/api/webui/plugins/mirrors",{headers:{Authorization:`Bearer ${z}`}});if(!Q.ok)throw new Error("获取镜像源列表失败");const F=await Q.json();r(F.mirrors||[])}catch(z){const Q=z instanceof Error?z.message:"加载镜像源失败";c(Q),e({title:"加载失败",description:Q,variant:"destructive"})}finally{i(!1)}},[e]);S.useEffect(()=>{O()},[O]);const j=async()=>{try{const z=localStorage.getItem("access-token"),Q=await fetch("/api/webui/plugins/mirrors",{method:"POST",headers:{Authorization:`Bearer ${z}`,"Content-Type":"application/json"},body:JSON.stringify(b)});if(!Q.ok){const F=await Q.json();throw new Error(F.detail||"添加镜像源失败")}e({title:"添加成功",description:"镜像源已添加"}),p(!1),k({id:"",name:"",raw_prefix:"",clone_prefix:"",enabled:!0,priority:1}),O()}catch(z){e({title:"添加失败",description:z instanceof Error?z.message:"未知错误",variant:"destructive"})}},T=async()=>{if(d)try{const z=localStorage.getItem("access-token");if(!(await fetch(`/api/webui/plugins/mirrors/${d.id}`,{method:"PUT",headers:{Authorization:`Bearer ${z}`,"Content-Type":"application/json"},body:JSON.stringify({name:b.name,raw_prefix:b.raw_prefix,clone_prefix:b.clone_prefix,enabled:b.enabled,priority:b.priority})})).ok)throw new Error("更新镜像源失败");e({title:"更新成功",description:"镜像源已更新"}),v(!1),h(null),O()}catch(z){e({title:"更新失败",description:z instanceof Error?z.message:"未知错误",variant:"destructive"})}},M=async z=>{if(confirm("确定要删除这个镜像源吗?"))try{const Q=localStorage.getItem("access-token");if(!(await fetch(`/api/webui/plugins/mirrors/${z}`,{method:"DELETE",headers:{Authorization:`Bearer ${Q}`}})).ok)throw new Error("删除镜像源失败");e({title:"删除成功",description:"镜像源已删除"}),O()}catch(Q){e({title:"删除失败",description:Q instanceof Error?Q.message:"未知错误",variant:"destructive"})}},_=async z=>{try{const Q=localStorage.getItem("access-token");if(!(await fetch(`/api/webui/plugins/mirrors/${z.id}`,{method:"PUT",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({enabled:!z.enabled})})).ok)throw new Error("更新状态失败");O()}catch(Q){e({title:"更新失败",description:Q instanceof Error?Q.message:"未知错误",variant:"destructive"})}},D=z=>{h(z),k({id:z.id,name:z.name,raw_prefix:z.raw_prefix,clone_prefix:z.clone_prefix,enabled:z.enabled,priority:z.priority}),v(!0)},E=async(z,Q)=>{const F=Q==="up"?z.priority-1:z.priority+1;if(!(F<1))try{const B=localStorage.getItem("access-token");if(!(await fetch(`/api/webui/plugins/mirrors/${z.id}`,{method:"PUT",headers:{Authorization:`Bearer ${B}`,"Content-Type":"application/json"},body:JSON.stringify({priority:F})})).ok)throw new Error("更新优先级失败");O()}catch(B){e({title:"更新失败",description:B instanceof Error?B.message:"未知错误",variant:"destructive"})}};return a.jsx(fn,{className:"h-full",children:a.jsxs("div",{className:"space-y-6 p-4 sm:p-6",children:[a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[a.jsxs("div",{className:"flex items-center gap-4",children:[a.jsx(ie,{variant:"ghost",size:"icon",onClick:()=>t({to:"/plugins"}),children:a.jsx(R9,{className:"h-5 w-5"})}),a.jsxs("div",{children:[a.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"镜像源配置"}),a.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"管理 Git 克隆和文件下载的镜像源"})]})]}),a.jsxs(ie,{onClick:()=>p(!0),children:[a.jsx(Wr,{className:"h-4 w-4 mr-2"}),"添加镜像源"]})]}),s?a.jsx(yt,{className:"p-6",children:a.jsx("div",{className:"flex items-center justify-center py-8",children:a.jsx(hf,{className:"h-8 w-8 animate-spin text-primary"})})}):l?a.jsx(yt,{className:"p-6",children:a.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[a.jsx(Hu,{className:"h-12 w-12 text-destructive mb-4"}),a.jsx("h3",{className:"text-lg font-semibold mb-2",children:"加载失败"}),a.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:l}),a.jsx(ie,{onClick:O,children:"重新加载"})]})}):a.jsxs(yt,{children:[a.jsx("div",{className:"hidden md:block",children:a.jsxs(Ac,{children:[a.jsx(Ec,{children:a.jsxs(xr,{children:[a.jsx(gt,{children:"状态"}),a.jsx(gt,{children:"名称"}),a.jsx(gt,{children:"ID"}),a.jsx(gt,{children:"优先级"}),a.jsx(gt,{className:"text-right",children:"操作"})]})}),a.jsx(_c,{children:n.map(z=>a.jsxs(xr,{children:[a.jsx(it,{children:a.jsx(jt,{checked:z.enabled,onCheckedChange:()=>_(z)})}),a.jsx(it,{children:a.jsxs("div",{children:[a.jsx("div",{className:"font-medium",children:z.name}),a.jsxs("div",{className:"text-xs text-muted-foreground mt-1",children:["Raw: ",z.raw_prefix]})]})}),a.jsx(it,{children:a.jsx($n,{variant:"outline",children:z.id})}),a.jsx(it,{children:a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"font-mono",children:z.priority}),a.jsxs("div",{className:"flex flex-col gap-1",children:[a.jsx(ie,{variant:"ghost",size:"icon",className:"h-5 w-5",onClick:()=>E(z,"up"),disabled:z.priority===1,children:a.jsx(e2,{className:"h-3 w-3"})}),a.jsx(ie,{variant:"ghost",size:"icon",className:"h-5 w-5",onClick:()=>E(z,"down"),children:a.jsx(df,{className:"h-3 w-3"})})]})]})}),a.jsx(it,{className:"text-right",children:a.jsxs("div",{className:"flex items-center justify-end gap-2",children:[a.jsx(ie,{variant:"ghost",size:"icon",onClick:()=>D(z),children:a.jsx(nd,{className:"h-4 w-4"})}),a.jsx(ie,{variant:"ghost",size:"icon",onClick:()=>M(z.id),children:a.jsx(Ht,{className:"h-4 w-4 text-destructive"})})]})})]},z.id))})]})}),a.jsx("div",{className:"md:hidden p-4 space-y-4",children:n.map(z=>a.jsx(yt,{className:"p-4",children:a.jsxs("div",{className:"space-y-3",children:[a.jsxs("div",{className:"flex items-start justify-between",children:[a.jsxs("div",{className:"flex-1",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("h3",{className:"font-semibold",children:z.name}),z.enabled&&a.jsx($n,{variant:"default",className:"text-xs",children:"启用"})]}),a.jsx($n,{variant:"outline",className:"mt-1 text-xs",children:z.id})]}),a.jsx(jt,{checked:z.enabled,onCheckedChange:()=>_(z)})]}),a.jsxs("div",{className:"text-sm space-y-1",children:[a.jsxs("div",{className:"text-muted-foreground",children:[a.jsx("span",{className:"font-medium",children:"Raw: "}),a.jsx("span",{className:"break-all",children:z.raw_prefix})]}),a.jsxs("div",{className:"text-muted-foreground",children:[a.jsx("span",{className:"font-medium",children:"优先级: "}),a.jsx("span",{className:"font-mono",children:z.priority})]})]}),a.jsxs("div",{className:"flex items-center gap-2 pt-2 border-t",children:[a.jsxs(ie,{variant:"outline",size:"sm",className:"flex-1",onClick:()=>D(z),children:[a.jsx(nd,{className:"h-4 w-4 mr-1"}),"编辑"]}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>E(z,"up"),disabled:z.priority===1,children:a.jsx(e2,{className:"h-4 w-4"})}),a.jsx(ie,{variant:"outline",size:"sm",onClick:()=>E(z,"down"),children:a.jsx(df,{className:"h-4 w-4"})}),a.jsx(ie,{variant:"destructive",size:"sm",onClick:()=>M(z.id),children:a.jsx(Ht,{className:"h-4 w-4"})})]})]})},z.id))})]}),a.jsx(Rr,{open:m,onOpenChange:p,children:a.jsxs(Nr,{className:"max-w-lg",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"添加镜像源"}),a.jsx(Gr,{children:"添加新的 Git 镜像源配置"})]}),a.jsxs("div",{className:"space-y-4 py-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"add-id",children:"镜像源 ID *"}),a.jsx(Ae,{id:"add-id",placeholder:"例如: my-mirror",value:b.id,onChange:z=>k({...b,id:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"add-name",children:"名称 *"}),a.jsx(Ae,{id:"add-name",placeholder:"例如: 我的镜像源",value:b.name,onChange:z=>k({...b,name:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"add-raw",children:"Raw 文件前缀 *"}),a.jsx(Ae,{id:"add-raw",placeholder:"https://example.com/raw",value:b.raw_prefix,onChange:z=>k({...b,raw_prefix:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"add-clone",children:"克隆前缀 *"}),a.jsx(Ae,{id:"add-clone",placeholder:"https://example.com/clone",value:b.clone_prefix,onChange:z=>k({...b,clone_prefix:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"add-priority",children:"优先级"}),a.jsx(Ae,{id:"add-priority",type:"number",min:"1",value:b.priority,onChange:z=>k({...b,priority:parseInt(z.target.value)||1})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"数字越小优先级越高"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"add-enabled",checked:b.enabled,onCheckedChange:z=>k({...b,enabled:z})}),a.jsx(te,{htmlFor:"add-enabled",children:"启用此镜像源"})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>p(!1),children:"取消"}),a.jsx(ie,{onClick:j,children:"添加"})]})]})}),a.jsx(Rr,{open:x,onOpenChange:v,children:a.jsxs(Nr,{className:"max-w-lg",children:[a.jsxs(Cr,{children:[a.jsx(Tr,{children:"编辑镜像源"}),a.jsx(Gr,{children:"修改镜像源配置"})]}),a.jsxs("div",{className:"space-y-4 py-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{children:"镜像源 ID"}),a.jsx(Ae,{value:b.id,disabled:!0})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit-name",children:"名称 *"}),a.jsx(Ae,{id:"edit-name",value:b.name,onChange:z=>k({...b,name:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit-raw",children:"Raw 文件前缀 *"}),a.jsx(Ae,{id:"edit-raw",value:b.raw_prefix,onChange:z=>k({...b,raw_prefix:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit-clone",children:"克隆前缀 *"}),a.jsx(Ae,{id:"edit-clone",value:b.clone_prefix,onChange:z=>k({...b,clone_prefix:z.target.value})})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx(te,{htmlFor:"edit-priority",children:"优先级"}),a.jsx(Ae,{id:"edit-priority",type:"number",min:"1",value:b.priority,onChange:z=>k({...b,priority:parseInt(z.target.value)||1})}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"数字越小优先级越高"})]}),a.jsxs("div",{className:"flex items-center space-x-2",children:[a.jsx(jt,{id:"edit-enabled",checked:b.enabled,onCheckedChange:z=>k({...b,enabled:z})}),a.jsx(te,{htmlFor:"edit-enabled",children:"启用此镜像源"})]})]}),a.jsxs(ps,{children:[a.jsx(ie,{variant:"outline",onClick:()=>v(!1),children:"取消"}),a.jsx(ie,{onClick:T,children:"保存"})]})]})})]})})}const Rme=Nd("pointer-events-none inline-flex select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono font-medium opacity-100",{variants:{size:{sm:"h-5 text-[10px]",default:"h-6 text-xs",lg:"h-7 text-sm"}},defaultVariants:{size:"default"}}),Pz=S.forwardRef(({className:t,size:e,abbrTitle:n,children:r,...s},i)=>a.jsx("kbd",{className:ye(Rme({size:e,className:t})),ref:i,...s,children:n?a.jsx("abbr",{title:n,children:r}):r}));Pz.displayName="Kbd";const zme=[{icon:hg,title:"首页",description:"查看仪表板概览",path:"/",category:"概览"},{icon:io,title:"麦麦主程序配置",description:"配置麦麦的核心设置",path:"/config/bot",category:"配置"},{icon:z9,title:"麦麦模型提供商配置",description:"配置模型提供商",path:"/config/modelProvider",category:"配置"},{icon:P9,title:"麦麦模型配置",description:"配置模型参数",path:"/config/model",category:"配置"},{icon:K4,title:"表情包管理",description:"管理麦麦的表情包",path:"/resource/emoji",category:"资源"},{icon:Wf,title:"表达方式管理",description:"管理麦麦的表达方式",path:"/resource/expression",category:"资源"},{icon:L9,title:"人物信息管理",description:"管理人物信息",path:"/resource/person",category:"资源"},{icon:Tq,title:"统计信息",description:"查看使用统计",path:"/statistics",category:"监控"},{icon:pg,title:"插件市场",description:"浏览和安装插件",path:"/plugins",category:"扩展"},{icon:fg,title:"日志查看器",description:"查看系统日志",path:"/logs",category:"监控"},{icon:dc,title:"系统设置",description:"配置系统参数",path:"/settings",category:"系统"}];function Pme({open:t,onOpenChange:e}){const[n,r]=S.useState(""),[s,i]=S.useState(0),l=ba(),c=zme.filter(m=>m.title.toLowerCase().includes(n.toLowerCase())||m.description.toLowerCase().includes(n.toLowerCase())||m.category.toLowerCase().includes(n.toLowerCase()));S.useEffect(()=>{t&&(r(""),i(0))},[t]);const d=S.useCallback(m=>{l({to:m}),e(!1)},[l,e]),h=S.useCallback(m=>{m.key==="ArrowDown"?(m.preventDefault(),i(p=>(p+1)%c.length)):m.key==="ArrowUp"?(m.preventDefault(),i(p=>(p-1+c.length)%c.length)):m.key==="Enter"&&c[s]&&(m.preventDefault(),d(c[s].path))},[c,s,d]);return a.jsx(Rr,{open:t,onOpenChange:e,children:a.jsxs(Nr,{className:"max-w-2xl p-0 gap-0",children:[a.jsxs(Cr,{className:"px-4 pt-4 pb-0",children:[a.jsx(Tr,{className:"sr-only",children:"搜索"}),a.jsxs("div",{className:"relative",children:[a.jsx(Ps,{className:"absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground"}),a.jsx(Ae,{value:n,onChange:m=>{r(m.target.value),i(0)},onKeyDown:h,placeholder:"搜索页面...",className:"h-12 pl-11 text-base border-0 focus-visible:ring-0 shadow-none",autoFocus:!0})]})]}),a.jsx("div",{className:"border-t",children:a.jsx(fn,{className:"h-[400px]",children:c.length>0?a.jsx("div",{className:"p-2",children:c.map((m,p)=>{const x=m.icon;return a.jsxs("button",{onClick:()=>d(m.path),onMouseEnter:()=>i(p),className:ye("w-full flex items-center gap-3 px-3 py-2.5 rounded-md text-left transition-colors",p===s?"bg-accent text-accent-foreground":"hover:bg-accent/50"),children:[a.jsx(x,{className:"h-5 w-5 flex-shrink-0"}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:"font-medium text-sm",children:m.title}),a.jsx("div",{className:"text-xs text-muted-foreground truncate",children:m.description})]}),a.jsx("div",{className:"text-xs text-muted-foreground px-2 py-1 bg-muted rounded",children:m.category})]},m.path)})}):a.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[a.jsx(Ps,{className:"h-12 w-12 text-muted-foreground/50 mb-4"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:n?"未找到匹配的页面":"输入关键词开始搜索"})]})})}),a.jsx("div",{className:"border-t px-4 py-3 flex items-center justify-between text-xs text-muted-foreground",children:a.jsxs("div",{className:"flex items-center gap-4",children:[a.jsxs("span",{className:"flex items-center gap-1",children:[a.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"↑"}),a.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"↓"}),"导航"]}),a.jsxs("span",{className:"flex items-center gap-1",children:[a.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"Enter"}),"选择"]}),a.jsxs("span",{className:"flex items-center gap-1",children:[a.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"Esc"}),"关闭"]})]})})]})})}function Lme(t){const e=Bme(t),n=S.forwardRef((r,s)=>{const{children:i,...l}=r,c=S.Children.toArray(i),d=c.find(qme);if(d){const h=d.props.children,m=c.map(p=>p===d?S.Children.count(h)>1?S.Children.only(null):S.isValidElement(h)?h.props.children:null:p);return a.jsx(e,{...l,ref:s,children:S.isValidElement(h)?S.cloneElement(h,void 0,m):null})}return a.jsx(e,{...l,ref:s,children:i})});return n.displayName=`${t}.Slot`,n}function Bme(t){const e=S.forwardRef((n,r)=>{const{children:s,...i}=n;if(S.isValidElement(s)){const l=Qme(s),c=Fme(i,s.props);return s.type!==S.Fragment&&(c.ref=r?lo(r,l):l),S.cloneElement(s,c)}return S.Children.count(s)>1?S.Children.only(null):null});return e.displayName=`${t}.SlotClone`,e}var Ime=Symbol("radix.slottable");function qme(t){return S.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===Ime}function Fme(t,e){const n={...e};for(const r in e){const s=t[r],i=e[r];/^on[A-Z]/.test(r)?s&&i?n[r]=(...c)=>{const d=i(...c);return s(...c),d}:s&&(n[r]=s):r==="style"?n[r]={...s,...i}:r==="className"&&(n[r]=[s,i].filter(Boolean).join(" "))}return{...t,...n}}function Qme(t){let e=Object.getOwnPropertyDescriptor(t.props,"ref")?.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=Object.getOwnPropertyDescriptor(t,"ref")?.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}var z4=["Enter"," "],$me=["ArrowDown","PageUp","Home"],Lz=["ArrowUp","PageDown","End"],Hme=[...$me,...Lz],Ume={ltr:[...z4,"ArrowRight"],rtl:[...z4,"ArrowLeft"]},Vme={ltr:["ArrowLeft"],rtl:["ArrowRight"]},T0="Menu",[$f,Wme,Gme]=tx(T0),[Bc,Bz]=Hi(T0,[Gme,wd,fx]),M0=wd(),Iz=fx(),[qz,Ao]=Bc(T0),[Xme,A0]=Bc(T0),Fz=t=>{const{__scopeMenu:e,open:n=!1,children:r,dir:s,onOpenChange:i,modal:l=!0}=t,c=M0(e),[d,h]=S.useState(null),m=S.useRef(!1),p=es(i),x=Vf(s);return S.useEffect(()=>{const v=()=>{m.current=!0,document.addEventListener("pointerdown",b,{capture:!0,once:!0}),document.addEventListener("pointermove",b,{capture:!0,once:!0})},b=()=>m.current=!1;return document.addEventListener("keydown",v,{capture:!0}),()=>{document.removeEventListener("keydown",v,{capture:!0}),document.removeEventListener("pointerdown",b,{capture:!0}),document.removeEventListener("pointermove",b,{capture:!0})}},[]),a.jsx(ix,{...c,children:a.jsx(qz,{scope:e,open:n,onOpenChange:p,content:d,onContentChange:h,children:a.jsx(Xme,{scope:e,onClose:S.useCallback(()=>p(!1),[p]),isUsingKeyboardRef:m,dir:x,modal:l,children:r})})})};Fz.displayName=T0;var Yme="MenuAnchor",Z5=S.forwardRef((t,e)=>{const{__scopeMenu:n,...r}=t,s=M0(n);return a.jsx(ax,{...s,...r,ref:e})});Z5.displayName=Yme;var J5="MenuPortal",[Kme,Qz]=Bc(J5,{forceMount:void 0}),$z=t=>{const{__scopeMenu:e,forceMount:n,children:r,container:s}=t,i=Ao(J5,e);return a.jsx(Kme,{scope:e,forceMount:n,children:a.jsx(Ls,{present:n||i.open,children:a.jsx(sx,{asChild:!0,container:s,children:r})})})};$z.displayName=J5;var Ni="MenuContent",[Zme,e3]=Bc(Ni),Hz=S.forwardRef((t,e)=>{const n=Qz(Ni,t.__scopeMenu),{forceMount:r=n.forceMount,...s}=t,i=Ao(Ni,t.__scopeMenu),l=A0(Ni,t.__scopeMenu);return a.jsx($f.Provider,{scope:t.__scopeMenu,children:a.jsx(Ls,{present:r||i.open,children:a.jsx($f.Slot,{scope:t.__scopeMenu,children:l.modal?a.jsx(Jme,{...s,ref:e}):a.jsx(epe,{...s,ref:e})})})})}),Jme=S.forwardRef((t,e)=>{const n=Ao(Ni,t.__scopeMenu),r=S.useRef(null),s=Cn(e,r);return S.useEffect(()=>{const i=r.current;if(i)return j9(i)},[]),a.jsx(t3,{...t,ref:s,trapFocus:n.open,disableOutsidePointerEvents:n.open,disableOutsideScroll:!0,onFocusOutside:$e(t.onFocusOutside,i=>i.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:()=>n.onOpenChange(!1)})}),epe=S.forwardRef((t,e)=>{const n=Ao(Ni,t.__scopeMenu);return a.jsx(t3,{...t,ref:e,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:()=>n.onOpenChange(!1)})}),tpe=Lme("MenuContent.ScrollLock"),t3=S.forwardRef((t,e)=>{const{__scopeMenu:n,loop:r=!1,trapFocus:s,onOpenAutoFocus:i,onCloseAutoFocus:l,disableOutsidePointerEvents:c,onEntryFocus:d,onEscapeKeyDown:h,onPointerDownOutside:m,onFocusOutside:p,onInteractOutside:x,onDismiss:v,disableOutsideScroll:b,...k}=t,O=Ao(Ni,n),j=A0(Ni,n),T=M0(n),M=Iz(n),_=Wme(n),[D,E]=S.useState(null),z=S.useRef(null),Q=Cn(e,z,O.onContentChange),F=S.useRef(0),B=S.useRef(""),U=S.useRef(0),V=S.useRef(null),ce=S.useRef("right"),W=S.useRef(0),J=b?N9:S.Fragment,H=b?{as:tpe,allowPinchZoom:!0}:void 0,ae=ue=>{const R=B.current+ue,me=_().filter(ve=>!ve.disabled),Y=document.activeElement,P=me.find(ve=>ve.ref.current===Y)?.textValue,K=me.map(ve=>ve.textValue),$=fpe(K,R,P),fe=me.find(ve=>ve.textValue===$)?.ref.current;(function ve(Re){B.current=Re,window.clearTimeout(F.current),Re!==""&&(F.current=window.setTimeout(()=>ve(""),1e3))})(R),fe&&setTimeout(()=>fe.focus())};S.useEffect(()=>()=>window.clearTimeout(F.current),[]),C9();const ne=S.useCallback(ue=>ce.current===V.current?.side&&ppe(ue,V.current?.area),[]);return a.jsx(Zme,{scope:n,searchRef:B,onItemEnter:S.useCallback(ue=>{ne(ue)&&ue.preventDefault()},[ne]),onItemLeave:S.useCallback(ue=>{ne(ue)||(z.current?.focus(),E(null))},[ne]),onTriggerLeave:S.useCallback(ue=>{ne(ue)&&ue.preventDefault()},[ne]),pointerGraceTimerRef:U,onPointerGraceIntentChange:S.useCallback(ue=>{V.current=ue},[]),children:a.jsx(J,{...H,children:a.jsx(T9,{asChild:!0,trapped:s,onMountAutoFocus:$e(i,ue=>{ue.preventDefault(),z.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:l,children:a.jsx(G4,{asChild:!0,disableOutsidePointerEvents:c,onEscapeKeyDown:h,onPointerDownOutside:m,onFocusOutside:p,onInteractOutside:x,onDismiss:v,children:a.jsx(NC,{asChild:!0,...M,dir:j.dir,orientation:"vertical",loop:r,currentTabStopId:D,onCurrentTabStopIdChange:E,onEntryFocus:$e(d,ue=>{j.isUsingKeyboardRef.current||ue.preventDefault()}),preventScrollOnEntryFocus:!0,children:a.jsx(X4,{role:"menu","aria-orientation":"vertical","data-state":lP(O.open),"data-radix-menu-content":"",dir:j.dir,...T,...k,ref:Q,style:{outline:"none",...k.style},onKeyDown:$e(k.onKeyDown,ue=>{const me=ue.target.closest("[data-radix-menu-content]")===ue.currentTarget,Y=ue.ctrlKey||ue.altKey||ue.metaKey,P=ue.key.length===1;me&&(ue.key==="Tab"&&ue.preventDefault(),!Y&&P&&ae(ue.key));const K=z.current;if(ue.target!==K||!Hme.includes(ue.key))return;ue.preventDefault();const fe=_().filter(ve=>!ve.disabled).map(ve=>ve.ref.current);Lz.includes(ue.key)&&fe.reverse(),dpe(fe)}),onBlur:$e(t.onBlur,ue=>{ue.currentTarget.contains(ue.target)||(window.clearTimeout(F.current),B.current="")}),onPointerMove:$e(t.onPointerMove,Hf(ue=>{const R=ue.target,me=W.current!==ue.clientX;if(ue.currentTarget.contains(R)&&me){const Y=ue.clientX>W.current?"right":"left";ce.current=Y,W.current=ue.clientX}}))})})})})})})});Hz.displayName=Ni;var npe="MenuGroup",n3=S.forwardRef((t,e)=>{const{__scopeMenu:n,...r}=t;return a.jsx(Yt.div,{role:"group",...r,ref:e})});n3.displayName=npe;var rpe="MenuLabel",Uz=S.forwardRef((t,e)=>{const{__scopeMenu:n,...r}=t;return a.jsx(Yt.div,{...r,ref:e})});Uz.displayName=rpe;var Jg="MenuItem",l9="menu.itemSelect",Kx=S.forwardRef((t,e)=>{const{disabled:n=!1,onSelect:r,...s}=t,i=S.useRef(null),l=A0(Jg,t.__scopeMenu),c=e3(Jg,t.__scopeMenu),d=Cn(e,i),h=S.useRef(!1),m=()=>{const p=i.current;if(!n&&p){const x=new CustomEvent(l9,{bubbles:!0,cancelable:!0});p.addEventListener(l9,v=>r?.(v),{once:!0}),A9(p,x),x.defaultPrevented?h.current=!1:l.onClose()}};return a.jsx(Vz,{...s,ref:d,disabled:n,onClick:$e(t.onClick,m),onPointerDown:p=>{t.onPointerDown?.(p),h.current=!0},onPointerUp:$e(t.onPointerUp,p=>{h.current||p.currentTarget?.click()}),onKeyDown:$e(t.onKeyDown,p=>{const x=c.searchRef.current!=="";n||x&&p.key===" "||z4.includes(p.key)&&(p.currentTarget.click(),p.preventDefault())})})});Kx.displayName=Jg;var Vz=S.forwardRef((t,e)=>{const{__scopeMenu:n,disabled:r=!1,textValue:s,...i}=t,l=e3(Jg,n),c=Iz(n),d=S.useRef(null),h=Cn(e,d),[m,p]=S.useState(!1),[x,v]=S.useState("");return S.useEffect(()=>{const b=d.current;b&&v((b.textContent??"").trim())},[i.children]),a.jsx($f.ItemSlot,{scope:n,disabled:r,textValue:s??x,children:a.jsx(CC,{asChild:!0,...c,focusable:!r,children:a.jsx(Yt.div,{role:"menuitem","data-highlighted":m?"":void 0,"aria-disabled":r||void 0,"data-disabled":r?"":void 0,...i,ref:h,onPointerMove:$e(t.onPointerMove,Hf(b=>{r?l.onItemLeave(b):(l.onItemEnter(b),b.defaultPrevented||b.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:$e(t.onPointerLeave,Hf(b=>l.onItemLeave(b))),onFocus:$e(t.onFocus,()=>p(!0)),onBlur:$e(t.onBlur,()=>p(!1))})})})}),spe="MenuCheckboxItem",Wz=S.forwardRef((t,e)=>{const{checked:n=!1,onCheckedChange:r,...s}=t;return a.jsx(Zz,{scope:t.__scopeMenu,checked:n,children:a.jsx(Kx,{role:"menuitemcheckbox","aria-checked":ex(n)?"mixed":n,...s,ref:e,"data-state":i3(n),onSelect:$e(s.onSelect,()=>r?.(ex(n)?!0:!n),{checkForDefaultPrevented:!1})})})});Wz.displayName=spe;var Gz="MenuRadioGroup",[ipe,ape]=Bc(Gz,{value:void 0,onValueChange:()=>{}}),Xz=S.forwardRef((t,e)=>{const{value:n,onValueChange:r,...s}=t,i=es(r);return a.jsx(ipe,{scope:t.__scopeMenu,value:n,onValueChange:i,children:a.jsx(n3,{...s,ref:e})})});Xz.displayName=Gz;var Yz="MenuRadioItem",Kz=S.forwardRef((t,e)=>{const{value:n,...r}=t,s=ape(Yz,t.__scopeMenu),i=n===s.value;return a.jsx(Zz,{scope:t.__scopeMenu,checked:i,children:a.jsx(Kx,{role:"menuitemradio","aria-checked":i,...r,ref:e,"data-state":i3(i),onSelect:$e(r.onSelect,()=>s.onValueChange?.(n),{checkForDefaultPrevented:!1})})})});Kz.displayName=Yz;var r3="MenuItemIndicator",[Zz,lpe]=Bc(r3,{checked:!1}),Jz=S.forwardRef((t,e)=>{const{__scopeMenu:n,forceMount:r,...s}=t,i=lpe(r3,n);return a.jsx(Ls,{present:r||ex(i.checked)||i.checked===!0,children:a.jsx(Yt.span,{...s,ref:e,"data-state":i3(i.checked)})})});Jz.displayName=r3;var ope="MenuSeparator",eP=S.forwardRef((t,e)=>{const{__scopeMenu:n,...r}=t;return a.jsx(Yt.div,{role:"separator","aria-orientation":"horizontal",...r,ref:e})});eP.displayName=ope;var cpe="MenuArrow",tP=S.forwardRef((t,e)=>{const{__scopeMenu:n,...r}=t,s=M0(n);return a.jsx(Y4,{...s,...r,ref:e})});tP.displayName=cpe;var s3="MenuSub",[upe,nP]=Bc(s3),rP=t=>{const{__scopeMenu:e,children:n,open:r=!1,onOpenChange:s}=t,i=Ao(s3,e),l=M0(e),[c,d]=S.useState(null),[h,m]=S.useState(null),p=es(s);return S.useEffect(()=>(i.open===!1&&p(!1),()=>p(!1)),[i.open,p]),a.jsx(ix,{...l,children:a.jsx(qz,{scope:e,open:r,onOpenChange:p,content:h,onContentChange:m,children:a.jsx(upe,{scope:e,contentId:Oi(),triggerId:Oi(),trigger:c,onTriggerChange:d,children:n})})})};rP.displayName=s3;var Gh="MenuSubTrigger",sP=S.forwardRef((t,e)=>{const n=Ao(Gh,t.__scopeMenu),r=A0(Gh,t.__scopeMenu),s=nP(Gh,t.__scopeMenu),i=e3(Gh,t.__scopeMenu),l=S.useRef(null),{pointerGraceTimerRef:c,onPointerGraceIntentChange:d}=i,h={__scopeMenu:t.__scopeMenu},m=S.useCallback(()=>{l.current&&window.clearTimeout(l.current),l.current=null},[]);return S.useEffect(()=>m,[m]),S.useEffect(()=>{const p=c.current;return()=>{window.clearTimeout(p),d(null)}},[c,d]),a.jsx(Z5,{asChild:!0,...h,children:a.jsx(Vz,{id:s.triggerId,"aria-haspopup":"menu","aria-expanded":n.open,"aria-controls":s.contentId,"data-state":lP(n.open),...t,ref:lo(e,s.onTriggerChange),onClick:p=>{t.onClick?.(p),!(t.disabled||p.defaultPrevented)&&(p.currentTarget.focus(),n.open||n.onOpenChange(!0))},onPointerMove:$e(t.onPointerMove,Hf(p=>{i.onItemEnter(p),!p.defaultPrevented&&!t.disabled&&!n.open&&!l.current&&(i.onPointerGraceIntentChange(null),l.current=window.setTimeout(()=>{n.onOpenChange(!0),m()},100))})),onPointerLeave:$e(t.onPointerLeave,Hf(p=>{m();const x=n.content?.getBoundingClientRect();if(x){const v=n.content?.dataset.side,b=v==="right",k=b?-5:5,O=x[b?"left":"right"],j=x[b?"right":"left"];i.onPointerGraceIntentChange({area:[{x:p.clientX+k,y:p.clientY},{x:O,y:x.top},{x:j,y:x.top},{x:j,y:x.bottom},{x:O,y:x.bottom}],side:v}),window.clearTimeout(c.current),c.current=window.setTimeout(()=>i.onPointerGraceIntentChange(null),300)}else{if(i.onTriggerLeave(p),p.defaultPrevented)return;i.onPointerGraceIntentChange(null)}})),onKeyDown:$e(t.onKeyDown,p=>{const x=i.searchRef.current!=="";t.disabled||x&&p.key===" "||Ume[r.dir].includes(p.key)&&(n.onOpenChange(!0),n.content?.focus(),p.preventDefault())})})})});sP.displayName=Gh;var iP="MenuSubContent",aP=S.forwardRef((t,e)=>{const n=Qz(Ni,t.__scopeMenu),{forceMount:r=n.forceMount,...s}=t,i=Ao(Ni,t.__scopeMenu),l=A0(Ni,t.__scopeMenu),c=nP(iP,t.__scopeMenu),d=S.useRef(null),h=Cn(e,d);return a.jsx($f.Provider,{scope:t.__scopeMenu,children:a.jsx(Ls,{present:r||i.open,children:a.jsx($f.Slot,{scope:t.__scopeMenu,children:a.jsx(t3,{id:c.contentId,"aria-labelledby":c.triggerId,...s,ref:h,align:"start",side:l.dir==="rtl"?"left":"right",disableOutsidePointerEvents:!1,disableOutsideScroll:!1,trapFocus:!1,onOpenAutoFocus:m=>{l.isUsingKeyboardRef.current&&d.current?.focus(),m.preventDefault()},onCloseAutoFocus:m=>m.preventDefault(),onFocusOutside:$e(t.onFocusOutside,m=>{m.target!==c.trigger&&i.onOpenChange(!1)}),onEscapeKeyDown:$e(t.onEscapeKeyDown,m=>{l.onClose(),m.preventDefault()}),onKeyDown:$e(t.onKeyDown,m=>{const p=m.currentTarget.contains(m.target),x=Vme[l.dir].includes(m.key);p&&x&&(i.onOpenChange(!1),c.trigger?.focus(),m.preventDefault())})})})})})});aP.displayName=iP;function lP(t){return t?"open":"closed"}function ex(t){return t==="indeterminate"}function i3(t){return ex(t)?"indeterminate":t?"checked":"unchecked"}function dpe(t){const e=document.activeElement;for(const n of t)if(n===e||(n.focus(),document.activeElement!==e))return}function hpe(t,e){return t.map((n,r)=>t[(e+r)%t.length])}function fpe(t,e,n){const s=e.length>1&&Array.from(e).every(h=>h===e[0])?e[0]:e,i=n?t.indexOf(n):-1;let l=hpe(t,Math.max(i,0));s.length===1&&(l=l.filter(h=>h!==n));const d=l.find(h=>h.toLowerCase().startsWith(s.toLowerCase()));return d!==n?d:void 0}function mpe(t,e){const{x:n,y:r}=t;let s=!1;for(let i=0,l=e.length-1;ir!=x>r&&n<(p-h)*(r-m)/(x-m)+h&&(s=!s)}return s}function ppe(t,e){if(!e)return!1;const n={x:t.clientX,y:t.clientY};return mpe(n,e)}function Hf(t){return e=>e.pointerType==="mouse"?t(e):void 0}var gpe=Fz,xpe=Z5,vpe=$z,ype=Hz,bpe=n3,wpe=Uz,Spe=Kx,kpe=Wz,Ope=Xz,jpe=Kz,Npe=Jz,Cpe=eP,Tpe=tP,Mpe=rP,Ape=sP,Epe=aP,a3="ContextMenu",[_pe]=Hi(a3,[Bz]),ls=Bz(),[Dpe,oP]=_pe(a3),cP=t=>{const{__scopeContextMenu:e,children:n,onOpenChange:r,dir:s,modal:i=!0}=t,[l,c]=S.useState(!1),d=ls(e),h=es(r),m=S.useCallback(p=>{c(p),h(p)},[h]);return a.jsx(Dpe,{scope:e,open:l,onOpenChange:m,modal:i,children:a.jsx(gpe,{...d,dir:s,open:l,onOpenChange:m,modal:i,children:n})})};cP.displayName=a3;var uP="ContextMenuTrigger",dP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,disabled:r=!1,...s}=t,i=oP(uP,n),l=ls(n),c=S.useRef({x:0,y:0}),d=S.useRef({getBoundingClientRect:()=>DOMRect.fromRect({width:0,height:0,...c.current})}),h=S.useRef(0),m=S.useCallback(()=>window.clearTimeout(h.current),[]),p=x=>{c.current={x:x.clientX,y:x.clientY},i.onOpenChange(!0)};return S.useEffect(()=>m,[m]),S.useEffect(()=>void(r&&m()),[r,m]),a.jsxs(a.Fragment,{children:[a.jsx(xpe,{...l,virtualRef:d}),a.jsx(Yt.span,{"data-state":i.open?"open":"closed","data-disabled":r?"":void 0,...s,ref:e,style:{WebkitTouchCallout:"none",...t.style},onContextMenu:r?t.onContextMenu:$e(t.onContextMenu,x=>{m(),p(x),x.preventDefault()}),onPointerDown:r?t.onPointerDown:$e(t.onPointerDown,Fp(x=>{m(),h.current=window.setTimeout(()=>p(x),700)})),onPointerMove:r?t.onPointerMove:$e(t.onPointerMove,Fp(m)),onPointerCancel:r?t.onPointerCancel:$e(t.onPointerCancel,Fp(m)),onPointerUp:r?t.onPointerUp:$e(t.onPointerUp,Fp(m))})]})});dP.displayName=uP;var Rpe="ContextMenuPortal",hP=t=>{const{__scopeContextMenu:e,...n}=t,r=ls(e);return a.jsx(vpe,{...r,...n})};hP.displayName=Rpe;var fP="ContextMenuContent",mP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=oP(fP,n),i=ls(n),l=S.useRef(!1);return a.jsx(ype,{...i,...r,ref:e,side:"right",sideOffset:2,align:"start",onCloseAutoFocus:c=>{t.onCloseAutoFocus?.(c),!c.defaultPrevented&&l.current&&c.preventDefault(),l.current=!1},onInteractOutside:c=>{t.onInteractOutside?.(c),!c.defaultPrevented&&!s.modal&&(l.current=!0)},style:{...t.style,"--radix-context-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-context-menu-content-available-width":"var(--radix-popper-available-width)","--radix-context-menu-content-available-height":"var(--radix-popper-available-height)","--radix-context-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-context-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});mP.displayName=fP;var zpe="ContextMenuGroup",Ppe=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(bpe,{...s,...r,ref:e})});Ppe.displayName=zpe;var Lpe="ContextMenuLabel",pP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(wpe,{...s,...r,ref:e})});pP.displayName=Lpe;var Bpe="ContextMenuItem",gP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Spe,{...s,...r,ref:e})});gP.displayName=Bpe;var Ipe="ContextMenuCheckboxItem",xP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(kpe,{...s,...r,ref:e})});xP.displayName=Ipe;var qpe="ContextMenuRadioGroup",Fpe=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Ope,{...s,...r,ref:e})});Fpe.displayName=qpe;var Qpe="ContextMenuRadioItem",vP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(jpe,{...s,...r,ref:e})});vP.displayName=Qpe;var $pe="ContextMenuItemIndicator",yP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Npe,{...s,...r,ref:e})});yP.displayName=$pe;var Hpe="ContextMenuSeparator",bP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Cpe,{...s,...r,ref:e})});bP.displayName=Hpe;var Upe="ContextMenuArrow",Vpe=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Tpe,{...s,...r,ref:e})});Vpe.displayName=Upe;var wP="ContextMenuSub",SP=t=>{const{__scopeContextMenu:e,children:n,onOpenChange:r,open:s,defaultOpen:i}=t,l=ls(e),[c,d]=So({prop:s,defaultProp:i??!1,onChange:r,caller:wP});return a.jsx(Mpe,{...l,open:c,onOpenChange:d,children:n})};SP.displayName=wP;var Wpe="ContextMenuSubTrigger",kP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Ape,{...s,...r,ref:e})});kP.displayName=Wpe;var Gpe="ContextMenuSubContent",OP=S.forwardRef((t,e)=>{const{__scopeContextMenu:n,...r}=t,s=ls(n);return a.jsx(Epe,{...s,...r,ref:e,style:{...t.style,"--radix-context-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-context-menu-content-available-width":"var(--radix-popper-available-width)","--radix-context-menu-content-available-height":"var(--radix-popper-available-height)","--radix-context-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-context-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});OP.displayName=Gpe;function Fp(t){return e=>e.pointerType!=="mouse"?t(e):void 0}var Xpe=cP,Ype=dP,Kpe=hP,jP=mP,NP=pP,CP=gP,TP=xP,MP=vP,AP=yP,EP=bP,Zpe=SP,_P=kP,DP=OP;const Jpe=Xpe,ege=Ype,tge=Zpe,RP=S.forwardRef(({className:t,inset:e,children:n,...r},s)=>a.jsxs(_P,{ref:s,className:ye("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",e&&"pl-8",t),...r,children:[n,a.jsx(Mc,{className:"ml-auto h-4 w-4"})]}));RP.displayName=_P.displayName;const zP=S.forwardRef(({className:t,...e},n)=>a.jsx(DP,{ref:n,className:ye("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-context-menu-content-transform-origin]",t),...e}));zP.displayName=DP.displayName;const PP=S.forwardRef(({className:t,...e},n)=>a.jsx(Kpe,{children:a.jsx(jP,{ref:n,className:ye("z-50 max-h-[--radix-context-menu-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-context-menu-content-transform-origin]",t),...e})}));PP.displayName=jP.displayName;const Pi=S.forwardRef(({className:t,inset:e,...n},r)=>a.jsx(CP,{ref:r,className:ye("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",e&&"pl-8",t),...n}));Pi.displayName=CP.displayName;const nge=S.forwardRef(({className:t,children:e,checked:n,...r},s)=>a.jsxs(TP,{ref:s,className:ye("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),checked:n,...r,children:[a.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:a.jsx(AP,{children:a.jsx(hc,{className:"h-4 w-4"})})}),e]}));nge.displayName=TP.displayName;const rge=S.forwardRef(({className:t,children:e,...n},r)=>a.jsxs(MP,{ref:r,className:ye("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...n,children:[a.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:a.jsx(AP,{children:a.jsx(Mq,{className:"h-2 w-2 fill-current"})})}),e]}));rge.displayName=MP.displayName;const sge=S.forwardRef(({className:t,inset:e,...n},r)=>a.jsx(NP,{ref:r,className:ye("px-2 py-1.5 text-sm font-semibold text-foreground",e&&"pl-8",t),...n}));sge.displayName=NP.displayName;const Xh=S.forwardRef(({className:t,...e},n)=>a.jsx(EP,{ref:n,className:ye("-mx-1 my-1 h-px bg-border",t),...e}));Xh.displayName=EP.displayName;const qu=({className:t,...e})=>a.jsx("span",{className:ye("ml-auto text-xs tracking-widest text-muted-foreground",t),...e});qu.displayName="ContextMenuShortcut";var ige=Symbol("radix.slottable");function age(t){const e=({children:n})=>a.jsx(a.Fragment,{children:n});return e.displayName=`${t}.Slottable`,e.__radixId=ige,e}var[Zx]=Hi("Tooltip",[wd]),Jx=wd(),LP="TooltipProvider",lge=700,P4="tooltip.open",[oge,l3]=Zx(LP),BP=t=>{const{__scopeTooltip:e,delayDuration:n=lge,skipDelayDuration:r=300,disableHoverableContent:s=!1,children:i}=t,l=S.useRef(!0),c=S.useRef(!1),d=S.useRef(0);return S.useEffect(()=>{const h=d.current;return()=>window.clearTimeout(h)},[]),a.jsx(oge,{scope:e,isOpenDelayedRef:l,delayDuration:n,onOpen:S.useCallback(()=>{window.clearTimeout(d.current),l.current=!1},[]),onClose:S.useCallback(()=>{window.clearTimeout(d.current),d.current=window.setTimeout(()=>l.current=!0,r)},[r]),isPointerInTransitRef:c,onPointerInTransitChange:S.useCallback(h=>{c.current=h},[]),disableHoverableContent:s,children:i})};BP.displayName=LP;var Uf="Tooltip",[cge,E0]=Zx(Uf),IP=t=>{const{__scopeTooltip:e,children:n,open:r,defaultOpen:s,onOpenChange:i,disableHoverableContent:l,delayDuration:c}=t,d=l3(Uf,t.__scopeTooltip),h=Jx(e),[m,p]=S.useState(null),x=Oi(),v=S.useRef(0),b=l??d.disableHoverableContent,k=c??d.delayDuration,O=S.useRef(!1),[j,T]=So({prop:r,defaultProp:s??!1,onChange:z=>{z?(d.onOpen(),document.dispatchEvent(new CustomEvent(P4))):d.onClose(),i?.(z)},caller:Uf}),M=S.useMemo(()=>j?O.current?"delayed-open":"instant-open":"closed",[j]),_=S.useCallback(()=>{window.clearTimeout(v.current),v.current=0,O.current=!1,T(!0)},[T]),D=S.useCallback(()=>{window.clearTimeout(v.current),v.current=0,T(!1)},[T]),E=S.useCallback(()=>{window.clearTimeout(v.current),v.current=window.setTimeout(()=>{O.current=!0,T(!0),v.current=0},k)},[k,T]);return S.useEffect(()=>()=>{v.current&&(window.clearTimeout(v.current),v.current=0)},[]),a.jsx(ix,{...h,children:a.jsx(cge,{scope:e,contentId:x,open:j,stateAttribute:M,trigger:m,onTriggerChange:p,onTriggerEnter:S.useCallback(()=>{d.isOpenDelayedRef.current?E():_()},[d.isOpenDelayedRef,E,_]),onTriggerLeave:S.useCallback(()=>{b?D():(window.clearTimeout(v.current),v.current=0)},[D,b]),onOpen:_,onClose:D,disableHoverableContent:b,children:n})})};IP.displayName=Uf;var L4="TooltipTrigger",qP=S.forwardRef((t,e)=>{const{__scopeTooltip:n,...r}=t,s=E0(L4,n),i=l3(L4,n),l=Jx(n),c=S.useRef(null),d=Cn(e,c,s.onTriggerChange),h=S.useRef(!1),m=S.useRef(!1),p=S.useCallback(()=>h.current=!1,[]);return S.useEffect(()=>()=>document.removeEventListener("pointerup",p),[p]),a.jsx(ax,{asChild:!0,...l,children:a.jsx(Yt.button,{"aria-describedby":s.open?s.contentId:void 0,"data-state":s.stateAttribute,...r,ref:d,onPointerMove:$e(t.onPointerMove,x=>{x.pointerType!=="touch"&&!m.current&&!i.isPointerInTransitRef.current&&(s.onTriggerEnter(),m.current=!0)}),onPointerLeave:$e(t.onPointerLeave,()=>{s.onTriggerLeave(),m.current=!1}),onPointerDown:$e(t.onPointerDown,()=>{s.open&&s.onClose(),h.current=!0,document.addEventListener("pointerup",p,{once:!0})}),onFocus:$e(t.onFocus,()=>{h.current||s.onOpen()}),onBlur:$e(t.onBlur,s.onClose),onClick:$e(t.onClick,s.onClose)})})});qP.displayName=L4;var o3="TooltipPortal",[uge,dge]=Zx(o3,{forceMount:void 0}),FP=t=>{const{__scopeTooltip:e,forceMount:n,children:r,container:s}=t,i=E0(o3,e);return a.jsx(uge,{scope:e,forceMount:n,children:a.jsx(Ls,{present:n||i.open,children:a.jsx(sx,{asChild:!0,container:s,children:r})})})};FP.displayName=o3;var bd="TooltipContent",QP=S.forwardRef((t,e)=>{const n=dge(bd,t.__scopeTooltip),{forceMount:r=n.forceMount,side:s="top",...i}=t,l=E0(bd,t.__scopeTooltip);return a.jsx(Ls,{present:r||l.open,children:l.disableHoverableContent?a.jsx($P,{side:s,...i,ref:e}):a.jsx(hge,{side:s,...i,ref:e})})}),hge=S.forwardRef((t,e)=>{const n=E0(bd,t.__scopeTooltip),r=l3(bd,t.__scopeTooltip),s=S.useRef(null),i=Cn(e,s),[l,c]=S.useState(null),{trigger:d,onClose:h}=n,m=s.current,{onPointerInTransitChange:p}=r,x=S.useCallback(()=>{c(null),p(!1)},[p]),v=S.useCallback((b,k)=>{const O=b.currentTarget,j={x:b.clientX,y:b.clientY},T=xge(j,O.getBoundingClientRect()),M=vge(j,T),_=yge(k.getBoundingClientRect()),D=wge([...M,..._]);c(D),p(!0)},[p]);return S.useEffect(()=>()=>x(),[x]),S.useEffect(()=>{if(d&&m){const b=O=>v(O,m),k=O=>v(O,d);return d.addEventListener("pointerleave",b),m.addEventListener("pointerleave",k),()=>{d.removeEventListener("pointerleave",b),m.removeEventListener("pointerleave",k)}}},[d,m,v,x]),S.useEffect(()=>{if(l){const b=k=>{const O=k.target,j={x:k.clientX,y:k.clientY},T=d?.contains(O)||m?.contains(O),M=!bge(j,l);T?x():M&&(x(),h())};return document.addEventListener("pointermove",b),()=>document.removeEventListener("pointermove",b)}},[d,m,l,h,x]),a.jsx($P,{...t,ref:i})}),[fge,mge]=Zx(Uf,{isInside:!1}),pge=age("TooltipContent"),$P=S.forwardRef((t,e)=>{const{__scopeTooltip:n,children:r,"aria-label":s,onEscapeKeyDown:i,onPointerDownOutside:l,...c}=t,d=E0(bd,n),h=Jx(n),{onClose:m}=d;return S.useEffect(()=>(document.addEventListener(P4,m),()=>document.removeEventListener(P4,m)),[m]),S.useEffect(()=>{if(d.trigger){const p=x=>{x.target?.contains(d.trigger)&&m()};return window.addEventListener("scroll",p,{capture:!0}),()=>window.removeEventListener("scroll",p,{capture:!0})}},[d.trigger,m]),a.jsx(G4,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:i,onPointerDownOutside:l,onFocusOutside:p=>p.preventDefault(),onDismiss:m,children:a.jsxs(X4,{"data-state":d.stateAttribute,...h,...c,ref:e,style:{...c.style,"--radix-tooltip-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-tooltip-content-available-width":"var(--radix-popper-available-width)","--radix-tooltip-content-available-height":"var(--radix-popper-available-height)","--radix-tooltip-trigger-width":"var(--radix-popper-anchor-width)","--radix-tooltip-trigger-height":"var(--radix-popper-anchor-height)"},children:[a.jsx(pge,{children:r}),a.jsx(fge,{scope:n,isInside:!0,children:a.jsx(sq,{id:d.contentId,role:"tooltip",children:s||r})})]})})});QP.displayName=bd;var HP="TooltipArrow",gge=S.forwardRef((t,e)=>{const{__scopeTooltip:n,...r}=t,s=Jx(n);return mge(HP,n).isInside?null:a.jsx(Y4,{...s,...r,ref:e})});gge.displayName=HP;function xge(t,e){const n=Math.abs(e.top-t.y),r=Math.abs(e.bottom-t.y),s=Math.abs(e.right-t.x),i=Math.abs(e.left-t.x);switch(Math.min(n,r,s,i)){case i:return"left";case s:return"right";case n:return"top";case r:return"bottom";default:throw new Error("unreachable")}}function vge(t,e,n=5){const r=[];switch(e){case"top":r.push({x:t.x-n,y:t.y+n},{x:t.x+n,y:t.y+n});break;case"bottom":r.push({x:t.x-n,y:t.y-n},{x:t.x+n,y:t.y-n});break;case"left":r.push({x:t.x+n,y:t.y-n},{x:t.x+n,y:t.y+n});break;case"right":r.push({x:t.x-n,y:t.y-n},{x:t.x-n,y:t.y+n});break}return r}function yge(t){const{top:e,right:n,bottom:r,left:s}=t;return[{x:s,y:e},{x:n,y:e},{x:n,y:r},{x:s,y:r}]}function bge(t,e){const{x:n,y:r}=t;let s=!1;for(let i=0,l=e.length-1;ir!=x>r&&n<(p-h)*(r-m)/(x-m)+h&&(s=!s)}return s}function wge(t){const e=t.slice();return e.sort((n,r)=>n.xr.x?1:n.yr.y?1:0),Sge(e)}function Sge(t){if(t.length<=1)return t.slice();const e=[];for(let r=0;r=2;){const i=e[e.length-1],l=e[e.length-2];if((i.x-l.x)*(s.y-l.y)>=(i.y-l.y)*(s.x-l.x))e.pop();else break}e.push(s)}e.pop();const n=[];for(let r=t.length-1;r>=0;r--){const s=t[r];for(;n.length>=2;){const i=n[n.length-1],l=n[n.length-2];if((i.x-l.x)*(s.y-l.y)>=(i.y-l.y)*(s.x-l.x))n.pop();else break}n.push(s)}return n.pop(),e.length===1&&n.length===1&&e[0].x===n[0].x&&e[0].y===n[0].y?e:e.concat(n)}var kge=BP,Oge=IP,jge=qP,Nge=FP,UP=QP;const Cge=kge,Tge=Oge,Mge=jge,VP=S.forwardRef(({className:t,sideOffset:e=4,...n},r)=>a.jsx(Nge,{children:a.jsx(UP,{ref:r,sideOffset:e,className:ye("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]",t),...n})}));VP.displayName=UP.displayName;function Age({children:t}){CH();const[e,n]=S.useState(!0),[r,s]=S.useState(!1),[i,l]=S.useState(!1),{theme:c,setTheme:d}=dw(),h=MI(),m=ba();S.useEffect(()=>{const k=O=>{(O.metaKey||O.ctrlKey)&&O.key==="k"&&(O.preventDefault(),l(!0))};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[]);const p=[{title:"概览",items:[{icon:hg,label:"首页",path:"/"}]},{title:"麦麦配置编辑",items:[{icon:io,label:"麦麦主程序配置",path:"/config/bot"},{icon:z9,label:"麦麦模型提供商配置",path:"/config/modelProvider"},{icon:P9,label:"麦麦模型配置",path:"/config/model"},{icon:hO,label:"麦麦适配器配置",path:"/config/adapter"}]},{title:"麦麦资源管理",items:[{icon:K4,label:"表情包管理",path:"/resource/emoji"},{icon:Wf,label:"表达方式管理",path:"/resource/expression"},{icon:L9,label:"人物信息管理",path:"/resource/person"}]},{title:"扩展与监控",items:[{icon:pg,label:"插件市场",path:"/plugins"},{icon:hO,label:"插件配置",path:"/plugin-config"},{icon:fg,label:"日志查看器",path:"/logs"}]},{title:"系统",items:[{icon:dc,label:"系统设置",path:"/settings"}]}],v=c==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":c,b=()=>{localStorage.removeItem("access-token"),m({to:"/auth"})};return a.jsx(Cge,{delayDuration:300,children:a.jsxs("div",{className:"flex h-screen overflow-hidden",children:[a.jsxs("aside",{className:ye("fixed inset-y-0 left-0 z-50 flex flex-col border-r bg-card transition-all duration-300 lg:relative lg:z-0","w-64 lg:w-auto",e?"lg:w-64":"lg:w-16",r?"translate-x-0":"-translate-x-full lg:translate-x-0"),children:[a.jsx("div",{className:"flex h-16 items-center border-b px-4",children:a.jsxs("div",{className:ye("relative flex items-center justify-center flex-1 transition-all overflow-hidden","lg:flex-1",!e&&"lg:flex-none lg:w-8"),children:[a.jsxs("div",{className:ye("flex items-baseline gap-2",!e&&"lg:hidden"),children:[a.jsx("span",{className:"font-bold text-xl text-primary-gradient whitespace-nowrap",children:"MaiBot WebUI"}),a.jsx("span",{className:"text-xs text-primary/60 whitespace-nowrap",children:rH()})]}),!e&&a.jsx("span",{className:"hidden lg:block font-bold text-primary-gradient text-2xl",children:"M"})]})}),a.jsx(fn,{className:"flex-1",children:a.jsx("nav",{className:"p-4",children:a.jsx("ul",{className:ye("space-y-6",!e&&"lg:space-y-3"),children:p.map((k,O)=>a.jsxs("li",{children:[a.jsx("div",{className:ye("px-3 h-[1.25rem]","mb-2",!e&&"lg:mb-1 lg:invisible"),children:a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground/60 whitespace-nowrap",children:k.title})}),!e&&O>0&&a.jsx("div",{className:"hidden lg:block mb-2 border-t border-border"}),a.jsx("ul",{className:"space-y-1",children:k.items.map(j=>{const T=h({to:j.path}),M=j.icon,_=a.jsxs(a.Fragment,{children:[T&&a.jsx("div",{className:"absolute left-0 top-1/2 h-8 w-1 -translate-y-1/2 rounded-r-full bg-primary transition-opacity duration-300"}),a.jsxs("div",{className:ye("flex items-center transition-all duration-300",e?"gap-3":"lg:gap-0"),children:[a.jsx(M,{className:ye("h-5 w-5 flex-shrink-0",T&&"text-primary"),strokeWidth:2,fill:"none"}),a.jsx("span",{className:ye("text-sm font-medium whitespace-nowrap transition-all duration-300",T&&"font-semibold",e?"opacity-100 max-w-[200px]":"lg:opacity-0 lg:max-w-0 lg:overflow-hidden"),children:j.label})]})]});return a.jsx("li",{className:"relative",children:a.jsxs(Tge,{children:[a.jsx(Mge,{asChild:!0,children:a.jsx(AI,{to:j.path,className:ye("relative flex items-center rounded-lg py-2 transition-all duration-300","hover:bg-accent hover:text-accent-foreground",T?"bg-accent text-foreground":"text-muted-foreground hover:text-foreground",e?"px-3":"lg:px-0 lg:justify-center"),onClick:()=>s(!1),children:_})}),!e&&a.jsx(VP,{side:"right",className:"hidden lg:block",children:a.jsx("p",{children:j.label})})]})},j.path)})})]},k.title))})})})]}),r&&a.jsx("div",{className:"fixed inset-0 z-40 bg-black/50 lg:hidden",onClick:()=>s(!1)}),a.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[a.jsxs("header",{className:"flex h-16 items-center justify-between border-b bg-card/80 backdrop-blur-md px-4 sticky top-0 z-10",children:[a.jsxs("div",{className:"flex items-center gap-4",children:[a.jsx("button",{onClick:()=>s(!r),className:"rounded-lg p-2 hover:bg-accent lg:hidden",children:a.jsx(Aq,{className:"h-5 w-5"})}),a.jsx("button",{onClick:()=>n(!e),className:"hidden rounded-lg p-2 hover:bg-accent lg:block",title:e?"收起侧边栏":"展开侧边栏",children:a.jsx(Tc,{className:ye("h-5 w-5 transition-transform",!e&&"rotate-180")})})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsxs("button",{onClick:()=>l(!0),className:"relative hidden md:flex items-center w-64 h-9 pl-9 pr-16 bg-background/50 border rounded-md hover:bg-accent/50 transition-colors text-left",children:[a.jsx(Ps,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),a.jsx("span",{className:"text-sm text-muted-foreground",children:"搜索..."}),a.jsxs(Pz,{size:"sm",className:"absolute right-2 top-1/2 -translate-y-1/2",children:[a.jsx("span",{className:"text-xs",children:"⌘"}),"K"]})]}),a.jsx(Pme,{open:i,onOpenChange:l}),a.jsxs(ie,{variant:"ghost",size:"sm",onClick:()=>window.open("https://docs.mai-mai.org","_blank"),className:"gap-2",title:"查看麦麦文档",children:[a.jsx(Eq,{className:"h-4 w-4"}),a.jsx("span",{className:"hidden sm:inline",children:"麦麦文档"})]}),a.jsx("button",{onClick:k=>{Q$(v==="dark"?"light":"dark",d,k)},className:"rounded-lg p-2 hover:bg-accent",title:v==="dark"?"切换到浅色模式":"切换到深色模式",children:v==="dark"?a.jsx(Zb,{className:"h-5 w-5"}):a.jsx(Jb,{className:"h-5 w-5"})}),a.jsx("div",{className:"h-6 w-px bg-border"}),a.jsxs(ie,{variant:"ghost",size:"sm",onClick:b,className:"gap-2",title:"登出系统",children:[a.jsx(fO,{className:"h-4 w-4"}),a.jsx("span",{className:"hidden sm:inline",children:"登出"})]})]})]}),a.jsxs(Jpe,{children:[a.jsx(ege,{asChild:!0,children:a.jsx("main",{className:"flex-1 overflow-hidden bg-background",children:t})}),a.jsxs(PP,{className:"w-64",children:[a.jsxs(Pi,{onClick:()=>m({to:"/"}),children:[a.jsx(hg,{className:"mr-2 h-4 w-4"}),"首页"]}),a.jsxs(Pi,{onClick:()=>m({to:"/settings"}),children:[a.jsx(dc,{className:"mr-2 h-4 w-4"}),"系统设置"]}),a.jsxs(Pi,{onClick:()=>m({to:"/logs"}),children:[a.jsx(fg,{className:"mr-2 h-4 w-4"}),"日志查看器"]}),a.jsx(Xh,{}),a.jsxs(tge,{children:[a.jsxs(RP,{children:[a.jsx(_9,{className:"mr-2 h-4 w-4"}),"切换主题"]}),a.jsxs(zP,{className:"w-48",children:[a.jsxs(Pi,{onClick:()=>d("light"),disabled:c==="light",children:[a.jsx(Zb,{className:"mr-2 h-4 w-4"}),"浅色",c==="light"&&a.jsx(qu,{children:"✓"})]}),a.jsxs(Pi,{onClick:()=>d("dark"),disabled:c==="dark",children:[a.jsx(Jb,{className:"mr-2 h-4 w-4"}),"深色",c==="dark"&&a.jsx(qu,{children:"✓"})]}),a.jsxs(Pi,{onClick:()=>d("system"),disabled:c==="system",children:[a.jsx(dc,{className:"mr-2 h-4 w-4"}),"跟随系统",c==="system"&&a.jsx(qu,{children:"✓"})]})]})]}),a.jsx(Xh,{}),a.jsxs(Pi,{onClick:()=>window.location.reload(),children:[a.jsx(_q,{className:"mr-2 h-4 w-4"}),"刷新页面",a.jsx(qu,{children:"⌘R"})]}),a.jsxs(Pi,{onClick:()=>l(!0),children:[a.jsx(Ps,{className:"mr-2 h-4 w-4"}),"搜索",a.jsx(qu,{children:"⌘K"})]}),a.jsx(Xh,{}),a.jsxs(Pi,{onClick:()=>window.open("https://docs.mai-mai.org","_blank"),children:[a.jsx(Yh,{className:"mr-2 h-4 w-4"}),"麦麦文档"]}),a.jsx(Xh,{}),a.jsxs(Pi,{onClick:b,className:"text-destructive focus:text-destructive",children:[a.jsx(fO,{className:"mr-2 h-4 w-4"}),"登出系统"]})]})]})]})]})})}const _0=EI({component:()=>a.jsxs(a.Fragment,{children:[a.jsx(c9,{}),!1]}),beforeLoad:()=>{if(window.location.pathname==="/"&&!qT())throw DI({to:"/auth"})}}),Ege=Xr({getParentRoute:()=>_0,path:"/auth",component:TH}),_ge=Xr({getParentRoute:()=>_0,path:"/setup",component:WH}),Fs=Xr({getParentRoute:()=>_0,id:"protected",component:()=>a.jsx(Age,{children:a.jsx(c9,{})})}),Dge=Xr({getParentRoute:()=>Fs,path:"/",component:q$}),Rge=Xr({getParentRoute:()=>Fs,path:"/config/bot",component:Vee}),zge=Xr({getParentRoute:()=>Fs,path:"/config/modelProvider",component:ote}),Pge=Xr({getParentRoute:()=>Fs,path:"/config/model",component:Pte}),Lge=Xr({getParentRoute:()=>Fs,path:"/config/adapter",component:qte}),Bge=Xr({getParentRoute:()=>Fs,path:"/resource/emoji",component:ude}),Ige=Xr({getParentRoute:()=>Fs,path:"/resource/expression",component:bde}),qge=Xr({getParentRoute:()=>Fs,path:"/resource/person",component:Ede}),Fge=Xr({getParentRoute:()=>Fs,path:"/logs",component:hme}),Qge=Xr({getParentRoute:()=>Fs,path:"/plugins",component:Eme}),$ge=Xr({getParentRoute:()=>Fs,path:"/plugin-config",component:_me}),Hge=Xr({getParentRoute:()=>Fs,path:"/plugin-mirrors",component:Dme}),Uge=Xr({getParentRoute:()=>Fs,path:"/settings",component:bH}),Vge=Xr({getParentRoute:()=>_0,path:"*",component:$T}),Wge=_0.addChildren([Ege,_ge,Fs.addChildren([Dge,Rge,zge,Pge,Lge,Bge,Ige,qge,Qge,$ge,Hge,Fge,Uge]),Vge]),Gge=_I({routeTree:Wge,defaultNotFoundComponent:$T});function Xge({children:t,defaultTheme:e="system",storageKey:n="ui-theme",...r}){const[s,i]=S.useState(()=>localStorage.getItem(n)||e);S.useEffect(()=>{const c=window.document.documentElement;if(c.classList.remove("light","dark"),s==="system"){const d=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";c.classList.add(d);return}c.classList.add(s)},[s]),S.useEffect(()=>{const c=localStorage.getItem("accent-color");if(c){const d=document.documentElement,m={blue:{hsl:"221.2 83.2% 53.3%",darkHsl:"217.2 91.2% 59.8%",gradient:null},purple:{hsl:"271 91% 65%",darkHsl:"270 95% 75%",gradient:null},green:{hsl:"142 71% 45%",darkHsl:"142 76% 36%",gradient:null},orange:{hsl:"25 95% 53%",darkHsl:"20 90% 48%",gradient:null},pink:{hsl:"330 81% 60%",darkHsl:"330 85% 70%",gradient:null},red:{hsl:"0 84% 60%",darkHsl:"0 90% 70%",gradient:null},"gradient-sunset":{hsl:"15 95% 60%",darkHsl:"15 95% 65%",gradient:"linear-gradient(135deg, hsl(25 95% 53%) 0%, hsl(330 81% 60%) 100%)"},"gradient-ocean":{hsl:"200 90% 55%",darkHsl:"200 90% 60%",gradient:"linear-gradient(135deg, hsl(221.2 83.2% 53.3%) 0%, hsl(189 94% 43%) 100%)"},"gradient-forest":{hsl:"150 70% 45%",darkHsl:"150 75% 40%",gradient:"linear-gradient(135deg, hsl(142 71% 45%) 0%, hsl(158 64% 52%) 100%)"},"gradient-aurora":{hsl:"310 85% 65%",darkHsl:"310 90% 70%",gradient:"linear-gradient(135deg, hsl(271 91% 65%) 0%, hsl(330 81% 60%) 100%)"},"gradient-fire":{hsl:"15 95% 55%",darkHsl:"15 95% 60%",gradient:"linear-gradient(135deg, hsl(0 84% 60%) 0%, hsl(25 95% 53%) 100%)"},"gradient-twilight":{hsl:"250 90% 60%",darkHsl:"250 95% 65%",gradient:"linear-gradient(135deg, hsl(239 84% 67%) 0%, hsl(271 91% 65%) 100%)"}}[c];m&&(d.style.setProperty("--primary",m.hsl),m.gradient?(d.style.setProperty("--primary-gradient",m.gradient),d.classList.add("has-gradient")):(d.style.removeProperty("--primary-gradient"),d.classList.remove("has-gradient")))}},[]);const l={theme:s,setTheme:c=>{localStorage.setItem(n,c),i(c)}};return a.jsx(uT.Provider,{...r,value:l,children:t})}function Yge({children:t,defaultEnabled:e=!0,defaultWavesEnabled:n=!0,storageKey:r="enable-animations",wavesStorageKey:s="enable-waves-background"}){const[i,l]=S.useState(()=>{const m=localStorage.getItem(r);return m!==null?m==="true":e}),[c,d]=S.useState(()=>{const m=localStorage.getItem(s);return m!==null?m==="true":n});S.useEffect(()=>{const m=document.documentElement;i?m.classList.remove("no-animations"):m.classList.add("no-animations"),localStorage.setItem(r,String(i))},[i,r]),S.useEffect(()=>{localStorage.setItem(s,String(c))},[c,s]);const h={enableAnimations:i,setEnableAnimations:l,enableWavesBackground:c,setEnableWavesBackground:d};return a.jsx(dT.Provider,{value:h,children:t})}var c3="ToastProvider",[u3,Kge,Zge]=tx("Toast"),[WP]=Hi("Toast",[Zge]),[Jge,e1]=WP(c3),GP=t=>{const{__scopeToast:e,label:n="Notification",duration:r=5e3,swipeDirection:s="right",swipeThreshold:i=50,children:l}=t,[c,d]=S.useState(null),[h,m]=S.useState(0),p=S.useRef(!1),x=S.useRef(!1);return n.trim()||console.error(`Invalid prop \`label\` supplied to \`${c3}\`. Expected non-empty \`string\`.`),a.jsx(u3.Provider,{scope:e,children:a.jsx(Jge,{scope:e,label:n,duration:r,swipeDirection:s,swipeThreshold:i,toastCount:h,viewport:c,onViewportChange:d,onToastAdd:S.useCallback(()=>m(v=>v+1),[]),onToastRemove:S.useCallback(()=>m(v=>v-1),[]),isFocusedToastEscapeKeyDownRef:p,isClosePausedRef:x,children:l})})};GP.displayName=c3;var XP="ToastViewport",exe=["F8"],B4="toast.viewportPause",I4="toast.viewportResume",YP=S.forwardRef((t,e)=>{const{__scopeToast:n,hotkey:r=exe,label:s="Notifications ({hotkey})",...i}=t,l=e1(XP,n),c=Kge(n),d=S.useRef(null),h=S.useRef(null),m=S.useRef(null),p=S.useRef(null),x=Cn(e,p,l.onViewportChange),v=r.join("+").replace(/Key/g,"").replace(/Digit/g,""),b=l.toastCount>0;S.useEffect(()=>{const O=j=>{r.length!==0&&r.every(M=>j[M]||j.code===M)&&p.current?.focus()};return document.addEventListener("keydown",O),()=>document.removeEventListener("keydown",O)},[r]),S.useEffect(()=>{const O=d.current,j=p.current;if(b&&O&&j){const T=()=>{if(!l.isClosePausedRef.current){const E=new CustomEvent(B4);j.dispatchEvent(E),l.isClosePausedRef.current=!0}},M=()=>{if(l.isClosePausedRef.current){const E=new CustomEvent(I4);j.dispatchEvent(E),l.isClosePausedRef.current=!1}},_=E=>{!O.contains(E.relatedTarget)&&M()},D=()=>{O.contains(document.activeElement)||M()};return O.addEventListener("focusin",T),O.addEventListener("focusout",_),O.addEventListener("pointermove",T),O.addEventListener("pointerleave",D),window.addEventListener("blur",T),window.addEventListener("focus",M),()=>{O.removeEventListener("focusin",T),O.removeEventListener("focusout",_),O.removeEventListener("pointermove",T),O.removeEventListener("pointerleave",D),window.removeEventListener("blur",T),window.removeEventListener("focus",M)}}},[b,l.isClosePausedRef]);const k=S.useCallback(({tabbingDirection:O})=>{const T=c().map(M=>{const _=M.ref.current,D=[_,...fxe(_)];return O==="forwards"?D:D.reverse()});return(O==="forwards"?T.reverse():T).flat()},[c]);return S.useEffect(()=>{const O=p.current;if(O){const j=T=>{const M=T.altKey||T.ctrlKey||T.metaKey;if(T.key==="Tab"&&!M){const D=document.activeElement,E=T.shiftKey;if(T.target===O&&E){h.current?.focus();return}const F=k({tabbingDirection:E?"backwards":"forwards"}),B=F.findIndex(U=>U===D);Gb(F.slice(B+1))?T.preventDefault():E?h.current?.focus():m.current?.focus()}};return O.addEventListener("keydown",j),()=>O.removeEventListener("keydown",j)}},[c,k]),a.jsxs(iq,{ref:d,role:"region","aria-label":s.replace("{hotkey}",v),tabIndex:-1,style:{pointerEvents:b?void 0:"none"},children:[b&&a.jsx(q4,{ref:h,onFocusFromOutsideViewport:()=>{const O=k({tabbingDirection:"forwards"});Gb(O)}}),a.jsx(u3.Slot,{scope:n,children:a.jsx(Yt.ol,{tabIndex:-1,...i,ref:x})}),b&&a.jsx(q4,{ref:m,onFocusFromOutsideViewport:()=>{const O=k({tabbingDirection:"backwards"});Gb(O)}})]})});YP.displayName=XP;var KP="ToastFocusProxy",q4=S.forwardRef((t,e)=>{const{__scopeToast:n,onFocusFromOutsideViewport:r,...s}=t,i=e1(KP,n);return a.jsx(E9,{tabIndex:0,...s,ref:e,style:{position:"fixed"},onFocus:l=>{const c=l.relatedTarget;!i.viewport?.contains(c)&&r()}})});q4.displayName=KP;var D0="Toast",txe="toast.swipeStart",nxe="toast.swipeMove",rxe="toast.swipeCancel",sxe="toast.swipeEnd",ZP=S.forwardRef((t,e)=>{const{forceMount:n,open:r,defaultOpen:s,onOpenChange:i,...l}=t,[c,d]=So({prop:r,defaultProp:s??!0,onChange:i,caller:D0});return a.jsx(Ls,{present:n||c,children:a.jsx(lxe,{open:c,...l,ref:e,onClose:()=>d(!1),onPause:es(t.onPause),onResume:es(t.onResume),onSwipeStart:$e(t.onSwipeStart,h=>{h.currentTarget.setAttribute("data-swipe","start")}),onSwipeMove:$e(t.onSwipeMove,h=>{const{x:m,y:p}=h.detail.delta;h.currentTarget.setAttribute("data-swipe","move"),h.currentTarget.style.setProperty("--radix-toast-swipe-move-x",`${m}px`),h.currentTarget.style.setProperty("--radix-toast-swipe-move-y",`${p}px`)}),onSwipeCancel:$e(t.onSwipeCancel,h=>{h.currentTarget.setAttribute("data-swipe","cancel"),h.currentTarget.style.removeProperty("--radix-toast-swipe-move-x"),h.currentTarget.style.removeProperty("--radix-toast-swipe-move-y"),h.currentTarget.style.removeProperty("--radix-toast-swipe-end-x"),h.currentTarget.style.removeProperty("--radix-toast-swipe-end-y")}),onSwipeEnd:$e(t.onSwipeEnd,h=>{const{x:m,y:p}=h.detail.delta;h.currentTarget.setAttribute("data-swipe","end"),h.currentTarget.style.removeProperty("--radix-toast-swipe-move-x"),h.currentTarget.style.removeProperty("--radix-toast-swipe-move-y"),h.currentTarget.style.setProperty("--radix-toast-swipe-end-x",`${m}px`),h.currentTarget.style.setProperty("--radix-toast-swipe-end-y",`${p}px`),d(!1)})})})});ZP.displayName=D0;var[ixe,axe]=WP(D0,{onClose(){}}),lxe=S.forwardRef((t,e)=>{const{__scopeToast:n,type:r="foreground",duration:s,open:i,onClose:l,onEscapeKeyDown:c,onPause:d,onResume:h,onSwipeStart:m,onSwipeMove:p,onSwipeCancel:x,onSwipeEnd:v,...b}=t,k=e1(D0,n),[O,j]=S.useState(null),T=Cn(e,W=>j(W)),M=S.useRef(null),_=S.useRef(null),D=s||k.duration,E=S.useRef(0),z=S.useRef(D),Q=S.useRef(0),{onToastAdd:F,onToastRemove:B}=k,U=es(()=>{O?.contains(document.activeElement)&&k.viewport?.focus(),l()}),V=S.useCallback(W=>{!W||W===1/0||(window.clearTimeout(Q.current),E.current=new Date().getTime(),Q.current=window.setTimeout(U,W))},[U]);S.useEffect(()=>{const W=k.viewport;if(W){const J=()=>{V(z.current),h?.()},H=()=>{const ae=new Date().getTime()-E.current;z.current=z.current-ae,window.clearTimeout(Q.current),d?.()};return W.addEventListener(B4,H),W.addEventListener(I4,J),()=>{W.removeEventListener(B4,H),W.removeEventListener(I4,J)}}},[k.viewport,D,d,h,V]),S.useEffect(()=>{i&&!k.isClosePausedRef.current&&V(D)},[i,D,k.isClosePausedRef,V]),S.useEffect(()=>(F(),()=>B()),[F,B]);const ce=S.useMemo(()=>O?iL(O):null,[O]);return k.viewport?a.jsxs(a.Fragment,{children:[ce&&a.jsx(oxe,{__scopeToast:n,role:"status","aria-live":r==="foreground"?"assertive":"polite",children:ce}),a.jsx(ixe,{scope:n,onClose:U,children:RI.createPortal(a.jsx(u3.ItemSlot,{scope:n,children:a.jsx(aq,{asChild:!0,onEscapeKeyDown:$e(c,()=>{k.isFocusedToastEscapeKeyDownRef.current||U(),k.isFocusedToastEscapeKeyDownRef.current=!1}),children:a.jsx(Yt.li,{tabIndex:0,"data-state":i?"open":"closed","data-swipe-direction":k.swipeDirection,...b,ref:T,style:{userSelect:"none",touchAction:"none",...t.style},onKeyDown:$e(t.onKeyDown,W=>{W.key==="Escape"&&(c?.(W.nativeEvent),W.nativeEvent.defaultPrevented||(k.isFocusedToastEscapeKeyDownRef.current=!0,U()))}),onPointerDown:$e(t.onPointerDown,W=>{W.button===0&&(M.current={x:W.clientX,y:W.clientY})}),onPointerMove:$e(t.onPointerMove,W=>{if(!M.current)return;const J=W.clientX-M.current.x,H=W.clientY-M.current.y,ae=!!_.current,ne=["left","right"].includes(k.swipeDirection),ue=["left","up"].includes(k.swipeDirection)?Math.min:Math.max,R=ne?ue(0,J):0,me=ne?0:ue(0,H),Y=W.pointerType==="touch"?10:2,P={x:R,y:me},K={originalEvent:W,delta:P};ae?(_.current=P,Qp(nxe,p,K,{discrete:!1})):o9(P,k.swipeDirection,Y)?(_.current=P,Qp(txe,m,K,{discrete:!1}),W.target.setPointerCapture(W.pointerId)):(Math.abs(J)>Y||Math.abs(H)>Y)&&(M.current=null)}),onPointerUp:$e(t.onPointerUp,W=>{const J=_.current,H=W.target;if(H.hasPointerCapture(W.pointerId)&&H.releasePointerCapture(W.pointerId),_.current=null,M.current=null,J){const ae=W.currentTarget,ne={originalEvent:W,delta:J};o9(J,k.swipeDirection,k.swipeThreshold)?Qp(sxe,v,ne,{discrete:!0}):Qp(rxe,x,ne,{discrete:!0}),ae.addEventListener("click",ue=>ue.preventDefault(),{once:!0})}})})})}),k.viewport)})]}):null}),oxe=t=>{const{__scopeToast:e,children:n,...r}=t,s=e1(D0,e),[i,l]=S.useState(!1),[c,d]=S.useState(!1);return dxe(()=>l(!0)),S.useEffect(()=>{const h=window.setTimeout(()=>d(!0),1e3);return()=>window.clearTimeout(h)},[]),c?null:a.jsx(sx,{asChild:!0,children:a.jsx(E9,{...r,children:i&&a.jsxs(a.Fragment,{children:[s.label," ",n]})})})},cxe="ToastTitle",JP=S.forwardRef((t,e)=>{const{__scopeToast:n,...r}=t;return a.jsx(Yt.div,{...r,ref:e})});JP.displayName=cxe;var uxe="ToastDescription",eL=S.forwardRef((t,e)=>{const{__scopeToast:n,...r}=t;return a.jsx(Yt.div,{...r,ref:e})});eL.displayName=uxe;var tL="ToastAction",nL=S.forwardRef((t,e)=>{const{altText:n,...r}=t;return n.trim()?a.jsx(sL,{altText:n,asChild:!0,children:a.jsx(d3,{...r,ref:e})}):(console.error(`Invalid prop \`altText\` supplied to \`${tL}\`. Expected non-empty \`string\`.`),null)});nL.displayName=tL;var rL="ToastClose",d3=S.forwardRef((t,e)=>{const{__scopeToast:n,...r}=t,s=axe(rL,n);return a.jsx(sL,{asChild:!0,children:a.jsx(Yt.button,{type:"button",...r,ref:e,onClick:$e(t.onClick,s.onClose)})})});d3.displayName=rL;var sL=S.forwardRef((t,e)=>{const{__scopeToast:n,altText:r,...s}=t;return a.jsx(Yt.div,{"data-radix-toast-announce-exclude":"","data-radix-toast-announce-alt":r||void 0,...s,ref:e})});function iL(t){const e=[];return Array.from(t.childNodes).forEach(r=>{if(r.nodeType===r.TEXT_NODE&&r.textContent&&e.push(r.textContent),hxe(r)){const s=r.ariaHidden||r.hidden||r.style.display==="none",i=r.dataset.radixToastAnnounceExclude==="";if(!s)if(i){const l=r.dataset.radixToastAnnounceAlt;l&&e.push(l)}else e.push(...iL(r))}}),e}function Qp(t,e,n,{discrete:r}){const s=n.originalEvent.currentTarget,i=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e&&s.addEventListener(t,e,{once:!0}),r?A9(s,i):s.dispatchEvent(i)}var o9=(t,e,n=0)=>{const r=Math.abs(t.x),s=Math.abs(t.y),i=r>s;return e==="left"||e==="right"?i&&r>n:!i&&s>n};function dxe(t=()=>{}){const e=es(t);h9(()=>{let n=0,r=0;return n=window.requestAnimationFrame(()=>r=window.requestAnimationFrame(e)),()=>{window.cancelAnimationFrame(n),window.cancelAnimationFrame(r)}},[e])}function hxe(t){return t.nodeType===t.ELEMENT_NODE}function fxe(t){const e=[],n=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const s=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||s?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)e.push(n.currentNode);return e}function Gb(t){const e=document.activeElement;return t.some(n=>n===e?!0:(n.focus(),document.activeElement!==e))}var mxe=GP,aL=YP,lL=ZP,oL=JP,cL=eL,uL=nL,dL=d3;const pxe=mxe,hL=S.forwardRef(({className:t,...e},n)=>a.jsx(aL,{ref:n,className:ye("fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",t),...e}));hL.displayName=aL.displayName;const gxe=Nd("group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",{variants:{variant:{default:"border bg-background text-foreground",destructive:"destructive group border-destructive bg-destructive text-destructive-foreground"}},defaultVariants:{variant:"default"}}),fL=S.forwardRef(({className:t,variant:e,...n},r)=>a.jsx(lL,{ref:r,className:ye(gxe({variant:e}),t),...n}));fL.displayName=lL.displayName;const xxe=S.forwardRef(({className:t,...e},n)=>a.jsx(uL,{ref:n,className:ye("inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",t),...e}));xxe.displayName=uL.displayName;const mL=S.forwardRef(({className:t,...e},n)=>a.jsx(dL,{ref:n,className:ye("absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",t),"toast-close":"",...e,children:a.jsx(Gf,{className:"h-4 w-4"})}));mL.displayName=dL.displayName;const pL=S.forwardRef(({className:t,...e},n)=>a.jsx(oL,{ref:n,className:ye("text-sm font-semibold [&+div]:text-xs",t),...e}));pL.displayName=oL.displayName;const gL=S.forwardRef(({className:t,...e},n)=>a.jsx(cL,{ref:n,className:ye("text-sm opacity-90",t),...e}));gL.displayName=cL.displayName;function vxe(){const{toasts:t}=Pr();return a.jsxs(pxe,{children:[t.map(function({id:e,title:n,description:r,action:s,...i}){return a.jsxs(fL,{...i,children:[a.jsxs("div",{className:"grid gap-1",children:[n&&a.jsx(pL,{children:n}),r&&a.jsx(gL,{children:r})]}),s,a.jsx(mL,{})]},e)}),a.jsx(hL,{})]})}Lq.createRoot(document.getElementById("root")).render(a.jsx(S.StrictMode,{children:a.jsx(Xge,{defaultTheme:"system",children:a.jsxs(Yge,{children:[a.jsx(zI,{router:Gge}),a.jsx(vxe,{})]})})})); diff --git a/webui/dist/assets/index-Din59EIC.css b/webui/dist/assets/index-Din59EIC.css new file mode 100644 index 00000000..57c924d8 --- /dev/null +++ b/webui/dist/assets/index-Din59EIC.css @@ -0,0 +1 @@ +@charset "UTF-8";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--primary: 221.2 83.2% 53.3%;--primary-foreground: 210 40% 98%;--primary-gradient: none;--secondary: 210 40% 96.1%;--secondary-foreground: 222.2 47.4% 11.2%;--muted: 210 40% 96.1%;--muted-foreground: 215.4 16.3% 46.9%;--accent: 210 40% 96.1%;--accent-foreground: 222.2 47.4% 11.2%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;--border: 214.3 31.8% 91.4%;--input: 214.3 31.8% 91.4%;--ring: 221.2 83.2% 53.3%;--radius: .5rem;--chart-1: 221.2 83.2% 53.3%;--chart-2: 160 60% 45%;--chart-3: 30 80% 55%;--chart-4: 280 65% 60%;--chart-5: 340 75% 55%}.dark{--background: 222.2 84% 4.9%;--foreground: 210 40% 98%;--card: 222.2 84% 4.9%;--card-foreground: 210 40% 98%;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--primary: 217.2 91.2% 59.8%;--primary-foreground: 210 40% 98%;--primary-gradient: none;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 215 20.2% 65.1%;--accent: 217.2 32.6% 17.5%;--accent-foreground: 210 40% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 210 40% 98%;--border: 217.2 32.6% 17.5%;--input: 217.2 32.6% 17.5%;--ring: 224.3 76.3% 48%;--chart-1: 217.2 91.2% 59.8%;--chart-2: 160 60% 50%;--chart-3: 30 80% 60%;--chart-4: 280 65% 65%;--chart-5: 340 75% 60%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-16{inset:4rem}.inset-8{inset:2rem}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.bottom-1\/4{bottom:25%}.bottom-24{bottom:6rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-1{left:.25rem}.left-1\/2{left:50%}.left-1\/4{left:25%}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-\[50\%\]{left:50%}.right-0{right:0}.right-1{right:.25rem}.right-1\.5{right:.375rem}.right-1\/3{right:33.333333%}.right-1\/4{right:25%}.right-2{right:.5rem}.right-4{right:1rem}.right-8{right:2rem}.top-0{top:0}.top-1{top:.25rem}.top-1\.5{top:.375rem}.top-1\/2{top:50%}.top-1\/4{top:25%}.top-2{top:.5rem}.top-2\.5{top:.625rem}.top-3{top:.75rem}.top-3\/4{top:75%}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.order-1{order:1}.order-2{order:2}.col-span-2{grid-column:span 2 / span 2}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.-mt-1{margin-top:-.25rem}.-mt-2{margin-top:-.5rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-10{margin-left:2.5rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-auto{aspect-ratio:auto}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.size-4{width:1rem;height:1rem}.size-\[--cell-size\]{width:var(--cell-size);height:var(--cell-size)}.h-0\.5{height:.125rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-60{height:15rem}.h-64{height:16rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-96{height:24rem}.h-\[--cell-size\]{height:var(--cell-size)}.h-\[1\.25rem\]{height:1.25rem}.h-\[140px\]{height:140px}.h-\[1px\]{height:1px}.h-\[200px\]{height:200px}.h-\[250px\]{height:250px}.h-\[280px\]{height:280px}.h-\[300px\]{height:300px}.h-\[350px\]{height:350px}.h-\[400px\]{height:400px}.h-\[600px\]{height:600px}.h-\[calc\(100vh-12rem\)\]{height:calc(100vh - 12rem)}.h-\[calc\(100vh-200px\)\]{height:calc(100vh - 200px)}.h-\[calc\(100vh-240px\)\]{height:calc(100vh - 240px)}.h-\[calc\(100vh-260px\)\]{height:calc(100vh - 260px)}.h-\[calc\(100vh-4rem\)\]{height:calc(100vh - 4rem)}.h-\[calc\(85vh-220px\)\]{height:calc(85vh - 220px)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-64{max-height:16rem}.max-h-\[--radix-context-menu-content-available-height\]{max-height:var(--radix-context-menu-content-available-height)}.max-h-\[--radix-select-content-available-height\]{max-height:var(--radix-select-content-available-height)}.max-h-\[200px\]{max-height:200px}.max-h-\[300px\]{max-height:300px}.max-h-\[60vh\]{max-height:60vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(90vh-120px\)\]{max-height:calc(90vh - 120px)}.max-h-\[calc\(90vh-8rem\)\]{max-height:calc(90vh - 8rem)}.max-h-full{max-height:100%}.max-h-none{max-height:none}.max-h-screen{max-height:100vh}.min-h-0{min-height:0px}.min-h-10{min-height:2.5rem}.min-h-\[100px\]{min-height:100px}.min-h-\[140px\]{min-height:140px}.min-h-\[300px\]{min-height:300px}.min-h-\[400px\]{min-height:400px}.min-h-\[40px\]{min-height:40px}.min-h-\[60px\]{min-height:60px}.min-h-screen{min-height:100vh}.w-0{width:0px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-2\/3{width:66.666667%}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[--cell-size\]{width:var(--cell-size)}.w-\[100px\]{width:100px}.w-\[120px\]{width:120px}.w-\[130px\]{width:130px}.w-\[140px\]{width:140px}.w-\[1px\]{width:1px}.w-\[200px\]{width:200px}.w-\[600px\]{width:600px}.w-\[65px\]{width:65px}.w-\[95vw\]{width:95vw}.w-auto{width:auto}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[--cell-size\]{min-width:var(--cell-size)}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[140px\]{min-width:140px}.min-w-\[160px\]{min-width:160px}.min-w-\[200px\]{min-width:200px}.min-w-\[80px\]{min-width:80px}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-32{max-width:8rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[100px\]{max-width:100px}.max-w-\[150px\]{max-width:150px}.max-w-\[200px\]{max-width:200px}.max-w-\[60px\]{max-width:60px}.max-w-\[75\%\]{max-width:75%}.max-w-\[90\%\]{max-width:90%}.max-w-\[95vw\]{max-width:95vw}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.origin-\[--radix-context-menu-content-transform-origin\]{transform-origin:var(--radix-context-menu-content-transform-origin)}.origin-\[--radix-popover-content-transform-origin\]{transform-origin:var(--radix-popover-content-transform-origin)}.origin-\[--radix-select-content-transform-origin\]{transform-origin:var(--radix-select-content-transform-origin)}.origin-\[--radix-tooltip-content-transform-origin\]{transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-32{--tw-translate-x: 8rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.animate-\[ping_3s_ease-in-out_infinite\]{animation:ping 3s ease-in-out infinite}.animate-\[ping_3s_ease-in-out_infinite_0\.5s\]{animation:ping 3s ease-in-out infinite .5s}.animate-\[ping_3s_ease-in-out_infinite_1s\]{animation:ping 3s ease-in-out infinite 1s}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}@keyframes ping{75%,to{transform:scale(2);opacity:0}}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-move{cursor:move}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.resize-y{resize:vertical}.resize{resize:both}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[1fr_1fr_90px_32px\]{grid-template-columns:1fr 1fr 90px 32px}.grid-rows-\[auto_1fr_auto\]{grid-template-rows:auto 1fr auto}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.rounded-l-md{border-top-left-radius:calc(var(--radius) - 2px);border-bottom-left-radius:calc(var(--radius) - 2px)}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.rounded-r-md{border-top-right-radius:calc(var(--radius) - 2px);border-bottom-right-radius:calc(var(--radius) - 2px)}.rounded-tl-sm{border-top-left-radius:calc(var(--radius) - 4px)}.rounded-tr-sm{border-top-right-radius:calc(var(--radius) - 4px)}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-4{border-width:4px}.border-\[1\.5px\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[--color-border\]{border-color:var(--color-border)}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500\/20{border-color:#f59e0b33}.border-amber-500\/50{border-color:#f59e0b80}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-blue-700{--tw-border-opacity: 1;border-color:rgb(29 78 216 / var(--tw-border-opacity, 1))}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border) / .5)}.border-current{border-color:currentColor}.border-gray-800{--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-green-500{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.border-green-600{--tw-border-opacity: 1;border-color:rgb(22 163 74 / var(--tw-border-opacity, 1))}.border-green-700{--tw-border-opacity: 1;border-color:rgb(21 128 61 / var(--tw-border-opacity, 1))}.border-input{border-color:hsl(var(--input))}.border-muted{border-color:hsl(var(--muted))}.border-muted-foreground\/30{border-color:hsl(var(--muted-foreground) / .3)}.border-muted-foreground\/50{border-color:hsl(var(--muted-foreground) / .5)}.border-orange-200{--tw-border-opacity: 1;border-color:rgb(254 215 170 / var(--tw-border-opacity, 1))}.border-orange-500{--tw-border-opacity: 1;border-color:rgb(249 115 22 / var(--tw-border-opacity, 1))}.border-orange-600{--tw-border-opacity: 1;border-color:rgb(234 88 12 / var(--tw-border-opacity, 1))}.border-primary{border-color:hsl(var(--primary))}.border-primary\/10{border-color:hsl(var(--primary) / .1)}.border-primary\/20{border-color:hsl(var(--primary) / .2)}.border-primary\/30{border-color:hsl(var(--primary) / .3)}.border-primary\/50{border-color:hsl(var(--primary) / .5)}.border-purple-500{--tw-border-opacity: 1;border-color:rgb(168 85 247 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-red-500\/50{border-color:#ef444480}.border-transparent{border-color:transparent}.border-yellow-200{--tw-border-opacity: 1;border-color:rgb(254 240 138 / var(--tw-border-opacity, 1))}.border-yellow-500\/50{border-color:#eab30880}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-\[--color-bg\]{background-color:var(--color-bg)}.bg-accent{background-color:hsl(var(--accent))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-background{background-color:hsl(var(--background))}.bg-background\/50{background-color:hsl(var(--background) / .5)}.bg-background\/80{background-color:hsl(var(--background) / .8)}.bg-background\/95{background-color:hsl(var(--background) / .95)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-black\/80{background-color:#000c}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-blue-900\/20{background-color:#1e3a8a33}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-card\/50{background-color:hsl(var(--card) / .5)}.bg-card\/80{background-color:hsl(var(--card) / .8)}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-800\/20{background-color:#1f293733}.bg-gray-800\/30{background-color:#1f29374d}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted-foreground\/50{background-color:hsl(var(--muted-foreground) / .5)}.bg-muted\/20{background-color:hsl(var(--muted) / .2)}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-muted\/60{background-color:hsl(var(--muted) / .6)}.bg-orange-50{--tw-bg-opacity: 1;background-color:rgb(255 247 237 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-orange-600{--tw-bg-opacity: 1;background-color:rgb(234 88 12 / var(--tw-bg-opacity, 1))}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary-foreground\/20{background-color:hsl(var(--primary-foreground) / .2)}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-primary\/20{background-color:hsl(var(--primary) / .2)}.bg-primary\/5{background-color:hsl(var(--primary) / .05)}.bg-primary\/60{background-color:hsl(var(--primary) / .6)}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-purple-500{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-red-900\/20{background-color:#7f1d1d33}.bg-red-900\/30{background-color:#7f1d1d4d}.bg-secondary{background-color:hsl(var(--secondary))}.bg-secondary\/5{background-color:hsl(var(--secondary) / .05)}.bg-slate-200{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.bg-slate-300{--tw-bg-opacity: 1;background-color:rgb(203 213 225 / var(--tw-bg-opacity, 1))}.bg-slate-400{--tw-bg-opacity: 1;background-color:rgb(148 163 184 / var(--tw-bg-opacity, 1))}.bg-slate-700{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-200{--tw-bg-opacity: 1;background-color:rgb(254 240 138 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-yellow-500\/10{background-color:#eab3081a}.bg-yellow-500\/5{background-color:#eab3080d}.bg-yellow-900\/20{background-color:#713f1233}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-blue-500{--tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-500{--tw-gradient-from: #22c55e var(--tw-gradient-from-position);--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-500{--tw-gradient-from: #f97316 var(--tw-gradient-from-position);--tw-gradient-to: rgb(249 115 22 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-primary\/5{--tw-gradient-from: hsl(var(--primary) / .05) var(--tw-gradient-from-position);--tw-gradient-to: hsl(var(--primary) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-500{--tw-gradient-from: #ef4444 var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 68 68 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-200{--tw-gradient-from: #e2e8f0 var(--tw-gradient-from-position);--tw-gradient-to: rgb(226 232 240 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-300{--tw-gradient-from: #cbd5e1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(203 213 225 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-400{--tw-gradient-from: #94a3b8 var(--tw-gradient-from-position);--tw-gradient-to: rgb(148 163 184 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-background{--tw-gradient-to: hsl(var(--background) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), hsl(var(--background)) var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-blue-600{--tw-gradient-to: #2563eb var(--tw-gradient-to-position)}.to-cyan-500{--tw-gradient-to: #06b6d4 var(--tw-gradient-to-position)}.to-emerald-500{--tw-gradient-to: #10b981 var(--tw-gradient-to-position)}.to-green-600{--tw-gradient-to: #16a34a var(--tw-gradient-to-position)}.to-orange-500{--tw-gradient-to: #f97316 var(--tw-gradient-to-position)}.to-pink-500{--tw-gradient-to: #ec4899 var(--tw-gradient-to-position)}.to-primary\/10{--tw-gradient-to: hsl(var(--primary) / .1) var(--tw-gradient-to-position)}.to-purple-500{--tw-gradient-to: #a855f7 var(--tw-gradient-to-position)}.to-secondary\/5{--tw-gradient-to: hsl(var(--secondary) / .05) var(--tw-gradient-to-position)}.to-slate-700{--tw-gradient-to: #334155 var(--tw-gradient-to-position)}.to-slate-800{--tw-gradient-to: #1e293b var(--tw-gradient-to-position)}.to-slate-900{--tw-gradient-to: #0f172a var(--tw-gradient-to-position)}.fill-current{fill:currentColor}.fill-red-500{fill:#ef4444}.fill-yellow-400{fill:#facc15}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-\[1px\]{padding:1px}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[--cell-size\]{padding-left:var(--cell-size);padding-right:var(--cell-size)}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0{padding-bottom:0}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-10{padding-left:2.5rem}.pl-11{padding-left:2.75rem}.pl-2{padding-left:.5rem}.pl-2\.5{padding-left:.625rem}.pl-4{padding-left:1rem}.pl-6{padding-left:1.5rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-1{padding-right:.25rem}.pr-10{padding-right:2.5rem}.pr-16{padding-right:4rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pr-4{padding-right:1rem}.pr-6{padding-right:1.5rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[10px\]{font-size:10px}.text-\[150px\]{font-size:150px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-blue-900{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-foreground\/50{color:hsl(var(--foreground) / .5)}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/10{color:hsl(var(--muted-foreground) / .1)}.text-muted-foreground\/50{color:hsl(var(--muted-foreground) / .5)}.text-muted-foreground\/60{color:hsl(var(--muted-foreground) / .6)}.text-orange-500{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-orange-800{--tw-text-opacity: 1;color:rgb(154 52 18 / var(--tw-text-opacity, 1))}.text-orange-900{--tw-text-opacity: 1;color:rgb(124 45 18 / var(--tw-text-opacity, 1))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-primary-foreground\/70{color:hsl(var(--primary-foreground) / .7)}.text-primary\/10{color:hsl(var(--primary) / .1)}.text-primary\/30{color:hsl(var(--primary) / .3)}.text-primary\/60{color:hsl(var(--primary) / .6)}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-800{--tw-text-opacity: 1;color:rgb(133 77 14 / var(--tw-text-opacity, 1))}.text-yellow-900{--tw-text-opacity: 1;color:rgb(113 63 18 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-primary{--tw-ring-color: hsl(var(--primary))}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.blur-3xl{--tw-blur: blur(64px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.delay-150{transition-delay:.15s}.delay-300{transition-delay:.3s}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.text-primary-gradient{color:hsl(var(--primary))}.has-gradient .text-primary-gradient{background:var(--primary-gradient);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}.\[--cell-size\:2rem\]{--cell-size: 2rem}.no-animations *,.no-animations *:before,.no-animations *:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}.no-animations *:hover{transition-duration:.01ms!important}::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}::view-transition-old(root){z-index:1}::view-transition-new(root){z-index:999}.__floater{z-index:99999!important;pointer-events:auto!important}.react-joyride__overlay,.react-joyride__spotlight{z-index:99998!important}.react-joyride__tooltip{pointer-events:auto!important}#tour-portal-container *{pointer-events:auto}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:text-foreground::file-selector-button{color:hsl(var(--foreground))}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:scale-110:hover{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-muted-foreground\/50:hover{border-color:hsl(var(--muted-foreground) / .5)}.hover\:border-primary\/50:hover{border-color:hsl(var(--primary) / .5)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-accent\/50:hover{background-color:hsl(var(--accent) / .5)}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted-foreground\/20:hover{background-color:hsl(var(--muted-foreground) / .2)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-orange-700:hover{--tw-bg-opacity: 1;background-color:rgb(194 65 12 / var(--tw-bg-opacity, 1))}.hover\:bg-primary\/10:hover{background-color:hsl(var(--primary) / .1)}.hover\:bg-primary\/80:hover{background-color:hsl(var(--primary) / .8)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-secondary:hover{background-color:hsl(var(--secondary))}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:bg-secondary\/90:hover{background-color:hsl(var(--secondary) / .9)}.hover\:bg-transparent:hover{background-color:transparent}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-amber-900:hover{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-green-700:hover{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.hover\:text-orange-700:hover{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.hover\:text-primary\/80:hover{color:hsl(var(--primary) / .8)}.hover\:text-red-500:hover{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.hover\:text-red-700:hover{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.hover\:text-yellow-300:hover{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-2xl:hover{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:ring-2:hover{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:ring-primary:hover{--tw-ring-color: hsl(var(--primary))}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:bg-gray-100:focus{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-0:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-red-500:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background))}.active\:cursor-grabbing:active{cursor:grabbing}.active\:border-primary\/70:active{border-color:hsl(var(--primary) / .7)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group[open] .group-open\:rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:-translate-y-1{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:opacity-100{opacity:1}.group.destructive .group-\[\.destructive\]\:border-muted\/40{border-color:hsl(var(--muted) / .4)}.group.destructive .group-\[\.destructive\]\:text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:text-red-50:hover{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-red-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-offset-red-600:focus{--tw-ring-offset-color: #dc2626}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}.aria-selected\:text-muted-foreground[aria-selected=true]{color:hsl(var(--muted-foreground))}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true],.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=checked\]\:translate-x-4[data-state=checked]{--tw-translate-x: 1rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked],.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe=end]{--tw-translate-x: var(--radix-toast-swipe-end-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move]{--tw-translate-x: var(--radix-toast-swipe-move-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes fade-out{0%{opacity:1}to{opacity:0}}.data-\[state\=closed\]\:animate-fade-out[data-state=closed]{animation:fade-out .15s ease-in}.data-\[state\=closed\]\:animate-slide-out-to-right[data-state=closed]{animation:slide-out-to-right .2s ease-in}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.data-\[state\=open\]\:animate-fade-in[data-state=open]{animation:fade-in .2s ease-out}@keyframes slide-in-from-right{0%{transform:translate(100%)}to{transform:translate(0)}}.data-\[state\=open\]\:animate-slide-in-from-right[data-state=open]{animation:slide-in-from-right .3s ease-out}@keyframes slide-out-to-right{0%{transform:translate(0)}to{transform:translate(100%)}}.data-\[swipe\=end\]\:animate-slide-out-to-right[data-swipe=end]{animation:slide-out-to-right .2s ease-in}.data-\[range-end\=true\]\:rounded-md[data-range-end=true]{border-radius:calc(var(--radius) - 2px)}.data-\[range-middle\=true\]\:rounded-none[data-range-middle=true]{border-radius:0}.data-\[range-start\=true\]\:rounded-md[data-range-start=true]{border-radius:calc(var(--radius) - 2px)}.data-\[selected\=true\]\:rounded-none[data-selected=true]{border-radius:0}.data-\[range-end\=true\]\:bg-primary[data-range-end=true]{background-color:hsl(var(--primary))}.data-\[range-middle\=true\]\:bg-accent[data-range-middle=true]{background-color:hsl(var(--accent))}.data-\[range-start\=true\]\:bg-primary[data-range-start=true],.data-\[selected-single\=true\]\:bg-primary[data-selected-single=true]{background-color:hsl(var(--primary))}.data-\[selected\=true\]\:bg-accent[data-selected=true]{background-color:hsl(var(--accent))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:hsl(var(--muted-foreground))}.data-\[range-end\=true\]\:text-primary-foreground[data-range-end=true]{color:hsl(var(--primary-foreground))}.data-\[range-middle\=true\]\:text-accent-foreground[data-range-middle=true]{color:hsl(var(--accent-foreground))}.data-\[range-start\=true\]\:text-primary-foreground[data-range-start=true],.data-\[selected-single\=true\]\:text-primary-foreground[data-selected-single=true]{color:hsl(var(--primary-foreground))}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:hsl(var(--accent-foreground))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[state\=open\]\:text-accent-foreground[data-state=open]{color:hsl(var(--accent-foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[disabled\=true\]\:opacity-50[data-disabled=true],.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[swipe\=move\]\:transition-none[data-swipe=move]{transition-property:none}.data-\[state\=active\]\:duration-300[data-state=active]{transition-duration:.3s}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:relative{position:relative}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:z-10{z-index:10}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:border-ring{border-color:hsl(var(--ring))}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-\[3px\]{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.group\/day[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-ring\/50{--tw-ring-color: hsl(var(--ring) / .5)}@supports (backdrop-filter: var(--tw)){.supports-\[backdrop-filter\]\:bg-background\/60{background-color:hsl(var(--background) / .6)}}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:border-blue-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 64 175 / var(--tw-border-opacity, 1))}.dark\:border-blue-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 58 138 / var(--tw-border-opacity, 1))}.dark\:border-gray-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(17 24 39 / var(--tw-border-opacity, 1))}.dark\:border-green-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(22 101 52 / var(--tw-border-opacity, 1))}.dark\:border-green-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(20 83 45 / var(--tw-border-opacity, 1))}.dark\:border-orange-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(124 45 18 / var(--tw-border-opacity, 1))}.dark\:border-red-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(127 29 29 / var(--tw-border-opacity, 1))}.dark\:border-yellow-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(113 63 18 / var(--tw-border-opacity, 1))}.dark\:bg-amber-950\/30:is(.dark *){background-color:#451a034d}.dark\:bg-blue-500\/20:is(.dark *){background-color:#3b82f633}.dark\:bg-blue-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 58 138 / var(--tw-bg-opacity, 1))}.dark\:bg-blue-900\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-blue-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(23 37 84 / var(--tw-bg-opacity, 1))}.dark\:bg-blue-950\/20:is(.dark *){background-color:#17255433}.dark\:bg-blue-950\/30:is(.dark *){background-color:#1725544d}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800\/30:is(.dark *){background-color:#1f29374d}.dark\:bg-gray-800\/50:is(.dark *){background-color:#1f293780}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-green-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(5 46 22 / var(--tw-bg-opacity, 1))}.dark\:bg-green-950\/20:is(.dark *){background-color:#052e1633}.dark\:bg-orange-950\/20:is(.dark *){background-color:#43140733}.dark\:bg-purple-900\/30:is(.dark *){background-color:#581c874d}.dark\:bg-red-500\/20:is(.dark *){background-color:#ef444433}.dark\:bg-red-600\/30:is(.dark *){background-color:#dc26264d}.dark\:bg-red-900\/30:is(.dark *){background-color:#7f1d1d4d}.dark\:bg-red-950\/20:is(.dark *){background-color:#450a0a33}.dark\:bg-red-950\/50:is(.dark *){background-color:#450a0a80}.dark\:bg-yellow-500\/20:is(.dark *){background-color:#eab30833}.dark\:bg-yellow-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(113 63 18 / var(--tw-bg-opacity, 1))}.dark\:bg-yellow-950\/30:is(.dark *){background-color:#4220064d}.dark\:text-amber-100:is(.dark *){--tw-text-opacity: 1;color:rgb(254 243 199 / var(--tw-text-opacity, 1))}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-amber-500:is(.dark *){--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.dark\:text-blue-100:is(.dark *){--tw-text-opacity: 1;color:rgb(219 234 254 / var(--tw-text-opacity, 1))}.dark\:text-blue-200:is(.dark *){--tw-text-opacity: 1;color:rgb(191 219 254 / var(--tw-text-opacity, 1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-cyan-500:is(.dark *){--tw-text-opacity: 1;color:rgb(6 182 212 / var(--tw-text-opacity, 1))}.dark\:text-gray-100:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-gray-600:is(.dark *){--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-orange-100:is(.dark *){--tw-text-opacity: 1;color:rgb(255 237 213 / var(--tw-text-opacity, 1))}.dark\:text-orange-200:is(.dark *){--tw-text-opacity: 1;color:rgb(254 215 170 / var(--tw-text-opacity, 1))}.dark\:text-purple-400:is(.dark *){--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-red-500:is(.dark *){--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.dark\:text-yellow-200:is(.dark *){--tw-text-opacity: 1;color:rgb(254 240 138 / var(--tw-text-opacity, 1))}.dark\:text-yellow-300:is(.dark *){--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:text-yellow-500:is(.dark *){--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.dark\:hover\:bg-gray-800:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:hover\:text-amber-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:focus\:bg-gray-800:focus:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}@media(min-width:640px){.sm\:right-2{right:.5rem}.sm\:right-3{right:.75rem}.sm\:top-2{top:.5rem}.sm\:top-3{top:.75rem}.sm\:order-1{order:1}.sm\:order-2{order:2}.sm\:col-span-2{grid-column:span 2 / span 2}.sm\:mx-0{margin-left:0;margin-right:0}.sm\:mb-3{margin-bottom:.75rem}.sm\:mb-4{margin-bottom:1rem}.sm\:mb-6{margin-bottom:1.5rem}.sm\:ml-0{margin-left:0}.sm\:ml-1{margin-left:.25rem}.sm\:mr-1{margin-right:.25rem}.sm\:mt-0{margin-top:0}.sm\:mt-2{margin-top:.5rem}.sm\:mt-3{margin-top:.75rem}.sm\:mt-6{margin-top:1.5rem}.sm\:block{display:block}.sm\:inline{display:inline}.sm\:flex{display:flex}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:h-10{height:2.5rem}.sm\:h-12{height:3rem}.sm\:h-2{height:.5rem}.sm\:h-2\.5{height:.625rem}.sm\:h-24{height:6rem}.sm\:h-4{height:1rem}.sm\:h-5{height:1.25rem}.sm\:h-8{height:2rem}.sm\:h-9{height:2.25rem}.sm\:h-\[300px\]{height:300px}.sm\:h-\[400px\]{height:400px}.sm\:h-\[500px\]{height:500px}.sm\:h-\[calc\(100vh-220px\)\]{height:calc(100vh - 220px)}.sm\:h-\[calc\(100vh-280px\)\]{height:calc(100vh - 280px)}.sm\:w-10{width:2.5rem}.sm\:w-2{width:.5rem}.sm\:w-2\.5{width:.625rem}.sm\:w-24{width:6rem}.sm\:w-28{width:7rem}.sm\:w-4{width:1rem}.sm\:w-5{width:1.25rem}.sm\:w-8{width:2rem}.sm\:w-80{width:20rem}.sm\:w-96{width:24rem}.sm\:w-\[200px\]{width:200px}.sm\:w-\[500px\]{width:500px}.sm\:w-auto{width:auto}.sm\:w-full{width:100%}.sm\:min-w-\[120px\]{min-width:120px}.sm\:max-w-2xl{max-width:42rem}.sm\:max-w-\[420px\]{max-width:420px}.sm\:max-w-\[500px\]{max-width:500px}.sm\:max-w-\[70\%\]{max-width:70%}.sm\:max-w-\[900px\]{max-width:900px}.sm\:max-w-md{max-width:28rem}.sm\:max-w-sm{max-width:24rem}.sm\:flex-1{flex:1 1 0%}.sm\:flex-none{flex:none}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-start{align-items:flex-start}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:justify-between{justify-content:space-between}.sm\:gap-0{gap:0px}.sm\:gap-1{gap:.25rem}.sm\:gap-2{gap:.5rem}.sm\:gap-3{gap:.75rem}.sm\:gap-4{gap:1rem}.sm\:gap-6{gap:1.5rem}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.sm\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.sm\:space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.sm\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.sm\:space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:p-3{padding:.75rem}.sm\:p-4{padding:1rem}.sm\:p-6{padding:1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-3{padding-left:.75rem;padding-right:.75rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-2{padding-top:.5rem;padding-bottom:.5rem}.sm\:pb-3{padding-bottom:.75rem}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}.sm\:text-3xl{font-size:1.875rem;line-height:2.25rem}.sm\:text-\[200px\]{font-size:200px}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:text-lg{font-size:1.125rem;line-height:1.75rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}.sm\:text-xs{font-size:.75rem;line-height:1rem}}@media(min-width:768px){.md\:top-4{top:1rem}.md\:mb-4{margin-bottom:1rem}.md\:mb-6{margin-bottom:1.5rem}.md\:mb-8{margin-bottom:2rem}.md\:mt-8{margin-top:2rem}.md\:block{display:block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-16{height:4rem}.md\:h-4{height:1rem}.md\:h-5{height:1.25rem}.md\:h-8{height:2rem}.md\:h-96{height:24rem}.md\:h-\[500px\]{height:500px}.md\:min-h-\[400px\]{min-height:400px}.md\:w-16{width:4rem}.md\:w-4{width:1rem}.md\:w-5{width:1.25rem}.md\:w-8{width:2rem}.md\:w-96{width:24rem}.md\:max-w-none{max-width:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:gap-2{gap:.5rem}.md\:gap-3{gap:.75rem}.md\:gap-4{gap:1rem}.md\:gap-6{gap:1.5rem}.md\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.md\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.md\:whitespace-normal{white-space:normal}.md\:p-12{padding:3rem}.md\:p-4{padding:1rem}.md\:p-6{padding:1.5rem}.md\:p-8{padding:2rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:text-xs{font-size:.75rem;line-height:1rem}}@media(min-width:1024px){.lg\:invisible{visibility:hidden}.lg\:relative{position:relative}.lg\:z-0{z-index:0}.lg\:col-span-1{grid-column:span 1 / span 1}.lg\:col-span-2{grid-column:span 2 / span 2}.lg\:mx-auto{margin-left:auto;margin-right:auto}.lg\:mb-1{margin-bottom:.25rem}.lg\:block{display:block}.lg\:inline{display:inline}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-12{width:3rem}.lg\:w-16{width:4rem}.lg\:w-64{width:16rem}.lg\:w-8{width:2rem}.lg\:w-\[130px\]{width:130px}.lg\:w-\[160px\]{width:160px}.lg\:w-\[75px\]{width:75px}.lg\:w-auto{width:auto}.lg\:w-full{width:100%}.lg\:max-w-0{max-width:0px}.lg\:flex-1{flex:1 1 0%}.lg\:flex-none{flex:none}.lg\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.lg\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.lg\:justify-center{justify-content:center}.lg\:gap-0{gap:0px}.lg\:space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.lg\:overflow-hidden{overflow:hidden}.lg\:p-2{padding:.5rem}.lg\:p-4{padding:1rem}.lg\:px-0{padding-left:0;padding-right:0}.lg\:px-4{padding-left:1rem;padding-right:1rem}.lg\:pb-4{padding-bottom:1rem}.lg\:text-2xl{font-size:1.5rem;line-height:2rem}.lg\:opacity-0{opacity:0}}@media(min-width:1280px){.xl\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}}.\[\&\+div\]\:text-xs+div{font-size:.75rem;line-height:1rem}.\[\&\:\:-webkit-scrollbar-thumb\:hover\]\:bg-border\/80::-webkit-scrollbar-thumb:hover{background-color:hsl(var(--border) / .8)}.\[\&\:\:-webkit-scrollbar-thumb\]\:rounded-full::-webkit-scrollbar-thumb{border-radius:9999px}.\[\&\:\:-webkit-scrollbar-thumb\]\:bg-border::-webkit-scrollbar-thumb{background-color:hsl(var(--border))}.\[\&\:\:-webkit-scrollbar-track\]\:bg-transparent::-webkit-scrollbar-track{background-color:transparent}.\[\&\:\:-webkit-scrollbar\]\:w-2\.5::-webkit-scrollbar{width:.625rem}.\[\&\:first-child\[data-selected\=true\]_button\]\:rounded-l-md:first-child[data-selected=true] button{border-top-left-radius:calc(var(--radius) - 2px);border-bottom-left-radius:calc(var(--radius) - 2px)}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\:last-child\[data-selected\=true\]_button\]\:rounded-r-md:last-child[data-selected=true] button{border-top-right-radius:calc(var(--radius) - 2px);border-bottom-right-radius:calc(var(--radius) - 2px)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>div\]\:bg-green-500>div{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&\>span\]\:text-xs>span{font-size:.75rem;line-height:1rem}.\[\&\>span\]\:opacity-70>span{opacity:.7}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:left-4>svg{left:1rem}.\[\&\>svg\]\:top-4>svg{top:1rem}.\[\&\>svg\]\:size-3\.5>svg{width:.875rem;height:.875rem}.\[\&\>svg\]\:h-2\.5>svg{height:.625rem}.\[\&\>svg\]\:h-3>svg{height:.75rem}.\[\&\>svg\]\:w-2\.5>svg{width:.625rem}.\[\&\>svg\]\:w-3>svg{width:.75rem}.\[\&\>svg\]\:text-foreground>svg{color:hsl(var(--foreground))}.\[\&\>svg\]\:text-muted-foreground>svg{color:hsl(var(--muted-foreground))}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:1.75rem}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state=open]>svg{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&_\.recharts-cartesian-axis-tick_text\]\:fill-muted-foreground .recharts-cartesian-axis-tick text{fill:hsl(var(--muted-foreground))}.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke="#ccc"]{stroke:hsl(var(--border) / .5)}.\[\&_\.recharts-curve\.recharts-tooltip-cursor\]\:stroke-border .recharts-curve.recharts-tooltip-cursor{stroke:hsl(var(--border))}.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-dot[stroke="#fff"]{stroke:transparent}.\[\&_\.recharts-layer\]\:outline-none .recharts-layer{outline:2px solid transparent;outline-offset:2px}.\[\&_\.recharts-polar-grid_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-polar-grid [stroke="#ccc"]{stroke:hsl(var(--border))}.\[\&_\.recharts-radial-bar-background-sector\]\:fill-muted .recharts-radial-bar-background-sector,.\[\&_\.recharts-rectangle\.recharts-tooltip-cursor\]\:fill-muted .recharts-rectangle.recharts-tooltip-cursor{fill:hsl(var(--muted))}.\[\&_\.recharts-reference-line_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-reference-line [stroke="#ccc"]{stroke:hsl(var(--border))}.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-sector[stroke="#fff"]{stroke:transparent}.\[\&_\.recharts-sector\]\:outline-none .recharts-sector,.\[\&_\.recharts-surface\]\:outline-none .recharts-surface{outline:2px solid transparent;outline-offset:2px}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-top:.375rem;padding-bottom:.375rem}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:.75rem;line-height:1rem}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{font-weight:500}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:hsl(var(--muted-foreground))}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:0}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:1.25rem}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:1.25rem}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:3rem}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-top:.75rem;padding-bottom:.75rem}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:1.25rem}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:1.25rem}.\[\&_p\]\:leading-relaxed p{line-height:1.625}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:invisible svg{visibility:hidden}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}[data-slot=card-content] .\[\[data-slot\=card-content\]_\&\]\:bg-transparent,[data-slot=popover-content] .\[\[data-slot\=popover-content\]_\&\]\:bg-transparent{background-color:transparent}@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2) format("woff2"),url(/assets/KaTeX_AMS-Regular-DMm9YOAa.woff) format("woff"),url(/assets/KaTeX_AMS-Regular-DRggAlZN.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff) format("woff"),url(/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff) format("woff"),url(/assets/KaTeX_Fraktur-Regular-CB_wures.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Main-Bold-Cx986IdX.woff2) format("woff2"),url(/assets/KaTeX_Main-Bold-Jm3AIy58.woff) format("woff"),url(/assets/KaTeX_Main-Bold-waoOVXN0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2) format("woff2"),url(/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff) format("woff"),url(/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2) format("woff2"),url(/assets/KaTeX_Main-Italic-BMLOBm91.woff) format("woff"),url(/assets/KaTeX_Main-Italic-3WenGoN9.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Main-Regular-B22Nviop.woff2) format("woff2"),url(/assets/KaTeX_Main-Regular-Dr94JaBh.woff) format("woff"),url(/assets/KaTeX_Main-Regular-ypZvNtVU.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2) format("woff2"),url(/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff) format("woff"),url(/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Math-Italic-t53AETM-.woff2) format("woff2"),url(/assets/KaTeX_Math-Italic-DA0__PXp.woff) format("woff"),url(/assets/KaTeX_Math-Italic-flOr_0UB.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:700;src:url(/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff) format("woff"),url(/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:italic;font-weight:400;src:url(/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff) format("woff"),url(/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:400;src:url(/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff) format("woff"),url(/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Script-Regular-D3wIWfF6.woff2) format("woff2"),url(/assets/KaTeX_Script-Regular-D5yQViql.woff) format("woff"),url(/assets/KaTeX_Script-Regular-C5JkGWo-.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2) format("woff2"),url(/assets/KaTeX_Size1-Regular-C195tn64.woff) format("woff"),url(/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2) format("woff2"),url(/assets/KaTeX_Size2-Regular-oD1tc_U0.woff) format("woff"),url(/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA4oAA4AAAAAHbQAAA3TAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQIDgmcDBEICo1oijYBNgIkA14LMgAEIAWJAAeBHAyBHBvbGiMRdnO0IkRRkiYDgr9KsJ1NUAf2kILNxgUmgqIgq1P89vcbIcmsQbRps3vCcXdYOKSWEPEKgZgQkprQQsxIXUgq0DqpGKmIvrgkeVGtEQD9DzAO29fM9jYhxZEsL2FeURH2JN4MIcTdO049NCVdxQ/w9NrSYFEBKTDKpLKfNkCGDc1RwjZLQcm3vqJ2UW9Xfa3tgAHz6ivp6vgC2yD4/6352ndnN0X0TL7seypkjZlMsjmZnf0Mm5Q+JykRWQBKCVCVPbARPXWyQtb5VgLB6Biq7/Uixcj2WGqdI8tGSgkuRG+t910GKP2D7AQH0DB9FMDW/obJZ8giFI3Wg8Cvevz0M+5m0rTh7XDBlvo9Y4vm13EXmfttwI4mBo1EG15fxJhUiCLbiiyCf/ZA6MFAhg3pGIZGdGIVjtPn6UcMk9A/UUr9PhoNsCENw1APAq0gpH73e+M+0ueyHbabc3vkbcdtzcf/fiy+NxQEjf9ud/ELBHAXJ0nk4z+MXH2Ev/kWyV4k7SkvpPc9Qr38F6RPWnM9cN6DJ0AdD1BhtgABtmoRoFCvPsBAumNm6soZG2Gk5GyVTo2sJncSyp0jQTYoR6WDvTwaaEcHsxHfvuWhHA3a6bN7twRKtcGok6NsCi7jYRrM2jExsUFMxMQYuJbMhuWNOumEJy9hi29Dmg5zMp/A5+hhPG19j1vBrq8JTLr8ki5VLPmG/PynJHVul440bxg5xuymHUFPBshC+nA9I1FmwbRBTNHAcik3Oae0cxKoI3MOriM42UrPe51nsaGxJ+WfXubAsP84aabUlQSJ1IiE0iPETLUU4CATgfXSCSpuRFRmCGbO+wSpAnzaeaCYW1VNEysRtuXCEL1kUFUbbtMv3Tilt/1c11jt3Q5bbMa84cpWipp8Elw3MZhOHsOlwwVUQM3lAR35JiFQbaYCRnMF2lxAWoOg2gyoIV4PouX8HytNIfLhqpJtXB4vjiViUI8IJ7bkC4ikkQvKksnOTKICwnqWSZ9YS5f0WCxmpgjbIq7EJcM4aI2nmhLNY2JIUgOjXZFWBHb+x5oh6cwb0Tv1ackHdKi0I9OO2wE9aogIOn540CCCziyhN+IaejtgAONKznHlHyutPrHGwCx9S6B8kfS4Mfi4Eyv7OU730bT1SCBjt834cXsf43zVjPUqqJjgrjeGnBxSG4aYAKFuVbeCfkDIjAqMb6yLNIbCuvXhMH2/+k2vkNpkORhR59N1CkzoOENvneIosjYmuTxlhUzaGEJQ/iWqx4dmwpmKjrwTiTGTCVozNAYqk/zXOndWxuWSmJkQpJw3pK5KX6QrLt5LATMqpmPAQhkhK6PUjzHUn7E0gHE0kPE0iKkolgkUx9SZmVAdDgpffdyJKg3k7VmzYGCwVXGz/tXmkOIp+vcWs+EMuhhvN0h9uhfzWJziBQmCREGSIFmQIkgVpAnSBRmC//6hkLZwaVhwxlrJSOdqlFtOYxlau9F2QN5Y98xmIAsiM1HVp2VFX+DHHGg6Ecjh3vmqtidX3qHI2qycTk/iwxSt5UzTmEP92ZBnEWTk4Mx8Mpl78ZDokxg/KWb+Q0QkvdKVmq3TMW+RXEgrsziSAfNXFMhDc60N5N9jQzjfO0kBKpUZl0ZmwJ41j/B9Hz6wmRaJB84niNmQrzp9eSlQCDDzazGDdVi3P36VZQ+Jy4f9UBNp+3zTjqI4abaFAm+GShVaXlsGdF3FYzZcDI6cori4kMxUECl9IjJZpzkvitAoxKue+90pDMvcKRxLl53TmOKCmV/xRolNKSqqUxc6LStOETmFOiLZZptlZepcKiAzteG8PEdpnQpbOMNcMsR4RR2Bs0cKFEvSmIjAFcnarqwUL4lDhHmnVkwu1IwshbiCcgvOheZuYyOteufZZwlcTlLgnZ3o/WcYdzZHW/WGaqaVfmTZ1aWCceJjkbZqsfbkOtcFlUZM/jy+hXHDbaUobWqqXaeWobbLO99yG5N3U4wxco0rQGGcOLASFMXeJoham8M+/x6O2WywK2l4HGbq1CoUyC/IZikQhdq3SiuNrvAEj0AVu9x2x3lp/xWzahaxidezFVtdcb5uEnzyl0ZmYiuKI0exvCd4Xc9CV1KB0db00z92wDPde0kukbvZIWN6jUWFTmPIC/Y4UPCm8UfDTFZpZNon1qLFTkBhxzB+FjQRA2Q/YRJT8pQigslMaUpFyAG8TMlXigiqmAZX4xgijKjRlGpLE0GdplRfCaJo0JQaSxNBk6ZmMzcya0FmrcisDdn0Q3HI2sWSppYigmlM1XT/kLQZSNpMJG0WkjYbSZuDpM1F0uYhFc1HxU4m1QJjDK6iL0S5uSj5rgXc3RejEigtcRBtqYPQsiTskmO5vosV+q4VGIKbOkDg0jtRrq+Em1YloaTFar3EGr1EUC8R0kus1Uus00usL97ABr2BjXoDm/QGNhuWtMVBKOwg/i78lT7hBsAvDmwHc/ao3vmUbBmhjeYySZNWvGkfZAgISDSaDo1SVpzGDsAEkF8B+gEapViUoZgUWXcRIGFZNm6gWbAKk0bp0k1MHG9fLYtV4iS2SmLEQFARzRcnf9PUS0LVn05/J9MiRRBU3v2IrvW974v4N00L7ZMk0wXP1409CHo/an8zTRHD3eSJ6m8D4YMkZNl3M79sqeuAsr/m3f+8/yl7A50aiAEJgeBeMWzu7ui9UfUBCe2TIqZIoOd/3/udRBOQidQZUERzb2/VwZN1H/Sju82ew2H2Wfr6qvfVf3hqwDvAIpkQVFy4B9Pe9e4/XvPeceu7h3dvO56iJPf0+A6cqA2ip18ER+iFgggiuOkvj24bby0N9j2UHIkgqIt+sVgfodC4YghLSMjSZbH0VR/6dMDrYJeKHilKTemt6v6kvzvn3/RrdWtr0GoN/xL+Sex/cPYLUpepx9cz/D46UPU5KXgAQa+NDps1v6J3xP1i2HtaDB0M9aX2deA7SYff//+gUCovMmIK/qfsFcOk+4Y5ZN97XlG6zebqtMbKgeRFi51vnxTQYBUik2rS/Cn6PC8ADR8FGxsRPB82dzfND90gIcshOcYUkfjherBz53odpm6TP8txlwOZ71xmfHHOvq053qFF/MRlS3jP0ELudrf2OeN8DHvp6ZceLe8qKYvWz/7yp0u4dKPfli3CYq0O13Ih71mylJ80tOi10On8wi+F4+LWgDPeJ30msSQt9/vkmHq9/Lvo2b461mP801v3W4xTcs6CbvF9UDdrSt+A8OUbpSh55qAUFXWznBBfdeJ8a4d7ugT5tvxUza3h9m4H7ptTqiG4z0g5dc0X29OcGlhpGFMpQo9ytTS+NViZpNdvU4kWx+LKxNY10kQ1yqGXrhe4/1nvP7E+nd5A92TtaRplbHSqoIdOqtRWti+fkB5/n1+/VvCmz12pG1kpQWsfi1ftlBobm0bpngs16CHkbIwdLnParxtTV3QYRlfJ0KFskH7pdN/YDn+yRuSd7sNH3aO0DYPggk6uWuXrfOc+fa3VTxFVvKaNxHsiHmsXyCLIE5yuOeN3/Jdf8HBL/5M6shjyhxHx9BjB1O0+4NLOnjLLSxwO7ukN4jMbOIcD879KLSi6Pk61Oqm2377n8079PXEEQ7cy7OKEC9nbpet118fxweTafpt69x/Bt8UqGzNQt7aelpc44dn5cqhwf71+qKp/Zf/+a0zcizOUWpl/iBcSXip0pplkatCchoH5c5aUM8I7/dWxAej8WicPL1URFZ9BDJelUwEwTkGqUhgSlydVes95YdXvhh9Gfz/aeFWvgVb4tuLbcv4+wLdutVZv/cUonwBD/6eDlE0aSiKK/uoH3+J1wDE/jMVqY2ysGufN84oIXB0sPzy8ollX/LegY74DgJXJR57sn+VGza0x3DnuIgABFM15LmajjjsNlYj+JEZGbuRYcAMOWxFkPN2w6Wd46xo4gVWQR/X4lyI/R6K/YK0110GzudPRW7Y+UOBGTfNNzHeYT0fiH0taunBpq9HEW8OKSaBGj21L0MqenEmNRWBAWDWAk4CpNoEZJ2tTaPFgbQYj8HxtFilErs3BTRwT8uO1NXQaWfIotchmPkAF5mMBAliEmZiOGVgCG9LgRzpscMAOOwowlT3JhusdazXGSC/hxR3UlmWVwWHpOIKheqONvjyhSiTHIkVUco5bnji8m//zL7PKaT1Vl5I6UE609f+gkr6MZKVyKc7zJRmCahLsdlyA5fdQkRSan9LgnnLEyGSkaKJCJog0wAgvepWBt80+1yKln1bMVtCljfNWDueKLsWwaEbBSfSPTEmVRsUcYYMnEjcjeyCZzBXK9E9BYBXLKjOSpUDR+nEV3TFSUdQaz+ot98QxgXwx0GQ+EEUAKB2qZPkQQ0GqFD8UPFMqyaCHM24BZmSGic9EYMagKizOw9Hz50DMrDLrqqLkTAhplMictiCAx5S3BIUQdeJeLnBy2CNtMfz6cV4u8XKoFZQesbf9YZiIERiHjaNodDW6LgcirX/mPnJIkBGDUpTBhSa0EIr38D5hCIszhCM8URGBqImoWjpvpt1ebu/v3Gl3qJfMnNM+9V+kiRFyROTPHQWOcs1dNW94/ukKMPZBvDi55i5CttdeJz84DLngLqjcdwEZ87bFFR8CIG35OAkDVN6VRDZ7aq67NteYqZ2lpT8oYB2CytoBd6VuAx4WgiAsnuj3WohG+LugzXiQRDeM3XYXlULv4dp5VFYC) format("woff2"),url(/assets/KaTeX_Size3-Regular-CTq5MqoE.woff) format("woff"),url(/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2) format("woff2"),url(/assets/KaTeX_Size4-Regular-BF-4gkZK.woff) format("woff"),url(/assets/KaTeX_Size4-Regular-DWFBv043.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2) format("woff2"),url(/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff) format("woff"),url(/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf) format("truetype")}.katex{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.27"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}.uppy-Root{box-sizing:border-box;color:#333;font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Segoe UI Symbol,Segoe UI Emoji,Apple Color Emoji,Roboto,Helvetica,Arial,sans-serif;line-height:1;position:relative;text-align:left;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.uppy-Root[dir=rtl],[dir=rtl] .uppy-Root{text-align:right}.uppy-Root *,.uppy-Root :after,.uppy-Root :before{box-sizing:inherit}.uppy-Root [hidden]{display:none}.uppy-u-reset{all:initial;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Segoe UI Symbol,Segoe UI Emoji,Apple Color Emoji,Roboto,Helvetica,Arial,sans-serif;line-height:1}[dir=rtl] .uppy-u-reset{text-align:right}.uppy-truncate-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.uppy-c-textInput{background-color:#fff;border:1px solid #ddd;border-radius:4px;font-family:inherit;font-size:14px;line-height:1.5;padding:6px 8px}.uppy-size--md .uppy-c-textInput{padding:8px 10px}.uppy-c-textInput:focus{border-color:#1269cf99;box-shadow:0 0 0 3px #1269cf26;outline:none}[data-uppy-theme=dark] .uppy-c-textInput{background-color:#333;border-color:#333;color:#eaeaea}[data-uppy-theme=dark] .uppy-c-textInput:focus{border-color:#525252;box-shadow:none}.uppy-c-icon{display:inline-block;max-height:100%;max-width:100%;overflow:hidden;fill:currentColor}.uppy-c-btn{align-items:center;color:inherit;display:inline-flex;font-family:inherit;font-size:inherit;font-weight:500;justify-content:center;line-height:1;transition-duration:.3s;transition-property:background-color,color;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.uppy-c-btn,[dir=rtl] .uppy-c-btn{text-align:center}.uppy-c-btn:not(:disabled):not(.disabled){cursor:pointer}.uppy-c-btn::-moz-focus-inner{border:0}.uppy-c-btn-primary{background-color:#1269cf;border-radius:4px;color:#fff;font-size:14px;padding:10px 18px}.uppy-c-btn-primary:not(:disabled):hover{background-color:#0e51a0}.uppy-c-btn-primary:focus{box-shadow:0 0 0 3px #1269cf66;outline:none}.uppy-size--md .uppy-c-btn-primary{padding:13px 22px}[data-uppy-theme=dark] .uppy-c-btn-primary{color:#eaeaea}[data-uppy-theme=dark] .uppy-c-btn-primary:focus{outline:none}[data-uppy-theme=dark] .uppy-c-btn-primary::-moz-focus-inner{border:0}[data-uppy-theme=dark] .uppy-c-btn-primary:focus{box-shadow:0 0 0 2px #aae1ffd9}.uppy-c-btn-primary.uppy-c-btn--disabled{background-color:#8eb2db}.uppy-c-btn-link{background-color:initial;border-radius:4px;color:#525252;font-size:14px;line-height:1;padding:10px 15px}.uppy-c-btn-link:hover{color:#333}.uppy-c-btn-link:focus{box-shadow:0 0 0 3px #1269cf40;outline:none}.uppy-size--md .uppy-c-btn-link{padding:13px 18px}[data-uppy-theme=dark] .uppy-c-btn-link{color:#eaeaea}[data-uppy-theme=dark] .uppy-c-btn-link:focus{outline:none}[data-uppy-theme=dark] .uppy-c-btn-link::-moz-focus-inner{border:0}[data-uppy-theme=dark] .uppy-c-btn-link:focus{box-shadow:0 0 0 2px #aae1ffd9}[data-uppy-theme=dark] .uppy-c-btn-link:hover{color:#939393}.uppy-ProviderBrowser-viewType--grid ul.uppy-ProviderBrowser-list,.uppy-ProviderBrowser-viewType--unsplash ul.uppy-ProviderBrowser-list{align-items:flex-start;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;padding:6px}.uppy-ProviderBrowser-viewType--grid ul.uppy-ProviderBrowser-list:after,.uppy-ProviderBrowser-viewType--unsplash ul.uppy-ProviderBrowser-list:after{content:"";flex:auto}.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem{margin:0;position:relative;width:50%}.uppy-size--md .uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem,.uppy-size--md .uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem{width:33.3333%}.uppy-size--lg .uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem,.uppy-size--lg .uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem{width:25%}.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem:before,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem:before{content:"";display:block;padding-top:100%}.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--selected img,.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--selected svg,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--selected img,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--selected svg{opacity:.85}.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--disabled,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--disabled{opacity:.5}.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--noPreview .uppy-ProviderBrowserItem-inner,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--noPreview .uppy-ProviderBrowserItem-inner{background-color:#93939333}[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--noPreview .uppy-ProviderBrowserItem-inner,[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--noPreview .uppy-ProviderBrowserItem-inner{background-color:#eaeaea33}.uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--noPreview svg,.uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--noPreview svg{height:30%;width:30%;fill:#000000b3}[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--grid li.uppy-ProviderBrowserItem--noPreview svg,[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--unsplash li.uppy-ProviderBrowserItem--noPreview svg{fill:#fffc}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-inner,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-inner{border-radius:4px;height:calc(100% - 14px);inset:7px;overflow:hidden;position:absolute;text-align:center;width:calc(100% - 14px)}@media(hover:none){.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-inner .uppy-ProviderBrowserItem-author,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-inner .uppy-ProviderBrowserItem-author{display:block}}[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-inner,[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-inner{box-shadow:0 0 0 3px #aae1ffb3}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-inner img,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-inner img{border-radius:4px;height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-author,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-author{background:#0000004d;bottom:0;color:#fff;display:none;font-size:12px;font-weight:500;left:0;margin:0;padding:5px;position:absolute;text-decoration:none;width:100%}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-author:hover,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-author:hover{background:#0006;text-decoration:underline}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox{background-color:#1269cf;border-radius:50%;height:26px;opacity:0;position:absolute;right:16px;top:16px;width:26px;z-index:1002}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox:after,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox:after{height:7px;inset-inline-start:7px;top:8px;width:12px}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem--is-checked .uppy-ProviderBrowserItem-checkbox,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem--is-checked .uppy-ProviderBrowserItem-checkbox{opacity:1}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox--grid:focus+label .uppy-ProviderBrowserItem-author,.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox--grid:hover+label .uppy-ProviderBrowserItem-author,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox--grid:focus+label .uppy-ProviderBrowserItem-author,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox--grid:hover+label .uppy-ProviderBrowserItem-author{display:block}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox--grid:focus+label,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox--grid:focus+label{box-shadow:0 0 0 3px #1269cf80}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox--grid:focus+label:focus,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox--grid:focus+label:focus{outline:none}.uppy-ProviderBrowser-viewType--grid .uppy-ProviderBrowserItem-checkbox--grid:focus+label::-moz-focus-inner,.uppy-ProviderBrowser-viewType--unsplash .uppy-ProviderBrowserItem-checkbox--grid:focus+label::-moz-focus-inner{border:0}.uppy-ProviderBrowser-viewType--list{background-color:#fff}[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--list{background-color:#1f1f1f}.uppy-ProviderBrowser-viewType--list li.uppy-ProviderBrowserItem{align-items:center;display:flex;margin:0;padding:7px 15px}[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--list li.uppy-ProviderBrowserItem{color:#eaeaea}.uppy-ProviderBrowser-viewType--list li.uppy-ProviderBrowserItem--disabled{opacity:.6}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-checkbox{background-color:#fff;border:1px solid #cfcfcf;border-radius:3px;height:17px;margin-inline-end:15px;width:17px}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-checkbox:focus{border:1px solid #1269cf;box-shadow:0 0 0 3px #1269cf40;outline:none}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-checkbox:after{height:5px;inset-inline-start:3px;opacity:0;top:4px;width:9px}[data-uppy-theme=dark] .uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-checkbox:focus{border-color:#02baf2b3;box-shadow:0 0 0 3px #02baf233}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem--is-checked .uppy-ProviderBrowserItem-checkbox,.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem--is-partial .uppy-ProviderBrowserItem-checkbox{background-color:#1269cf;border-color:#1269cf}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem--is-checked .uppy-ProviderBrowserItem-checkbox:after,.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem--is-partial .uppy-ProviderBrowserItem-checkbox:after{opacity:1}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-inner{align-items:center;color:inherit;display:flex;font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Segoe UI Symbol,Segoe UI Emoji,Apple Color Emoji,Roboto,Helvetica,Arial,sans-serif;overflow:hidden;padding:2px;text-overflow:ellipsis;white-space:nowrap}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-inner:focus{outline:none;text-decoration:underline}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-inner img,.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-inner svg{margin-inline-end:8px}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-inner span{line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem--disabled .uppy-ProviderBrowserItem-inner{cursor:default}.uppy-ProviderBrowser-viewType--list .uppy-ProviderBrowserItem-iconWrap{margin-inline-end:7px;width:20px}.uppy-ProviderBrowserItem-checkbox{cursor:pointer;flex-shrink:0;position:relative}.uppy-ProviderBrowserItem-checkbox:disabled,.uppy-ProviderBrowserItem-checkbox:disabled:after{cursor:default}[data-uppy-theme=dark] .uppy-ProviderBrowserItem-checkbox{background-color:#1f1f1f;border-color:#939393}[data-uppy-theme=dark] .uppy-ProviderBrowserItem--is-checked .uppy-ProviderBrowserItem-checkbox{background-color:#333}.uppy-ProviderBrowserItem--is-checked .uppy-ProviderBrowserItem-checkbox:after{border-bottom:2px solid #eaeaea;border-left:2px solid #eaeaea;content:"";cursor:pointer;position:absolute;transform:rotate(-45deg)}.uppy-ProviderBrowserItem--is-partial .uppy-ProviderBrowserItem-checkbox:after{background-color:#eaeaea!important;content:""!important;height:2px!important;left:20%!important;position:absolute!important;right:20%!important;top:50%!important;transform:translateY(-50%)!important}.uppy-SearchProvider{align-items:center;display:flex;flex:1;flex-direction:column;height:100%;justify-content:center;width:100%}[data-uppy-theme=dark] .uppy-SearchProvider{background-color:#1f1f1f}.uppy-SearchProvider-input{margin-bottom:15px;max-width:650px;width:90%}.uppy-size--md .uppy-SearchProvider-input{margin-bottom:20px}.uppy-SearchProvider-input::-webkit-search-cancel-button{display:none}.uppy-SearchProvider-searchButton{padding:13px 25px}.uppy-size--md .uppy-SearchProvider-searchButton{padding:13px 30px}.uppy-DashboardContent-panelBody{align-items:center;display:flex;flex:1;justify-content:center}[data-uppy-theme=dark] .uppy-DashboardContent-panelBody{background-color:#1f1f1f}.uppy-Provider-auth,.uppy-Provider-empty,.uppy-Provider-error,.uppy-Provider-loading{align-items:center;color:#939393;display:flex;flex:1;flex-flow:column wrap;justify-content:center}.uppy-Provider-empty{color:#939393}.uppy-Provider-authIcon svg{height:75px;width:100px}.uppy-Provider-authTitle{color:#757575;font-size:17px;font-weight:400;line-height:1.4;margin-bottom:30px;max-width:500px;padding:0 15px;text-align:center}.uppy-size--md .uppy-Provider-authTitle{font-size:20px}[data-uppy-theme=dark] .uppy-Provider-authTitle{color:#cfcfcf}.uppy-Provider-btn-google{align-items:center;background:#4285f4;display:flex;padding:8px 12px!important}.uppy-Provider-btn-google:hover{background-color:#1266f1}.uppy-Provider-btn-google:focus{box-shadow:0 0 0 3px #4285f466;outline:none}.uppy-Provider-btn-google svg{margin-right:8px}.uppy-Provider-breadcrumbs{color:#525252;flex:1;font-size:12px;margin-bottom:10px;text-align:start}.uppy-size--md .uppy-Provider-breadcrumbs{margin-bottom:0}[data-uppy-theme=dark] .uppy-Provider-breadcrumbs{color:#eaeaea}.uppy-Provider-breadcrumbsIcon{color:#525252;display:inline-block;line-height:1;margin-inline-end:4px;vertical-align:middle}.uppy-Provider-breadcrumbsIcon svg{height:13px;width:13px;fill:#525252}.uppy-Provider-breadcrumbs button{border-radius:3px;display:inline-block;line-height:inherit;padding:4px}.uppy-Provider-breadcrumbs button:focus{outline:none}.uppy-Provider-breadcrumbs button::-moz-focus-inner{border:0}.uppy-Provider-breadcrumbs button:hover{color:#0e51a0}.uppy-Provider-breadcrumbs button:focus{background-color:#dfe6f1}[data-uppy-theme=dark] .uppy-Provider-breadcrumbs button:focus{background-color:#333}.uppy-Provider-breadcrumbs button:not(:last-of-type){text-decoration:underline}.uppy-Provider-breadcrumbs button:last-of-type{color:#333;cursor:normal;font-weight:500;pointer-events:none}.uppy-Provider-breadcrumbs button:hover{cursor:pointer}[data-uppy-theme=dark] .uppy-Provider-breadcrumbs button{color:#eaeaea}.uppy-ProviderBrowser{display:flex;flex:1;flex-direction:column;font-size:14px;font-weight:400;height:100%}.uppy-ProviderBrowser-user{color:#333;font-weight:500;margin:0 8px 0 0}[data-uppy-theme=dark] .uppy-ProviderBrowser-user{color:#eaeaea}.uppy-ProviderBrowser-user:after{color:#939393;content:"·";font-weight:400;inset-inline-start:4px;position:relative}.uppy-ProviderBrowser-header{border-bottom:1px solid #eaeaea;position:relative;z-index:1001}[data-uppy-theme=dark] .uppy-ProviderBrowser-header{border-bottom:1px solid #333}.uppy-ProviderBrowser-headerBar{background-color:#fafafa;color:#757575;font-size:12px;line-height:1.4;padding:7px 15px;z-index:1001}.uppy-size--md .uppy-ProviderBrowser-headerBar{align-items:center;display:flex}[data-uppy-theme=dark] .uppy-ProviderBrowser-headerBar{background-color:#1f1f1f}.uppy-ProviderBrowser-headerBar--simple{display:block;justify-content:center;text-align:center}.uppy-ProviderBrowser-headerBar--simple .uppy-Provider-breadcrumbsWrap{display:inline-block;flex:none;vertical-align:middle}.uppy-ProviderBrowser-searchFilter{align-items:center;display:flex;height:30px;margin-bottom:15px;margin-top:15px;padding-left:8px;padding-right:8px;position:relative;width:100%}.uppy-ProviderBrowser-searchFilterInput{background-color:#eaeaea;border:0;border-radius:4px;color:#333;font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Segoe UI Symbol,Segoe UI Emoji,Apple Color Emoji,Roboto,Helvetica,Arial,sans-serif;font-size:13px;height:30px;line-height:1.4;outline:0;padding-inline-end:30px;padding-inline-start:30px;width:100%;z-index:1001}.uppy-ProviderBrowser-searchFilterInput::-webkit-search-cancel-button{display:none}[data-uppy-theme=dark] .uppy-ProviderBrowser-searchFilterInput{background-color:#1f1f1f;color:#eaeaea}.uppy-ProviderBrowser-searchFilterInput:focus{background-color:#cfcfcf;border:0}[data-uppy-theme=dark] .uppy-ProviderBrowser-searchFilterInput:focus{background-color:#333}.uppy-ProviderBrowser-searchFilterIcon{color:#757575;height:12px;inset-inline-start:16px;position:absolute;width:12px;z-index:1002}.uppy-ProviderBrowser-searchFilterInput::-moz-placeholder{color:#939393;opacity:1}.uppy-ProviderBrowser-searchFilterInput::placeholder{color:#939393;opacity:1}.uppy-ProviderBrowser-searchFilterReset{border-radius:3px;color:#939393;cursor:pointer;height:22px;inset-inline-end:16px;padding:6px;position:absolute;width:22px;z-index:1002}.uppy-ProviderBrowser-searchFilterReset:focus{outline:none}.uppy-ProviderBrowser-searchFilterReset::-moz-focus-inner{border:0}.uppy-ProviderBrowser-searchFilterReset:focus{box-shadow:0 0 0 3px #1269cf80}.uppy-ProviderBrowser-searchFilterReset:hover{color:#757575}.uppy-ProviderBrowser-searchFilterReset svg{vertical-align:text-top}.uppy-ProviderBrowser-userLogout{border-radius:3px;color:#1269cf;cursor:pointer;line-height:inherit;padding:4px}.uppy-ProviderBrowser-userLogout:focus{outline:none}.uppy-ProviderBrowser-userLogout::-moz-focus-inner{border:0}.uppy-ProviderBrowser-userLogout:hover{color:#0e51a0}.uppy-ProviderBrowser-userLogout:focus{background-color:#dfe6f1}[data-uppy-theme=dark] .uppy-ProviderBrowser-userLogout:focus{background-color:#333}.uppy-ProviderBrowser-userLogout:hover{text-decoration:underline}[data-uppy-theme=dark] .uppy-ProviderBrowser-userLogout{color:#eaeaea}.uppy-ProviderBrowser-body{flex:1;position:relative}.uppy-ProviderBrowser-list{background-color:#fff;border-spacing:0;display:block;flex:1;height:100%;inset:0;list-style:none;margin:0;overflow-x:hidden;overflow-y:auto;padding:0;position:absolute;width:100%;-webkit-overflow-scrolling:touch}[data-uppy-theme=dark] .uppy-ProviderBrowser-list{background-color:#1f1f1f}.uppy-ProviderBrowser-list:focus{outline:none}.uppy-ProviderBrowserItem-inner{cursor:pointer;font-size:13px;font-weight:500}.uppy-ProviderBrowser-footer{align-items:center;background-color:#fff;border-top:1px solid #eaeaea;display:flex;justify-content:space-between;padding:15px}.uppy-ProviderBrowser-footer button{margin-inline-end:8px}[data-uppy-theme=dark] .uppy-ProviderBrowser-footer{background-color:#1f1f1f;border-top:1px solid #333}.uppy-ProviderBrowser-footer-buttons{flex-shrink:0}.uppy-ProviderBrowser-footer-error{color:#e32437;line-height:18px}@media(max-width:426px){.uppy-ProviderBrowser-footer{align-items:stretch;flex-direction:column-reverse}.uppy-ProviderBrowser-footer-error{padding-bottom:10px}}.picker-dialog-bg{z-index:20000!important}.picker-dialog{z-index:20001!important}.uppy-Dashboard-Item-previewInnerWrap{align-items:center;border-radius:3px;box-shadow:0 0 2px #0006;display:flex;flex-direction:column;height:100%;justify-content:center;overflow:hidden;position:relative;width:100%}.uppy-size--md .uppy-Dashboard-Item-previewInnerWrap{box-shadow:0 1px 2px #00000026}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-previewInnerWrap{box-shadow:none}.uppy-Dashboard-Item-previewInnerWrap:after{background-color:#000000a6;content:"";display:none;inset:0;position:absolute;z-index:1001}.uppy-Dashboard-Item-previewLink{inset:0;position:absolute;z-index:1002}.uppy-Dashboard-Item-previewLink:focus{box-shadow:inset 0 0 0 3px #579df0}[data-uppy-theme=dark] .uppy-Dashboard-Item-previewLink:focus{box-shadow:inset 0 0 0 3px #016c8d}.uppy-Dashboard-Item-preview img.uppy-Dashboard-Item-previewImg{border-radius:3px;height:100%;-o-object-fit:cover;object-fit:cover;transform:translateZ(0);width:100%}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-preview img.uppy-Dashboard-Item-previewImg{height:auto;max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain;padding:10px;width:auto}.uppy-Dashboard-Item-progress{color:#fff;left:50%;position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%);transition:all .35 ease;width:120px;z-index:1002}.uppy-Dashboard-Item-progressIndicator{color:#fff;display:inline-block;height:38px;opacity:.9;width:38px}.uppy-size--md .uppy-Dashboard-Item-progressIndicator{height:55px;width:55px}button.uppy-Dashboard-Item-progressIndicator{cursor:pointer}button.uppy-Dashboard-Item-progressIndicator:focus{outline:none}button.uppy-Dashboard-Item-progressIndicator::-moz-focus-inner{border:0}button.uppy-Dashboard-Item-progressIndicator:focus .uppy-Dashboard-Item-progressIcon--bg,button.uppy-Dashboard-Item-progressIndicator:focus .uppy-Dashboard-Item-progressIcon--retry{fill:#579df0}.uppy-Dashboard-Item-progressIcon--circle{height:100%;width:100%}.uppy-Dashboard-Item-progressIcon--bg{stroke:#fff6}.uppy-Dashboard-Item-progressIcon--progress{transition:stroke-dashoffset .5s ease-out;stroke:#fff}.uppy-Dashboard-Item-progressIcon--play{transition:all .2s;fill:#fff;stroke:#fff}.uppy-Dashboard-Item-progressIcon--cancel{transition:all .2s;fill:#fff}.uppy-Dashboard-Item-progressIcon--pause{transition:all .2s;fill:#fff;stroke:#fff}.uppy-Dashboard-Item-progressIcon--check{transition:all .2s;fill:#fff}.uppy-Dashboard-Item-progressIcon--retry{fill:#fff}.uppy-Dashboard-Item.is-complete .uppy-Dashboard-Item-progress{inset-inline-end:-8px;inset-inline-start:auto;top:-9px;transform:none;width:auto}.uppy-Dashboard-Item.is-error .uppy-Dashboard-Item-progressIndicator{height:18px;width:18px}.uppy-size--md .uppy-Dashboard-Item.is-error .uppy-Dashboard-Item-progressIndicator{height:28px;width:28px}.uppy-Dashboard-Item.is-complete .uppy-Dashboard-Item-progressIndicator{height:18px;opacity:1;width:18px}.uppy-size--md .uppy-Dashboard-Item.is-complete .uppy-Dashboard-Item-progressIndicator{height:22px;width:22px}.uppy-Dashboard-Item.is-processing .uppy-Dashboard-Item-progress{opacity:0}.uppy-Dashboard-Item-fileInfo{padding-inline-end:5px}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-fileInfo{padding-inline-end:10px}.uppy-size--md.uppy-Dashboard--singleFile .uppy-Dashboard-Item-fileInfo{padding-inline-end:15px}.uppy-Dashboard-Item-name{font-size:12px;font-weight:500;line-height:1.3;margin-bottom:5px;word-wrap:anywhere;word-break:break-all}[data-uppy-theme=dark] .uppy-Dashboard-Item-name{color:#eaeaea}.uppy-size--md.uppy-Dashboard--singleFile .uppy-Dashboard-Item-name{font-size:14px;line-height:1.4}.uppy-Dashboard-Item-fileName{align-items:baseline;display:flex}.uppy-Dashboard-Item-fileName button{margin-left:5px}.uppy-Dashboard-Item-author{color:#757575;display:inline-block;font-size:11px;font-weight:400;line-height:1;margin-bottom:5px;vertical-align:bottom}.uppy-Dashboard-Item-author a{color:#757575}.uppy-Dashboard-Item-status{color:#757575;font-size:11px;font-weight:400;line-height:1}[data-uppy-theme=dark] .uppy-Dashboard-Item-status{color:#bbb}.uppy-Dashboard-Item-statusSize{display:inline-block;margin-bottom:5px;text-transform:uppercase;vertical-align:bottom}.uppy-Dashboard-Item-reSelect{color:#1269cf;font-family:inherit;font-size:inherit;font-weight:600}.uppy-Dashboard-Item-errorMessage{background-color:#fdeff1;color:#a51523;font-size:11px;font-weight:500;line-height:1.3;padding:5px 6px}.uppy-Dashboard-Item-errorMessageBtn{color:#a51523;cursor:pointer;font-size:11px;font-weight:500;text-decoration:underline}.uppy-Dashboard-Item-preview .uppy-Dashboard-Item-errorMessage{display:none}.uppy-size--md .uppy-Dashboard-Item-preview .uppy-Dashboard-Item-errorMessage{border-bottom-left-radius:3px;border-bottom-right-radius:3px;border-top:1px solid #f7c2c8;bottom:0;display:block;left:0;line-height:1.4;padding:6px 8px;position:absolute;right:0}.uppy-Dashboard-Item-fileInfo .uppy-Dashboard-Item-errorMessage{border:1px solid #f7c2c8;border-radius:3px;display:inline-block;position:static}.uppy-size--md .uppy-Dashboard-Item-fileInfo .uppy-Dashboard-Item-errorMessage{display:none}.uppy-Dashboard-Item-action{color:#939393;cursor:pointer}.uppy-Dashboard-Item-action:focus{outline:none}.uppy-Dashboard-Item-action::-moz-focus-inner{border:0}.uppy-Dashboard-Item-action:focus{box-shadow:0 0 0 3px #1269cf80}.uppy-Dashboard-Item-action:hover{color:#1f1f1f;opacity:1}[data-uppy-theme=dark] .uppy-Dashboard-Item-action{color:#cfcfcf}[data-uppy-theme=dark] .uppy-Dashboard-Item-action:focus{outline:none}[data-uppy-theme=dark] .uppy-Dashboard-Item-action::-moz-focus-inner{border:0}[data-uppy-theme=dark] .uppy-Dashboard-Item-action:focus{box-shadow:0 0 0 2px #aae1ffd9}[data-uppy-theme=dark] .uppy-Dashboard-Item-action:hover{color:#eaeaea}.uppy-Dashboard-Item-action--remove{color:#1f1f1f;opacity:.95}.uppy-Dashboard-Item-action--remove:hover{color:#000;opacity:1}.uppy-size--md .uppy-Dashboard-Item-action--remove{height:18px;inset-inline-end:-8px;padding:0;position:absolute;top:-8px;width:18px;z-index:1002}.uppy-size--md .uppy-Dashboard-Item-action--remove:focus{border-radius:50%}.uppy-Dashboard--singleFile.uppy-size--height-md .uppy-Dashboard-Item-action--remove{inset-inline-end:8px;position:absolute;top:8px}[data-uppy-theme=dark] .uppy-Dashboard-Item-action--remove{color:#525252}[data-uppy-theme=dark] .uppy-Dashboard-Item-action--remove:hover{color:#333}.uppy-Dashboard:not(.uppy-size--md):not(.uppy-Dashboard--singleFile.uppy-size--height-md) .uppy-Dashboard-Item-actionWrapper{align-items:center;display:flex}.uppy-Dashboard:not(.uppy-size--md):not(.uppy-Dashboard--singleFile.uppy-size--height-md) .uppy-Dashboard-Item-action{height:22px;margin-left:3px;padding:3px;width:22px}.uppy-Dashboard:not(.uppy-size--md):not(.uppy-Dashboard--singleFile.uppy-size--height-md) .uppy-Dashboard-Item-action:focus{border-radius:3px}.uppy-size--md .uppy-Dashboard-Item-action--copyLink,.uppy-size--md .uppy-Dashboard-Item-action--edit{height:16px;padding:0;width:16px}.uppy-size--md .uppy-Dashboard-Item-action--copyLink:focus,.uppy-size--md .uppy-Dashboard-Item-action--edit:focus{border-radius:3px}.uppy-Dashboard-Item{align-items:center;border-bottom:1px solid #eaeaea;display:flex;padding:10px}.uppy-Dashboard:not(.uppy-Dashboard--singleFile) .uppy-Dashboard-Item{padding-inline-end:0}[data-uppy-theme=dark] .uppy-Dashboard-Item{border-bottom:1px solid #333}.uppy-size--md .uppy-Dashboard-Item{border-bottom:0;display:block;float:inline-start;height:215px;margin:5px 15px;padding:0;position:relative;width:calc(33.333% - 30px)}.uppy-size--lg .uppy-Dashboard-Item{height:190px;margin:5px 15px;padding:0;width:calc(25% - 30px)}.uppy-size--xl .uppy-Dashboard-Item{height:210px;padding:0;width:calc(20% - 30px)}.uppy-Dashboard--singleFile .uppy-Dashboard-Item{border-bottom:0;display:flex;flex-direction:column;height:100%;max-width:400px;padding:15px;position:relative;width:100%}.uppy-Dashboard-Item.is-ghost .uppy-Dashboard-Item-previewInnerWrap{opacity:.2}.uppy-Dashboard-Item.is-ghost .uppy-Dashboard-Item-name{opacity:.7}.uppy-Dashboard-Item.is-ghost .uppy-Dashboard-Item-preview:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='35' height='39' viewBox='0 0 35 39'%3E%3Cpath fill='%2523000' d='M1.708 38.66c1.709 0 3.417-3.417 6.834-3.417s5.125 3.417 8.61 3.417c3.348 0 5.056-3.417 8.473-3.417 4.305 0 5.125 3.417 6.833 3.417.889 0 1.709-.889 1.709-1.709v-19.68C34.167-5.757 0-5.757 0 17.271v19.68c0 .82.888 1.709 1.708 1.709m8.542-17.084a3.383 3.383 0 0 1-3.417-3.416 3.383 3.383 0 0 1 3.417-3.417 3.383 3.383 0 0 1 3.417 3.417 3.383 3.383 0 0 1-3.417 3.416m13.667 0A3.383 3.383 0 0 1 20.5 18.16a3.383 3.383 0 0 1 3.417-3.417 3.383 3.383 0 0 1 3.416 3.417 3.383 3.383 0 0 1-3.416 3.416'/%3E%3C/svg%3E");background-position:50% 10px;background-repeat:no-repeat;background-size:25px;content:"";inset:0;opacity:.5;position:absolute;z-index:1005}.uppy-size--md .uppy-Dashboard-Item.is-ghost .uppy-Dashboard-Item-preview:before{background-position:50% 50%;background-size:40px}.uppy-Dashboard--singleFile .uppy-Dashboard-Item.is-ghost .uppy-Dashboard-Item-preview:before{background-position:50% 50%;background-size:30%}.uppy-Dashboard-Item-preview{flex-grow:0;flex-shrink:0;height:50px;position:relative;width:50px}.uppy-size--md .uppy-Dashboard-Item-preview{height:140px;width:100%}.uppy-size--lg .uppy-Dashboard-Item-preview{height:120px}.uppy-size--xl .uppy-Dashboard-Item-preview{height:140px}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-preview{flex-grow:1;max-height:75%;width:100%}.uppy-Dashboard--singleFile.uppy-size--md .uppy-Dashboard-Item-preview{max-height:100%}.uppy-Dashboard-Item-fileInfoAndButtons{align-items:center;display:flex;flex-grow:1;justify-content:space-between;padding-inline-end:8px;padding-inline-start:12px}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-fileInfoAndButtons,.uppy-size--md .uppy-Dashboard-Item-fileInfoAndButtons{align-items:flex-start;padding:9px 0 0}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-fileInfoAndButtons{flex-grow:0;width:100%}.uppy-Dashboard-Item-fileInfo{flex-grow:1;flex-shrink:1}.uppy-Dashboard-Item-actionWrapper{flex-grow:0;flex-shrink:0}.uppy-Dashboard-Item.is-error .uppy-Dashboard-Item-previewInnerWrap:after,.uppy-Dashboard-Item.is-inprogress .uppy-Dashboard-Item-previewInnerWrap:after{display:block}.uppy-Dashboard-Item-errorDetails{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#939393;border:none;border-radius:50%;color:#fff;cursor:help;flex-shrink:0;font-size:10px;font-weight:600;height:13px;inset-inline-start:2px;line-height:12px;position:relative;text-align:center;top:0;width:13px}.uppy-Dashboard-Item-errorDetails:after{line-height:1.3;word-wrap:break-word}.uppy-Dashboard-FileCard{background-color:#fff;border-radius:5px;box-shadow:0 0 10px 4px #0000001a;display:flex;flex-direction:column;height:100%;inset:0;position:absolute;width:100%;z-index:1005}.uppy-Dashboard-FileCard .uppy-DashboardContent-bar{border-top-left-radius:5px;border-top-right-radius:5px}.uppy-Dashboard-FileCard .uppy-Dashboard-FileCard-actions{border-bottom-left-radius:5px;border-bottom-right-radius:5px}.uppy-Dashboard-FileCard-inner{display:flex;flex-direction:column;flex-grow:1;flex-shrink:1;height:100%;min-height:0}.uppy-Dashboard-FileCard-preview{align-items:center;border-bottom:1px solid #eaeaea;display:flex;flex-grow:0;flex-shrink:1;height:60%;justify-content:center;min-height:0;position:relative}[data-uppy-theme=dark] .uppy-Dashboard-FileCard-preview{background-color:#333;border-bottom:0}.uppy-Dashboard-FileCard-preview img.uppy-Dashboard-Item-previewImg{border-radius:3px;box-shadow:0 3px 20px #00000026;flex:0 0 auto;max-height:90%;max-width:90%;-o-object-fit:cover;object-fit:cover}.uppy-Dashboard-FileCard-edit{background-color:#00000080;border-radius:50px;color:#fff;font-size:13px;inset-inline-end:10px;padding:7px 15px;position:absolute;top:10px}.uppy-Dashboard-FileCard-edit:focus{outline:none}.uppy-Dashboard-FileCard-edit::-moz-focus-inner{border:0}.uppy-Dashboard-FileCard-edit:focus{box-shadow:0 0 0 3px #1269cf80}.uppy-Dashboard-FileCard-edit:hover{background-color:#000c}.uppy-Dashboard-FileCard-info{flex-grow:0;flex-shrink:0;height:40%;overflow-y:auto;padding:30px 20px 20px;-webkit-overflow-scrolling:touch}[data-uppy-theme=dark] .uppy-Dashboard-FileCard-info{background-color:#1f1f1f}.uppy-Dashboard-FileCard-fieldset{border:0;font-size:0;margin:auto auto 12px;max-width:640px;padding:0}.uppy-Dashboard-FileCard-label{color:#525252;display:inline-block;font-size:12px;vertical-align:middle;width:22%}.uppy-size--md .uppy-Dashboard-FileCard-label{font-size:14px}[data-uppy-theme=dark] .uppy-Dashboard-FileCard-label{color:#eaeaea}.uppy-Dashboard-FileCard-input{display:inline-block;vertical-align:middle;width:78%}.uppy-Dashboard-FileCard-actions{align-items:center;background-color:#fafafa;border-top:1px solid #eaeaea;display:flex;flex-grow:0;flex-shrink:0;height:55px;padding:0 15px}.uppy-size--md .uppy-Dashboard-FileCard-actions{height:65px}[data-uppy-theme=dark] .uppy-Dashboard-FileCard-actions{background-color:#1f1f1f;border-top:1px solid #333}.uppy-Dashboard-FileCard-actionsBtn{margin-inline-end:10px}.uppy-Informer{bottom:60px;left:0;position:absolute;right:0;text-align:center;z-index:1005}.uppy-Informer span>div{margin-bottom:6px}.uppy-Informer-animated{opacity:0;transform:translateY(350%);transition:all .3s ease-in;z-index:-1000}.uppy-Informer p{background-color:#757575;border-radius:18px;color:#fff;display:inline-block;font-size:12px;font-weight:400;line-height:1.4;margin:0;max-width:90%;padding:6px 15px}.uppy-size--md .uppy-Informer p{font-size:14px;line-height:1.3;max-width:500px;padding:10px 20px}[data-uppy-theme=dark] .uppy-Informer p{background-color:#333}.uppy-Informer p span{background-color:#fff;border-radius:50%;color:#525252;display:inline-block;font-size:10px;height:13px;inset-inline-start:3px;line-height:12px;margin-inline-start:-1px;position:relative;top:-1px;vertical-align:middle;width:13px}.uppy-Informer p span:hover{cursor:help}.uppy-Informer p span:after{line-height:1.3;word-wrap:break-word}.uppy-Root [aria-label][role~=tooltip]{position:relative}.uppy-Root [aria-label][role~=tooltip]:after,.uppy-Root [aria-label][role~=tooltip]:before{backface-visibility:hidden;box-sizing:border-box;opacity:0;pointer-events:none;position:absolute;transform:translateZ(0);transform-origin:top;transition:all var(--microtip-transition-duration,.18s) var(--microtip-transition-easing,ease-in-out) var(--microtip-transition-delay,0s);will-change:transform;z-index:10}.uppy-Root [aria-label][role~=tooltip]:before{background-size:100% auto!important;content:""}.uppy-Root [aria-label][role~=tooltip]:after{background:#111111e6;border-radius:4px;box-sizing:initial;color:#fff;content:attr(aria-label);font-size:var(--microtip-font-size,13px);font-weight:var(--microtip-font-weight,normal);padding:.5em 1em;text-transform:var(--microtip-text-transform,none);white-space:nowrap}.uppy-Root [aria-label][role~=tooltip]:focus:after,.uppy-Root [aria-label][role~=tooltip]:focus:before,.uppy-Root [aria-label][role~=tooltip]:hover:after,.uppy-Root [aria-label][role~=tooltip]:hover:before{opacity:1;pointer-events:auto}.uppy-Root [role~=tooltip][data-microtip-position|=top]:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='12'%3E%3Cpath fill='rgba(17, 17, 17, 0.9)' d='M2.658 0h32.004c-6 0-11.627 12.002-16.002 12.002S8.594 0 2.658 0'/%3E%3C/svg%3E") no-repeat;bottom:100%;height:6px;left:50%;margin-bottom:5px;transform:translate3d(-50%,0,0);width:18px}.uppy-Root [role~=tooltip][data-microtip-position|=top]:after{bottom:100%;left:50%;margin-bottom:11px;transform:translate3d(-50%,0,0)}.uppy-Root [role~=tooltip][data-microtip-position=top]:hover:after,.uppy-Root [role~=tooltip][data-microtip-position|=top]:hover:before{transform:translate3d(-50%,-5px,0)}.uppy-Root [role~=tooltip][data-microtip-position=top-left]:after{bottom:100%;transform:translate3d(calc(-100% + 16px),0,0)}.uppy-Root [role~=tooltip][data-microtip-position=top-left]:hover:after{transform:translate3d(calc(-100% + 16px),-5px,0)}.uppy-Root [role~=tooltip][data-microtip-position=top-right]:after{bottom:100%;transform:translate3d(-16px,0,0)}.uppy-Root [role~=tooltip][data-microtip-position=top-right]:hover:after{transform:translate3d(-16px,-5px,0)}.uppy-Root [role~=tooltip][data-microtip-position|=bottom]:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='12'%3E%3Cpath fill='rgba(17, 17, 17, 0.9)' d='M33.342 12H1.338c6 0 11.627-12.002 16.002-12.002S27.406 12 33.342 12'/%3E%3C/svg%3E") no-repeat;bottom:auto;height:6px;left:50%;margin-bottom:0;margin-top:5px;top:100%;transform:translate3d(-50%,-10px,0);width:18px}.uppy-Root [role~=tooltip][data-microtip-position|=bottom]:after{left:50%;margin-top:11px;top:100%;transform:translate3d(-50%,-10px,0)}.uppy-Root [role~=tooltip][data-microtip-position=bottom]:hover:after,.uppy-Root [role~=tooltip][data-microtip-position|=bottom]:hover:before{transform:translate3d(-50%,0,0)}.uppy-Root [role~=tooltip][data-microtip-position=bottom-left]:after{top:100%;transform:translate3d(calc(-100% + 16px),-10px,0)}.uppy-Root [role~=tooltip][data-microtip-position=bottom-left]:hover:after{transform:translate3d(calc(-100% + 16px),0,0)}.uppy-Root [role~=tooltip][data-microtip-position=bottom-right]:after{top:100%;transform:translate3d(-16px,-10px,0)}.uppy-Root [role~=tooltip][data-microtip-position=bottom-right]:hover:after{transform:translate3d(-16px,0,0)}.uppy-Root [role~=tooltip][data-microtip-position=left]:after,.uppy-Root [role~=tooltip][data-microtip-position=left]:before{inset:50% 100% auto auto;transform:translate3d(10px,-50%,0)}.uppy-Root [role~=tooltip][data-microtip-position=left]:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='36'%3E%3Cpath fill='rgba(17, 17, 17, 0.9)' d='M0 33.342V1.338c0 6 12.002 11.627 12.002 16.002S0 27.406 0 33.342'/%3E%3C/svg%3E") no-repeat;height:18px;margin-bottom:0;margin-right:5px;width:6px}.uppy-Root [role~=tooltip][data-microtip-position=left]:after{margin-right:11px}.uppy-Root [role~=tooltip][data-microtip-position=left]:hover:after,.uppy-Root [role~=tooltip][data-microtip-position=left]:hover:before{transform:translate3d(0,-50%,0)}.uppy-Root [role~=tooltip][data-microtip-position=right]:after,.uppy-Root [role~=tooltip][data-microtip-position=right]:before{bottom:auto;left:100%;top:50%;transform:translate3d(-10px,-50%,0)}.uppy-Root [role~=tooltip][data-microtip-position=right]:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='36'%3E%3Cpath fill='rgba(17, 17, 17, 0.9)' d='M12 2.658v32.004c0-6-12.002-11.627-12.002-16.002S12 8.594 12 2.658'/%3E%3C/svg%3E") no-repeat;height:18px;margin-bottom:0;margin-left:5px;width:6px}.uppy-Root [role~=tooltip][data-microtip-position=right]:after{margin-left:11px}.uppy-Root [role~=tooltip][data-microtip-position=right]:hover:after,.uppy-Root [role~=tooltip][data-microtip-position=right]:hover:before{transform:translate3d(0,-50%,0)}.uppy-Root [role~=tooltip][data-microtip-size=small]:after{white-space:normal;width:80px}.uppy-Root [role~=tooltip][data-microtip-size=medium]:after{white-space:normal;width:150px}.uppy-Root [role~=tooltip][data-microtip-size=large]:after{white-space:normal;width:260px}.uppy-StatusBar{background-color:#fff;color:#fff;display:flex;font-size:12px;font-weight:400;height:46px;line-height:40px;position:relative;transition:height .2s;z-index:1001}[data-uppy-theme=dark] .uppy-StatusBar{background-color:#1f1f1f}.uppy-StatusBar:before{background-color:#eaeaea;content:"";height:2px;inset:0;position:absolute;width:100%}[data-uppy-theme=dark] .uppy-StatusBar:before{background-color:#757575}.uppy-StatusBar[aria-hidden=true]{height:0;overflow-y:hidden}.uppy-StatusBar.is-complete .uppy-StatusBar-progress{background-color:#1bb240}.uppy-StatusBar.is-error .uppy-StatusBar-progress{background-color:#e32437}.uppy-StatusBar.is-complete .uppy-StatusBar-statusIndicator{color:#1bb240}.uppy-StatusBar.is-error .uppy-StatusBar-statusIndicator{color:#e32437}.uppy-StatusBar:not([aria-hidden=true]).is-waiting{background-color:#fff;border-top:1px solid #eaeaea;height:65px}[data-uppy-theme=dark] .uppy-StatusBar:not([aria-hidden=true]).is-waiting{background-color:#1f1f1f;border-top:1px solid #333}.uppy-StatusBar-progress{background-color:#1269cf;height:2px;position:absolute;transition:background-color,width .3s ease-out;z-index:1001}.uppy-StatusBar-progress.is-indeterminate{animation:uppy-StatusBar-ProgressStripes 1s linear infinite;background-image:linear-gradient(45deg,#0000004d 25%,#0000 0 50%,#0000004d 0 75%,#0000 0,#0000);background-size:64px 64px}@keyframes uppy-StatusBar-ProgressStripes{0%{background-position:0 0}to{background-position:64px 0}}.uppy-StatusBar.is-postprocessing .uppy-StatusBar-progress,.uppy-StatusBar.is-preprocessing .uppy-StatusBar-progress{background-color:#f6a623}.uppy-StatusBar.is-waiting .uppy-StatusBar-progress{display:none}.uppy-StatusBar-content{align-items:center;color:#333;display:flex;height:100%;padding-inline-start:10px;position:relative;text-overflow:ellipsis;white-space:nowrap;z-index:1002}.uppy-size--md .uppy-StatusBar-content{padding-inline-start:15px}[data-uppy-theme=dark] .uppy-StatusBar-content{color:#eaeaea}.uppy-StatusBar-status{display:flex;flex-direction:column;font-weight:400;justify-content:center;line-height:1.4;padding-inline-end:.3em}.uppy-StatusBar-statusPrimary{display:flex;font-weight:500;line-height:1}.uppy-StatusBar-statusPrimary button.uppy-StatusBar-details{margin-left:5px}[data-uppy-theme=dark] .uppy-StatusBar-statusPrimary{color:#eaeaea}.uppy-StatusBar-statusSecondary{color:#757575;display:inline-block;font-size:11px;line-height:1.2;margin-top:1px;white-space:nowrap}[data-uppy-theme=dark] .uppy-StatusBar-statusSecondary{color:#bbb}.uppy-StatusBar-statusSecondaryHint{display:inline-block;line-height:1;margin-inline-end:5px;vertical-align:middle}.uppy-size--md .uppy-StatusBar-statusSecondaryHint{margin-inline-end:8px}.uppy-StatusBar-statusIndicator{color:#525252;margin-inline-end:7px;position:relative;top:1px}.uppy-StatusBar-statusIndicator svg{vertical-align:text-bottom}.uppy-StatusBar-actions{align-items:center;bottom:0;display:flex;inset-inline-end:10px;position:absolute;top:0;z-index:1004}.uppy-StatusBar.is-waiting .uppy-StatusBar-actions{background-color:#fafafa;height:100%;padding:0 15px;position:static;width:100%}[data-uppy-theme=dark] .uppy-StatusBar.is-waiting .uppy-StatusBar-actions{background-color:#1f1f1f}.uppy-StatusBar:not([aria-hidden=true]).is-waiting.has-ghosts{flex-direction:column;height:90px}.uppy-size--md .uppy-StatusBar:not([aria-hidden=true]).is-waiting.has-ghosts{flex-direction:row;height:65px}.uppy-StatusBar:not([aria-hidden=true]).is-waiting.has-ghosts .uppy-StatusBar-actions{flex-direction:column;justify-content:center}.uppy-size--md .uppy-StatusBar:not([aria-hidden=true]).is-waiting.has-ghosts .uppy-StatusBar-actions{flex-direction:row;justify-content:normal}.uppy-StatusBar-actionCircleBtn{cursor:pointer;line-height:1;margin:3px;opacity:.9}.uppy-StatusBar-actionCircleBtn:focus{outline:none}.uppy-StatusBar-actionCircleBtn::-moz-focus-inner{border:0}.uppy-StatusBar-actionCircleBtn:focus{box-shadow:0 0 0 3px #1269cf80}[data-uppy-theme=dark] .uppy-StatusBar-actionCircleBtn:focus{outline:none}[data-uppy-theme=dark] .uppy-StatusBar-actionCircleBtn::-moz-focus-inner{border:0}[data-uppy-theme=dark] .uppy-StatusBar-actionCircleBtn:focus{box-shadow:0 0 0 2px #aae1ffd9}.uppy-StatusBar-actionCircleBtn:hover{opacity:1}.uppy-StatusBar-actionCircleBtn:focus{border-radius:50%}.uppy-StatusBar-actionCircleBtn svg{vertical-align:bottom}.uppy-StatusBar-actionBtn{color:#1269cf;display:inline-block;font-size:10px;line-height:inherit;vertical-align:middle}.uppy-size--md .uppy-StatusBar-actionBtn{font-size:11px}.uppy-StatusBar-actionBtn--disabled{opacity:.4}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--disabled{opacity:.7}.uppy-StatusBar-actionBtn--retry{background-color:#ff4b23;border-radius:8px;color:#fff;height:16px;line-height:1;margin-inline-end:6px;padding:1px 6px 3px 18px;position:relative}.uppy-StatusBar-actionBtn--retry:focus{outline:none}.uppy-StatusBar-actionBtn--retry::-moz-focus-inner{border:0}.uppy-StatusBar-actionBtn--retry:focus{box-shadow:0 0 0 3px #1269cf80}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--retry:focus{outline:none}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--retry::-moz-focus-inner{border:0}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--retry:focus{box-shadow:0 0 0 2px #aae1ffd9}.uppy-StatusBar-actionBtn--retry:hover{background-color:#f92d00}.uppy-StatusBar-actionBtn--retry svg{inset-inline-start:6px;position:absolute;top:3px}.uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload{background-color:#1bb240;color:#fff;font-size:14px;line-height:1;padding:15px 10px;width:100%}.uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload:hover{background-color:#189c38}[data-uppy-theme=dark] .uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload{background-color:#1c8b37}[data-uppy-theme=dark] .uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload:hover{background-color:#18762f}.uppy-size--md .uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload{padding:13px 22px;width:auto}.uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload.uppy-StatusBar-actionBtn--disabled:hover{background-color:#1bb240;cursor:not-allowed}[data-uppy-theme=dark] .uppy-StatusBar.is-waiting .uppy-StatusBar-actionBtn--upload.uppy-StatusBar-actionBtn--disabled:hover{background-color:#1c8b37}.uppy-StatusBar:not(.is-waiting) .uppy-StatusBar-actionBtn--upload{background-color:initial;color:#1269cf}.uppy-StatusBar-actionBtn--uploadNewlyAdded{border-radius:3px;padding-inline-end:3px;padding-bottom:1px;padding-inline-start:3px}.uppy-StatusBar-actionBtn--uploadNewlyAdded:focus{outline:none}.uppy-StatusBar-actionBtn--uploadNewlyAdded::-moz-focus-inner{border:0}.uppy-StatusBar-actionBtn--uploadNewlyAdded:focus{box-shadow:0 0 0 3px #1269cf80}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--uploadNewlyAdded:focus{outline:none}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--uploadNewlyAdded::-moz-focus-inner{border:0}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--uploadNewlyAdded:focus{box-shadow:0 0 0 2px #aae1ffd9}.uppy-StatusBar.is-postprocessing .uppy-StatusBar-actionBtn--uploadNewlyAdded,.uppy-StatusBar.is-preprocessing .uppy-StatusBar-actionBtn--uploadNewlyAdded{display:none}.uppy-StatusBar-actionBtn--done{border-radius:3px;line-height:1;padding:7px 8px}.uppy-StatusBar-actionBtn--done:focus{outline:none}.uppy-StatusBar-actionBtn--done::-moz-focus-inner{border:0}.uppy-StatusBar-actionBtn--done:hover{color:#0e51a0}.uppy-StatusBar-actionBtn--done:focus{background-color:#dfe6f1}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--done:focus{background-color:#333}[data-uppy-theme=dark] .uppy-StatusBar-actionBtn--done{color:#02baf2}.uppy-size--md .uppy-StatusBar-actionBtn--done{font-size:14px}.uppy-StatusBar-serviceMsg{color:#000;font-size:11px;line-height:1.1;padding-left:10px}.uppy-size--md .uppy-StatusBar-serviceMsg{font-size:14px;padding-left:15px}[data-uppy-theme=dark] .uppy-StatusBar-serviceMsg{color:#eaeaea}.uppy-StatusBar-serviceMsg-ghostsIcon{left:6px;opacity:.5;position:relative;top:2px;vertical-align:text-bottom;width:10px}.uppy-size--md .uppy-StatusBar-serviceMsg-ghostsIcon{left:10px;top:1px;width:15px}.uppy-StatusBar-details{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#939393;border-radius:50%;color:#fff;cursor:help;display:inline-block;font-size:10px;font-weight:600;height:13px;inset-inline-start:2px;line-height:12px;position:relative;text-align:center;top:0;vertical-align:middle;width:13px}.uppy-StatusBar-details:after{line-height:1.3;word-wrap:break-word}.uppy-StatusBar-spinner{animation-duration:1s;animation-iteration-count:infinite;animation-name:uppy-StatusBar-spinnerAnimation;animation-timing-function:linear;fill:#1269cf;margin-inline-end:10px}.uppy-StatusBar.is-postprocessing .uppy-StatusBar-spinner,.uppy-StatusBar.is-preprocessing .uppy-StatusBar-spinner{fill:#f6a623}@keyframes uppy-StatusBar-spinnerAnimation{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.uppy-transition-slideDownUp-enter{opacity:.01;transform:translate3d(0,-105%,0);transition:transform .25s ease-in-out,opacity .25s ease-in-out}.uppy-transition-slideDownUp-enter.uppy-transition-slideDownUp-enter-active{opacity:1;transform:translateZ(0)}.uppy-transition-slideDownUp-leave{opacity:1;transform:translateZ(0);transition:transform .25s ease-in-out,opacity .25s ease-in-out}.uppy-transition-slideDownUp-leave.uppy-transition-slideDownUp-leave-active{opacity:.01;transform:translate3d(0,-105%,0)}@keyframes uppy-Dashboard-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes uppy-Dashboard-fadeOut{0%{opacity:1}to{opacity:0}}@keyframes uppy-Dashboard-slideDownAndFadeIn{0%{opacity:0;transform:translate3d(-50%,-70%,0)}to{opacity:1;transform:translate3d(-50%,-50%,0)}}@keyframes uppy-Dashboard-slideDownAndFadeIn--small{0%{opacity:0;transform:translate3d(0,-20%,0)}to{opacity:1;transform:translateZ(0)}}@keyframes uppy-Dashboard-slideUpFadeOut{0%{opacity:1;transform:translate3d(-50%,-50%,0)}to{opacity:0;transform:translate3d(-50%,-70%,0)}}@keyframes uppy-Dashboard-slideUpFadeOut--small{0%{opacity:1;transform:translateZ(0)}to{opacity:0;transform:translate3d(0,-20%,0)}}.uppy-Dashboard--modal{z-index:1001}.uppy-Dashboard--modal[aria-hidden=true]{display:none}.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose>.uppy-Dashboard-inner{animation:uppy-Dashboard-slideDownAndFadeIn--small .3s cubic-bezier(0,0,.2,1)}@media only screen and (min-width:820px){.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose>.uppy-Dashboard-inner{animation:uppy-Dashboard-slideDownAndFadeIn .3s cubic-bezier(0,0,.2,1)}}.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose>.uppy-Dashboard-overlay{animation:uppy-Dashboard-fadeIn .3s cubic-bezier(0,0,.2,1)}.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose.uppy-Dashboard--isClosing>.uppy-Dashboard-inner{animation:uppy-Dashboard-slideUpFadeOut--small .3s cubic-bezier(0,0,.2,1)}@media only screen and (min-width:820px){.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose.uppy-Dashboard--isClosing>.uppy-Dashboard-inner{animation:uppy-Dashboard-slideUpFadeOut .3s cubic-bezier(0,0,.2,1)}}.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose.uppy-Dashboard--isClosing>.uppy-Dashboard-overlay{animation:uppy-Dashboard-fadeOut .3s cubic-bezier(0,0,.2,1)}.uppy-Dashboard-isFixed{height:100vh;overflow:hidden}.uppy-Dashboard--modal .uppy-Dashboard-overlay{background-color:#00000080;inset:0;position:fixed;z-index:1001}.uppy-Dashboard-inner{background-color:#f4f4f4;border:1px solid #eaeaea;border-radius:5px;max-height:100%;max-width:100%;outline:none;position:relative}.uppy-size--md .uppy-Dashboard-inner{min-height:auto}@media only screen and (min-width:820px){.uppy-Dashboard-inner{height:500px;width:650px}}.uppy-Dashboard--modal .uppy-Dashboard-inner{z-index:1002}[data-uppy-theme=dark] .uppy-Dashboard-inner{background-color:#1f1f1f}.uppy-Dashboard--isDisabled .uppy-Dashboard-inner{cursor:not-allowed}.uppy-Dashboard-innerWrap{border-radius:5px;display:flex;flex-direction:column;height:100%;opacity:0;overflow:hidden;position:relative}.uppy-Dashboard--isInnerWrapVisible .uppy-Dashboard-innerWrap{opacity:1}.uppy-Dashboard--isDisabled .uppy-Dashboard-innerWrap{cursor:not-allowed;filter:grayscale(100%);opacity:.6;-webkit-user-select:none;-moz-user-select:none;user-select:none}.uppy-Dashboard--isDisabled .uppy-ProviderIconBg{fill:#9f9f9f}.uppy-Dashboard--isDisabled [aria-disabled],.uppy-Dashboard--isDisabled [disabled]{cursor:not-allowed;pointer-events:none}.uppy-Dashboard--modal .uppy-Dashboard-inner{border:none;inset:35px 15px 15px;position:fixed}@media only screen and (min-width:820px){.uppy-Dashboard--modal .uppy-Dashboard-inner{box-shadow:0 5px 15px 4px #00000026;left:50%;right:auto;top:50%;transform:translate(-50%,-50%)}}.uppy-Dashboard-close{color:#ffffffe6;cursor:pointer;display:block;font-size:27px;inset-inline-end:-2px;position:absolute;top:-33px;z-index:1005}.uppy-Dashboard-close:focus{outline:none}.uppy-Dashboard-close::-moz-focus-inner{border:0}.uppy-Dashboard-close:focus{color:#6eabf2}@media only screen and (min-width:820px){.uppy-Dashboard-close{font-size:35px;inset-inline-end:-35px;top:-10px}}.uppy-Dashboard-serviceMsg{background-color:#fffbf7;border-bottom:1px solid #edd4b9;border-top:1px solid #edd4b9;font-size:12px;font-weight:500;line-height:1.3;padding:12px 0;position:relative;top:-1px;z-index:1004}.uppy-size--md .uppy-Dashboard-serviceMsg{font-size:14px;line-height:1.4}[data-uppy-theme=dark] .uppy-Dashboard-serviceMsg{background-color:#1f1f1f;border-bottom:1px solid #333;border-top:1px solid #333;color:#eaeaea}.uppy-Dashboard-serviceMsg-title{display:block;line-height:1;margin-bottom:4px;padding-left:42px}.uppy-Dashboard-serviceMsg-text{padding:0 15px}.uppy-Dashboard-serviceMsg-actionBtn{color:#1269cf;font-size:inherit;font-weight:inherit;vertical-align:initial}[data-uppy-theme=dark] .uppy-Dashboard-serviceMsg-actionBtn{color:#02baf2e6}.uppy-Dashboard-serviceMsg-icon{left:15px;position:absolute;top:10px}.uppy-Dashboard-AddFiles{align-items:center;display:flex;flex-direction:column;height:100%;justify-content:center;position:relative;text-align:center}[data-uppy-drag-drop-supported=true] .uppy-Dashboard-AddFiles{border:1px dashed #dfdfdf;border-radius:3px;height:calc(100% - 14px);margin:7px}.uppy-Dashboard-AddFilesPanel .uppy-Dashboard-AddFiles{border:none;height:calc(100% - 54px)}.uppy-Dashboard--modal .uppy-Dashboard-AddFiles{border-color:#cfcfcf}[data-uppy-theme=dark] .uppy-Dashboard-AddFiles{border-color:#757575}.uppy-Dashboard-AddFiles-info{display:none;margin-top:auto;padding-bottom:15px;padding-top:15px}.uppy-size--height-md .uppy-Dashboard-AddFiles-info{display:block}.uppy-size--md .uppy-Dashboard-AddFiles-info{bottom:25px;left:0;padding-bottom:0;padding-top:30px;position:absolute;right:0}[data-uppy-num-acquirers="0"] .uppy-Dashboard-AddFiles-info{margin-top:0}.uppy-Dashboard-browse{color:#1269cf;cursor:pointer}.uppy-Dashboard-browse:focus{outline:none}.uppy-Dashboard-browse::-moz-focus-inner{border:0}.uppy-Dashboard-browse:focus,.uppy-Dashboard-browse:hover{border-bottom:1px solid #1269cf}[data-uppy-theme=dark] .uppy-Dashboard-browse{color:#02baf2e6}[data-uppy-theme=dark] .uppy-Dashboard-browse:focus,[data-uppy-theme=dark] .uppy-Dashboard-browse:hover{border-bottom:1px solid #02baf2}.uppy-Dashboard-browseBtn{display:block;font-size:14px;font-weight:500;margin-bottom:5px;margin-top:8px;width:100%}.uppy-size--md .uppy-Dashboard-browseBtn{font-size:15px;margin:15px auto;padding:13px 44px;width:auto}.uppy-Dashboard-AddFiles-list{display:flex;flex:1;flex-direction:column;margin-top:2px;overflow-y:auto;padding:2px 0;width:100%;-webkit-overflow-scrolling:touch}.uppy-size--md .uppy-Dashboard-AddFiles-list{flex:none;flex-direction:row;flex-wrap:wrap;justify-content:center;margin-top:15px;max-width:600px;overflow-y:visible;padding-top:0}.uppy-DashboardTab{border-bottom:1px solid #eaeaea;text-align:center;width:100%}[data-uppy-theme=dark] .uppy-DashboardTab{border-bottom:1px solid #333}.uppy-size--md .uppy-DashboardTab{border-bottom:none;display:inline-block;margin-bottom:10px;width:auto}.uppy-DashboardTab-btn{align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:initial;color:#525252;cursor:pointer;flex-direction:row;height:100%;justify-content:left;padding:12px 15px;width:100%}.uppy-DashboardTab-btn:focus{outline:none}.uppy-size--md .uppy-DashboardTab-btn{border-radius:5px;flex-direction:column;margin-inline-end:1px;padding:10px 3px;width:86px}[data-uppy-theme=dark] .uppy-DashboardTab-btn{color:#eaeaea}.uppy-DashboardTab-btn::-moz-focus-inner{border:0}.uppy-DashboardTab-btn:hover{background-color:#e9ecef}[data-uppy-theme=dark] .uppy-DashboardTab-btn:hover{background-color:#333}.uppy-DashboardTab-btn:active,.uppy-DashboardTab-btn:focus{background-color:#dfe6f1}[data-uppy-theme=dark] .uppy-DashboardTab-btn:active,[data-uppy-theme=dark] .uppy-DashboardTab-btn:focus{background-color:#525252}.uppy-DashboardTab-btn svg{display:inline-block;max-height:100%;max-width:100%;overflow:hidden;transition:transform .15s ease-in-out;vertical-align:text-top}.uppy-DashboardTab-inner{align-items:center;background-color:#fff;border-radius:8px;box-shadow:0 1px 1px #0000001a,0 1px 2px #0000001a,0 2px 3px #00000005;display:flex;height:32px;justify-content:center;margin-inline-end:10px;width:32px}.uppy-size--md .uppy-DashboardTab-inner{margin-inline-end:0}[data-uppy-theme=dark] .uppy-DashboardTab-inner{background-color:#323232;box-shadow:0 1px 1px #0003,0 1px 2px #0003,0 2px 3px #00000014}.uppy-DashboardTab-name{font-size:14px;font-weight:400}.uppy-size--md .uppy-DashboardTab-name{font-size:12px;line-height:15px;margin-bottom:0;margin-top:8px}.uppy-DashboardTab-iconMyDevice{color:#1269cf}[data-uppy-theme=dark] .uppy-DashboardTab-iconMyDevice{color:#02baf2}.uppy-DashboardTab-iconBox{color:#0061d5}[data-uppy-theme=dark] .uppy-DashboardTab-iconBox{color:#eaeaea}.uppy-DashboardTab-iconDropbox{color:#0061fe}[data-uppy-theme=dark] .uppy-DashboardTab-iconDropbox{color:#eaeaea}.uppy-DashboardTab-iconUnsplash{color:#111}[data-uppy-theme=dark] .uppy-DashboardTab-iconUnsplash{color:#eaeaea}.uppy-DashboardTab-iconWebdav{color:#111}[data-uppy-theme=dark] .uppy-DashboardTab-iconWebdav{color:#eaeaea}.uppy-DashboardTab-iconScreenRec{color:#2c3e50}[data-uppy-theme=dark] .uppy-DashboardTab-iconScreenRec{color:#eaeaea}.uppy-DashboardTab-iconAudio{color:#8030a3}[data-uppy-theme=dark] .uppy-DashboardTab-iconAudio{color:#bf6ee3}.uppy-Dashboard-input{height:.1px;opacity:0;overflow:hidden;position:absolute;width:.1px;z-index:-1}.uppy-DashboardContent-bar{align-items:center;background-color:#fafafa;border-bottom:1px solid #eaeaea;display:flex;flex-shrink:0;height:40px;justify-content:space-between;padding:0 10px;position:relative;width:100%;z-index:1004}.uppy-size--md .uppy-DashboardContent-bar{height:50px;padding:0 15px}[data-uppy-theme=dark] .uppy-DashboardContent-bar{background-color:#1f1f1f;border-bottom:1px solid #333}.uppy-DashboardContent-title{font-size:12px;font-weight:500;left:0;line-height:40px;margin:auto;max-width:170px;overflow-x:hidden;position:absolute;right:0;text-align:center;text-overflow:ellipsis;top:0;white-space:nowrap;width:100%}.uppy-size--md .uppy-DashboardContent-title{font-size:14px;line-height:50px;max-width:300px}[data-uppy-theme=dark] .uppy-DashboardContent-title{color:#eaeaea}.uppy-DashboardContent-back,.uppy-DashboardContent-save{-webkit-appearance:none;background:none;border:0;border-radius:3px;color:inherit;color:#1269cf;cursor:pointer;font-family:inherit;font-size:inherit;font-size:12px;font-weight:400;line-height:1;margin:0;margin-inline-start:-6px;padding:7px 6px}.uppy-DashboardContent-back:focus,.uppy-DashboardContent-save:focus{outline:none}.uppy-DashboardContent-back::-moz-focus-inner,.uppy-DashboardContent-save::-moz-focus-inner{border:0}.uppy-DashboardContent-back:hover,.uppy-DashboardContent-save:hover{color:#0e51a0}.uppy-DashboardContent-back:focus,.uppy-DashboardContent-save:focus{background-color:#dfe6f1}[data-uppy-theme=dark] .uppy-DashboardContent-back:focus,[data-uppy-theme=dark] .uppy-DashboardContent-save:focus{background-color:#333}.uppy-size--md .uppy-DashboardContent-back,.uppy-size--md .uppy-DashboardContent-save{font-size:14px}[data-uppy-theme=dark] .uppy-DashboardContent-back,[data-uppy-theme=dark] .uppy-DashboardContent-save{color:#02baf2}.uppy-DashboardContent-addMore{-webkit-appearance:none;background:none;border:0;border-radius:3px;color:inherit;color:#1269cf;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:500;height:29px;line-height:1;margin:0;margin-inline-end:-5px;padding:7px 8px;width:29px}.uppy-DashboardContent-addMore:focus{outline:none}.uppy-DashboardContent-addMore::-moz-focus-inner{border:0}.uppy-DashboardContent-addMore:hover{color:#0e51a0}.uppy-DashboardContent-addMore:focus{background-color:#dfe6f1}[data-uppy-theme=dark] .uppy-DashboardContent-addMore:focus{background-color:#333}.uppy-size--md .uppy-DashboardContent-addMore{font-size:14px;height:auto;margin-inline-end:-8px;width:auto}[data-uppy-theme=dark] .uppy-DashboardContent-addMore{color:#02baf2}.uppy-DashboardContent-addMore svg{margin-inline-end:4px;vertical-align:initial}.uppy-size--md .uppy-DashboardContent-addMore svg{height:11px;width:11px}.uppy-DashboardContent-addMoreCaption{display:none}.uppy-size--md .uppy-DashboardContent-addMoreCaption{display:inline}.uppy-DashboardContent-panel{background-color:#f5f5f5;flex:1}.uppy-Dashboard-AddFilesPanel,.uppy-DashboardContent-panel{border-radius:5px;display:flex;flex-direction:column;inset:0;overflow:hidden;position:absolute;z-index:1005}.uppy-Dashboard-AddFilesPanel{background:#fafafa;background:linear-gradient(0deg,#fafafa 35%,#fafafad9);box-shadow:0 0 10px 5px #00000026}[data-uppy-theme=dark] .uppy-Dashboard-AddFilesPanel{background-color:#333;background-image:linear-gradient(0deg,#1f1f1f 35%,#1f1f1fd9)}.uppy-Dashboard--isAddFilesPanelVisible .uppy-Dashboard-files{filter:blur(2px)}.uppy-Dashboard-progress{bottom:0;height:12%;left:0;position:absolute;width:100%}.uppy-Dashboard-progressBarContainer.is-active{height:100%;left:0;position:absolute;top:0;width:100%;z-index:1004}.uppy-Dashboard-filesContainer{flex:1;margin:0;overflow-y:hidden;position:relative}.uppy-Dashboard-filesContainer:after{clear:both;content:"";display:table}.uppy-Dashboard-files{flex:1;margin:0;overflow-y:auto;padding:0 0 10px;-webkit-overflow-scrolling:touch}.uppy-size--md .uppy-Dashboard-files{padding-top:10px}.uppy-Dashboard--singleFile .uppy-Dashboard-filesInner{align-items:center;display:flex;height:100%;justify-content:center}.uppy-Dashboard-dropFilesHereHint{align-items:center;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cpath fill='%231269CF' d='M24 1v1C11.85 2 2 11.85 2 24s9.85 22 22 22 22-9.85 22-22S36.15 2 24 2zm0 0V0c13.254 0 24 10.746 24 24S37.254 48 24 48 0 37.254 0 24 10.746 0 24 0zm7.707 19.293a.999.999 0 1 1-1.414 1.414L25 16.414V34a1 1 0 1 1-2 0V16.414l-5.293 5.293a.999.999 0 1 1-1.414-1.414l7-7a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E");background-position:50% 50%;background-repeat:no-repeat;border:1px dashed #1269cf;border-radius:3px;color:#757575;display:flex;font-size:16px;justify-content:center;inset:7px;padding-top:90px;position:absolute;text-align:center;visibility:hidden;z-index:2000}[data-uppy-theme=dark] .uppy-Dashboard-dropFilesHereHint{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cpath fill='%2302BAF2' d='M24 1v1C11.85 2 2 11.85 2 24s9.85 22 22 22 22-9.85 22-22S36.15 2 24 2zm0 0V0c13.254 0 24 10.746 24 24S37.254 48 24 48 0 37.254 0 24 10.746 0 24 0zm7.707 19.293a.999.999 0 1 1-1.414 1.414L25 16.414V34a1 1 0 1 1-2 0V16.414l-5.293 5.293a.999.999 0 1 1-1.414-1.414l7-7a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E");border-color:#02baf2;color:#bbb}.uppy-Dashboard.uppy-Dashboard--isDraggingOver .uppy-Dashboard-dropFilesHereHint{pointer-events:none;visibility:visible}.uppy-Dashboard.uppy-Dashboard--isDraggingOver .uppy-Dashboard-files,.uppy-Dashboard.uppy-Dashboard--isDraggingOver .uppy-Dashboard-progressindicators,.uppy-Dashboard.uppy-Dashboard--isDraggingOver .uppy-Dashboard-serviceMsg,.uppy-Dashboard.uppy-Dashboard--isDraggingOver .uppy-DashboardContent-bar{opacity:.15}.uppy-Dashboard.uppy-Dashboard--isDraggingOver .uppy-Dashboard-AddFiles{opacity:.03}.uppy-Dashboard-AddFiles-title{color:#000;font-size:17px;font-weight:500;line-height:1.35;margin-bottom:5px;margin-top:15px;padding:0 15px;text-align:inline-start;width:100%}.uppy-size--md .uppy-Dashboard-AddFiles-title{font-size:21px;font-weight:400;margin-top:5px;max-width:480px;padding:0 35px;text-align:center}[data-uppy-num-acquirers="0"] .uppy-Dashboard-AddFiles-title{text-align:center}[data-uppy-theme=dark] .uppy-Dashboard-AddFiles-title{color:#eaeaea}.uppy-Dashboard-AddFiles-title button{font-weight:500}.uppy-size--md .uppy-Dashboard-AddFiles-title button{font-weight:400}.uppy-Dashboard-note{color:#757575;font-size:14px;line-height:1.25;margin:auto;max-width:350px;padding:0 15px;text-align:center}.uppy-size--md .uppy-Dashboard-note{line-height:1.35;max-width:600px}[data-uppy-theme=dark] .uppy-Dashboard-note{color:#cfcfcf}a.uppy-Dashboard-poweredBy{color:#939393;display:inline-block;font-size:11px;margin-top:8px;text-align:center;text-decoration:none}.uppy-Dashboard-poweredByIcon{margin-left:1px;margin-right:1px;opacity:.9;position:relative;top:1px;vertical-align:text-top;fill:none;stroke:#939393}.uppy-Dashboard-Item-previewIcon{height:25px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:25px;z-index:100}.uppy-size--md .uppy-Dashboard-Item-previewIcon{height:38px;width:38px}.uppy-Dashboard-Item-previewIcon svg{height:100%;width:100%}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-previewIcon{height:100%;max-height:60%;max-width:60%;width:100%}.uppy-Dashboard-Item-previewIconWrap{height:76px;max-height:75%;position:relative}.uppy-Dashboard--singleFile .uppy-Dashboard-Item-previewIconWrap{height:100%;width:100%}.uppy-Dashboard-Item-previewIconBg{filter:drop-shadow(rgba(0,0,0,.1) 0 1px 1px);height:100%;width:100%}.uppy-Dashboard-upload{height:50px;position:relative;width:50px}.uppy-size--md .uppy-Dashboard-upload{height:60px;width:60px}.uppy-Dashboard-upload .uppy-c-icon{position:relative;top:1px;width:50%}.uppy-Dashboard-uploadCount{background-color:#1bb240;border-radius:50%;color:#fff;font-size:8px;height:16px;inset-inline-end:-12px;line-height:16px;position:absolute;top:-12px;width:16px}.uppy-size--md .uppy-Dashboard-uploadCount{font-size:9px;height:18px;line-height:18px;width:18px}.uppy-Dashboard-inner{border:none!important;background:transparent!important}.uppy-Dashboard-innerWrap{border-radius:.5rem;overflow:hidden}.uppy-Dashboard-AddFiles{border:2px dashed hsl(var(--border))!important;border-radius:.5rem!important;background:hsl(var(--muted) / .3)!important;transition:all .2s ease}.uppy-Dashboard-AddFiles:hover{border-color:hsl(var(--primary))!important;background:hsl(var(--muted) / .5)!important}.uppy-Dashboard-AddFiles-title{color:hsl(var(--foreground))!important;font-weight:500!important}.uppy-Dashboard-AddFiles-info{color:hsl(var(--muted-foreground))!important}.uppy-Dashboard-browse{color:hsl(var(--primary))!important;font-weight:500!important}.uppy-Dashboard-browse:hover{text-decoration:underline!important}.uppy-Dashboard-files{background:transparent!important}.uppy-Dashboard-Item{border-bottom-color:hsl(var(--border))!important}.uppy-Dashboard-Item-name{color:hsl(var(--foreground))!important}.uppy-Dashboard-Item-status{color:hsl(var(--muted-foreground))!important}.uppy-StatusBar{background:hsl(var(--muted))!important;border-top:1px solid hsl(var(--border))!important}.uppy-StatusBar-progress{background:hsl(var(--primary))!important}.uppy-StatusBar-content{color:hsl(var(--foreground))!important}.uppy-StatusBar-actionBtn--upload{background:hsl(var(--primary))!important;color:hsl(var(--primary-foreground))!important;border-radius:.375rem!important;font-weight:500!important;padding:.5rem 1rem!important}.uppy-StatusBar-actionBtn--upload:hover{background:hsl(var(--primary) / .9)!important}.uppy-Dashboard-note{color:hsl(var(--muted-foreground))!important;font-size:.75rem!important}[data-uppy-theme=dark] .uppy-Dashboard-AddFiles,.dark .uppy-Dashboard-AddFiles{background:hsl(var(--muted) / .2)!important}[data-uppy-theme=dark] .uppy-Dashboard-AddFiles-title,.dark .uppy-Dashboard-AddFiles-title{color:hsl(var(--foreground))!important}[data-uppy-theme=dark] .uppy-StatusBar,.dark .uppy-StatusBar{background:hsl(var(--muted) / .5)!important}.uppy-Dashboard{font-family:inherit!important}.uppy-Dashboard-Item-preview{border-radius:.375rem!important;overflow:hidden}.uppy-Dashboard-Item-action--remove{color:hsl(var(--destructive))!important}.uppy-Dashboard-Item-action--remove:hover{opacity:.8}.uppy-Dashboard-Item.is-complete .uppy-Dashboard-Item-progress{color:hsl(var(--success, 142 76% 36%))!important}.uppy-Dashboard-Item.is-error .uppy-Dashboard-Item-progress{color:hsl(var(--destructive))!important}.uppy-Dashboard-files::-webkit-scrollbar{width:6px}.uppy-Dashboard-files::-webkit-scrollbar-track{background:transparent}.uppy-Dashboard-files::-webkit-scrollbar-thumb{background:hsl(var(--muted-foreground) / .3);border-radius:3px}.uppy-Dashboard-files::-webkit-scrollbar-thumb:hover{background:hsl(var(--muted-foreground) / .5)}.react-flow{direction:ltr}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;cursor:grab}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:grabbing}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{pointer-events:none;overflow:visible}.react-flow__edge-path,.react-flow__connection-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{pointer-events:visibleStroke;cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:grab}.react-flow__node.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background:#1a192b;border:1px solid white;border-radius:100%}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:-4px;transform:translate(-50%)}.react-flow__handle-top{left:50%;top:-4px;transform:translate(-50%)}.react-flow__handle-left{top:50%;left:-4px;transform:translateY(-50%)}.react-flow__handle-right{right:-4px;top:50%;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-50%)}.react-flow__attribution{font-size:10px;background:#ffffff80;padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-input,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:3px;width:150px;font-size:12px;color:#222;text-align:center;border-width:1px;border-style:solid;border-color:#1a192b;background-color:#fff}.react-flow__node-default.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted rgba(0,89,220,.8)}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{border:none;background:#fefefe;border-bottom:1px solid #eee;box-sizing:content-box;display:flex;justify-content:center;align-items:center;width:16px;height:16px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:5px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:4px;height:4px;border:1px solid #fff;border-radius:1px;background-color:#3367d9;transform:translate(-50%,-50%)}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:#3367d9;border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%} diff --git a/webui/dist/assets/index-ppcjeAmG.js b/webui/dist/assets/index-ppcjeAmG.js new file mode 100644 index 00000000..f5a4dcd5 --- /dev/null +++ b/webui/dist/assets/index-ppcjeAmG.js @@ -0,0 +1,90 @@ +import{r as m,j as e,L as Cr,e as aa,R as Es,b as e0,f as s0,g as t0,h as a0,k as l0,l as Zs,m as n0,n as r0,O as bg,o as i0}from"./router-9vIXuQkh.js";import{a as c0,b as o0,g as d0}from"./react-vendor-BmxF9s7Q.js";import{N as u0,c as m0,O as Lr,P as x0,g as cm}from"./utils-BqoaXoQ1.js";import{L as yg,T as wg,C as _g,R as h0,a as Sg,V as f0,b as p0,S as kg,c as g0,d as Cg,I as j0,e as Tg,f as v0,g as Eg,h as N0,i as b0,j as y0,O as Mg,P as w0,k as Ag,l as zg,D as Dg,A as Og,m as Rg,n as _0,o as S0,p as Lg,q as k0,r as Ug,s as C0,t as T0,u as Bg,v as E0,w as M0,x as $g,y as Ig,F as Pg,z as Hg,B as A0,E as z0,G as Gg,H as D0,J as O0,K as R0,M as L0,N as U0,Q as B0,U as $0,W as I0,X as P0,Y as H0,Z as G0,_ as F0,$ as q0,a0 as V0,a1 as K0,a2 as Fg,a3 as Q0,a4 as Y0}from"./radix-extra-CTMrA3du.js";import{R as J0,T as X0,L as Z0,g as W0,C as fo,X as po,Y as Ai,h as ew,B as om,j as go,P as sw,k as tw,l as aw}from"./charts-simvewUa.js";import{S as lw,H as qg,O as Vg,o as nw,C as Kg,p as rw,T as Qg,D as Yg,R as iw,q as cw,I as Jg,J as ow,K as Xg,L as Zg,M as dw,N as Wg,V as uw,Q as ej,U as sj,X as mw,Y as xw,Z as tj,_ as hw,$ as fw,a0 as aj,a1 as pw,e as lj,f as Ro,c as Lo,P as $n,d as Uo,b as cn,h as gw,l as jw,m as vw,u as Cm,r as Nw,a as bw,a2 as yw,a3 as nj,a4 as ww,a5 as _w,a6 as Sw,a7 as rj,a8 as ij,a9 as cj,aa as oj,ab as dj,ac as uj,ad as kw}from"./radix-core-BdJoVJLV.js";import{R as kt,a as Pi,C as Ct,b as ea,L as zs,P as Ji,Z as zn,F as qa,c as Cw,S as In,d as Tw,M as on,A as Ew,D as Mw,e as zr,f as kl,T as Aw,X as _a,g as zw,h as mj,I as qt,i as Ft,j as St,k as ko,E as Hi,l as sa,m as xj,H as Dw,n as ls,o as Xt,U as Gi,p as hj,q as fj,r as qp,K as Om,s as pj,t as Ow,u as bo,v as Rw,B as Ri,w as Dn,x as Rm,y as Lw,z as Uw,G as Vt,J as Bo,N as Va,O as it,Q as $a,V as Dr,W as Lm,Y as gj,_ as Xi,$ as jj,a0 as vj,a1 as On,a2 as Ur,a3 as ll,a4 as Sa,a5 as Br,a6 as Um,a7 as Nj,a8 as Wt,a9 as Tl,aa as Rn,ab as Ln,ac as $o,ad as Bw,ae as $w,af as Iw,ag as bj,ah as yo,ai as Un,aj as Pw,ak as Or,al as Hw,am as Co,an as Tm,ao as yj,ap as Gw,aq as Fw,ar as Vp,as as qw,at as wj,au as Vw,av as an,aw as _j,ax as dm,ay as Kp,az as Kw,aA as um,aB as Qw,aC as Yw,aD as Jw,aE as Xw,aF as Sj,aG as kj,aH as To,aI as Zw,aJ as Cj,aK as Tj,aL as Ww,aM as e1,aN as Qp,aO as s1,aP as t1,aQ as a1,aR as l1}from"./icons-C3pAHJin.js";import{S as n1,p as r1,j as i1,a as c1,E as Yp,R as o1,o as d1}from"./codemirror-TZqPU532.js";import{u as Ej,a as Eo,s as Mj,K as Aj,P as zj,b as Dj,D as Oj,c as Rj,S as Lj,v as u1,d as Uj,C as Bj,h as m1}from"./dnd-BiPfFtVp.js";import{_ as xa,c as x1,g as $j,D as h1,z as jo}from"./misc-CDy9pI_Y.js";import{D as f1,U as p1}from"./uppy-x-2TBvZ1.js";import{M as g1,r as j1,a as v1,b as N1}from"./markdown-CKA5gBQ9.js";import{c as b1,H as Mo,P as Ao,u as y1,d as w1,R as _1,B as S1,e as k1,C as C1,M as T1,f as E1}from"./reactflow-DtsZHOR4.js";(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))c(u);new MutationObserver(u=>{for(const x of u)if(x.type==="childList")for(const h of x.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&c(h)}).observe(document,{childList:!0,subtree:!0});function i(u){const x={};return u.integrity&&(x.integrity=u.integrity),u.referrerPolicy&&(x.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?x.credentials="include":u.crossOrigin==="anonymous"?x.credentials="omit":x.credentials="same-origin",x}function c(u){if(u.ep)return;u.ep=!0;const x=i(u);fetch(u.href,x)}})();var mm={exports:{}},zi={},xm={exports:{}},hm={};var Jp;function M1(){return Jp||(Jp=1,(function(l){function n(z,V){var U=z.length;z.push(V);e:for(;0>>1,P=z[L];if(0>>1;L<_e;){var je=2*(L+1)-1,Se=z[je],Y=je+1,be=z[Y];if(0>u(Se,U))Yu(be,Se)?(z[L]=be,z[Y]=U,L=Y):(z[L]=Se,z[je]=U,L=je);else if(Yu(be,U))z[L]=be,z[Y]=U,L=Y;else break e}}return V}function u(z,V){var U=z.sortIndex-V.sortIndex;return U!==0?U:z.id-V.id}if(l.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var x=performance;l.unstable_now=function(){return x.now()}}else{var h=Date,f=h.now();l.unstable_now=function(){return h.now()-f}}var p=[],g=[],N=1,v=null,b=3,w=!1,y=!1,R=!1,D=!1,k=typeof setTimeout=="function"?setTimeout:null,I=typeof clearTimeout=="function"?clearTimeout:null,M=typeof setImmediate<"u"?setImmediate:null;function S(z){for(var V=i(g);V!==null;){if(V.callback===null)c(g);else if(V.startTime<=z)c(g),V.sortIndex=V.expirationTime,n(p,V);else break;V=i(g)}}function T(z){if(R=!1,S(z),!y)if(i(p)!==null)y=!0,$||($=!0,ve());else{var V=i(g);V!==null&&ge(T,V.startTime-z)}}var $=!1,A=-1,Q=5,G=-1;function de(){return D?!0:!(l.unstable_now()-Gz&&de());){var L=v.callback;if(typeof L=="function"){v.callback=null,b=v.priorityLevel;var P=L(v.expirationTime<=z);if(z=l.unstable_now(),typeof P=="function"){v.callback=P,S(z),V=!0;break s}v===i(p)&&c(p),S(z)}else c(p);v=i(p)}if(v!==null)V=!0;else{var _e=i(g);_e!==null&&ge(T,_e.startTime-z),V=!1}}break e}finally{v=null,b=U,w=!1}V=void 0}}finally{V?ve():$=!1}}}var ve;if(typeof M=="function")ve=function(){M(oe)};else if(typeof MessageChannel<"u"){var le=new MessageChannel,fe=le.port2;le.port1.onmessage=oe,ve=function(){fe.postMessage(null)}}else ve=function(){k(oe,0)};function ge(z,V){A=k(function(){z(l.unstable_now())},V)}l.unstable_IdlePriority=5,l.unstable_ImmediatePriority=1,l.unstable_LowPriority=4,l.unstable_NormalPriority=3,l.unstable_Profiling=null,l.unstable_UserBlockingPriority=2,l.unstable_cancelCallback=function(z){z.callback=null},l.unstable_forceFrameRate=function(z){0>z||125L?(z.sortIndex=U,n(g,z),i(p)===null&&z===i(g)&&(R?(I(A),A=-1):R=!0,ge(T,U-L))):(z.sortIndex=P,n(p,z),y||w||(y=!0,$||($=!0,ve()))),z},l.unstable_shouldYield=de,l.unstable_wrapCallback=function(z){var V=b;return function(){var U=b;b=V;try{return z.apply(this,arguments)}finally{b=U}}}})(hm)),hm}var Xp;function A1(){return Xp||(Xp=1,xm.exports=M1()),xm.exports}var Zp;function z1(){if(Zp)return zi;Zp=1;var l=A1(),n=c0(),i=o0();function c(s){var t="https://react.dev/errors/"+s;if(1P||(s.current=L[P],L[P]=null,P--)}function Se(s,t){P++,L[P]=s.current,s.current=t}var Y=_e(null),be=_e(null),Z=_e(null),xe=_e(null);function Me(s,t){switch(Se(Z,t),Se(be,s),Se(Y,null),t.nodeType){case 9:case 11:s=(s=t.documentElement)&&(s=s.namespaceURI)?hp(s):0;break;default:if(s=t.tagName,t=t.namespaceURI)t=hp(t),s=fp(t,s);else switch(s){case"svg":s=1;break;case"math":s=2;break;default:s=0}}je(Y),Se(Y,s)}function J(){je(Y),je(be),je(Z)}function ce(s){s.memoizedState!==null&&Se(xe,s);var t=Y.current,a=fp(t,s.type);t!==a&&(Se(be,s),Se(Y,a))}function Fe(s){be.current===s&&(je(Y),je(be)),xe.current===s&&(je(xe),Ci._currentValue=U)}var q,ee;function ke(s){if(q===void 0)try{throw Error()}catch(a){var t=a.stack.trim().match(/\n( *(at )?)/);q=t&&t[1]||"",ee=-1)":-1o||O[r]!==te[o]){var he=` +`+O[r].replace(" at new "," at ");return s.displayName&&he.includes("")&&(he=he.replace("",s.displayName)),he}while(1<=r&&0<=o);break}}}finally{Te=!1,Error.prepareStackTrace=a}return(a=s?s.displayName||s.name:"")?ke(a):""}function me(s,t){switch(s.tag){case 26:case 27:case 5:return ke(s.type);case 16:return ke("Lazy");case 13:return s.child!==t&&t!==null?ke("Suspense Fallback"):ke("Suspense");case 19:return ke("SuspenseList");case 0:case 15:return Oe(s.type,!1);case 11:return Oe(s.type.render,!1);case 1:return Oe(s.type,!0);case 31:return ke("Activity");default:return""}}function ze(s){try{var t="",a=null;do t+=me(s,a),a=s,s=s.return;while(s);return t}catch(r){return` +Error generating stack: `+r.message+` +`+r.stack}}var rs=Object.prototype.hasOwnProperty,Kt=l.unstable_scheduleCallback,Qt=l.unstable_cancelCallback,ka=l.unstable_shouldYield,yt=l.unstable_requestPaint,st=l.unstable_now,F=l.unstable_getCurrentPriorityLevel,qe=l.unstable_ImmediatePriority,Ie=l.unstable_UserBlockingPriority,Ve=l.unstable_NormalPriority,Cs=l.unstable_LowPriority,ns=l.unstable_IdlePriority,Rs=l.log,Ee=l.unstable_setDisableYieldValue,gs=null,ts=null;function Ze(s){if(typeof Rs=="function"&&Ee(s),ts&&typeof ts.setStrictMode=="function")try{ts.setStrictMode(gs,s)}catch{}}var js=Math.clz32?Math.clz32:ut,dt=Math.log,Ot=Math.LN2;function ut(s){return s>>>=0,s===0?32:31-(dt(s)/Ot|0)|0}var _s=256,Tt=262144,Bt=4194304;function Ca(s){var t=s&42;if(t!==0)return t;switch(s&-s){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return s&261888;case 262144:case 524288:case 1048576:case 2097152:return s&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return s&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return s}}function Ya(s,t,a){var r=s.pendingLanes;if(r===0)return 0;var o=0,d=s.suspendedLanes,j=s.pingedLanes;s=s.warmLanes;var _=r&134217727;return _!==0?(r=_&~d,r!==0?o=Ca(r):(j&=_,j!==0?o=Ca(j):a||(a=_&~s,a!==0&&(o=Ca(a))))):(_=r&~d,_!==0?o=Ca(_):j!==0?o=Ca(j):a||(a=r&~s,a!==0&&(o=Ca(a)))),o===0?0:t!==0&&t!==o&&(t&d)===0&&(d=o&-o,a=t&-t,d>=a||d===32&&(a&4194048)!==0)?t:o}function nl(s,t){return(s.pendingLanes&~(s.suspendedLanes&~s.pingedLanes)&t)===0}function Yt(s,t){switch(s){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function X(){var s=Bt;return Bt<<=1,(Bt&62914560)===0&&(Bt=4194304),s}function ye(s){for(var t=[],a=0;31>a;a++)t.push(s);return t}function Ce(s,t){s.pendingLanes|=t,t!==268435456&&(s.suspendedLanes=0,s.pingedLanes=0,s.warmLanes=0)}function Ls(s,t,a,r,o,d){var j=s.pendingLanes;s.pendingLanes=a,s.suspendedLanes=0,s.pingedLanes=0,s.warmLanes=0,s.expiredLanes&=a,s.entangledLanes&=a,s.errorRecoveryDisabledLanes&=a,s.shellSuspendCounter=0;var _=s.entanglements,O=s.expirationTimes,te=s.hiddenUpdates;for(a=j&~a;0"u")return null;try{return s.activeElement||s.body}catch{return s.body}}var QN=/[\n"\\]/g;function Ea(s){return s.replace(QN,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function td(s,t,a,r,o,d,j,_){s.name="",j!=null&&typeof j!="function"&&typeof j!="symbol"&&typeof j!="boolean"?s.type=j:s.removeAttribute("type"),t!=null?j==="number"?(t===0&&s.value===""||s.value!=t)&&(s.value=""+Ta(t)):s.value!==""+Ta(t)&&(s.value=""+Ta(t)):j!=="submit"&&j!=="reset"||s.removeAttribute("value"),t!=null?ad(s,j,Ta(t)):a!=null?ad(s,j,Ta(a)):r!=null&&s.removeAttribute("value"),o==null&&d!=null&&(s.defaultChecked=!!d),o!=null&&(s.checked=o&&typeof o!="function"&&typeof o!="symbol"),_!=null&&typeof _!="function"&&typeof _!="symbol"&&typeof _!="boolean"?s.name=""+Ta(_):s.removeAttribute("name")}function ix(s,t,a,r,o,d,j,_){if(d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"&&(s.type=d),t!=null||a!=null){if(!(d!=="submit"&&d!=="reset"||t!=null)){sd(s);return}a=a!=null?""+Ta(a):"",t=t!=null?""+Ta(t):a,_||t===s.value||(s.value=t),s.defaultValue=t}r=r??o,r=typeof r!="function"&&typeof r!="symbol"&&!!r,s.checked=_?s.checked:!!r,s.defaultChecked=!!r,j!=null&&typeof j!="function"&&typeof j!="symbol"&&typeof j!="boolean"&&(s.name=j),sd(s)}function ad(s,t,a){t==="number"&&lc(s.ownerDocument)===s||s.defaultValue===""+a||(s.defaultValue=""+a)}function Kn(s,t,a,r){if(s=s.options,t){t={};for(var o=0;o"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),cd=!1;if(cl)try{var qr={};Object.defineProperty(qr,"passive",{get:function(){cd=!0}}),window.addEventListener("test",qr,qr),window.removeEventListener("test",qr,qr)}catch{cd=!1}var Ol=null,od=null,rc=null;function hx(){if(rc)return rc;var s,t=od,a=t.length,r,o="value"in Ol?Ol.value:Ol.textContent,d=o.length;for(s=0;s=Qr),Nx=" ",bx=!1;function yx(s,t){switch(s){case"keyup":return yb.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function wx(s){return s=s.detail,typeof s=="object"&&"data"in s?s.data:null}var Xn=!1;function _b(s,t){switch(s){case"compositionend":return wx(t);case"keypress":return t.which!==32?null:(bx=!0,Nx);case"textInput":return s=t.data,s===Nx&&bx?null:s;default:return null}}function Sb(s,t){if(Xn)return s==="compositionend"||!hd&&yx(s,t)?(s=hx(),rc=od=Ol=null,Xn=!1,s):null;switch(s){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:a,offset:t-s};s=r}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=Ax(a)}}function Dx(s,t){return s&&t?s===t?!0:s&&s.nodeType===3?!1:t&&t.nodeType===3?Dx(s,t.parentNode):"contains"in s?s.contains(t):s.compareDocumentPosition?!!(s.compareDocumentPosition(t)&16):!1:!1}function Ox(s){s=s!=null&&s.ownerDocument!=null&&s.ownerDocument.defaultView!=null?s.ownerDocument.defaultView:window;for(var t=lc(s.document);t instanceof s.HTMLIFrameElement;){try{var a=typeof t.contentWindow.location.href=="string"}catch{a=!1}if(a)s=t.contentWindow;else break;t=lc(s.document)}return t}function gd(s){var t=s&&s.nodeName&&s.nodeName.toLowerCase();return t&&(t==="input"&&(s.type==="text"||s.type==="search"||s.type==="tel"||s.type==="url"||s.type==="password")||t==="textarea"||s.contentEditable==="true")}var Db=cl&&"documentMode"in document&&11>=document.documentMode,Zn=null,jd=null,Zr=null,vd=!1;function Rx(s,t,a){var r=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;vd||Zn==null||Zn!==lc(r)||(r=Zn,"selectionStart"in r&&gd(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Zr&&Xr(Zr,r)||(Zr=r,r=Wc(jd,"onSelect"),0>=j,o-=j,Ja=1<<32-js(t)+o|a<cs?(ks=Pe,Pe=null):ks=Pe.sibling;var As=ne(K,Pe,se[cs],pe);if(As===null){Pe===null&&(Pe=ks);break}s&&Pe&&As.alternate===null&&t(K,Pe),H=d(As,H,cs),Ms===null?Ke=As:Ms.sibling=As,Ms=As,Pe=ks}if(cs===se.length)return a(K,Pe),Ts&&dl(K,cs),Ke;if(Pe===null){for(;cscs?(ks=Pe,Pe=null):ks=Pe.sibling;var tn=ne(K,Pe,As.value,pe);if(tn===null){Pe===null&&(Pe=ks);break}s&&Pe&&tn.alternate===null&&t(K,Pe),H=d(tn,H,cs),Ms===null?Ke=tn:Ms.sibling=tn,Ms=tn,Pe=ks}if(As.done)return a(K,Pe),Ts&&dl(K,cs),Ke;if(Pe===null){for(;!As.done;cs++,As=se.next())As=Ne(K,As.value,pe),As!==null&&(H=d(As,H,cs),Ms===null?Ke=As:Ms.sibling=As,Ms=As);return Ts&&dl(K,cs),Ke}for(Pe=r(Pe);!As.done;cs++,As=se.next())As=ue(Pe,K,cs,As.value,pe),As!==null&&(s&&As.alternate!==null&&Pe.delete(As.key===null?cs:As.key),H=d(As,H,cs),Ms===null?Ke=As:Ms.sibling=As,Ms=As);return s&&Pe.forEach(function(Wy){return t(K,Wy)}),Ts&&dl(K,cs),Ke}function Vs(K,H,se,pe){if(typeof se=="object"&&se!==null&&se.type===R&&se.key===null&&(se=se.props.children),typeof se=="object"&&se!==null){switch(se.$$typeof){case w:e:{for(var Ke=se.key;H!==null;){if(H.key===Ke){if(Ke=se.type,Ke===R){if(H.tag===7){a(K,H.sibling),pe=o(H,se.props.children),pe.return=K,K=pe;break e}}else if(H.elementType===Ke||typeof Ke=="object"&&Ke!==null&&Ke.$$typeof===Q&&wn(Ke)===H.type){a(K,H.sibling),pe=o(H,se.props),li(pe,se),pe.return=K,K=pe;break e}a(K,H);break}else t(K,H);H=H.sibling}se.type===R?(pe=jn(se.props.children,K.mode,pe,se.key),pe.return=K,K=pe):(pe=pc(se.type,se.key,se.props,null,K.mode,pe),li(pe,se),pe.return=K,K=pe)}return j(K);case y:e:{for(Ke=se.key;H!==null;){if(H.key===Ke)if(H.tag===4&&H.stateNode.containerInfo===se.containerInfo&&H.stateNode.implementation===se.implementation){a(K,H.sibling),pe=o(H,se.children||[]),pe.return=K,K=pe;break e}else{a(K,H);break}else t(K,H);H=H.sibling}pe=kd(se,K.mode,pe),pe.return=K,K=pe}return j(K);case Q:return se=wn(se),Vs(K,H,se,pe)}if(ge(se))return Re(K,H,se,pe);if(ve(se)){if(Ke=ve(se),typeof Ke!="function")throw Error(c(150));return se=Ke.call(se),Ye(K,H,se,pe)}if(typeof se.then=="function")return Vs(K,H,wc(se),pe);if(se.$$typeof===M)return Vs(K,H,vc(K,se),pe);_c(K,se)}return typeof se=="string"&&se!==""||typeof se=="number"||typeof se=="bigint"?(se=""+se,H!==null&&H.tag===6?(a(K,H.sibling),pe=o(H,se),pe.return=K,K=pe):(a(K,H),pe=Sd(se,K.mode,pe),pe.return=K,K=pe),j(K)):a(K,H)}return function(K,H,se,pe){try{ai=0;var Ke=Vs(K,H,se,pe);return or=null,Ke}catch(Pe){if(Pe===cr||Pe===bc)throw Pe;var Ms=ga(29,Pe,null,K.mode);return Ms.lanes=pe,Ms.return=K,Ms}finally{}}}var Sn=lh(!0),nh=lh(!1),$l=!1;function Bd(s){s.updateQueue={baseState:s.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function $d(s,t){s=s.updateQueue,t.updateQueue===s&&(t.updateQueue={baseState:s.baseState,firstBaseUpdate:s.firstBaseUpdate,lastBaseUpdate:s.lastBaseUpdate,shared:s.shared,callbacks:null})}function Il(s){return{lane:s,tag:0,payload:null,callback:null,next:null}}function Pl(s,t,a){var r=s.updateQueue;if(r===null)return null;if(r=r.shared,(Os&2)!==0){var o=r.pending;return o===null?t.next=t:(t.next=o.next,o.next=t),r.pending=t,t=fc(s),Hx(s,null,a),t}return hc(s,r,t,a),fc(s)}function ni(s,t,a){if(t=t.updateQueue,t!==null&&(t=t.shared,(a&4194048)!==0)){var r=t.lanes;r&=s.pendingLanes,a|=r,t.lanes=a,Jt(s,a)}}function Id(s,t){var a=s.updateQueue,r=s.alternate;if(r!==null&&(r=r.updateQueue,a===r)){var o=null,d=null;if(a=a.firstBaseUpdate,a!==null){do{var j={lane:a.lane,tag:a.tag,payload:a.payload,callback:null,next:null};d===null?o=d=j:d=d.next=j,a=a.next}while(a!==null);d===null?o=d=t:d=d.next=t}else o=d=t;a={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:d,shared:r.shared,callbacks:r.callbacks},s.updateQueue=a;return}s=a.lastBaseUpdate,s===null?a.firstBaseUpdate=t:s.next=t,a.lastBaseUpdate=t}var Pd=!1;function ri(){if(Pd){var s=ir;if(s!==null)throw s}}function ii(s,t,a,r){Pd=!1;var o=s.updateQueue;$l=!1;var d=o.firstBaseUpdate,j=o.lastBaseUpdate,_=o.shared.pending;if(_!==null){o.shared.pending=null;var O=_,te=O.next;O.next=null,j===null?d=te:j.next=te,j=O;var he=s.alternate;he!==null&&(he=he.updateQueue,_=he.lastBaseUpdate,_!==j&&(_===null?he.firstBaseUpdate=te:_.next=te,he.lastBaseUpdate=O))}if(d!==null){var Ne=o.baseState;j=0,he=te=O=null,_=d;do{var ne=_.lane&-536870913,ue=ne!==_.lane;if(ue?(Ss&ne)===ne:(r&ne)===ne){ne!==0&&ne===rr&&(Pd=!0),he!==null&&(he=he.next={lane:0,tag:_.tag,payload:_.payload,callback:null,next:null});e:{var Re=s,Ye=_;ne=t;var Vs=a;switch(Ye.tag){case 1:if(Re=Ye.payload,typeof Re=="function"){Ne=Re.call(Vs,Ne,ne);break e}Ne=Re;break e;case 3:Re.flags=Re.flags&-65537|128;case 0:if(Re=Ye.payload,ne=typeof Re=="function"?Re.call(Vs,Ne,ne):Re,ne==null)break e;Ne=v({},Ne,ne);break e;case 2:$l=!0}}ne=_.callback,ne!==null&&(s.flags|=64,ue&&(s.flags|=8192),ue=o.callbacks,ue===null?o.callbacks=[ne]:ue.push(ne))}else ue={lane:ne,tag:_.tag,payload:_.payload,callback:_.callback,next:null},he===null?(te=he=ue,O=Ne):he=he.next=ue,j|=ne;if(_=_.next,_===null){if(_=o.shared.pending,_===null)break;ue=_,_=ue.next,ue.next=null,o.lastBaseUpdate=ue,o.shared.pending=null}}while(!0);he===null&&(O=Ne),o.baseState=O,o.firstBaseUpdate=te,o.lastBaseUpdate=he,d===null&&(o.shared.lanes=0),Vl|=j,s.lanes=j,s.memoizedState=Ne}}function rh(s,t){if(typeof s!="function")throw Error(c(191,s));s.call(t)}function ih(s,t){var a=s.callbacks;if(a!==null)for(s.callbacks=null,s=0;sd?d:8;var j=z.T,_={};z.T=_,ru(s,!1,t,a);try{var O=o(),te=z.S;if(te!==null&&te(_,O),O!==null&&typeof O=="object"&&typeof O.then=="function"){var he=Hb(O,r);di(s,t,he,ya(s))}else di(s,t,r,ya(s))}catch(Ne){di(s,t,{then:function(){},status:"rejected",reason:Ne},ya())}finally{V.p=d,j!==null&&_.types!==null&&(j.types=_.types),z.T=j}}function Qb(){}function lu(s,t,a,r){if(s.tag!==5)throw Error(c(476));var o=$h(s).queue;Bh(s,o,t,U,a===null?Qb:function(){return Ih(s),a(r)})}function $h(s){var t=s.memoizedState;if(t!==null)return t;t={memoizedState:U,baseState:U,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:hl,lastRenderedState:U},next:null};var a={};return t.next={memoizedState:a,baseState:a,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:hl,lastRenderedState:a},next:null},s.memoizedState=t,s=s.alternate,s!==null&&(s.memoizedState=t),t}function Ih(s){var t=$h(s);t.next===null&&(t=s.alternate.memoizedState),di(s,t.next.queue,{},ya())}function nu(){return It(Ci)}function Ph(){return _t().memoizedState}function Hh(){return _t().memoizedState}function Yb(s){for(var t=s.return;t!==null;){switch(t.tag){case 24:case 3:var a=ya();s=Il(a);var r=Pl(t,s,a);r!==null&&(da(r,t,a),ni(r,t,a)),t={cache:Od()},s.payload=t;return}t=t.return}}function Jb(s,t,a){var r=ya();a={lane:r,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Oc(s)?Fh(t,a):(a=wd(s,t,a,r),a!==null&&(da(a,s,r),qh(a,t,r)))}function Gh(s,t,a){var r=ya();di(s,t,a,r)}function di(s,t,a,r){var o={lane:r,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null};if(Oc(s))Fh(t,o);else{var d=s.alternate;if(s.lanes===0&&(d===null||d.lanes===0)&&(d=t.lastRenderedReducer,d!==null))try{var j=t.lastRenderedState,_=d(j,a);if(o.hasEagerState=!0,o.eagerState=_,pa(_,j))return hc(s,t,o,0),Ys===null&&xc(),!1}catch{}finally{}if(a=wd(s,t,o,r),a!==null)return da(a,s,r),qh(a,t,r),!0}return!1}function ru(s,t,a,r){if(r={lane:2,revertLane:Bu(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Oc(s)){if(t)throw Error(c(479))}else t=wd(s,a,r,2),t!==null&&da(t,s,2)}function Oc(s){var t=s.alternate;return s===is||t!==null&&t===is}function Fh(s,t){ur=Cc=!0;var a=s.pending;a===null?t.next=t:(t.next=a.next,a.next=t),s.pending=t}function qh(s,t,a){if((a&4194048)!==0){var r=t.lanes;r&=s.pendingLanes,a|=r,t.lanes=a,Jt(s,a)}}var ui={readContext:It,use:Mc,useCallback:gt,useContext:gt,useEffect:gt,useImperativeHandle:gt,useLayoutEffect:gt,useInsertionEffect:gt,useMemo:gt,useReducer:gt,useRef:gt,useState:gt,useDebugValue:gt,useDeferredValue:gt,useTransition:gt,useSyncExternalStore:gt,useId:gt,useHostTransitionStatus:gt,useFormState:gt,useActionState:gt,useOptimistic:gt,useMemoCache:gt,useCacheRefresh:gt};ui.useEffectEvent=gt;var Vh={readContext:It,use:Mc,useCallback:function(s,t){return Zt().memoizedState=[s,t===void 0?null:t],s},useContext:It,useEffect:Eh,useImperativeHandle:function(s,t,a){a=a!=null?a.concat([s]):null,zc(4194308,4,Dh.bind(null,t,s),a)},useLayoutEffect:function(s,t){return zc(4194308,4,s,t)},useInsertionEffect:function(s,t){zc(4,2,s,t)},useMemo:function(s,t){var a=Zt();t=t===void 0?null:t;var r=s();if(kn){Ze(!0);try{s()}finally{Ze(!1)}}return a.memoizedState=[r,t],r},useReducer:function(s,t,a){var r=Zt();if(a!==void 0){var o=a(t);if(kn){Ze(!0);try{a(t)}finally{Ze(!1)}}}else o=t;return r.memoizedState=r.baseState=o,s={pending:null,lanes:0,dispatch:null,lastRenderedReducer:s,lastRenderedState:o},r.queue=s,s=s.dispatch=Jb.bind(null,is,s),[r.memoizedState,s]},useRef:function(s){var t=Zt();return s={current:s},t.memoizedState=s},useState:function(s){s=Wd(s);var t=s.queue,a=Gh.bind(null,is,t);return t.dispatch=a,[s.memoizedState,a]},useDebugValue:tu,useDeferredValue:function(s,t){var a=Zt();return au(a,s,t)},useTransition:function(){var s=Wd(!1);return s=Bh.bind(null,is,s.queue,!0,!1),Zt().memoizedState=s,[!1,s]},useSyncExternalStore:function(s,t,a){var r=is,o=Zt();if(Ts){if(a===void 0)throw Error(c(407));a=a()}else{if(a=t(),Ys===null)throw Error(c(349));(Ss&127)!==0||xh(r,t,a)}o.memoizedState=a;var d={value:a,getSnapshot:t};return o.queue=d,Eh(fh.bind(null,r,d,s),[s]),r.flags|=2048,xr(9,{destroy:void 0},hh.bind(null,r,d,a,t),null),a},useId:function(){var s=Zt(),t=Ys.identifierPrefix;if(Ts){var a=Xa,r=Ja;a=(r&~(1<<32-js(r)-1)).toString(32)+a,t="_"+t+"R_"+a,a=Tc++,0<\/script>",d=d.removeChild(d.firstChild);break;case"select":d=typeof r.is=="string"?j.createElement("select",{is:r.is}):j.createElement("select"),r.multiple?d.multiple=!0:r.size&&(d.size=r.size);break;default:d=typeof r.is=="string"?j.createElement(o,{is:r.is}):j.createElement(o)}}d[Ds]=t,d[pt]=r;e:for(j=t.child;j!==null;){if(j.tag===5||j.tag===6)d.appendChild(j.stateNode);else if(j.tag!==4&&j.tag!==27&&j.child!==null){j.child.return=j,j=j.child;continue}if(j===t)break e;for(;j.sibling===null;){if(j.return===null||j.return===t)break e;j=j.return}j.sibling.return=j.return,j=j.sibling}t.stateNode=d;e:switch(Ht(d,o,r),o){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}r&&pl(t)}}return lt(t),Nu(t,t.type,s===null?null:s.memoizedProps,t.pendingProps,a),null;case 6:if(s&&t.stateNode!=null)s.memoizedProps!==r&&pl(t);else{if(typeof r!="string"&&t.stateNode===null)throw Error(c(166));if(s=Z.current,lr(t)){if(s=t.stateNode,a=t.memoizedProps,r=null,o=$t,o!==null)switch(o.tag){case 27:case 5:r=o.memoizedProps}s[Ds]=t,s=!!(s.nodeValue===a||r!==null&&r.suppressHydrationWarning===!0||mp(s.nodeValue,a)),s||Ul(t,!0)}else s=eo(s).createTextNode(r),s[Ds]=t,t.stateNode=s}return lt(t),null;case 31:if(a=t.memoizedState,s===null||s.memoizedState!==null){if(r=lr(t),a!==null){if(s===null){if(!r)throw Error(c(318));if(s=t.memoizedState,s=s!==null?s.dehydrated:null,!s)throw Error(c(557));s[Ds]=t}else vn(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;lt(t),s=!1}else a=Md(),s!==null&&s.memoizedState!==null&&(s.memoizedState.hydrationErrors=a),s=!0;if(!s)return t.flags&256?(va(t),t):(va(t),null);if((t.flags&128)!==0)throw Error(c(558))}return lt(t),null;case 13:if(r=t.memoizedState,s===null||s.memoizedState!==null&&s.memoizedState.dehydrated!==null){if(o=lr(t),r!==null&&r.dehydrated!==null){if(s===null){if(!o)throw Error(c(318));if(o=t.memoizedState,o=o!==null?o.dehydrated:null,!o)throw Error(c(317));o[Ds]=t}else vn(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;lt(t),o=!1}else o=Md(),s!==null&&s.memoizedState!==null&&(s.memoizedState.hydrationErrors=o),o=!0;if(!o)return t.flags&256?(va(t),t):(va(t),null)}return va(t),(t.flags&128)!==0?(t.lanes=a,t):(a=r!==null,s=s!==null&&s.memoizedState!==null,a&&(r=t.child,o=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(o=r.alternate.memoizedState.cachePool.pool),d=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(d=r.memoizedState.cachePool.pool),d!==o&&(r.flags|=2048)),a!==s&&a&&(t.child.flags|=8192),$c(t,t.updateQueue),lt(t),null);case 4:return J(),s===null&&Hu(t.stateNode.containerInfo),lt(t),null;case 10:return ml(t.type),lt(t),null;case 19:if(je(wt),r=t.memoizedState,r===null)return lt(t),null;if(o=(t.flags&128)!==0,d=r.rendering,d===null)if(o)xi(r,!1);else{if(jt!==0||s!==null&&(s.flags&128)!==0)for(s=t.child;s!==null;){if(d=kc(s),d!==null){for(t.flags|=128,xi(r,!1),s=d.updateQueue,t.updateQueue=s,$c(t,s),t.subtreeFlags=0,s=a,a=t.child;a!==null;)Gx(a,s),a=a.sibling;return Se(wt,wt.current&1|2),Ts&&dl(t,r.treeForkCount),t.child}s=s.sibling}r.tail!==null&&st()>Fc&&(t.flags|=128,o=!0,xi(r,!1),t.lanes=4194304)}else{if(!o)if(s=kc(d),s!==null){if(t.flags|=128,o=!0,s=s.updateQueue,t.updateQueue=s,$c(t,s),xi(r,!0),r.tail===null&&r.tailMode==="hidden"&&!d.alternate&&!Ts)return lt(t),null}else 2*st()-r.renderingStartTime>Fc&&a!==536870912&&(t.flags|=128,o=!0,xi(r,!1),t.lanes=4194304);r.isBackwards?(d.sibling=t.child,t.child=d):(s=r.last,s!==null?s.sibling=d:t.child=d,r.last=d)}return r.tail!==null?(s=r.tail,r.rendering=s,r.tail=s.sibling,r.renderingStartTime=st(),s.sibling=null,a=wt.current,Se(wt,o?a&1|2:a&1),Ts&&dl(t,r.treeForkCount),s):(lt(t),null);case 22:case 23:return va(t),Gd(),r=t.memoizedState!==null,s!==null?s.memoizedState!==null!==r&&(t.flags|=8192):r&&(t.flags|=8192),r?(a&536870912)!==0&&(t.flags&128)===0&&(lt(t),t.subtreeFlags&6&&(t.flags|=8192)):lt(t),a=t.updateQueue,a!==null&&$c(t,a.retryQueue),a=null,s!==null&&s.memoizedState!==null&&s.memoizedState.cachePool!==null&&(a=s.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==a&&(t.flags|=2048),s!==null&&je(yn),null;case 24:return a=null,s!==null&&(a=s.memoizedState.cache),t.memoizedState.cache!==a&&(t.flags|=2048),ml(Et),lt(t),null;case 25:return null;case 30:return null}throw Error(c(156,t.tag))}function sy(s,t){switch(Td(t),t.tag){case 1:return s=t.flags,s&65536?(t.flags=s&-65537|128,t):null;case 3:return ml(Et),J(),s=t.flags,(s&65536)!==0&&(s&128)===0?(t.flags=s&-65537|128,t):null;case 26:case 27:case 5:return Fe(t),null;case 31:if(t.memoizedState!==null){if(va(t),t.alternate===null)throw Error(c(340));vn()}return s=t.flags,s&65536?(t.flags=s&-65537|128,t):null;case 13:if(va(t),s=t.memoizedState,s!==null&&s.dehydrated!==null){if(t.alternate===null)throw Error(c(340));vn()}return s=t.flags,s&65536?(t.flags=s&-65537|128,t):null;case 19:return je(wt),null;case 4:return J(),null;case 10:return ml(t.type),null;case 22:case 23:return va(t),Gd(),s!==null&&je(yn),s=t.flags,s&65536?(t.flags=s&-65537|128,t):null;case 24:return ml(Et),null;case 25:return null;default:return null}}function gf(s,t){switch(Td(t),t.tag){case 3:ml(Et),J();break;case 26:case 27:case 5:Fe(t);break;case 4:J();break;case 31:t.memoizedState!==null&&va(t);break;case 13:va(t);break;case 19:je(wt);break;case 10:ml(t.type);break;case 22:case 23:va(t),Gd(),s!==null&&je(yn);break;case 24:ml(Et)}}function hi(s,t){try{var a=t.updateQueue,r=a!==null?a.lastEffect:null;if(r!==null){var o=r.next;a=o;do{if((a.tag&s)===s){r=void 0;var d=a.create,j=a.inst;r=d(),j.destroy=r}a=a.next}while(a!==o)}}catch(_){$s(t,t.return,_)}}function Fl(s,t,a){try{var r=t.updateQueue,o=r!==null?r.lastEffect:null;if(o!==null){var d=o.next;r=d;do{if((r.tag&s)===s){var j=r.inst,_=j.destroy;if(_!==void 0){j.destroy=void 0,o=t;var O=a,te=_;try{te()}catch(he){$s(o,O,he)}}}r=r.next}while(r!==d)}}catch(he){$s(t,t.return,he)}}function jf(s){var t=s.updateQueue;if(t!==null){var a=s.stateNode;try{ih(t,a)}catch(r){$s(s,s.return,r)}}}function vf(s,t,a){a.props=Cn(s.type,s.memoizedProps),a.state=s.memoizedState;try{a.componentWillUnmount()}catch(r){$s(s,t,r)}}function fi(s,t){try{var a=s.ref;if(a!==null){switch(s.tag){case 26:case 27:case 5:var r=s.stateNode;break;case 30:r=s.stateNode;break;default:r=s.stateNode}typeof a=="function"?s.refCleanup=a(r):a.current=r}}catch(o){$s(s,t,o)}}function Za(s,t){var a=s.ref,r=s.refCleanup;if(a!==null)if(typeof r=="function")try{r()}catch(o){$s(s,t,o)}finally{s.refCleanup=null,s=s.alternate,s!=null&&(s.refCleanup=null)}else if(typeof a=="function")try{a(null)}catch(o){$s(s,t,o)}else a.current=null}function Nf(s){var t=s.type,a=s.memoizedProps,r=s.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":a.autoFocus&&r.focus();break e;case"img":a.src?r.src=a.src:a.srcSet&&(r.srcset=a.srcSet)}}catch(o){$s(s,s.return,o)}}function bu(s,t,a){try{var r=s.stateNode;wy(r,s.type,a,t),r[pt]=t}catch(o){$s(s,s.return,o)}}function bf(s){return s.tag===5||s.tag===3||s.tag===26||s.tag===27&&Xl(s.type)||s.tag===4}function yu(s){e:for(;;){for(;s.sibling===null;){if(s.return===null||bf(s.return))return null;s=s.return}for(s.sibling.return=s.return,s=s.sibling;s.tag!==5&&s.tag!==6&&s.tag!==18;){if(s.tag===27&&Xl(s.type)||s.flags&2||s.child===null||s.tag===4)continue e;s.child.return=s,s=s.child}if(!(s.flags&2))return s.stateNode}}function wu(s,t,a){var r=s.tag;if(r===5||r===6)s=s.stateNode,t?(a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a).insertBefore(s,t):(t=a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a,t.appendChild(s),a=a._reactRootContainer,a!=null||t.onclick!==null||(t.onclick=il));else if(r!==4&&(r===27&&Xl(s.type)&&(a=s.stateNode,t=null),s=s.child,s!==null))for(wu(s,t,a),s=s.sibling;s!==null;)wu(s,t,a),s=s.sibling}function Ic(s,t,a){var r=s.tag;if(r===5||r===6)s=s.stateNode,t?a.insertBefore(s,t):a.appendChild(s);else if(r!==4&&(r===27&&Xl(s.type)&&(a=s.stateNode),s=s.child,s!==null))for(Ic(s,t,a),s=s.sibling;s!==null;)Ic(s,t,a),s=s.sibling}function yf(s){var t=s.stateNode,a=s.memoizedProps;try{for(var r=s.type,o=t.attributes;o.length;)t.removeAttributeNode(o[0]);Ht(t,r,a),t[Ds]=s,t[pt]=a}catch(d){$s(s,s.return,d)}}var gl=!1,zt=!1,_u=!1,wf=typeof WeakSet=="function"?WeakSet:Set,Lt=null;function ty(s,t){if(s=s.containerInfo,qu=io,s=Ox(s),gd(s)){if("selectionStart"in s)var a={start:s.selectionStart,end:s.selectionEnd};else e:{a=(a=s.ownerDocument)&&a.defaultView||window;var r=a.getSelection&&a.getSelection();if(r&&r.rangeCount!==0){a=r.anchorNode;var o=r.anchorOffset,d=r.focusNode;r=r.focusOffset;try{a.nodeType,d.nodeType}catch{a=null;break e}var j=0,_=-1,O=-1,te=0,he=0,Ne=s,ne=null;s:for(;;){for(var ue;Ne!==a||o!==0&&Ne.nodeType!==3||(_=j+o),Ne!==d||r!==0&&Ne.nodeType!==3||(O=j+r),Ne.nodeType===3&&(j+=Ne.nodeValue.length),(ue=Ne.firstChild)!==null;)ne=Ne,Ne=ue;for(;;){if(Ne===s)break s;if(ne===a&&++te===o&&(_=j),ne===d&&++he===r&&(O=j),(ue=Ne.nextSibling)!==null)break;Ne=ne,ne=Ne.parentNode}Ne=ue}a=_===-1||O===-1?null:{start:_,end:O}}else a=null}a=a||{start:0,end:0}}else a=null;for(Vu={focusedElem:s,selectionRange:a},io=!1,Lt=t;Lt!==null;)if(t=Lt,s=t.child,(t.subtreeFlags&1028)!==0&&s!==null)s.return=t,Lt=s;else for(;Lt!==null;){switch(t=Lt,d=t.alternate,s=t.flags,t.tag){case 0:if((s&4)!==0&&(s=t.updateQueue,s=s!==null?s.events:null,s!==null))for(a=0;a title"))),Ht(d,r,a),d[Ds]=s,Rt(d),r=d;break e;case"link":var j=Ep("link","href",o).get(r+(a.href||""));if(j){for(var _=0;_Vs&&(j=Vs,Vs=Ye,Ye=j);var K=zx(_,Ye),H=zx(_,Vs);if(K&&H&&(ue.rangeCount!==1||ue.anchorNode!==K.node||ue.anchorOffset!==K.offset||ue.focusNode!==H.node||ue.focusOffset!==H.offset)){var se=Ne.createRange();se.setStart(K.node,K.offset),ue.removeAllRanges(),Ye>Vs?(ue.addRange(se),ue.extend(H.node,H.offset)):(se.setEnd(H.node,H.offset),ue.addRange(se))}}}}for(Ne=[],ue=_;ue=ue.parentNode;)ue.nodeType===1&&Ne.push({element:ue,left:ue.scrollLeft,top:ue.scrollTop});for(typeof _.focus=="function"&&_.focus(),_=0;_a?32:a,z.T=null,a=Au,Au=null;var d=Ql,j=yl;if(Dt=0,jr=Ql=null,yl=0,(Os&6)!==0)throw Error(c(331));var _=Os;if(Os|=4,Of(d.current),Af(d,d.current,j,a),Os=_,bi(0,!1),ts&&typeof ts.onPostCommitFiberRoot=="function")try{ts.onPostCommitFiberRoot(gs,d)}catch{}return!0}finally{V.p=o,z.T=r,Zf(s,t)}}function ep(s,t,a){t=Aa(a,t),t=du(s.stateNode,t,2),s=Pl(s,t,2),s!==null&&(Ce(s,2),Wa(s))}function $s(s,t,a){if(s.tag===3)ep(s,s,a);else for(;t!==null;){if(t.tag===3){ep(t,s,a);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof r.componentDidCatch=="function"&&(Kl===null||!Kl.has(r))){s=Aa(a,s),a=ef(2),r=Pl(t,a,2),r!==null&&(sf(a,r,t,s),Ce(r,2),Wa(r));break}}t=t.return}}function Ru(s,t,a){var r=s.pingCache;if(r===null){r=s.pingCache=new ny;var o=new Set;r.set(t,o)}else o=r.get(t),o===void 0&&(o=new Set,r.set(t,o));o.has(a)||(Cu=!0,o.add(a),s=dy.bind(null,s,t,a),t.then(s,s))}function dy(s,t,a){var r=s.pingCache;r!==null&&r.delete(t),s.pingedLanes|=s.suspendedLanes&a,s.warmLanes&=~a,Ys===s&&(Ss&a)===a&&(jt===4||jt===3&&(Ss&62914560)===Ss&&300>st()-Gc?(Os&2)===0&&vr(s,0):Tu|=a,gr===Ss&&(gr=0)),Wa(s)}function sp(s,t){t===0&&(t=X()),s=gn(s,t),s!==null&&(Ce(s,t),Wa(s))}function uy(s){var t=s.memoizedState,a=0;t!==null&&(a=t.retryLane),sp(s,a)}function my(s,t){var a=0;switch(s.tag){case 31:case 13:var r=s.stateNode,o=s.memoizedState;o!==null&&(a=o.retryLane);break;case 19:r=s.stateNode;break;case 22:r=s.stateNode._retryCache;break;default:throw Error(c(314))}r!==null&&r.delete(t),sp(s,a)}function xy(s,t){return Kt(s,t)}var Jc=null,br=null,Lu=!1,Xc=!1,Uu=!1,Jl=0;function Wa(s){s!==br&&s.next===null&&(br===null?Jc=br=s:br=br.next=s),Xc=!0,Lu||(Lu=!0,fy())}function bi(s,t){if(!Uu&&Xc){Uu=!0;do for(var a=!1,r=Jc;r!==null;){if(s!==0){var o=r.pendingLanes;if(o===0)var d=0;else{var j=r.suspendedLanes,_=r.pingedLanes;d=(1<<31-js(42|s)+1)-1,d&=o&~(j&~_),d=d&201326741?d&201326741|1:d?d|2:0}d!==0&&(a=!0,np(r,d))}else d=Ss,d=Ya(r,r===Ys?d:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),(d&3)===0||nl(r,d)||(a=!0,np(r,d));r=r.next}while(a);Uu=!1}}function hy(){tp()}function tp(){Xc=Lu=!1;var s=0;Jl!==0&&Sy()&&(s=Jl);for(var t=st(),a=null,r=Jc;r!==null;){var o=r.next,d=ap(r,t);d===0?(r.next=null,a===null?Jc=o:a.next=o,o===null&&(br=a)):(a=r,(s!==0||(d&3)!==0)&&(Xc=!0)),r=o}Dt!==0&&Dt!==5||bi(s),Jl!==0&&(Jl=0)}function ap(s,t){for(var a=s.suspendedLanes,r=s.pingedLanes,o=s.expirationTimes,d=s.pendingLanes&-62914561;0_)break;var he=O.transferSize,Ne=O.initiatorType;he&&xp(Ne)&&(O=O.responseEnd,j+=he*(O<_?1:(_-te)/(O-te)))}if(--r,t+=8*(d+j)/(o.duration/1e3),s++,10"u"?null:document;function Sp(s,t,a){var r=yr;if(r&&typeof t=="string"&&t){var o=Ea(t);o='link[rel="'+s+'"][href="'+o+'"]',typeof a=="string"&&(o+='[crossorigin="'+a+'"]'),_p.has(o)||(_p.add(o),s={rel:s,crossOrigin:a,href:t},r.querySelector(o)===null&&(t=r.createElement("link"),Ht(t,"link",s),Rt(t),r.head.appendChild(t)))}}function Oy(s){wl.D(s),Sp("dns-prefetch",s,null)}function Ry(s,t){wl.C(s,t),Sp("preconnect",s,t)}function Ly(s,t,a){wl.L(s,t,a);var r=yr;if(r&&s&&t){var o='link[rel="preload"][as="'+Ea(t)+'"]';t==="image"&&a&&a.imageSrcSet?(o+='[imagesrcset="'+Ea(a.imageSrcSet)+'"]',typeof a.imageSizes=="string"&&(o+='[imagesizes="'+Ea(a.imageSizes)+'"]')):o+='[href="'+Ea(s)+'"]';var d=o;switch(t){case"style":d=wr(s);break;case"script":d=_r(s)}Ua.has(d)||(s=v({rel:"preload",href:t==="image"&&a&&a.imageSrcSet?void 0:s,as:t},a),Ua.set(d,s),r.querySelector(o)!==null||t==="style"&&r.querySelector(Si(d))||t==="script"&&r.querySelector(ki(d))||(t=r.createElement("link"),Ht(t,"link",s),Rt(t),r.head.appendChild(t)))}}function Uy(s,t){wl.m(s,t);var a=yr;if(a&&s){var r=t&&typeof t.as=="string"?t.as:"script",o='link[rel="modulepreload"][as="'+Ea(r)+'"][href="'+Ea(s)+'"]',d=o;switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":d=_r(s)}if(!Ua.has(d)&&(s=v({rel:"modulepreload",href:s},t),Ua.set(d,s),a.querySelector(o)===null)){switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(a.querySelector(ki(d)))return}r=a.createElement("link"),Ht(r,"link",s),Rt(r),a.head.appendChild(r)}}}function By(s,t,a){wl.S(s,t,a);var r=yr;if(r&&s){var o=qn(r).hoistableStyles,d=wr(s);t=t||"default";var j=o.get(d);if(!j){var _={loading:0,preload:null};if(j=r.querySelector(Si(d)))_.loading=5;else{s=v({rel:"stylesheet",href:s,"data-precedence":t},a),(a=Ua.get(d))&&Wu(s,a);var O=j=r.createElement("link");Rt(O),Ht(O,"link",s),O._p=new Promise(function(te,he){O.onload=te,O.onerror=he}),O.addEventListener("load",function(){_.loading|=1}),O.addEventListener("error",function(){_.loading|=2}),_.loading|=4,to(j,t,r)}j={type:"stylesheet",instance:j,count:1,state:_},o.set(d,j)}}}function $y(s,t){wl.X(s,t);var a=yr;if(a&&s){var r=qn(a).hoistableScripts,o=_r(s),d=r.get(o);d||(d=a.querySelector(ki(o)),d||(s=v({src:s,async:!0},t),(t=Ua.get(o))&&em(s,t),d=a.createElement("script"),Rt(d),Ht(d,"link",s),a.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},r.set(o,d))}}function Iy(s,t){wl.M(s,t);var a=yr;if(a&&s){var r=qn(a).hoistableScripts,o=_r(s),d=r.get(o);d||(d=a.querySelector(ki(o)),d||(s=v({src:s,async:!0,type:"module"},t),(t=Ua.get(o))&&em(s,t),d=a.createElement("script"),Rt(d),Ht(d,"link",s),a.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},r.set(o,d))}}function kp(s,t,a,r){var o=(o=Z.current)?so(o):null;if(!o)throw Error(c(446));switch(s){case"meta":case"title":return null;case"style":return typeof a.precedence=="string"&&typeof a.href=="string"?(t=wr(a.href),a=qn(o).hoistableStyles,r=a.get(t),r||(r={type:"style",instance:null,count:0,state:null},a.set(t,r)),r):{type:"void",instance:null,count:0,state:null};case"link":if(a.rel==="stylesheet"&&typeof a.href=="string"&&typeof a.precedence=="string"){s=wr(a.href);var d=qn(o).hoistableStyles,j=d.get(s);if(j||(o=o.ownerDocument||o,j={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},d.set(s,j),(d=o.querySelector(Si(s)))&&!d._p&&(j.instance=d,j.state.loading=5),Ua.has(s)||(a={rel:"preload",as:"style",href:a.href,crossOrigin:a.crossOrigin,integrity:a.integrity,media:a.media,hrefLang:a.hrefLang,referrerPolicy:a.referrerPolicy},Ua.set(s,a),d||Py(o,s,a,j.state))),t&&r===null)throw Error(c(528,""));return j}if(t&&r!==null)throw Error(c(529,""));return null;case"script":return t=a.async,a=a.src,typeof a=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=_r(a),a=qn(o).hoistableScripts,r=a.get(t),r||(r={type:"script",instance:null,count:0,state:null},a.set(t,r)),r):{type:"void",instance:null,count:0,state:null};default:throw Error(c(444,s))}}function wr(s){return'href="'+Ea(s)+'"'}function Si(s){return'link[rel="stylesheet"]['+s+"]"}function Cp(s){return v({},s,{"data-precedence":s.precedence,precedence:null})}function Py(s,t,a,r){s.querySelector('link[rel="preload"][as="style"]['+t+"]")?r.loading=1:(t=s.createElement("link"),r.preload=t,t.addEventListener("load",function(){return r.loading|=1}),t.addEventListener("error",function(){return r.loading|=2}),Ht(t,"link",a),Rt(t),s.head.appendChild(t))}function _r(s){return'[src="'+Ea(s)+'"]'}function ki(s){return"script[async]"+s}function Tp(s,t,a){if(t.count++,t.instance===null)switch(t.type){case"style":var r=s.querySelector('style[data-href~="'+Ea(a.href)+'"]');if(r)return t.instance=r,Rt(r),r;var o=v({},a,{"data-href":a.href,"data-precedence":a.precedence,href:null,precedence:null});return r=(s.ownerDocument||s).createElement("style"),Rt(r),Ht(r,"style",o),to(r,a.precedence,s),t.instance=r;case"stylesheet":o=wr(a.href);var d=s.querySelector(Si(o));if(d)return t.state.loading|=4,t.instance=d,Rt(d),d;r=Cp(a),(o=Ua.get(o))&&Wu(r,o),d=(s.ownerDocument||s).createElement("link"),Rt(d);var j=d;return j._p=new Promise(function(_,O){j.onload=_,j.onerror=O}),Ht(d,"link",r),t.state.loading|=4,to(d,a.precedence,s),t.instance=d;case"script":return d=_r(a.src),(o=s.querySelector(ki(d)))?(t.instance=o,Rt(o),o):(r=a,(o=Ua.get(d))&&(r=v({},a),em(r,o)),s=s.ownerDocument||s,o=s.createElement("script"),Rt(o),Ht(o,"link",r),s.head.appendChild(o),t.instance=o);case"void":return null;default:throw Error(c(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(r=t.instance,t.state.loading|=4,to(r,a.precedence,s));return t.instance}function to(s,t,a){for(var r=a.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),o=r.length?r[r.length-1]:null,d=o,j=0;j title"):null)}function Hy(s,t,a){if(a===1||t.itemProp!=null)return!1;switch(s){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return s=t.disabled,typeof t.precedence=="string"&&s==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function Ap(s){return!(s.type==="stylesheet"&&(s.state.loading&3)===0)}function Gy(s,t,a,r){if(a.type==="stylesheet"&&(typeof r.media!="string"||matchMedia(r.media).matches!==!1)&&(a.state.loading&4)===0){if(a.instance===null){var o=wr(r.href),d=t.querySelector(Si(o));if(d){t=d._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(s.count++,s=lo.bind(s),t.then(s,s)),a.state.loading|=4,a.instance=d,Rt(d);return}d=t.ownerDocument||t,r=Cp(r),(o=Ua.get(o))&&Wu(r,o),d=d.createElement("link"),Rt(d);var j=d;j._p=new Promise(function(_,O){j.onload=_,j.onerror=O}),Ht(d,"link",r),a.instance=d}s.stylesheets===null&&(s.stylesheets=new Map),s.stylesheets.set(a,t),(t=a.state.preload)&&(a.state.loading&3)===0&&(s.count++,a=lo.bind(s),t.addEventListener("load",a),t.addEventListener("error",a))}}var sm=0;function Fy(s,t){return s.stylesheets&&s.count===0&&ro(s,s.stylesheets),0sm?50:800)+t);return s.unsuspend=a,function(){s.unsuspend=null,clearTimeout(r),clearTimeout(o)}}:null}function lo(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)ro(this,this.stylesheets);else if(this.unsuspend){var s=this.unsuspend;this.unsuspend=null,s()}}}var no=null;function ro(s,t){s.stylesheets=null,s.unsuspend!==null&&(s.count++,no=new Map,t.forEach(qy,s),no=null,lo.call(s))}function qy(s,t){if(!(t.state.loading&4)){var a=no.get(s);if(a)var r=a.get(null);else{a=new Map,no.set(s,a);for(var o=s.querySelectorAll("link[data-precedence],style[data-precedence]"),d=0;d"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(l)}catch(n){console.error(n)}}return l(),mm.exports=z1(),mm.exports}var O1=D1();function B(...l){return u0(m0(l))}const De=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("rounded-xl border bg-card text-card-foreground shadow",l),...n}));De.displayName="Card";const Xe=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("flex flex-col space-y-1.5 p-6",l),...n}));Xe.displayName="CardHeader";const We=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("font-semibold leading-none tracking-tight",l),...n}));We.displayName="CardTitle";const Is=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("text-sm text-muted-foreground",l),...n}));Is.displayName="CardDescription";const Qe=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("p-6 pt-0",l),...n}));Qe.displayName="CardContent";const Io=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("flex items-center p-6 pt-0",l),...n}));Io.displayName="CardFooter";const ma=h0,ta=m.forwardRef(({className:l,...n},i)=>e.jsx(yg,{ref:i,className:B("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",l),...n}));ta.displayName=yg.displayName;const as=m.forwardRef(({className:l,...n},i)=>e.jsx(wg,{ref:i,className:B("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",l),...n}));as.displayName=wg.displayName;const ys=m.forwardRef(({className:l,...n},i)=>e.jsx(_g,{ref:i,className:B("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 data-[state=active]:animate-in data-[state=active]:fade-in data-[state=active]:duration-300",l),...n}));ys.displayName=_g.displayName;const es=m.forwardRef(({className:l,children:n,viewportRef:i,...c},u)=>e.jsxs(Sg,{ref:u,className:B("relative overflow-hidden",l),...c,children:[e.jsx(f0,{ref:i,className:"h-full w-full rounded-[inherit]",children:n}),e.jsx(Em,{}),e.jsx(Em,{orientation:"horizontal"}),e.jsx(p0,{})]}));es.displayName=Sg.displayName;const Em=m.forwardRef(({className:l,orientation:n="vertical",...i},c)=>e.jsx(kg,{ref:c,orientation:n,className:B("flex touch-none select-none transition-colors",n==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",n==="horizontal"&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",l),...i,children:e.jsx(g0,{className:"relative flex-1 rounded-full bg-border"})}));Em.displayName=kg.displayName;function Js({className:l,...n}){return e.jsx("div",{className:B("animate-pulse rounded-md bg-primary/10",l),...n})}const Bn=m.forwardRef(({className:l,value:n,...i},c)=>e.jsx(Cg,{ref:c,className:B("relative h-2 w-full overflow-hidden rounded-full bg-primary/20",l),...i,children:e.jsx(j0,{className:"h-full w-full flex-1 bg-primary transition-all",style:{transform:`translateX(-${100-(n||0)}%)`}})}));Bn.displayName=Cg.displayName;async function we(l,n){const c=n?.body instanceof FormData?{...n?.headers}:{"Content-Type":"application/json",...n?.headers},u={...n,credentials:"include",headers:c},x=await fetch(l,u);if(x.status===401)throw window.location.href="/auth",new Error("认证失败,请重新登录");return x}function Us(){return{"Content-Type":"application/json"}}async function R1(){try{await fetch("/api/webui/auth/logout",{method:"POST",credentials:"include"})}catch(l){console.error("登出请求失败:",l)}window.location.href="/auth"}async function Fi(){try{return(await(await fetch("/api/webui/auth/check",{method:"GET",credentials:"include"})).json()).authenticated===!0}catch{return!1}}const L1={light:"",dark:".dark"},Ij=m.createContext(null);function Pj(){const l=m.useContext(Ij);if(!l)throw new Error("useChart must be used within a ");return l}const Tr=m.forwardRef(({id:l,className:n,children:i,config:c,...u},x)=>{const h=m.useId(),f=`chart-${l||h.replace(/:/g,"")}`;return e.jsx(Ij.Provider,{value:{config:c},children:e.jsxs("div",{"data-chart":f,ref:x,className:B("flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",n),...u,children:[e.jsx(U1,{id:f,config:c}),e.jsx(J0,{children:i})]})})});Tr.displayName="Chart";const U1=({id:l,config:n})=>{const i=Object.entries(n).filter(([,c])=>c.theme||c.color);return i.length?e.jsx("style",{dangerouslySetInnerHTML:{__html:Object.entries(L1).map(([c,u])=>` +${u} [data-chart=${l}] { +${i.map(([x,h])=>{const f=h.theme?.[c]||h.color;return f?` --color-${x}: ${f};`:null}).join(` +`)} +} +`).join(` +`)}}):null},Di=X0,Er=m.forwardRef(({active:l,payload:n,className:i,indicator:c="dot",hideLabel:u=!1,hideIndicator:x=!1,label:h,labelFormatter:f,labelClassName:p,formatter:g,color:N,nameKey:v,labelKey:b},w)=>{const{config:y}=Pj(),R=m.useMemo(()=>{if(u||!n?.length)return null;const[k]=n,I=`${b||k?.dataKey||k?.name||"value"}`,M=Mm(y,k,I),S=!b&&typeof h=="string"?y[h]?.label||h:M?.label;return f?e.jsx("div",{className:B("font-medium",p),children:f(S,n)}):S?e.jsx("div",{className:B("font-medium",p),children:S}):null},[h,f,n,u,p,y,b]);if(!l||!n?.length)return null;const D=n.length===1&&c!=="dot";return e.jsxs("div",{ref:w,className:B("grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",i),children:[D?null:R,e.jsx("div",{className:"grid gap-1.5",children:n.filter(k=>k.type!=="none").map((k,I)=>{const M=`${v||k.name||k.dataKey||"value"}`,S=Mm(y,k,M),T=N||k.payload.fill||k.color;return e.jsx("div",{className:B("flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",c==="dot"&&"items-center"),children:g&&k?.value!==void 0&&k.name?g(k.value,k.name,k,I,k.payload):e.jsxs(e.Fragment,{children:[S?.icon?e.jsx(S.icon,{}):!x&&e.jsx("div",{className:B("shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",{"h-2.5 w-2.5":c==="dot","w-1":c==="line","w-0 border-[1.5px] border-dashed bg-transparent":c==="dashed","my-0.5":D&&c==="dashed"}),style:{"--color-bg":T,"--color-border":T}}),e.jsxs("div",{className:B("flex flex-1 justify-between leading-none",D?"items-end":"items-center"),children:[e.jsxs("div",{className:"grid gap-1.5",children:[D?R:null,e.jsx("span",{className:"text-muted-foreground",children:S?.label||k.name})]}),k.value&&e.jsx("span",{className:"font-mono font-medium tabular-nums text-foreground",children:k.value.toLocaleString()})]})]})},k.dataKey)})})]})});Er.displayName="ChartTooltip";const B1=Z0,Hj=m.forwardRef(({className:l,hideIcon:n=!1,payload:i,verticalAlign:c="bottom",nameKey:u},x)=>{const{config:h}=Pj();return i?.length?e.jsx("div",{ref:x,className:B("flex items-center justify-center gap-4",c==="top"?"pb-3":"pt-3",l),children:i.filter(f=>f.type!=="none").map(f=>{const p=`${u||f.dataKey||"value"}`,g=Mm(h,f,p);return e.jsxs("div",{className:B("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"),children:[g?.icon&&!n?e.jsx(g.icon,{}):e.jsx("div",{className:"h-2 w-2 shrink-0 rounded-[2px]",style:{backgroundColor:f.color}}),g?.label]},f.value)})}):null});Hj.displayName="ChartLegend";function Mm(l,n,i){if(typeof n!="object"||n===null)return;const c="payload"in n&&typeof n.payload=="object"&&n.payload!==null?n.payload:void 0;let u=i;return i in n&&typeof n[i]=="string"?u=n[i]:c&&i in c&&typeof c[i]=="string"&&(u=c[i]),u in l?l[u]:l[i]}const Rr=Lr("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground shadow hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",outline:"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-md px-3 text-xs",lg:"h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),C=m.forwardRef(({className:l,variant:n,size:i,asChild:c=!1,...u},x)=>{const h=c?lw:"button";return e.jsx(h,{className:B(Rr({variant:n,size:i,className:l})),ref:x,...u})});C.displayName="Button";const $1=Lr("inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",outline:"text-foreground"}},defaultVariants:{variant:"default"}});function Ae({className:l,variant:n,...i}){return e.jsx("div",{className:B($1({variant:n}),l),...i})}async function I1(){const l=await we("/api/webui/system/restart",{method:"POST",headers:Us()});if(!l.ok){const n=await l.json();throw new Error(n.detail||"重启失败")}return await l.json()}async function P1(){const l=await we("/api/webui/system/status",{method:"GET",headers:Us()});if(!l.ok){const n=await l.json();throw new Error(n.detail||"获取状态失败")}return await l.json()}const kr={INITIAL_DELAY:3e3,CHECK_INTERVAL:2e3,CHECK_TIMEOUT:3e3,MAX_ATTEMPTS:60,PROGRESS_INTERVAL:200,SUCCESS_REDIRECT_DELAY:1500},Gj=m.createContext(null);function Pn({children:l,onRestartComplete:n,onRestartFailed:i,healthCheckUrl:c="/api/webui/system/status",maxAttempts:u=kr.MAX_ATTEMPTS}){const[x,h]=m.useState({status:"idle",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:u}),[f,p]=m.useState({}),g=m.useCallback(()=>{f.progress&&clearInterval(f.progress),f.elapsed&&clearInterval(f.elapsed),f.check&&clearTimeout(f.check),p({})},[f]),N=m.useCallback(()=>{g(),h({status:"idle",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:u})},[g,u]),v=m.useCallback(async()=>{try{const D=new AbortController,k=setTimeout(()=>D.abort(),kr.CHECK_TIMEOUT),I=await fetch(c,{method:"GET",headers:{"Content-Type":"application/json"},credentials:"include",signal:D.signal});return clearTimeout(k),I.ok}catch{return!1}},[c]),b=m.useCallback(()=>{let D=0;const k=async()=>{if(D++,h(M=>({...M,status:"checking",checkAttempts:D})),await v())g(),h(M=>({...M,status:"success",progress:100})),setTimeout(()=>{n?.(),window.location.href="/auth"},kr.SUCCESS_REDIRECT_DELAY);else if(D>=u){g();const M=`健康检查超时 (${D}/${u})`;h(S=>({...S,status:"failed",error:M})),i?.(M)}else{const M=setTimeout(k,kr.CHECK_INTERVAL);p(S=>({...S,check:M}))}};k()},[v,g,u,n,i]),w=m.useCallback(()=>{h(D=>({...D,status:"checking",checkAttempts:0,error:void 0})),b()},[b]),y=m.useCallback(async D=>{const{delay:k=0,skipApiCall:I=!1}=D??{};if(x.status!=="idle"&&x.status!=="failed")return;if(g(),h({status:"requesting",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:u}),k>0&&await new Promise(T=>setTimeout(T,k)),I)h(T=>({...T,status:"restarting"}));else try{h(T=>({...T,status:"restarting"})),await Promise.race([I1(),new Promise(T=>setTimeout(T,5e3))])}catch{}const M=setInterval(()=>{h(T=>({...T,progress:T.progress>=90?T.progress:T.progress+1}))},kr.PROGRESS_INTERVAL),S=setInterval(()=>{h(T=>({...T,elapsedTime:T.elapsedTime+1}))},1e3);p({progress:M,elapsed:S}),setTimeout(()=>{b()},kr.INITIAL_DELAY)},[x.status,g,u,b]),R={state:x,isRestarting:x.status!=="idle",triggerRestart:y,resetState:N,retryHealthCheck:w};return e.jsx(Gj.Provider,{value:R,children:l})}function dn(){const l=m.useContext(Gj);if(!l)throw new Error("useRestart must be used within a RestartProvider");return l}function H1(){try{return dn()}catch{return null}}const G1=(l,n,i,c,u)=>({idle:{icon:null,title:"",description:"",tip:""},requesting:{icon:e.jsx(zs,{className:"h-16 w-16 text-primary animate-spin"}),title:c??"准备重启",description:u??"正在发送重启请求...",tip:"🔄 正在准备重启麦麦..."},restarting:{icon:e.jsx(zs,{className:"h-16 w-16 text-primary animate-spin"}),title:c??"正在重启麦麦",description:u??"请稍候,麦麦正在重启中...",tip:"🔄 配置已保存,正在重启主程序..."},checking:{icon:e.jsx(zs,{className:"h-16 w-16 text-primary animate-spin"}),title:"检查服务状态",description:`等待服务恢复... (${n}/${i})`,tip:"⏳ 正在等待服务恢复,请勿关闭页面..."},success:{icon:e.jsx(ea,{className:"h-16 w-16 text-green-500"}),title:"重启成功",description:"正在跳转到登录页面...",tip:"✅ 配置已生效,服务运行正常"},failed:{icon:e.jsx(Ct,{className:"h-16 w-16 text-destructive"}),title:"重启超时",description:"服务未能在预期时间内恢复",tip:"⚠️ 如果长时间无响应,请尝试手动重启"}})[l];function Hn({visible:l,onComplete:n,onFailed:i,title:c,description:u,showAnimation:x=!0,className:h}){const f=H1();return(f?f.isRestarting:l)?f?e.jsx(Fj,{state:f.state,onRetry:f.retryHealthCheck,onComplete:n,onFailed:i,title:c,description:u,showAnimation:x,className:h}):e.jsx(F1,{onComplete:n,onFailed:i,title:c,description:u,showAnimation:x,className:h}):null}function Fj({state:l,onRetry:n,onComplete:i,onFailed:c,title:u,description:x,showAnimation:h,className:f}){const{status:p,progress:g,elapsedTime:N,checkAttempts:v,maxAttempts:b}=l;m.useEffect(()=>{p==="success"&&i?i():p==="failed"&&c&&c()},[p,i,c]);const w=G1(p,v,b,u,x),y=R=>{const D=Math.floor(R/60),k=R%60;return`${D}:${k.toString().padStart(2,"0")}`};return e.jsxs("div",{className:B("fixed inset-0 bg-background/95 backdrop-blur-sm z-50 flex items-center justify-center",f),children:[h&&e.jsx(q1,{}),e.jsxs("div",{className:"max-w-md w-full mx-4 space-y-8 relative z-10",children:[e.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[e.jsxs("div",{className:"relative",children:[w.icon,(p==="restarting"||p==="checking")&&e.jsx("div",{className:"absolute inset-0 rounded-full bg-primary/20 animate-ping"})]}),e.jsx("h2",{className:"text-2xl font-bold",children:w.title}),e.jsx("p",{className:"text-muted-foreground text-center",children:w.description})]}),p!=="failed"&&p!=="idle"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(Bn,{value:g,className:"h-2"}),e.jsxs("div",{className:"flex justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[g,"%"]}),e.jsxs("span",{children:["已用时: ",y(N)]})]})]}),e.jsx("div",{className:"bg-muted/50 rounded-lg p-4",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:w.tip})}),p==="failed"&&e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(C,{onClick:()=>window.location.reload(),variant:"default",className:"flex-1",children:[e.jsx(kt,{className:"mr-2 h-4 w-4"}),"刷新页面"]}),e.jsxs(C,{onClick:n,variant:"secondary",className:"flex-1",children:[e.jsx(Pi,{className:"mr-2 h-4 w-4"}),"重试检测"]})]})]})]})}function F1({onComplete:l,onFailed:n,title:i,description:c,showAnimation:u,className:x}){const[h,f]=m.useState({status:"restarting",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:60}),p=m.useCallback(()=>{let g=0;const N=60,v=async()=>{g++,f(b=>({...b,status:"checking",checkAttempts:g}));try{if((await fetch("/api/webui/system/status",{method:"GET",signal:AbortSignal.timeout(3e3)})).ok){f(w=>({...w,status:"success",progress:100})),setTimeout(()=>{l?.(),window.location.href="/auth"},1500);return}}catch{}g>=N?(f(b=>({...b,status:"failed"})),n?.()):setTimeout(v,2e3)};v()},[l,n]);return m.useEffect(()=>{const g=setInterval(()=>{f(b=>({...b,progress:b.progress>=90?b.progress:b.progress+1}))},200),N=setInterval(()=>{f(b=>({...b,elapsedTime:b.elapsedTime+1}))},1e3),v=setTimeout(()=>{p()},3e3);return()=>{clearInterval(g),clearInterval(N),clearTimeout(v)}},[p]),e.jsx(Fj,{state:h,onRetry:p,onComplete:l,onFailed:n,title:i,description:c,showAnimation:u,className:x})}function q1(){return e.jsxs("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:[e.jsxs("div",{className:"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px]",children:[e.jsx("div",{className:"absolute inset-0 rounded-full border border-primary/10 animate-[ping_3s_ease-in-out_infinite]"}),e.jsx("div",{className:"absolute inset-8 rounded-full border border-primary/10 animate-[ping_3s_ease-in-out_infinite_0.5s]"}),e.jsx("div",{className:"absolute inset-16 rounded-full border border-primary/10 animate-[ping_3s_ease-in-out_infinite_1s]"})]}),e.jsx("div",{className:"absolute top-1/4 left-1/4 w-2 h-2 bg-primary/20 rounded-full animate-bounce"}),e.jsx("div",{className:"absolute top-3/4 right-1/4 w-3 h-3 bg-primary/15 rounded-full animate-bounce delay-150"}),e.jsx("div",{className:"absolute top-1/2 right-1/3 w-2 h-2 bg-primary/20 rounded-full animate-bounce delay-300"})]})}function V1(){return e.jsx(Pn,{children:e.jsx(Q1,{})})}const K1=l=>{const n=[];for(let i=0;i{try{w(!0);const L=await x0.get("https://v1.hitokoto.cn/?c=a&c=b&c=c&c=d&c=h&c=i&c=k");v({hitokoto:L.data.hitokoto,from:L.data.from||L.data.from_who||"未知"})}catch(L){console.error("获取一言失败:",L),v({hitokoto:"人生就像一盒巧克力,你永远不知道下一颗是什么味道。",from:"阿甘正传"})}finally{w(!1)}},[]),M=m.useCallback(async()=>{try{const L=await we("/api/webui/system/status");if(L.ok){const P=await L.json();R(P)}else R(null)}catch(L){console.error("获取机器人状态失败:",L),R(null)}},[]),S=async()=>{await D()},T=m.useCallback(async()=>{try{const L=await we(`/api/webui/statistics/dashboard?hours=${h}`);if(L.ok){const P=await L.json();n(P)}c(!1),x(100)}catch(L){console.error("Failed to fetch dashboard data:",L),c(!1),x(100)}},[h]);if(m.useEffect(()=>{if(!i)return;x(0);const L=setTimeout(()=>x(15),200),P=setTimeout(()=>x(30),800),_e=setTimeout(()=>x(45),2e3),je=setTimeout(()=>x(60),4e3),Se=setTimeout(()=>x(75),6500),Y=setTimeout(()=>x(85),9e3),be=setTimeout(()=>x(92),11e3);return()=>{clearTimeout(L),clearTimeout(P),clearTimeout(_e),clearTimeout(je),clearTimeout(Se),clearTimeout(Y),clearTimeout(be)}},[i]),m.useEffect(()=>{T(),I(),M()},[T,I,M]),m.useEffect(()=>{if(!p)return;const L=setInterval(()=>{T(),M()},3e4);return()=>clearInterval(L)},[p,T,M]),i||!l)return e.jsx("div",{className:"flex items-center justify-center h-[calc(100vh-200px)]",children:e.jsxs("div",{className:"text-center space-y-6 w-full max-w-md px-4",children:[e.jsx(kt,{className:"h-12 w-12 animate-spin mx-auto text-primary"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-lg font-medium",children:"加载统计数据中..."}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"正在获取麦麦运行数据"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(Bn,{value:u,className:"h-2"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[u,"%"]})]})]})});const{summary:$,model_stats:A=[],hourly_data:Q=[],daily_data:G=[],recent_activity:de=[]}=l,oe=$??{total_requests:0,total_cost:0,total_tokens:0,online_time:0,total_messages:0,total_replies:0,avg_response_time:0,cost_per_hour:0,tokens_per_hour:0},ve=L=>{const P=Math.floor(L/3600),_e=Math.floor(L%3600/60);return`${P}小时${_e}分钟`},le=L=>{const P=L.toLocaleString("zh-CN");return L>=1e9?{display:`${(L/1e9).toFixed(2)}B`,exact:P,needsExact:!0}:L>=1e6?{display:`${(L/1e6).toFixed(2)}M`,exact:P,needsExact:!0}:L>=1e4?{display:`${(L/1e3).toFixed(1)}K`,exact:P,needsExact:!0}:L>=1e3?{display:`${(L/1e3).toFixed(2)}K`,exact:P,needsExact:!0}:{display:P,exact:P,needsExact:!1}},fe=L=>{const P=`¥${L.toLocaleString("zh-CN",{minimumFractionDigits:2,maximumFractionDigits:2})}`;return L>=1e6?{display:`¥${(L/1e6).toFixed(2)}M`,exact:P,needsExact:!0}:L>=1e4?{display:`¥${(L/1e3).toFixed(1)}K`,exact:P,needsExact:!0}:L>=1e3?{display:`¥${(L/1e3).toFixed(2)}K`,exact:P,needsExact:!0}:{display:P,exact:P,needsExact:!1}},ge=L=>new Date(L).toLocaleString("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}),z=K1(A.length),V=A.map((L,P)=>({name:L.model_name,value:L.request_count,fill:z[P]})),U={requests:{label:"请求数",color:"hsl(var(--chart-1))"},cost:{label:"花费(¥)",color:"hsl(var(--chart-2))"},tokens:{label:"Tokens",color:"hsl(var(--chart-3))"}};return e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"实时监控面板"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"麦麦运行状态和统计数据一览"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(ma,{value:h.toString(),onValueChange:L=>f(Number(L)),children:e.jsxs(ta,{className:"grid grid-cols-3 w-full sm:w-auto",children:[e.jsx(as,{value:"24",children:"24小时"}),e.jsx(as,{value:"168",children:"7天"}),e.jsx(as,{value:"720",children:"30天"})]})}),e.jsxs(C,{variant:p?"default":"outline",size:"sm",onClick:()=>g(!p),className:"gap-2",children:[e.jsx(kt,{className:`h-4 w-4 ${p?"animate-spin":""}`}),e.jsx("span",{className:"hidden sm:inline",children:"自动刷新"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:T,children:e.jsx(kt,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2 rounded-lg border border-dashed border-muted-foreground/30 bg-muted/20",children:[b?e.jsx(Js,{className:"h-5 flex-1"}):N?e.jsxs("p",{className:"flex-1 text-sm text-muted-foreground italic truncate",children:['"',N.hitokoto,'" —— ',N.from]}):null,e.jsx(C,{variant:"ghost",size:"icon",className:"h-7 w-7 shrink-0",onClick:I,disabled:b,children:e.jsx(kt,{className:`h-3.5 w-3.5 ${b?"animate-spin":""}`})})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-1 lg:grid-cols-3",children:[e.jsxs(De,{className:"lg:col-span-1",children:[e.jsx(Xe,{className:"pb-3",children:e.jsxs(We,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Ji,{className:"h-4 w-4"}),"麦麦状态"]})}),e.jsx(Qe,{children:e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("div",{className:"flex items-center gap-2",children:y?.running?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-3 w-3 rounded-full bg-green-500 animate-pulse"}),e.jsxs(Ae,{variant:"outline",className:"text-green-600 border-green-300 bg-green-50",children:[e.jsx(ea,{className:"h-3 w-3 mr-1"}),"运行中"]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-3 w-3 rounded-full bg-red-500"}),e.jsxs(Ae,{variant:"outline",className:"text-red-600 border-red-300 bg-red-50",children:[e.jsx(Ct,{className:"h-3 w-3 mr-1"}),"已停止"]})]})}),y&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsxs("span",{children:["v",y.version]}),e.jsx("span",{className:"mx-2",children:"|"}),e.jsxs("span",{children:["运行 ",ve(y.uptime)]})]})]})})]}),e.jsxs(De,{children:[e.jsx(Xe,{className:"pb-3",children:e.jsxs(We,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(zn,{className:"h-4 w-4"}),"快速操作"]})}),e.jsx(Qe,{children:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:S,disabled:k,className:"gap-2",children:[e.jsx(Pi,{className:`h-4 w-4 ${k?"animate-spin":""}`}),k?"重启中...":"重启麦麦"]}),e.jsx(C,{variant:"outline",size:"sm",asChild:!0,className:"gap-2",children:e.jsxs(Cr,{to:"/logs",children:[e.jsx(qa,{className:"h-4 w-4"}),"查看日志"]})}),e.jsx(C,{variant:"outline",size:"sm",asChild:!0,className:"gap-2",children:e.jsxs(Cr,{to:"/plugins",children:[e.jsx(Cw,{className:"h-4 w-4"}),"插件管理"]})}),e.jsx(C,{variant:"outline",size:"sm",asChild:!0,className:"gap-2",children:e.jsxs(Cr,{to:"/settings",children:[e.jsx(In,{className:"h-4 w-4"}),"系统设置"]})})]})})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"pb-3",children:[e.jsxs(We,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Tw,{className:"h-4 w-4"}),"反馈问卷"]}),e.jsx(Is,{className:"text-xs",children:"帮助我们改进产品体验"})]}),e.jsx(Qe,{children:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",asChild:!0,className:"gap-2",children:e.jsxs(Cr,{to:"/survey/webui-feedback",children:[e.jsx(qa,{className:"h-4 w-4"}),"WebUI 反馈"]})}),e.jsx(C,{variant:"outline",size:"sm",asChild:!0,className:"gap-2",children:e.jsxs(Cr,{to:"/survey/maibot-feedback",children:[e.jsx(on,{className:"h-4 w-4"}),"麦麦反馈"]})})]})})]})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-1 xs:grid-cols-2 lg:grid-cols-4",children:[e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"总请求数"}),e.jsx(Ew,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsxs("div",{className:"text-2xl font-bold",children:[le(oe.total_requests).display,le(oe.total_requests).needsExact&&e.jsxs("span",{className:"text-xs font-normal text-muted-foreground ml-1",children:["(",le(oe.total_requests).exact,")"]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["最近",h<48?h+"小时":Math.floor(h/24)+"天"]})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"总花费"}),e.jsx(Mw,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsxs("div",{className:"text-2xl font-bold",children:[fe(oe.total_cost).display,fe(oe.total_cost).needsExact&&e.jsxs("span",{className:"text-xs font-normal text-muted-foreground ml-1",children:["(",fe(oe.total_cost).exact,")"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:oe.cost_per_hour>0?`¥${oe.cost_per_hour.toFixed(2)}/小时`:"暂无数据"})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"Token消耗"}),e.jsx(zr,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsxs("div",{className:"text-2xl font-bold",children:[le(oe.total_tokens).display,le(oe.total_tokens).needsExact&&e.jsxs("span",{className:"text-xs font-normal text-muted-foreground ml-1",children:["(",le(oe.total_tokens).exact,")"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:oe.tokens_per_hour>0?`${le(oe.tokens_per_hour).display}/小时`:"暂无数据"})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"平均响应"}),e.jsx(zn,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsxs("div",{className:"text-2xl font-bold",children:[oe.avg_response_time.toFixed(2),"s"]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"API平均耗时"})]})]})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-1 sm:grid-cols-3",children:[e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"在线时长"}),e.jsx(kl,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx(Qe,{children:e.jsxs("div",{className:"text-xl font-bold",children:[ve(oe.online_time),e.jsxs("span",{className:"text-xs font-normal text-muted-foreground ml-1",children:["(",oe.online_time.toLocaleString(),"秒)"]})]})})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"消息处理"}),e.jsx(on,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsxs("div",{className:"text-xl font-bold",children:[le(oe.total_messages).display,le(oe.total_messages).needsExact&&e.jsxs("span",{className:"text-xs font-normal text-muted-foreground ml-1",children:["(",le(oe.total_messages).exact,")"]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["回复 ",le(oe.total_replies).display,le(oe.total_replies).needsExact&&e.jsxs("span",{children:["(",le(oe.total_replies).exact,")"]})," 条"]})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"成本效率"}),e.jsx(Aw,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsx("div",{className:"text-xl font-bold",children:oe.total_messages>0?`¥${(oe.total_cost/oe.total_messages*100).toFixed(2)}`:"¥0.00"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"每100条消息"})]})]})]}),e.jsxs(ma,{defaultValue:"trends",className:"space-y-4",children:[e.jsxs(ta,{className:"grid w-full grid-cols-2 sm:grid-cols-4",children:[e.jsx(as,{value:"trends",children:"趋势"}),e.jsx(as,{value:"models",children:"模型"}),e.jsx(as,{value:"activity",children:"活动"}),e.jsx(as,{value:"daily",children:"日统计"})]}),e.jsxs(ys,{value:"trends",className:"space-y-4",children:[e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"请求趋势"}),e.jsxs(Is,{children:["最近",h,"小时的请求量变化"]})]}),e.jsx(Qe,{children:e.jsx(Tr,{config:U,className:"h-[300px] sm:h-[400px] w-full aspect-auto",children:e.jsxs(W0,{data:Q,children:[e.jsx(fo,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),e.jsx(po,{dataKey:"timestamp",tickFormatter:L=>ge(L),angle:-45,textAnchor:"end",height:60,stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Ai,{stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Di,{content:e.jsx(Er,{labelFormatter:L=>ge(L)})}),e.jsx(ew,{type:"monotone",dataKey:"requests",stroke:"var(--color-requests)",strokeWidth:2})]})})})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-1 lg:grid-cols-2",children:[e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"花费趋势"}),e.jsx(Is,{children:"API调用成本变化"})]}),e.jsx(Qe,{children:e.jsx(Tr,{config:U,className:"h-[250px] sm:h-[300px] w-full aspect-auto",children:e.jsxs(om,{data:Q,children:[e.jsx(fo,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),e.jsx(po,{dataKey:"timestamp",tickFormatter:L=>ge(L),angle:-45,textAnchor:"end",height:60,stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Ai,{stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Di,{content:e.jsx(Er,{labelFormatter:L=>ge(L)})}),e.jsx(go,{dataKey:"cost",fill:"var(--color-cost)"})]})})})]}),e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"Token消耗"}),e.jsx(Is,{children:"Token使用量变化"})]}),e.jsx(Qe,{children:e.jsx(Tr,{config:U,className:"h-[250px] sm:h-[300px] w-full aspect-auto",children:e.jsxs(om,{data:Q,children:[e.jsx(fo,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),e.jsx(po,{dataKey:"timestamp",tickFormatter:L=>ge(L),angle:-45,textAnchor:"end",height:60,stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Ai,{stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Di,{content:e.jsx(Er,{labelFormatter:L=>ge(L)})}),e.jsx(go,{dataKey:"tokens",fill:"var(--color-tokens)"})]})})})]})]})]}),e.jsx(ys,{value:"models",className:"space-y-4",children:e.jsxs("div",{className:"grid gap-4 grid-cols-1 lg:grid-cols-2",children:[e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"模型请求分布"}),e.jsxs(Is,{children:["各模型使用占比 (共 ",A.length," 个模型)"]})]}),e.jsx(Qe,{children:e.jsx(Tr,{config:Object.fromEntries(A.map((L,P)=>[L.model_name,{label:L.model_name,color:z[P]}])),className:"h-[300px] sm:h-[400px] w-full aspect-auto",children:e.jsxs(sw,{children:[e.jsx(Di,{content:e.jsx(Er,{})}),e.jsx(tw,{data:V,cx:"50%",cy:"50%",labelLine:!1,label:({name:L,percent:P})=>P&&P<.05?"":`${L} ${P?(P*100).toFixed(0):0}%`,outerRadius:100,dataKey:"value",children:V.map((L,P)=>e.jsx(aw,{fill:L.fill},`cell-${P}`))})]})})})]}),e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"模型详细统计"}),e.jsx(Is,{children:"请求数、花费和性能"})]}),e.jsx(Qe,{children:e.jsx(es,{className:"h-[300px] sm:h-[400px]",children:e.jsx("div",{className:"space-y-3",children:A.map((L,P)=>e.jsxs("div",{className:"p-4 rounded-lg border bg-card hover:bg-accent/50 transition-colors",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h4",{className:"font-semibold text-sm truncate flex-1 min-w-0",children:L.model_name}),e.jsx("div",{className:"w-3 h-3 rounded-full ml-2 flex-shrink-0",style:{backgroundColor:`hsl(var(--chart-${P%5+1}))`}})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"请求数:"}),e.jsx("span",{className:"ml-1 font-medium",children:L.request_count.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"花费:"}),e.jsxs("span",{className:"ml-1 font-medium",children:["¥",L.total_cost.toFixed(2)]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Tokens:"}),e.jsxs("span",{className:"ml-1 font-medium",children:[(L.total_tokens/1e3).toFixed(1),"K"]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"平均耗时:"}),e.jsxs("span",{className:"ml-1 font-medium",children:[L.avg_response_time.toFixed(2),"s"]})]})]})]},P))})})})]})]})}),e.jsx(ys,{value:"activity",children:e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"最近活动"}),e.jsx(Is,{children:"最新的API调用记录"})]}),e.jsx(Qe,{children:e.jsx(es,{className:"h-[400px] sm:h-[500px]",children:e.jsx("div",{className:"space-y-2",children:de.map((L,P)=>e.jsxs("div",{className:"p-3 sm:p-4 rounded-lg border bg-card hover:bg-accent/50 transition-colors",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-2 mb-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"font-medium text-sm truncate",children:L.model}),e.jsx("div",{className:"text-xs text-muted-foreground",children:L.request_type})]}),e.jsx("div",{className:"text-xs text-muted-foreground flex-shrink-0",children:ge(L.timestamp)})]}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Tokens:"}),e.jsx("span",{className:"ml-1",children:L.tokens})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"花费:"}),e.jsxs("span",{className:"ml-1",children:["¥",L.cost.toFixed(4)]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"耗时:"}),e.jsxs("span",{className:"ml-1",children:[L.time_cost.toFixed(2),"s"]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"状态:"}),e.jsx("span",{className:`ml-1 ${L.status==="success"?"text-green-600":"text-red-600"}`,children:L.status})]})]})]},P))})})})]})}),e.jsx(ys,{value:"daily",children:e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"每日统计"}),e.jsx(Is,{children:"最近7天的数据汇总"})]}),e.jsx(Qe,{children:e.jsx(Tr,{config:{requests:{label:"请求数",color:"hsl(var(--chart-1))"},cost:{label:"花费(¥)",color:"hsl(var(--chart-2))"}},className:"h-[400px] sm:h-[500px] w-full aspect-auto",children:e.jsxs(om,{data:G,children:[e.jsx(fo,{strokeDasharray:"3 3",stroke:"hsl(var(--muted-foreground) / 0.2)"}),e.jsx(po,{dataKey:"timestamp",tickFormatter:L=>{const P=new Date(L);return`${P.getMonth()+1}/${P.getDate()}`},stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Ai,{yAxisId:"left",stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Ai,{yAxisId:"right",orientation:"right",stroke:"hsl(var(--muted-foreground))",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(Di,{content:e.jsx(Er,{labelFormatter:L=>new Date(L).toLocaleDateString("zh-CN")})}),e.jsx(B1,{content:e.jsx(Hj,{})}),e.jsx(go,{yAxisId:"left",dataKey:"requests",fill:"var(--color-requests)"}),e.jsx(go,{yAxisId:"right",dataKey:"cost",fill:"var(--color-cost)"})]})})})]})})]}),e.jsx(Hn,{})]})})}const Y1={theme:"system",setTheme:()=>null},qj=m.createContext(Y1),Bm=()=>{const l=m.useContext(qj);if(l===void 0)throw new Error("useTheme must be used within a ThemeProvider");return l},J1=(l,n,i)=>{const c=document.documentElement.classList.contains("no-animations");if(!document.startViewTransition||c){n(l);return}const u=i.clientX,x=i.clientY,h=Math.hypot(Math.max(u,innerWidth-u),Math.max(x,innerHeight-x));document.startViewTransition(()=>{n(l)}).ready.then(()=>{document.documentElement.animate({clipPath:[`circle(0px at ${u}px ${x}px)`,`circle(${h}px at ${u}px ${x}px)`]},{duration:500,easing:"ease-in-out",pseudoElement:"::view-transition-new(root)"})})},Vj=m.createContext(void 0),Kj=()=>{const l=m.useContext(Vj);if(l===void 0)throw new Error("useAnimation must be used within an AnimationProvider");return l},Ge=m.forwardRef(({className:l,...n},i)=>e.jsx(Tg,{className:B("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",l),...n,ref:i,children:e.jsx(v0,{className:B("pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0")})}));Ge.displayName=Tg.displayName;const X1=Lr("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),E=m.forwardRef(({className:l,...n},i)=>e.jsx(qg,{ref:i,className:B(X1(),l),...n}));E.displayName=qg.displayName;const ie=m.forwardRef(({className:l,type:n,...i},c)=>e.jsx("input",{type:n,className:B("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",l),ref:c,...i}));ie.displayName="Input";const Z1=5,W1=5e3;let fm=0;function e2(){return fm=(fm+1)%Number.MAX_SAFE_INTEGER,fm.toString()}const pm=new Map,eg=l=>{if(pm.has(l))return;const n=setTimeout(()=>{pm.delete(l),$i({type:"REMOVE_TOAST",toastId:l})},W1);pm.set(l,n)},s2=(l,n)=>{switch(n.type){case"ADD_TOAST":return{...l,toasts:[n.toast,...l.toasts].slice(0,Z1)};case"UPDATE_TOAST":return{...l,toasts:l.toasts.map(i=>i.id===n.toast.id?{...i,...n.toast}:i)};case"DISMISS_TOAST":{const{toastId:i}=n;return i?eg(i):l.toasts.forEach(c=>{eg(c.id)}),{...l,toasts:l.toasts.map(c=>c.id===i||i===void 0?{...c,open:!1}:c)}}case"REMOVE_TOAST":return n.toastId===void 0?{...l,toasts:[]}:{...l,toasts:l.toasts.filter(i=>i.id!==n.toastId)}}},wo=[];let _o={toasts:[]};function $i(l){_o=s2(_o,l),wo.forEach(n=>{n(_o)})}function Gt({...l}){const n=e2(),i=u=>$i({type:"UPDATE_TOAST",toast:{...u,id:n}}),c=()=>$i({type:"DISMISS_TOAST",toastId:n});return $i({type:"ADD_TOAST",toast:{...l,id:n,open:!0,onOpenChange:u=>{u||c()}}}),{id:n,dismiss:c,update:i}}function Ws(){const[l,n]=m.useState(_o);return m.useEffect(()=>(wo.push(n),()=>{const i=wo.indexOf(n);i>-1&&wo.splice(i,1)}),[l]),{...l,toast:Gt,dismiss:i=>$i({type:"DISMISS_TOAST",toastId:i})}}const t2=[{id:"minLength",label:"长度至少 10 位",description:"Token 长度必须大于等于 10 个字符",validate:l=>l.length>=10},{id:"hasUppercase",label:"包含大写字母",description:"至少包含一个大写字母 (A-Z)",validate:l=>/[A-Z]/.test(l)},{id:"hasLowercase",label:"包含小写字母",description:"至少包含一个小写字母 (a-z)",validate:l=>/[a-z]/.test(l)},{id:"hasSpecialChar",label:"包含特殊符号",description:"至少包含一个特殊符号 (!@#$%^&*()_+-=[]{}|;:,.<>?/)",validate:l=>/[!@#$%^&*()_+\-=[\]{}|;:,.<>?/]/.test(l)}];function a2(l){const n=t2.map(c=>({id:c.id,label:c.label,description:c.description,passed:c.validate(l)}));return{isValid:n.every(c=>c.passed),rules:n}}const Po="0.12.0",$m="MaiBot Dashboard",l2=`${$m} v${Po}`,n2=(l="v")=>`${l}${Po}`,ua={THEME:"maibot-ui-theme",ACCENT_COLOR:"accent-color",ENABLE_ANIMATIONS:"maibot-animations",ENABLE_WAVES_BACKGROUND:"maibot-waves-background",LOG_CACHE_SIZE:"maibot-log-cache-size",LOG_AUTO_SCROLL:"maibot-log-auto-scroll",LOG_FONT_SIZE:"maibot-log-font-size",LOG_LINE_SPACING:"maibot-log-line-spacing",DATA_SYNC_INTERVAL:"maibot-data-sync-interval",WS_RECONNECT_INTERVAL:"maibot-ws-reconnect-interval",WS_MAX_RECONNECT_ATTEMPTS:"maibot-ws-max-reconnect-attempts",COMPLETED_TOURS:"maibot-completed-tours"},sl={theme:"system",accentColor:"blue",enableAnimations:!0,enableWavesBackground:!0,logCacheSize:1e3,logAutoScroll:!0,logFontSize:"xs",logLineSpacing:4,dataSyncInterval:30,wsReconnectInterval:3e3,wsMaxReconnectAttempts:10};function Nt(l){const n=Qj(l),i=localStorage.getItem(n);if(i===null)return sl[l];const c=sl[l];if(typeof c=="boolean")return i==="true";if(typeof c=="number"){const u=parseFloat(i);return isNaN(u)?c:u}return i}function Mr(l,n){const i=Qj(l);localStorage.setItem(i,String(n)),window.dispatchEvent(new CustomEvent("maibot-settings-change",{detail:{key:l,value:n}}))}function r2(){return{theme:Nt("theme"),accentColor:Nt("accentColor"),enableAnimations:Nt("enableAnimations"),enableWavesBackground:Nt("enableWavesBackground"),logCacheSize:Nt("logCacheSize"),logAutoScroll:Nt("logAutoScroll"),logFontSize:Nt("logFontSize"),logLineSpacing:Nt("logLineSpacing"),dataSyncInterval:Nt("dataSyncInterval"),wsReconnectInterval:Nt("wsReconnectInterval"),wsMaxReconnectAttempts:Nt("wsMaxReconnectAttempts")}}function i2(){const l=r2(),n=localStorage.getItem(ua.COMPLETED_TOURS),i=n?JSON.parse(n):[];return{...l,completedTours:i}}function c2(l){const n=[],i=[];for(const[c,u]of Object.entries(l)){if(c==="completedTours"){Array.isArray(u)?(localStorage.setItem(ua.COMPLETED_TOURS,JSON.stringify(u)),n.push("completedTours")):i.push("completedTours");continue}if(c in sl){const x=c,h=sl[x];if(typeof u==typeof h){if(x==="theme"&&!["light","dark","system"].includes(u)){i.push(c);continue}if(x==="logFontSize"&&!["xs","sm","base"].includes(u)){i.push(c);continue}Mr(x,u),n.push(c)}else i.push(c)}else i.push(c)}return{success:n.length>0,imported:n,skipped:i}}function o2(){for(const l of Object.keys(sl))Mr(l,sl[l]);localStorage.removeItem(ua.COMPLETED_TOURS),window.dispatchEvent(new CustomEvent("maibot-settings-reset"))}function d2(){const l=[],n=[],i=[];for(let c=0;cc.size-i.size),{used:l,items:localStorage.length,details:n}}function u2(l){if(l===0)return"0 B";const n=1024,i=["B","KB","MB"],c=Math.floor(Math.log(l)/Math.log(n));return parseFloat((l/Math.pow(n,c)).toFixed(2))+" "+i[c]}function Qj(l){return{theme:ua.THEME,accentColor:ua.ACCENT_COLOR,enableAnimations:ua.ENABLE_ANIMATIONS,enableWavesBackground:ua.ENABLE_WAVES_BACKGROUND,logCacheSize:ua.LOG_CACHE_SIZE,logAutoScroll:ua.LOG_AUTO_SCROLL,logFontSize:ua.LOG_FONT_SIZE,logLineSpacing:ua.LOG_LINE_SPACING,dataSyncInterval:ua.DATA_SYNC_INTERVAL,wsReconnectInterval:ua.WS_RECONNECT_INTERVAL,wsMaxReconnectAttempts:ua.WS_MAX_RECONNECT_ATTEMPTS}[l]}const wa=m.forwardRef(({className:l,...n},i)=>e.jsxs(Eg,{ref:i,className:B("relative flex w-full touch-none select-none items-center",l),...n,children:[e.jsx(N0,{className:"relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20",children:e.jsx(b0,{className:"absolute h-full bg-primary"})}),e.jsx(y0,{className:"block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"})]}));wa.displayName=Eg.displayName;class m2{ws=null;reconnectTimeout=null;reconnectAttempts=0;heartbeatInterval=null;logCallbacks=new Set;connectionCallbacks=new Set;isConnected=!1;logCache=[];getMaxCacheSize(){return Nt("logCacheSize")}getMaxReconnectAttempts(){return Nt("wsMaxReconnectAttempts")}getReconnectInterval(){return Nt("wsReconnectInterval")}getWebSocketUrl(n){let i;{const c=window.location.protocol==="https:"?"wss:":"ws:",u=window.location.host;i=`${c}//${u}/ws/logs`}return n?`${i}?token=${encodeURIComponent(n)}`:i}async getWsToken(){try{const n=await we("/api/webui/ws-token",{method:"GET",credentials:"include"});if(!n.ok)return console.error("获取 WebSocket token 失败:",n.status),null;const i=await n.json();return i.success&&i.token?i.token:null}catch(n){return console.error("获取 WebSocket token 失败:",n),null}}async connect(){if(this.ws?.readyState===WebSocket.OPEN||this.ws?.readyState===WebSocket.CONNECTING)return;if(window.location.pathname==="/auth"){console.log("📡 在登录页面,跳过 WebSocket 连接");return}if(!await Fi()){console.log("📡 未登录,跳过 WebSocket 连接");return}const i=await this.getWsToken();if(!i){console.log("📡 无法获取 WebSocket token,跳过连接");return}const c=this.getWebSocketUrl(i);try{this.ws=new WebSocket(c),this.ws.onopen=()=>{this.isConnected=!0,this.reconnectAttempts=0,this.notifyConnection(!0),this.startHeartbeat()},this.ws.onmessage=u=>{try{if(u.data==="pong")return;const x=JSON.parse(u.data);this.notifyLog(x)}catch(x){console.error("解析日志消息失败:",x)}},this.ws.onerror=u=>{console.error("❌ WebSocket 错误:",u),this.isConnected=!1,this.notifyConnection(!1)},this.ws.onclose=()=>{this.isConnected=!1,this.notifyConnection(!1),this.stopHeartbeat(),this.attemptReconnect()}}catch(u){console.error("创建 WebSocket 连接失败:",u),this.attemptReconnect()}}attemptReconnect(){const n=this.getMaxReconnectAttempts();if(this.reconnectAttempts>=n)return;this.reconnectAttempts+=1;const i=this.getReconnectInterval(),c=Math.min(i*this.reconnectAttempts,3e4);this.reconnectTimeout=window.setTimeout(()=>{this.connect()},c)}startHeartbeat(){this.heartbeatInterval=window.setInterval(()=>{this.ws?.readyState===WebSocket.OPEN&&this.ws.send("ping")},3e4)}stopHeartbeat(){this.heartbeatInterval!==null&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null)}disconnect(){this.reconnectTimeout!==null&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.stopHeartbeat(),this.ws&&(this.ws.close(),this.ws=null),this.isConnected=!1,this.reconnectAttempts=0}onLog(n){return this.logCallbacks.add(n),()=>this.logCallbacks.delete(n)}onConnectionChange(n){return this.connectionCallbacks.add(n),n(this.isConnected),()=>this.connectionCallbacks.delete(n)}notifyLog(n){if(!this.logCache.some(c=>c.id===n.id)){this.logCache.push(n);const c=this.getMaxCacheSize();this.logCache.length>c&&(this.logCache=this.logCache.slice(-c)),this.logCallbacks.forEach(u=>{try{u(n)}catch(x){console.error("日志回调执行失败:",x)}})}}notifyConnection(n){this.connectionCallbacks.forEach(i=>{try{i(n)}catch(c){console.error("连接状态回调执行失败:",c)}})}getAllLogs(){return[...this.logCache]}clearLogs(){this.logCache=[]}getConnectionStatus(){return this.isConnected}}const Mn=new m2;typeof window<"u"&&setTimeout(()=>{Mn.connect()},100);const Ks=iw,Ho=cw,x2=nw,Yj=m.forwardRef(({className:l,...n},i)=>e.jsx(Vg,{ref:i,className:B("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",l),...n}));Yj.displayName=Vg.displayName;const Ps=m.forwardRef(({className:l,children:n,preventOutsideClose:i=!1,...c},u)=>e.jsxs(x2,{children:[e.jsx(Yj,{}),e.jsxs(Kg,{ref:u,className:B("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",l),onPointerDownOutside:i?x=>x.preventDefault():void 0,onInteractOutside:i?x=>x.preventDefault():void 0,...c,children:[n,e.jsxs(rw,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[e.jsx(_a,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));Ps.displayName=Kg.displayName;const Hs=({className:l,...n})=>e.jsx("div",{className:B("flex flex-col space-y-1.5 text-center sm:text-left",l),...n});Hs.displayName="DialogHeader";const xt=({className:l,...n})=>e.jsx("div",{className:B("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",l),...n});xt.displayName="DialogFooter";const Gs=m.forwardRef(({className:l,...n},i)=>e.jsx(Qg,{ref:i,className:B("text-lg font-semibold leading-none tracking-tight",l),...n}));Gs.displayName=Qg.displayName;const ot=m.forwardRef(({className:l,...n},i)=>e.jsx(Yg,{ref:i,className:B("text-sm text-muted-foreground",l),...n}));ot.displayName=Yg.displayName;const ps=_0,bt=S0,h2=w0,Jj=m.forwardRef(({className:l,...n},i)=>e.jsx(Mg,{className:B("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",l),...n,ref:i}));Jj.displayName=Mg.displayName;const os=m.forwardRef(({className:l,...n},i)=>e.jsxs(h2,{children:[e.jsx(Jj,{}),e.jsx(Ag,{ref:i,className:B("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",l),...n})]}));os.displayName=Ag.displayName;const ds=({className:l,...n})=>e.jsx("div",{className:B("flex flex-col space-y-2 text-center sm:text-left",l),...n});ds.displayName="AlertDialogHeader";const us=({className:l,...n})=>e.jsx("div",{className:B("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",l),...n});us.displayName="AlertDialogFooter";const ms=m.forwardRef(({className:l,...n},i)=>e.jsx(zg,{ref:i,className:B("text-lg font-semibold",l),...n}));ms.displayName=zg.displayName;const xs=m.forwardRef(({className:l,...n},i)=>e.jsx(Dg,{ref:i,className:B("text-sm text-muted-foreground",l),...n}));xs.displayName=Dg.displayName;const hs=m.forwardRef(({className:l,variant:n,...i},c)=>e.jsx(Og,{ref:c,className:B(Rr({variant:n}),l),...i}));hs.displayName=Og.displayName;const fs=m.forwardRef(({className:l,...n},i)=>e.jsx(Rg,{ref:i,className:B(Rr({variant:"outline"}),"mt-2 sm:mt-0",l),...n}));fs.displayName=Rg.displayName;function f2(){return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"系统设置"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理您的应用偏好设置"})]})}),e.jsxs(ma,{defaultValue:"appearance",className:"w-full",children:[e.jsxs(ta,{className:"grid w-full grid-cols-2 sm:grid-cols-4 gap-0.5 sm:gap-1 h-auto p-1",children:[e.jsxs(as,{value:"appearance",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[e.jsx(zw,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),e.jsx("span",{children:"外观"})]}),e.jsxs(as,{value:"security",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[e.jsx(mj,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),e.jsx("span",{children:"安全"})]}),e.jsxs(as,{value:"other",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[e.jsx(In,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),e.jsx("span",{children:"其他"})]}),e.jsxs(as,{value:"about",className:"gap-1 sm:gap-2 text-xs sm:text-sm px-2 sm:px-3 py-2",children:[e.jsx(qt,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4",strokeWidth:2,fill:"none"}),e.jsx("span",{children:"关于"})]})]}),e.jsxs(es,{className:"h-[calc(100vh-240px)] sm:h-[calc(100vh-280px)] mt-4 sm:mt-6",children:[e.jsx(ys,{value:"appearance",className:"mt-0",children:e.jsx(p2,{})}),e.jsx(ys,{value:"security",className:"mt-0",children:e.jsx(g2,{})}),e.jsx(ys,{value:"other",className:"mt-0",children:e.jsx(j2,{})}),e.jsx(ys,{value:"about",className:"mt-0",children:e.jsx(v2,{})})]})]})]})}function tg(l){const n=document.documentElement,c={blue:{hsl:"221.2 83.2% 53.3%",darkHsl:"217.2 91.2% 59.8%",gradient:null},purple:{hsl:"271 91% 65%",darkHsl:"270 95% 75%",gradient:null},green:{hsl:"142 71% 45%",darkHsl:"142 76% 36%",gradient:null},orange:{hsl:"25 95% 53%",darkHsl:"20 90% 48%",gradient:null},pink:{hsl:"330 81% 60%",darkHsl:"330 85% 70%",gradient:null},red:{hsl:"0 84% 60%",darkHsl:"0 90% 70%",gradient:null},"gradient-sunset":{hsl:"15 95% 60%",darkHsl:"15 95% 65%",gradient:"linear-gradient(135deg, hsl(25 95% 53%) 0%, hsl(330 81% 60%) 100%)"},"gradient-ocean":{hsl:"200 90% 55%",darkHsl:"200 90% 60%",gradient:"linear-gradient(135deg, hsl(221.2 83.2% 53.3%) 0%, hsl(189 94% 43%) 100%)"},"gradient-forest":{hsl:"150 70% 45%",darkHsl:"150 75% 40%",gradient:"linear-gradient(135deg, hsl(142 71% 45%) 0%, hsl(158 64% 52%) 100%)"},"gradient-aurora":{hsl:"310 85% 65%",darkHsl:"310 90% 70%",gradient:"linear-gradient(135deg, hsl(271 91% 65%) 0%, hsl(330 81% 60%) 100%)"},"gradient-fire":{hsl:"15 95% 55%",darkHsl:"15 95% 60%",gradient:"linear-gradient(135deg, hsl(0 84% 60%) 0%, hsl(25 95% 53%) 100%)"},"gradient-twilight":{hsl:"250 90% 60%",darkHsl:"250 95% 65%",gradient:"linear-gradient(135deg, hsl(239 84% 67%) 0%, hsl(271 91% 65%) 100%)"}}[l];if(c)n.style.setProperty("--primary",c.hsl),c.gradient?(n.style.setProperty("--primary-gradient",c.gradient),n.classList.add("has-gradient")):(n.style.removeProperty("--primary-gradient"),n.classList.remove("has-gradient"));else if(l.startsWith("#")){const u=x=>{x=x.replace("#","");const h=parseInt(x.substring(0,2),16)/255,f=parseInt(x.substring(2,4),16)/255,p=parseInt(x.substring(4,6),16)/255,g=Math.max(h,f,p),N=Math.min(h,f,p);let v=0,b=0;const w=(g+N)/2;if(g!==N){const y=g-N;switch(b=w>.5?y/(2-g-N):y/(g+N),g){case h:v=((f-p)/y+(flocalStorage.getItem("accent-color")||"blue");m.useEffect(()=>{const g=localStorage.getItem("accent-color")||"blue";tg(g)},[]);const p=g=>{f(g),localStorage.setItem("accent-color",g),tg(g)};return e.jsxs("div",{className:"space-y-6 sm:space-y-8",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"主题模式"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3 sm:gap-4",children:[e.jsx(gm,{value:"light",current:l,onChange:n,label:"浅色",description:"始终使用浅色主题"}),e.jsx(gm,{value:"dark",current:l,onChange:n,label:"深色",description:"始终使用深色主题"}),e.jsx(gm,{value:"system",current:l,onChange:n,label:"跟随系统",description:"根据系统设置自动切换"})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"主题色"}),e.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs sm:text-sm font-medium mb-2 sm:mb-3",children:"单色"}),e.jsxs("div",{className:"grid grid-cols-3 sm:grid-cols-6 gap-2 sm:gap-3",children:[e.jsx(Ba,{value:"blue",current:h,onChange:p,label:"蓝色",colorClass:"bg-blue-500"}),e.jsx(Ba,{value:"purple",current:h,onChange:p,label:"紫色",colorClass:"bg-purple-500"}),e.jsx(Ba,{value:"green",current:h,onChange:p,label:"绿色",colorClass:"bg-green-500"}),e.jsx(Ba,{value:"orange",current:h,onChange:p,label:"橙色",colorClass:"bg-orange-500"}),e.jsx(Ba,{value:"pink",current:h,onChange:p,label:"粉色",colorClass:"bg-pink-500"}),e.jsx(Ba,{value:"red",current:h,onChange:p,label:"红色",colorClass:"bg-red-500"})]})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs sm:text-sm font-medium mb-2 sm:mb-3",children:"渐变色"}),e.jsxs("div",{className:"grid grid-cols-3 sm:grid-cols-6 gap-2 sm:gap-3",children:[e.jsx(Ba,{value:"gradient-sunset",current:h,onChange:p,label:"日落",colorClass:"bg-gradient-to-r from-orange-500 to-pink-500"}),e.jsx(Ba,{value:"gradient-ocean",current:h,onChange:p,label:"海洋",colorClass:"bg-gradient-to-r from-blue-500 to-cyan-500"}),e.jsx(Ba,{value:"gradient-forest",current:h,onChange:p,label:"森林",colorClass:"bg-gradient-to-r from-green-500 to-emerald-500"}),e.jsx(Ba,{value:"gradient-aurora",current:h,onChange:p,label:"极光",colorClass:"bg-gradient-to-r from-purple-500 to-pink-500"}),e.jsx(Ba,{value:"gradient-fire",current:h,onChange:p,label:"烈焰",colorClass:"bg-gradient-to-r from-red-500 to-orange-500"}),e.jsx(Ba,{value:"gradient-twilight",current:h,onChange:p,label:"暮光",colorClass:"bg-gradient-to-r from-indigo-500 to-purple-500"})]})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs sm:text-sm font-medium mb-2 sm:mb-3",children:"自定义颜色"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3 sm:gap-4",children:[e.jsx("div",{className:"flex-1",children:e.jsx("input",{type:"color",value:h.startsWith("#")?h:"#3b82f6",onChange:g=>p(g.target.value),className:"h-10 sm:h-12 w-full rounded-lg border-2 border-border cursor-pointer",title:"选择自定义颜色"})}),e.jsx("div",{className:"flex-1",children:e.jsx(ie,{type:"text",value:h,onChange:g=>p(g.target.value),placeholder:"#3b82f6",className:"font-mono text-sm"})})]}),e.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground mt-2",children:"点击色块选择颜色,或手动输入 HEX 颜色代码"})]})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"动画效果"}),e.jsxs("div",{className:"space-y-2 sm:space-y-3",children:[e.jsx("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5 flex-1",children:[e.jsx(E,{htmlFor:"animations",className:"text-base font-medium cursor-pointer",children:"启用动画效果"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"关闭后将禁用所有过渡动画和特效,提升性能"})]}),e.jsx(Ge,{id:"animations",checked:i,onCheckedChange:c})]})}),e.jsx("div",{className:"rounded-lg border bg-card p-4",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5 flex-1",children:[e.jsx(E,{htmlFor:"waves-background",className:"text-base font-medium cursor-pointer",children:"登录页波浪背景"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"关闭后登录页将使用纯色背景,适合低性能设备"})]}),e.jsx(Ge,{id:"waves-background",checked:u,onCheckedChange:x})]})})]})]})]})}function g2(){const l=aa(),[n,i]=m.useState(""),[c,u]=m.useState(""),[x,h]=m.useState(!1),[f,p]=m.useState(!1),[g,N]=m.useState(!1),[v,b]=m.useState(!1),[w,y]=m.useState(!1),[R,D]=m.useState(!1),[k,I]=m.useState(""),[M,S]=m.useState(!1),{toast:T}=Ws(),$=m.useMemo(()=>a2(c),[c]),A=async le=>{if(!n){T({title:"无法复制",description:"Token 存储在安全 Cookie 中,请重新生成以获取新 Token",variant:"destructive"});return}try{await navigator.clipboard.writeText(le),y(!0),T({title:"复制成功",description:"Token 已复制到剪贴板"}),setTimeout(()=>y(!1),2e3)}catch{T({title:"复制失败",description:"请手动复制 Token",variant:"destructive"})}},Q=async()=>{if(!c.trim()){T({title:"输入错误",description:"请输入新的 Token",variant:"destructive"});return}if(!$.isValid){const le=$.rules.filter(fe=>!fe.passed).map(fe=>fe.label).join(", ");T({title:"格式错误",description:`Token 不符合要求: ${le}`,variant:"destructive"});return}N(!0);try{const le=await fetch("/api/webui/auth/update",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({new_token:c.trim()})}),fe=await le.json();le.ok&&fe.success?(u(""),i(c.trim()),T({title:"更新成功",description:"Access Token 已更新,即将跳转到登录页"}),setTimeout(()=>{l({to:"/auth"})},1500)):T({title:"更新失败",description:fe.message||"无法更新 Token",variant:"destructive"})}catch(le){console.error("更新 Token 错误:",le),T({title:"更新失败",description:"连接服务器失败",variant:"destructive"})}finally{N(!1)}},G=async()=>{b(!0);try{const le=await fetch("/api/webui/auth/regenerate",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include"}),fe=await le.json();le.ok&&fe.success?(i(fe.token),I(fe.token),D(!0),S(!1),T({title:"生成成功",description:"新的 Access Token 已生成,请及时保存"})):T({title:"生成失败",description:fe.message||"无法生成新 Token",variant:"destructive"})}catch(le){console.error("生成 Token 错误:",le),T({title:"生成失败",description:"连接服务器失败",variant:"destructive"})}finally{b(!1)}},de=async()=>{try{await navigator.clipboard.writeText(k),S(!0),T({title:"复制成功",description:"Token 已复制到剪贴板"})}catch{T({title:"复制失败",description:"请手动复制 Token",variant:"destructive"})}},oe=()=>{D(!1),setTimeout(()=>{I(""),S(!1)},300),setTimeout(()=>{l({to:"/auth"})},500)},ve=le=>{le||oe()};return e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsx(Ks,{open:R,onOpenChange:ve,children:e.jsxs(Ps,{className:"sm:max-w-md",children:[e.jsxs(Hs,{children:[e.jsxs(Gs,{className:"flex items-center gap-2",children:[e.jsx(Ft,{className:"h-5 w-5 text-yellow-500"}),"新的 Access Token"]}),e.jsx(ot,{children:"这是您的新 Token,请立即保存。关闭此窗口后将跳转到登录页面。"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border-2 border-primary/20 bg-primary/5 p-4",children:[e.jsx(E,{className:"text-xs text-muted-foreground mb-2 block",children:"您的新 Token (64位安全令牌)"}),e.jsx("div",{className:"font-mono text-sm break-all select-all bg-background p-3 rounded border",children:k})]}),e.jsx("div",{className:"rounded-lg border border-yellow-200 dark:border-yellow-900 bg-yellow-50 dark:bg-yellow-950/30 p-3",children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Ft,{className:"h-4 w-4 text-yellow-600 dark:text-yellow-500 flex-shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm text-yellow-800 dark:text-yellow-300 space-y-1",children:[e.jsx("p",{className:"font-semibold",children:"重要提示"}),e.jsxs("ul",{className:"list-disc list-inside space-y-0.5 text-xs",children:[e.jsx("li",{children:"此 Token 仅显示一次,关闭后无法再查看"}),e.jsx("li",{children:"请立即复制并保存到安全的位置"}),e.jsx("li",{children:"关闭窗口后将自动跳转到登录页面"}),e.jsx("li",{children:"请使用新 Token 重新登录系统"})]})]})]})})]}),e.jsxs(xt,{className:"gap-2 sm:gap-0",children:[e.jsx(C,{variant:"outline",onClick:de,className:"gap-2",children:M?e.jsxs(e.Fragment,{children:[e.jsx(St,{className:"h-4 w-4 text-green-500"}),"已复制"]}):e.jsxs(e.Fragment,{children:[e.jsx(ko,{className:"h-4 w-4"}),"复制 Token"]})}),e.jsx(C,{onClick:oe,children:"我已保存,关闭"})]})]})}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"当前 Access Token"}),e.jsx("div",{className:"space-y-3 sm:space-y-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"current-token",className:"text-sm",children:"您的访问令牌"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(ie,{id:"current-token",type:x?"text":"password",value:n||"••••••••••••••••••••••••••••••••",readOnly:!0,className:"pr-10 font-mono text-sm",placeholder:"Token 存储在安全 Cookie 中"}),e.jsx("button",{onClick:()=>{n?h(!x):T({title:"无法查看",description:'Token 存储在安全 Cookie 中,如需新 Token 请点击"重新生成"'})},className:"absolute right-2 top-1/2 -translate-y-1/2 p-1.5 hover:bg-accent rounded",title:x?"隐藏":"显示",children:x?e.jsx(Hi,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(sa,{className:"h-4 w-4 text-muted-foreground"})})]}),e.jsxs("div",{className:"flex gap-2 w-full sm:w-auto",children:[e.jsx(C,{variant:"outline",size:"icon",onClick:()=>A(n),title:"复制到剪贴板",className:"flex-shrink-0",disabled:!n,children:w?e.jsx(St,{className:"h-4 w-4 text-green-500"}):e.jsx(ko,{className:"h-4 w-4"})}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{variant:"outline",disabled:v,className:"gap-2 flex-1 sm:flex-none",children:[e.jsx(kt,{className:B("h-4 w-4",v&&"animate-spin")}),e.jsx("span",{className:"hidden sm:inline",children:"重新生成"}),e.jsx("span",{className:"sm:hidden",children:"生成"})]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认重新生成 Token"}),e.jsx(xs,{children:"这将生成一个新的 64 位安全令牌,并使当前 Token 立即失效。 您需要使用新 Token 重新登录系统。此操作不可撤销,确定要继续吗?"})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:G,children:"确认生成"})]})]})]})]})]}),e.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground",children:"请妥善保管您的 Access Token,不要泄露给他人"})]})})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"自定义 Access Token"}),e.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"new-token",className:"text-sm",children:"新的访问令牌"}),e.jsxs("div",{className:"relative",children:[e.jsx(ie,{id:"new-token",type:f?"text":"password",value:c,onChange:le=>u(le.target.value),className:"pr-10 font-mono text-sm",placeholder:"输入自定义 Token"}),e.jsx("button",{onClick:()=>p(!f),className:"absolute right-2 top-1/2 -translate-y-1/2 p-1.5 hover:bg-accent rounded",title:f?"隐藏":"显示",children:f?e.jsx(Hi,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(sa,{className:"h-4 w-4 text-muted-foreground"})})]}),c&&e.jsxs("div",{className:"mt-3 space-y-2 p-3 rounded-lg bg-muted/50",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"Token 安全要求:"}),e.jsx("div",{className:"space-y-1.5",children:$.rules.map(le=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[le.passed?e.jsx(ea,{className:"h-4 w-4 text-green-500 flex-shrink-0"}):e.jsx(xj,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),e.jsx("span",{className:B(le.passed?"text-green-600 dark:text-green-400":"text-muted-foreground"),children:le.label})]},le.id))}),$.isValid&&e.jsx("div",{className:"mt-2 pt-2 border-t border-border",children:e.jsxs("div",{className:"flex items-center gap-2 text-sm text-green-600 dark:text-green-400",children:[e.jsx(St,{className:"h-4 w-4"}),e.jsx("span",{className:"font-medium",children:"Token 格式正确,可以使用"})]})})]})]}),e.jsx(C,{onClick:Q,disabled:g||!$.isValid||!c,className:"w-full sm:w-auto",children:g?"更新中...":"更新自定义 Token"})]})]}),e.jsxs("div",{className:"rounded-lg border border-yellow-200 dark:border-yellow-900 bg-yellow-50 dark:bg-yellow-950/30 p-3 sm:p-4",children:[e.jsx("h4",{className:"text-sm sm:text-base font-semibold text-yellow-900 dark:text-yellow-200 mb-2",children:"安全提示"}),e.jsxs("ul",{className:"text-xs sm:text-sm text-yellow-800 dark:text-yellow-300 space-y-1 list-disc list-inside",children:[e.jsx("li",{children:"重新生成 Token 会创建系统随机生成的 64 位安全令牌"}),e.jsx("li",{children:"自定义 Token 必须满足所有安全要求才能使用"}),e.jsx("li",{children:"更新 Token 后,旧的 Token 将立即失效"}),e.jsx("li",{children:"请在安全的环境下查看和复制 Token"}),e.jsx("li",{children:"如果怀疑 Token 泄露,请立即重新生成或更新"}),e.jsx("li",{children:"建议使用系统生成的 Token 以获得最高安全性"})]})]})]})}function j2(){const l=aa(),{toast:n}=Ws(),[i,c]=m.useState(!1),[u,x]=m.useState(!1),[h,f]=m.useState(()=>Nt("logCacheSize")),[p,g]=m.useState(()=>Nt("wsReconnectInterval")),[N,v]=m.useState(()=>Nt("wsMaxReconnectAttempts")),[b,w]=m.useState(()=>Nt("dataSyncInterval")),[y,R]=m.useState(()=>sg()),[D,k]=m.useState(!1),[I,M]=m.useState(!1),S=m.useRef(null);if(u)throw new Error("这是一个手动触发的测试错误,用于验证错误边界组件是否正常工作。");const T=()=>{R(sg())},$=z=>{const V=z[0];f(V),Mr("logCacheSize",V)},A=z=>{const V=z[0];g(V),Mr("wsReconnectInterval",V)},Q=z=>{const V=z[0];v(V),Mr("wsMaxReconnectAttempts",V)},G=z=>{const V=z[0];w(V),Mr("dataSyncInterval",V)},de=()=>{Mn.clearLogs(),n({title:"日志已清除",description:"日志缓存已清空"})},oe=()=>{const z=d2();T(),n({title:"缓存已清除",description:`已清除 ${z.clearedKeys.length} 项缓存数据`})},ve=()=>{k(!0);try{const z=i2(),V=JSON.stringify(z,null,2),U=new Blob([V],{type:"application/json"}),L=URL.createObjectURL(U),P=document.createElement("a");P.href=L,P.download=`maibot-webui-settings-${new Date().toISOString().slice(0,10)}.json`,document.body.appendChild(P),P.click(),document.body.removeChild(P),URL.revokeObjectURL(L),n({title:"导出成功",description:"设置已导出为 JSON 文件"})}catch(z){console.error("导出设置失败:",z),n({title:"导出失败",description:"无法导出设置",variant:"destructive"})}finally{k(!1)}},le=z=>{const V=z.target.files?.[0];if(!V)return;M(!0);const U=new FileReader;U.onload=L=>{try{const P=L.target?.result,_e=JSON.parse(P),je=c2(_e);je.success?(f(Nt("logCacheSize")),g(Nt("wsReconnectInterval")),v(Nt("wsMaxReconnectAttempts")),w(Nt("dataSyncInterval")),T(),n({title:"导入成功",description:`成功导入 ${je.imported.length} 项设置${je.skipped.length>0?`,跳过 ${je.skipped.length} 项`:""}`}),(je.imported.includes("theme")||je.imported.includes("accentColor"))&&n({title:"提示",description:"部分设置需要刷新页面才能完全生效"})):n({title:"导入失败",description:"没有有效的设置项可导入",variant:"destructive"})}catch(P){console.error("导入设置失败:",P),n({title:"导入失败",description:"文件格式无效",variant:"destructive"})}finally{M(!1),S.current&&(S.current.value="")}},U.readAsText(V)},fe=()=>{o2(),f(sl.logCacheSize),g(sl.wsReconnectInterval),v(sl.wsMaxReconnectAttempts),w(sl.dataSyncInterval),T(),n({title:"已重置",description:"所有设置已恢复为默认值,刷新页面以应用更改"})},ge=async()=>{c(!0);try{const z=await we("/api/webui/setup/reset",{method:"POST"}),V=await z.json();z.ok&&V.success?(n({title:"重置成功",description:"即将进入初次配置向导"}),setTimeout(()=>{l({to:"/setup"})},1e3)):n({title:"重置失败",description:V.message||"无法重置配置状态",variant:"destructive"})}catch(z){console.error("重置配置状态错误:",z),n({title:"重置失败",description:"连接服务器失败",variant:"destructive"})}finally{c(!1)}};return e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsxs("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4 flex items-center gap-2",children:[e.jsx(zr,{className:"h-5 w-5"}),"性能与存储"]}),e.jsxs("div",{className:"space-y-4 sm:space-y-5",children:[e.jsxs("div",{className:"rounded-lg bg-muted/50 p-3 sm:p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("span",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Dw,{className:"h-4 w-4"}),"本地存储使用"]}),e.jsx(C,{variant:"ghost",size:"sm",onClick:T,className:"h-7 px-2",children:e.jsx(kt,{className:"h-3 w-3"})})]}),e.jsx("div",{className:"text-2xl font-bold text-primary",children:u2(y.used)}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[y.items," 个存储项"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-sm font-medium",children:"日志缓存大小"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[h," 条"]})]}),e.jsx(wa,{value:[h],onValueChange:$,min:100,max:5e3,step:100,className:"w-full"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"控制日志查看器最多缓存的日志条数,较大的值会占用更多内存"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-sm font-medium",children:"首页数据刷新间隔"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[b," 秒"]})]}),e.jsx(wa,{value:[b],onValueChange:G,min:10,max:120,step:5,className:"w-full"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"控制首页统计数据的自动刷新间隔"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-sm font-medium",children:"WebSocket 重连间隔"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[p/1e3," 秒"]})]}),e.jsx(wa,{value:[p],onValueChange:A,min:1e3,max:1e4,step:500,className:"w-full"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"日志 WebSocket 连接断开后的重连基础间隔"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-sm font-medium",children:"WebSocket 最大重连次数"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[N," 次"]})]}),e.jsx(wa,{value:[N],onValueChange:Q,min:3,max:30,step:1,className:"w-full"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"连接失败后的最大重连尝试次数"})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-2",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:de,className:"gap-2",children:[e.jsx(ls,{className:"h-4 w-4"}),"清除日志缓存"]}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",className:"gap-2",children:[e.jsx(ls,{className:"h-4 w-4"}),"清除本地缓存"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认清除本地缓存"}),e.jsx(xs,{children:"这将清除所有本地缓存的设置和数据(不包括登录凭证)。 您可能需要重新配置部分偏好设置。确定要继续吗?"})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:oe,children:"确认清除"})]})]})]})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsxs("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4 flex items-center gap-2",children:[e.jsx(Xt,{className:"h-5 w-5"}),"导入/导出设置"]}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"导出当前的界面设置以便备份,或从之前导出的文件中恢复设置。"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(C,{variant:"outline",onClick:ve,disabled:D,className:"gap-2",children:[e.jsx(Xt,{className:"h-4 w-4"}),D?"导出中...":"导出设置"]}),e.jsx("input",{ref:S,type:"file",accept:".json",onChange:le,className:"hidden"}),e.jsxs(C,{variant:"outline",onClick:()=>S.current?.click(),disabled:I,className:"gap-2",children:[e.jsx(Gi,{className:"h-4 w-4"}),I?"导入中...":"导入设置"]})]}),e.jsx("div",{className:"pt-2 border-t",children:e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",className:"gap-2 text-destructive hover:text-destructive",children:[e.jsx(Pi,{className:"h-4 w-4"}),"重置所有设置为默认值"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认重置所有设置"}),e.jsx(xs,{children:"这将把所有界面设置恢复为默认值,包括主题、颜色、动画等偏好设置。 此操作不会影响您的登录状态。确定要继续吗?"})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:fe,children:"确认重置"})]})]})]})})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"配置向导"}),e.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[e.jsx("div",{className:"space-y-2",children:e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"重新进行初次配置向导,可以帮助您重新设置系统的基础配置。"})}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{variant:"outline",disabled:i,className:"gap-2",children:[e.jsx(Pi,{className:B("h-4 w-4",i&&"animate-spin")}),"重新进行初次配置"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认重新配置"}),e.jsx(xs,{children:"这将带您重新进入初次配置向导。您可以重新设置系统的基础配置项。确定要继续吗?"})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:ge,children:"确认重置"})]})]})]})]})]}),e.jsxs("div",{className:"rounded-lg border border-dashed border-yellow-500/50 bg-yellow-500/5 p-4 sm:p-6",children:[e.jsxs("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4 flex items-center gap-2",children:[e.jsx(Ft,{className:"h-5 w-5 text-yellow-500"}),"开发者工具"]}),e.jsxs("div",{className:"space-y-3 sm:space-y-4",children:[e.jsx("div",{className:"space-y-2",children:e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"以下功能仅供开发调试使用,可能会导致页面崩溃或异常。"})}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{variant:"destructive",className:"gap-2",children:[e.jsx(Ft,{className:"h-4 w-4"}),"触发测试错误"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认触发错误"}),e.jsx(xs,{children:"这将手动触发一个 React 错误,用于测试错误边界组件的显示效果。 页面将显示错误界面,您可以通过刷新页面或点击返回首页来恢复。"})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>x(!0),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认触发"})]})]})]})]})]})]})}function v2(){return e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsx("div",{className:"rounded-lg border-2 border-primary/30 bg-gradient-to-r from-primary/5 to-primary/10 p-4 sm:p-6",children:e.jsxs("div",{className:"flex items-start gap-3 sm:gap-4",children:[e.jsx("div",{className:"flex-shrink-0 rounded-lg bg-primary/10 p-2 sm:p-3",children:e.jsx("svg",{className:"h-6 w-6 sm:h-8 sm:w-8 text-primary",fill:"currentColor",viewBox:"0 0 24 24","aria-hidden":"true",children:e.jsx("path",{fillRule:"evenodd",d:"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z",clipRule:"evenodd"})})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("h3",{className:"text-lg sm:text-xl font-bold text-foreground mb-2",children:"开源项目"}),e.jsx("p",{className:"text-sm sm:text-base text-muted-foreground mb-3",children:"本项目在 GitHub 开源,欢迎 Star ⭐ 支持!"}),e.jsxs("a",{href:"https://github.com/Mai-with-u/MaiBot-Dashboard",target:"_blank",rel:"noopener noreferrer",className:B("inline-flex items-center gap-2 px-4 py-2 rounded-lg","bg-primary text-primary-foreground font-medium text-sm","hover:bg-primary/90 transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"),children:[e.jsx("svg",{className:"h-4 w-4",fill:"currentColor",viewBox:"0 0 24 24","aria-hidden":"true",children:e.jsx("path",{fillRule:"evenodd",d:"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z",clipRule:"evenodd"})}),"前往 GitHub",e.jsx("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"})})]})]})]})}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsxs("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:["关于 ",$m]}),e.jsxs("div",{className:"space-y-2 text-xs sm:text-sm text-muted-foreground",children:[e.jsxs("p",{children:["版本: ",Po]}),e.jsx("p",{children:"麦麦(MaiBot)的现代化 Web 管理界面"})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"作者"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-sm font-medium",children:"MaiBot 核心"}),e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"Mai-with-u"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-sm font-medium",children:"WebUI"}),e.jsxs("p",{className:"text-xs sm:text-sm text-muted-foreground",children:["Mai-with-u ",e.jsx("a",{href:"https://github.com/DrSmoothl",target:"_blank",rel:"noopener noreferrer",className:"text-primary underline",children:"@MotricSeven"})]})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"技术栈"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 text-xs sm:text-sm text-muted-foreground",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"font-medium text-foreground",children:"前端框架"}),e.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[e.jsx("li",{children:"React 19.2.0"}),e.jsx("li",{children:"TypeScript 5.7.2"}),e.jsx("li",{children:"Vite 6.0.7"}),e.jsx("li",{children:"TanStack Router 1.94.2"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"font-medium text-foreground",children:"UI 组件"}),e.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[e.jsx("li",{children:"shadcn/ui"}),e.jsx("li",{children:"Radix UI"}),e.jsx("li",{children:"Tailwind CSS 3.4.17"}),e.jsx("li",{children:"Lucide Icons"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"font-medium text-foreground",children:"后端"}),e.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[e.jsx("li",{children:"Python 3.12+"}),e.jsx("li",{children:"FastAPI"}),e.jsx("li",{children:"Uvicorn"}),e.jsx("li",{children:"WebSocket"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"font-medium text-foreground",children:"构建工具"}),e.jsxs("ul",{className:"space-y-0.5 list-disc list-inside",children:[e.jsx("li",{children:"Bun / npm"}),e.jsx("li",{children:"ESLint 9.17.0"}),e.jsx("li",{children:"PostCSS"})]})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"开源库感谢"}),e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground mb-3",children:"本项目使用了以下优秀的开源库,感谢他们的贡献:"}),e.jsx(es,{className:"h-[300px] sm:h-[400px]",children:e.jsxs("div",{className:"space-y-4 pr-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"UI 框架与组件"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"React",description:"用户界面构建库",license:"MIT"}),e.jsx(ft,{name:"shadcn/ui",description:"优雅的 React 组件库",license:"MIT"}),e.jsx(ft,{name:"Radix UI",description:"无样式的可访问组件库",license:"MIT"}),e.jsx(ft,{name:"Tailwind CSS",description:"实用优先的 CSS 框架",license:"MIT"}),e.jsx(ft,{name:"Lucide React",description:"精美的图标库",license:"ISC"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"路由与状态管理"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"TanStack Router",description:"类型安全的路由库",license:"MIT"}),e.jsx(ft,{name:"Zustand",description:"轻量级状态管理",license:"MIT"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"表单处理"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"React Hook Form",description:"高性能表单库",license:"MIT"}),e.jsx(ft,{name:"Zod",description:"TypeScript 优先的 schema 验证",license:"MIT"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"工具库"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"clsx",description:"条件 className 构建工具",license:"MIT"}),e.jsx(ft,{name:"tailwind-merge",description:"Tailwind 类名合并工具",license:"MIT"}),e.jsx(ft,{name:"class-variance-authority",description:"组件变体管理",license:"Apache-2.0"}),e.jsx(ft,{name:"date-fns",description:"现代化日期处理库",license:"MIT"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"动画效果"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"Framer Motion",description:"React 动画库",license:"MIT"}),e.jsx(ft,{name:"vaul",description:"抽屉组件动画",license:"MIT"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"后端框架"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"FastAPI",description:"现代化 Python Web 框架",license:"MIT"}),e.jsx(ft,{name:"Uvicorn",description:"ASGI 服务器",license:"BSD-3-Clause"}),e.jsx(ft,{name:"Pydantic",description:"数据验证库",license:"MIT"}),e.jsx(ft,{name:"python-multipart",description:"文件上传支持",license:"Apache-2.0"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"开发工具"}),e.jsxs("div",{className:"grid gap-2 text-xs sm:text-sm",children:[e.jsx(ft,{name:"TypeScript",description:"JavaScript 的超集",license:"Apache-2.0"}),e.jsx(ft,{name:"Vite",description:"下一代前端构建工具",license:"MIT"}),e.jsx(ft,{name:"ESLint",description:"JavaScript 代码检查工具",license:"MIT"}),e.jsx(ft,{name:"PostCSS",description:"CSS 转换工具",license:"MIT"})]})]})]})})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6",children:[e.jsx("h3",{className:"text-base sm:text-lg font-semibold mb-3 sm:mb-4",children:"开源许可"}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"rounded-lg bg-primary/5 border border-primary/20 p-3 sm:p-4",children:e.jsxs("div",{className:"flex items-start gap-2 sm:gap-3",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("div",{className:"rounded-md bg-primary/10 px-2 py-1",children:e.jsx("span",{className:"text-xs sm:text-sm font-bold text-primary",children:"GPLv3"})})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm sm:text-base font-semibold text-foreground mb-1",children:"MaiBot WebUI"}),e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"本项目采用 GNU General Public License v3.0 开源许可证。 您可以自由地使用、修改和分发本软件,但必须保持相同的开源许可。"})]})]})}),e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground",children:"本项目依赖的所有开源库均遵循各自的开源许可证(MIT、Apache-2.0、BSD 等)。 感谢所有开源贡献者的无私奉献。"})]})]})]})}function ft({name:l,description:n,license:i}){return e.jsxs("div",{className:"flex items-start justify-between gap-2 rounded-lg border bg-muted/30 p-2.5 sm:p-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-medium text-foreground truncate",children:l}),e.jsx("p",{className:"text-muted-foreground text-xs mt-0.5",children:n})]}),e.jsx("span",{className:"inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary flex-shrink-0",children:i})]})}function gm({value:l,current:n,onChange:i,label:c,description:u}){const x=n===l;return e.jsxs("button",{onClick:()=>i(l),className:B("relative rounded-lg border-2 p-3 sm:p-4 text-left transition-all","hover:border-primary/50 hover:bg-accent/50",x?"border-primary bg-accent":"border-border"),children:[x&&e.jsx("div",{className:"absolute top-2 right-2 sm:top-3 sm:right-3 h-2 w-2 rounded-full bg-primary"}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-sm sm:text-base font-medium",children:c}),e.jsx("div",{className:"text-[10px] sm:text-xs text-muted-foreground",children:u})]}),e.jsxs("div",{className:"mt-2 sm:mt-3 flex gap-1",children:[l==="light"&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-200"}),e.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-300"}),e.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-400"})]}),l==="dark"&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-700"}),e.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-800"}),e.jsx("div",{className:"h-2 w-2 rounded-full bg-slate-900"})]}),l==="system"&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-2 w-2 rounded-full bg-gradient-to-r from-slate-200 to-slate-700"}),e.jsx("div",{className:"h-2 w-2 rounded-full bg-gradient-to-r from-slate-300 to-slate-800"}),e.jsx("div",{className:"h-2 w-2 rounded-full bg-gradient-to-r from-slate-400 to-slate-900"})]})]})]})}function Ba({value:l,current:n,onChange:i,label:c,colorClass:u}){const x=n===l;return e.jsxs("button",{onClick:()=>i(l),className:B("relative rounded-lg border-2 p-2 sm:p-3 text-left transition-all","hover:border-primary/50 hover:bg-accent/50",x?"border-primary bg-accent":"border-border"),children:[x&&e.jsx("div",{className:"absolute top-1.5 right-1.5 sm:top-2 sm:right-2 h-1.5 w-1.5 sm:h-2 sm:w-2 rounded-full bg-primary"}),e.jsxs("div",{className:"flex flex-col items-center gap-1.5 sm:gap-2",children:[e.jsx("div",{className:B("h-8 w-8 sm:h-10 sm:w-10 rounded-full",u)}),e.jsx("div",{className:"text-[10px] sm:text-xs font-medium text-center",children:c})]})]})}const N2=Date.now()%1e6;class b2{grad3;p;perm;constructor(n=0){this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.p=[];for(let i=0;i<256;i++)this.p[i]=Math.floor(Math.random()*256);this.perm=[];for(let i=0;i<512;i++)this.perm[i]=this.p[i&255]}dot(n,i,c){return n[0]*i+n[1]*c}mix(n,i,c){return(1-c)*n+c*i}fade(n){return n*n*n*(n*(n*6-15)+10)}perlin2(n,i){const c=Math.floor(n)&255,u=Math.floor(i)&255;n-=Math.floor(n),i-=Math.floor(i);const x=this.fade(n),h=this.fade(i),f=this.perm[c]+u,p=this.perm[f],g=this.perm[f+1],N=this.perm[c+1]+u,v=this.perm[N],b=this.perm[N+1];return this.mix(this.mix(this.dot(this.grad3[p%12],n,i),this.dot(this.grad3[v%12],n-1,i),x),this.mix(this.dot(this.grad3[g%12],n,i-1),this.dot(this.grad3[b%12],n-1,i-1),x),h)}}function ag(){const l=m.useRef(null),n=m.useRef(null),i=m.useRef(void 0),[c]=m.useState(()=>new b2(N2)),u=m.useRef({mouse:{x:-10,y:0,lx:0,ly:0,sx:0,sy:0,v:0,vs:0,a:0,set:!1},lines:[],paths:[],noise:c,bounding:null});return m.useEffect(()=>{const x=n.current,h=l.current;if(!x||!h)return;const f=u.current;f.noise=c;const p=()=>{const D=x.getBoundingClientRect();f.bounding=D,h.style.width=`${D.width}px`,h.style.height=`${D.height}px`},g=()=>{if(!f.bounding)return;const{width:D,height:k}=f.bounding;f.lines=[],f.paths.forEach(de=>de.remove()),f.paths=[];const I=10,M=32,S=D+200,T=k+30,$=Math.ceil(S/I),A=Math.ceil(T/M),Q=(D-I*$)/2,G=(k-M*A)/2;for(let de=0;de<=$;de++){const oe=[];for(let le=0;le<=A;le++){const fe={x:Q+I*de,y:G+M*le,wave:{x:0,y:0},cursor:{x:0,y:0,vx:0,vy:0}};oe.push(fe)}const ve=document.createElementNS("http://www.w3.org/2000/svg","path");h.appendChild(ve),f.paths.push(ve),f.lines.push(oe)}},N=D=>{const{lines:k,mouse:I,noise:M}=f;k.forEach(S=>{S.forEach(T=>{const $=M.perlin2((T.x+D*.0125)*.002,(T.y+D*.005)*.0015)*12;T.wave.x=Math.cos($)*32,T.wave.y=Math.sin($)*16;const A=T.x-I.sx,Q=T.y-I.sy,G=Math.hypot(A,Q),de=Math.max(175,I.vs);if(G{const I={x:D.x+D.wave.x+(k?D.cursor.x:0),y:D.y+D.wave.y+(k?D.cursor.y:0)};return I.x=Math.round(I.x*10)/10,I.y=Math.round(I.y*10)/10,I},b=()=>{const{lines:D,paths:k}=f;D.forEach((I,M)=>{let S=v(I[0],!1),T=`M ${S.x} ${S.y}`;I.forEach(($,A)=>{const Q=A===I.length-1;S=v($,!Q),T+=`L ${S.x} ${S.y}`}),k[M].setAttribute("d",T)})},w=D=>{const{mouse:k}=f;k.sx+=(k.x-k.sx)*.1,k.sy+=(k.y-k.sy)*.1;const I=k.x-k.lx,M=k.y-k.ly,S=Math.hypot(I,M);k.v=S,k.vs+=(S-k.vs)*.1,k.vs=Math.min(100,k.vs),k.lx=k.x,k.ly=k.y,k.a=Math.atan2(M,I),x&&(x.style.setProperty("--x",`${k.sx}px`),x.style.setProperty("--y",`${k.sy}px`)),N(D),b(),i.current=requestAnimationFrame(w)},y=D=>{if(!f.bounding)return;const{mouse:k}=f;k.x=D.pageX-f.bounding.left,k.y=D.pageY-f.bounding.top+window.scrollY,k.set||(k.sx=k.x,k.sy=k.y,k.lx=k.x,k.ly=k.y,k.set=!0)},R=()=>{p(),g()};return p(),g(),window.addEventListener("resize",R),window.addEventListener("mousemove",y),i.current=requestAnimationFrame(w),()=>{window.removeEventListener("resize",R),window.removeEventListener("mousemove",y),i.current&&cancelAnimationFrame(i.current)}},[c]),e.jsxs("div",{ref:n,className:"waves-background",style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",overflow:"hidden",pointerEvents:"none"},children:[e.jsx("div",{className:"waves-cursor",style:{position:"absolute",top:0,left:0,width:"0.5rem",height:"0.5rem",background:"hsl(var(--primary) / 0.3)",borderRadius:"50%",transform:"translate3d(calc(var(--x, -0.5rem) - 50%), calc(var(--y, 50%) - 50%), 0)",willChange:"transform",pointerEvents:"none"}}),e.jsx("svg",{ref:l,style:{display:"block",width:"100%",height:"100%"},children:e.jsx("style",{children:` + path { + fill: none; + stroke: hsl(var(--primary) / 0.20); + stroke-width: 1px; + } + `})})]})}function y2(){const[l,n]=m.useState(""),[i,c]=m.useState(!1),[u,x]=m.useState(""),[h,f]=m.useState(!0),p=aa(),{enableWavesBackground:g,setEnableWavesBackground:N}=Kj(),{theme:v,setTheme:b}=Bm();m.useEffect(()=>{(async()=>{try{await Fi()&&p({to:"/"})}catch{}finally{f(!1)}})()},[p]);const y=v==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":v,R=()=>{b(y==="dark"?"light":"dark")},D=async k=>{if(k.preventDefault(),x(""),!l.trim()){x("请输入 Access Token");return}c(!0),console.log("开始验证 token...");try{const I=await fetch("/api/webui/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({token:l.trim()})});console.log("Token 验证响应状态:",I.status);const M=await I.json();if(console.log("Token 验证响应数据:",M),I.ok&&M.valid){console.log("Token 验证成功,准备跳转..."),console.log("is_first_setup:",M.is_first_setup),await new Promise(T=>setTimeout(T,100));const S=await Fi();console.log("跳转前认证状态检查:",S),M.is_first_setup?(console.log("跳转到首次配置页面"),p({to:"/setup"})):(console.log("跳转到首页"),p({to:"/"}))}else console.error("Token 验证失败:",M.message),x(M.message||"Token 验证失败,请检查后重试")}catch(I){console.error("Token 验证错误:",I),x("连接服务器失败,请检查网络连接")}finally{c(!1)}};return h?e.jsxs("div",{className:"relative flex min-h-screen items-center justify-center overflow-hidden bg-background p-4",children:[g&&e.jsx(ag,{}),e.jsx("div",{className:"text-muted-foreground",children:"正在检查登录状态..."})]}):e.jsxs("div",{className:"relative flex min-h-screen items-center justify-center overflow-hidden bg-background p-4",children:[g&&e.jsx(ag,{}),e.jsxs(De,{className:"relative z-10 w-full max-w-md shadow-2xl backdrop-blur-xl bg-card/80 border-border/50",children:[e.jsx("button",{onClick:R,className:"absolute right-4 top-4 rounded-lg p-2 hover:bg-accent transition-colors z-10 text-foreground",title:y==="dark"?"切换到浅色模式":"切换到深色模式",children:y==="dark"?e.jsx(hj,{className:"h-5 w-5",strokeWidth:2.5,fill:"none"}):e.jsx(fj,{className:"h-5 w-5",strokeWidth:2.5,fill:"none"})}),e.jsxs(Xe,{className:"space-y-4 text-center",children:[e.jsx("div",{className:"mx-auto flex h-16 w-16 items-center justify-center rounded-2xl bg-primary/10",children:e.jsx(qp,{className:"h-8 w-8 text-primary",strokeWidth:2,fill:"none"})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(We,{className:"text-2xl font-bold",children:"欢迎使用 MaiBot"}),e.jsx(Is,{className:"text-base",children:"请输入您的 Access Token 以继续访问系统"})]})]}),e.jsx(Qe,{children:e.jsxs("form",{onSubmit:D,className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"token",className:"text-sm font-medium",children:"Access Token"}),e.jsxs("div",{className:"relative",children:[e.jsx(Om,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground",strokeWidth:2,fill:"none"}),e.jsx(ie,{id:"token",type:"password",placeholder:"请输入您的 Access Token",value:l,onChange:k=>n(k.target.value),className:B("pl-10",u&&"border-red-500 focus-visible:ring-red-500"),disabled:i,autoFocus:!0,autoComplete:"off"})]})]}),u&&e.jsxs("div",{className:"flex items-center gap-2 rounded-md bg-red-50 p-3 text-sm text-red-600 dark:bg-red-950/50 dark:text-red-400",children:[e.jsx(Ct,{className:"h-4 w-4 flex-shrink-0",strokeWidth:2,fill:"none"}),e.jsx("span",{children:u})]}),e.jsx(C,{type:"submit",className:"w-full",disabled:i,children:i?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"}),"验证中..."]}):"验证并进入"}),e.jsxs(Ks,{children:[e.jsx(Ho,{asChild:!0,children:e.jsxs("button",{className:"w-full text-center text-sm text-primary hover:text-primary/80 transition-colors underline-offset-4 hover:underline flex items-center justify-center gap-1",children:[e.jsx(pj,{className:"h-4 w-4",strokeWidth:2,fill:"none"}),"我没有 Token,我该去哪里获得 Token?"]})}),e.jsxs(Ps,{className:"sm:max-w-md",children:[e.jsxs(Hs,{children:[e.jsxs(Gs,{className:"flex items-center gap-2",children:[e.jsx(qp,{className:"h-5 w-5 text-primary",strokeWidth:2,fill:"none"}),"如何获取 Access Token"]}),e.jsx(ot,{children:"Access Token 是访问 MaiBot WebUI 的唯一凭证,请按以下方式获取"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"rounded-lg border bg-muted/50 p-4 space-y-2",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Ow,{className:"h-5 w-5 text-primary flex-shrink-0 mt-0.5",strokeWidth:2,fill:"none"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx("h4",{className:"font-semibold text-sm",children:"方式一:查看启动日志"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"在 MaiBot 启动时,控制台会显示 WebUI Access Token。"}),e.jsxs("div",{className:"rounded bg-background p-2 font-mono text-xs",children:[e.jsx("p",{className:"text-muted-foreground",children:"🔑 WebUI Access Token: abc123..."}),e.jsx("p",{className:"text-muted-foreground",children:"💡 请使用此 Token 登录 WebUI"})]})]})]})}),e.jsx("div",{className:"rounded-lg border bg-muted/50 p-4 space-y-2",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(qa,{className:"h-5 w-5 text-primary flex-shrink-0 mt-0.5",strokeWidth:2,fill:"none"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx("h4",{className:"font-semibold text-sm",children:"方式二:查看配置文件"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Token 保存在项目根目录的配置文件中:"}),e.jsx("div",{className:"rounded bg-background p-2 font-mono text-xs break-all",children:e.jsx("code",{className:"text-primary",children:"data/webui.json"})}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["打开此文件,复制 ",e.jsx("code",{className:"px-1 py-0.5 bg-background rounded",children:"access_token"})," 字段的值"]})]})]})}),e.jsx("div",{className:"rounded-lg border border-yellow-200 dark:border-yellow-900 bg-yellow-50 dark:bg-yellow-950/30 p-3",children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Ct,{className:"h-4 w-4 text-yellow-600 dark:text-yellow-500 flex-shrink-0 mt-0.5",strokeWidth:2,fill:"none"}),e.jsxs("div",{className:"text-sm text-yellow-800 dark:text-yellow-300 space-y-1",children:[e.jsx("p",{className:"font-semibold",children:"安全提示"}),e.jsxs("ul",{className:"list-disc list-inside space-y-0.5 text-xs",children:[e.jsx("li",{children:"请妥善保管您的 Token,不要泄露给他人"}),e.jsx("li",{children:"如需重置 Token,请在登录后前往系统设置"})]})]})]})})]})]})]}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs("button",{className:"w-full text-center text-sm text-muted-foreground hover:text-foreground transition-colors underline-offset-4 hover:underline flex items-center justify-center gap-1",children:[e.jsx(zn,{className:"h-4 w-4",strokeWidth:2,fill:"none"}),"我觉得这个界面很卡怎么办?"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsxs(ms,{className:"flex items-center gap-2",children:[e.jsx(zn,{className:"h-5 w-5 text-primary",strokeWidth:2,fill:"none"}),"关闭背景动画"]}),e.jsx(xs,{children:"背景动画可能会在低性能设备上造成卡顿。关闭动画可以显著提升界面流畅度。"})]}),e.jsx("div",{className:"rounded-lg border bg-muted/50 p-4 space-y-2",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:"关闭动画后,背景将变为纯色,但不影响任何功能的使用。您可以随时在系统设置中重新开启动画。"})}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>N(!1),children:"关闭动画"})]})]})]})]})})]}),e.jsx("div",{className:"absolute bottom-4 left-0 right-0 text-center text-xs text-muted-foreground",children:e.jsx("p",{children:l2})})]})}const et=m.forwardRef(({className:l,...n},i)=>e.jsx("textarea",{className:B("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",l),ref:i,...n}));et.displayName="Textarea";const $r=m.forwardRef(({className:l,orientation:n="horizontal",decorative:i=!0,...c},u)=>e.jsx(Lg,{ref:u,decorative:i,orientation:n,className:B("shrink-0 bg-border",n==="horizontal"?"h-[1px] w-full":"h-full w-[1px]",l),...c}));$r.displayName=Lg.displayName;function w2({config:l,onChange:n}){const i=u=>{u.trim()&&!l.alias_names.includes(u.trim())&&n({...l,alias_names:[...l.alias_names,u.trim()]})},c=u=>{n({...l,alias_names:l.alias_names.filter((x,h)=>h!==u)})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"qq_account",children:"QQ账号 *"}),e.jsx(ie,{id:"qq_account",type:"number",placeholder:"请输入机器人的QQ账号",value:l.qq_account||"",onChange:u=>n({...l,qq_account:Number(u.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人登录使用的QQ账号"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"nickname",children:"昵称 *"}),e.jsx(ie,{id:"nickname",placeholder:"请输入机器人的昵称",value:l.nickname,onChange:u=>n({...l,nickname:u.target.value})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人的主要称呼名称"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{children:"别名"}),e.jsx("div",{className:"flex flex-wrap gap-2 mb-2",children:l.alias_names.map((u,x)=>e.jsxs(Ae,{variant:"secondary",className:"gap-1",children:[u,e.jsx("button",{type:"button",onClick:()=>c(x),className:"ml-1 hover:text-destructive",children:e.jsx(_a,{className:"h-3 w-3"})})]},x))}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{id:"alias_input",placeholder:"输入别名后按回车添加",onKeyPress:u=>{u.key==="Enter"&&(i(u.target.value),u.target.value="")}}),e.jsx(C,{type:"button",variant:"outline",onClick:()=>{const u=document.getElementById("alias_input");u&&(i(u.value),u.value="")},children:"添加"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人的其他称呼,可以添加多个"})]})]})}function _2({config:l,onChange:n}){return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"personality",children:"人格特征 *"}),e.jsx(et,{id:"personality",placeholder:"描述机器人的人格特质和身份特征(建议120字以内)",value:l.personality,onChange:i=>n({...l,personality:i.target.value}),rows:3}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"例如:是一个女大学生,现在在读大二,会刷贴吧"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"reply_style",children:"表达风格 *"}),e.jsx(et,{id:"reply_style",placeholder:"描述机器人说话的表达风格、表达习惯",value:l.reply_style,onChange:i=>n({...l,reply_style:i.target.value}),rows:3}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"例如:回复平淡一些,简短一些,说中文,参考贴吧、知乎和微博的回复风格"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"interest",children:"兴趣 *"}),e.jsx(et,{id:"interest",placeholder:"描述机器人感兴趣的话题",value:l.interest,onChange:i=>n({...l,interest:i.target.value}),rows:2}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"会影响机器人对什么话题进行回复"})]}),e.jsx($r,{}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"plan_style",children:"群聊说话规则 *"}),e.jsx(et,{id:"plan_style",placeholder:"机器人在群聊中的行为风格和规则",value:l.plan_style,onChange:i=>n({...l,plan_style:i.target.value}),rows:4}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"定义机器人在群聊中如何行动,例如回复频率、条件等"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"private_plan_style",children:"私聊说话规则 *"}),e.jsx(et,{id:"private_plan_style",placeholder:"机器人在私聊中的行为风格和规则",value:l.private_plan_style,onChange:i=>n({...l,private_plan_style:i.target.value}),rows:3}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"定义机器人在私聊中的行为方式"})]})]})}function S2({config:l,onChange:n}){return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{htmlFor:"emoji_chance",children:"表情包激活概率"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[(l.emoji_chance*100).toFixed(0),"%"]})]}),e.jsx(ie,{id:"emoji_chance",type:"range",min:"0",max:"1",step:"0.1",value:l.emoji_chance,onChange:i=>n({...l,emoji_chance:Number(i.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人发送表情包的概率"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"max_reg_num",children:"最大表情包数量"}),e.jsx(ie,{id:"max_reg_num",type:"number",min:"1",max:"200",value:l.max_reg_num,onChange:i=>n({...l,max_reg_num:Number(i.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"机器人最多保存的表情包数量"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{htmlFor:"do_replace",children:"达到最大数量时替换"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"开启后会删除旧表情包,关闭则不再收集新表情包"})]}),e.jsx(Ge,{id:"do_replace",checked:l.do_replace,onCheckedChange:i=>n({...l,do_replace:i})})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"check_interval",children:"检查间隔(分钟)"}),e.jsx(ie,{id:"check_interval",type:"number",min:"1",max:"120",value:l.check_interval,onChange:i=>n({...l,check_interval:Number(i.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"检查表情包注册、破损、删除的时间间隔"})]}),e.jsx($r,{}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{htmlFor:"steal_emoji",children:"偷取表情包"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"允许机器人将一些表情包据为己有"})]}),e.jsx(Ge,{id:"steal_emoji",checked:l.steal_emoji,onCheckedChange:i=>n({...l,steal_emoji:i})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{htmlFor:"content_filtration",children:"启用表情包过滤"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"只保存符合要求的表情包"})]}),e.jsx(Ge,{id:"content_filtration",checked:l.content_filtration,onCheckedChange:i=>n({...l,content_filtration:i})})]}),l.content_filtration&&e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"filtration_prompt",children:"过滤要求"}),e.jsx(ie,{id:"filtration_prompt",placeholder:"例如:符合公序良俗",value:l.filtration_prompt,onChange:i=>n({...l,filtration_prompt:i.target.value})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"描述表情包应该符合的要求"})]})]})}function k2({config:l,onChange:n}){return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{htmlFor:"enable_tool",children:"启用工具系统"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"允许机器人使用各种工具增强功能"})]}),e.jsx(Ge,{id:"enable_tool",checked:l.enable_tool,onCheckedChange:i=>n({...l,enable_tool:i})})]}),e.jsx($r,{}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{htmlFor:"all_global",children:"启用全局黑话模式"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"允许机器人学习和使用群组黑话"})]}),e.jsx(Ge,{id:"all_global",checked:l.all_global,onCheckedChange:i=>n({...l,all_global:i})})]})]})}function C2({config:l,onChange:n}){const[i,c]=m.useState(!1);return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"rounded-lg bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"mt-0.5",children:e.jsx("svg",{className:"h-5 w-5 text-blue-600 dark:text-blue-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})})}),e.jsxs("div",{className:"flex-1 text-sm",children:[e.jsx("p",{className:"font-medium text-blue-900 dark:text-blue-100 mb-1",children:"关于硅基流动 (SiliconFlow)"}),e.jsx("p",{className:"text-blue-700 dark:text-blue-300 mb-2",children:"硅基流动提供了完整的模型覆盖,包括 DeepSeek V3、Qwen、视觉模型、语音识别和嵌入模型。 只需一个 API Key 即可使用麦麦的所有功能!"}),e.jsxs("a",{href:"https://cloud.siliconflow.cn",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-blue-600 dark:text-blue-400 hover:underline font-medium",children:["前往硅基流动获取 API Key",e.jsx(bo,{className:"h-3 w-3"})]})]})]})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(E,{htmlFor:"siliconflow_api_key",children:"SiliconFlow API Key *"}),e.jsxs("div",{className:"relative",children:[e.jsx(ie,{id:"siliconflow_api_key",type:i?"text":"password",placeholder:"sk-...",value:l.api_key,onChange:u=>n({api_key:u.target.value}),className:"font-mono pr-10"}),e.jsx(C,{type:"button",variant:"ghost",size:"sm",className:"absolute right-0 top-0 h-full px-3 hover:bg-transparent",onClick:()=>c(!i),children:i?e.jsx(Hi,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(sa,{className:"h-4 w-4 text-muted-foreground"})})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"请输入您的硅基流动 API 密钥。获取后,麦麦将自动配置所有必需的模型。"})]}),e.jsxs("div",{className:"rounded-lg bg-muted/50 p-4 text-sm space-y-2",children:[e.jsx("p",{className:"font-medium",children:"将自动配置以下模型:"}),e.jsxs("ul",{className:"list-disc list-inside space-y-1 text-muted-foreground ml-2",children:[e.jsx("li",{children:"DeepSeek V3 - 主要对话和工具模型"}),e.jsx("li",{children:"Qwen3 30B - 高频小任务和工具调用"}),e.jsx("li",{children:"Qwen3 VL 30B - 图像识别"}),e.jsx("li",{children:"SenseVoice - 语音识别"}),e.jsx("li",{children:"BGE-M3 - 文本嵌入"}),e.jsx("li",{children:"知识库相关模型 (LPMM)"})]})]}),e.jsx("div",{className:"rounded-lg border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-950/30 p-4",children:e.jsxs("p",{className:"text-sm text-amber-900 dark:text-amber-100",children:[e.jsx("span",{className:"font-medium",children:"💡 提示:"}),'完成向导后,您可以在"系统设置 → 模型配置"中添加更多 API 提供商和模型。']})})]})}async function T2(){const l=await we("/api/webui/config/bot",{method:"GET",headers:Us()});if(!l.ok)throw new Error("读取Bot配置失败");const i=(await l.json()).config.bot||{};return{qq_account:i.qq_account||0,nickname:i.nickname||"",alias_names:i.alias_names||[]}}async function E2(){const l=await we("/api/webui/config/bot",{method:"GET",headers:Us()});if(!l.ok)throw new Error("读取人格配置失败");const i=(await l.json()).config.personality||{};return{personality:i.personality||"",reply_style:i.reply_style||"",interest:i.interest||"",plan_style:i.plan_style||"",private_plan_style:i.private_plan_style||""}}async function M2(){const l=await we("/api/webui/config/bot",{method:"GET",headers:Us()});if(!l.ok)throw new Error("读取表情包配置失败");const i=(await l.json()).config.emoji||{};return{emoji_chance:i.emoji_chance??.4,max_reg_num:i.max_reg_num??40,do_replace:i.do_replace??!0,check_interval:i.check_interval??10,steal_emoji:i.steal_emoji??!0,content_filtration:i.content_filtration??!1,filtration_prompt:i.filtration_prompt||""}}async function A2(){const l=await we("/api/webui/config/bot",{method:"GET",headers:Us()});if(!l.ok)throw new Error("读取其他配置失败");const i=(await l.json()).config,c=i.tool||{},u=i.expression||{};return{enable_tool:c.enable_tool??!0,all_global:u.all_global_jargon??!0}}async function z2(){const l=await we("/api/webui/config/model",{method:"GET",headers:Us()});if(!l.ok)throw new Error("读取模型配置失败");return{api_key:((await l.json()).config.api_providers||[]).find(x=>x.name==="SiliconFlow")?.api_key||""}}async function D2(l){const n=await we("/api/webui/config/bot/section/bot",{method:"POST",headers:Us(),body:JSON.stringify(l)});if(!n.ok){const i=await n.json();throw new Error(i.detail||"保存Bot基础配置失败")}return await n.json()}async function O2(l){const n=await we("/api/webui/config/bot/section/personality",{method:"POST",headers:Us(),body:JSON.stringify(l)});if(!n.ok){const i=await n.json();throw new Error(i.detail||"保存人格配置失败")}return await n.json()}async function R2(l){const n=await we("/api/webui/config/bot/section/emoji",{method:"POST",headers:Us(),body:JSON.stringify(l)});if(!n.ok){const i=await n.json();throw new Error(i.detail||"保存表情包配置失败")}return await n.json()}async function L2(l){const n=[];n.push(we("/api/webui/config/bot/section/tool",{method:"POST",headers:Us(),body:JSON.stringify({enable_tool:l.enable_tool})})),n.push(we("/api/webui/config/bot/section/expression",{method:"POST",headers:Us(),body:JSON.stringify({all_global_jargon:l.all_global})}));const i=await Promise.all(n);for(const c of i)if(!c.ok){const u=await c.json();throw new Error(u.detail||"保存其他配置失败")}return{success:!0}}async function U2(l){const n=await we("/api/webui/config/model",{method:"GET",headers:Us()});if(!n.ok)throw new Error("读取模型配置失败");const c=(await n.json()).config,u=c.api_providers||[],x=u.findIndex(p=>p.name==="SiliconFlow");x>=0?u[x]={...u[x],api_key:l.api_key}:u.push({name:"SiliconFlow",base_url:"https://api.siliconflow.cn/v1",api_key:l.api_key,client_type:"openai",max_retry:3,timeout:120,retry_interval:5});const h={...c,api_providers:u},f=await we("/api/webui/config/model",{method:"POST",headers:Us(),body:JSON.stringify(h)});if(!f.ok){const p=await f.json();throw new Error(p.detail||"保存模型配置失败")}return await f.json()}async function lg(){const l=await we("/api/webui/setup/complete",{method:"POST"});if(!l.ok){const n=await l.json();throw new Error(n.message||"标记配置完成失败")}return await l.json()}function B2(){return e.jsx(Pn,{children:e.jsx($2,{})})}function $2(){const l=aa(),{toast:n}=Ws(),{triggerRestart:i}=dn(),[c,u]=m.useState(0),[x,h]=m.useState(!1),[f,p]=m.useState(!1),[g,N]=m.useState(!0),[v,b]=m.useState({qq_account:0,nickname:"",alias_names:[]}),[w,y]=m.useState({personality:"是一个女大学生,现在在读大二,会刷贴吧。",reply_style:"请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。",interest:"对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题",plan_style:`1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 +2.如果相同的内容已经被执行,请不要重复执行 +3.请控制你的发言频率,不要太过频繁的发言 +4.如果有人对你感到厌烦,请减少回复 +5.如果有人对你进行攻击,或者情绪激动,请你以合适的方法应对`,private_plan_style:`1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用 +2.如果相同的内容已经被执行,请不要重复执行 +3.某句话如果已经被回复过,不要重复回复`}),[R,D]=m.useState({emoji_chance:.4,max_reg_num:40,do_replace:!0,check_interval:10,steal_emoji:!0,content_filtration:!1,filtration_prompt:"符合公序良俗"}),[k,I]=m.useState({enable_tool:!0,all_global:!0}),[M,S]=m.useState({api_key:""}),T=[{id:"bot-basic",title:"Bot基础",description:"配置机器人的基本信息",icon:Ri},{id:"personality",title:"人格配置",description:"定义机器人的性格和说话风格",icon:Dn},{id:"emoji",title:"表情包",description:"配置表情包相关设置",icon:Rm},{id:"other",title:"其他设置",description:"工具、情绪系统等配置",icon:In},{id:"siliconflow",title:"API配置",description:"配置硅基流动API密钥",icon:Om}],$=(c+1)/T.length*100;m.useEffect(()=>{(async()=>{try{N(!0);const[fe,ge,z,V,U]=await Promise.all([T2(),E2(),M2(),A2(),z2()]);b(fe),y(ge),D(z),I(V),S(U)}catch(fe){n({title:"加载配置失败",description:fe instanceof Error?fe.message:"无法加载现有配置,将使用默认值",variant:"destructive"})}finally{N(!1)}})()},[n]);const A=async()=>{p(!0);try{switch(c){case 0:await D2(v);break;case 1:await O2(w);break;case 2:await R2(R);break;case 3:await L2(k);break;case 4:await U2(M);break}return n({title:"保存成功",description:`${T[c].title}配置已保存`}),!0}catch(le){return n({title:"保存失败",description:le instanceof Error?le.message:"未知错误",variant:"destructive"}),!1}finally{p(!1)}},Q=async()=>{await A()&&c{c>0&&u(c-1)},de=async()=>{h(!0);try{if(!await A()){h(!1);return}await lg(),n({title:"配置完成",description:"麦麦正在重启以应用新配置..."}),await i()}catch(le){n({title:"配置失败",description:le instanceof Error?le.message:"未知错误",variant:"destructive"})}finally{h(!1)}},oe=async()=>{try{await lg(),l({to:"/"})}catch(le){n({title:"跳过失败",description:le instanceof Error?le.message:"未知错误",variant:"destructive"})}},ve=()=>{switch(c){case 0:return e.jsx(w2,{config:v,onChange:b});case 1:return e.jsx(_2,{config:w,onChange:y});case 2:return e.jsx(S2,{config:R,onChange:D});case 3:return e.jsx(k2,{config:k,onChange:I});case 4:return e.jsx(C2,{config:M,onChange:S});default:return null}};return e.jsxs("div",{className:"relative flex min-h-screen flex-col items-center justify-center overflow-hidden bg-gradient-to-br from-primary/5 via-background to-secondary/5 p-4 md:p-6",children:[e.jsx(Hn,{}),e.jsxs("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:[e.jsx("div",{className:"absolute left-1/4 top-1/4 h-64 w-64 md:h-96 md:w-96 rounded-full bg-primary/5 blur-3xl"}),e.jsx("div",{className:"absolute right-1/4 bottom-1/4 h-64 w-64 md:h-96 md:w-96 rounded-full bg-secondary/5 blur-3xl"})]}),g?e.jsxs("div",{className:"relative z-10 text-center",children:[e.jsx("div",{className:"mx-auto mb-4 flex h-16 w-16 items-center justify-center",children:e.jsx("div",{className:"h-12 w-12 animate-spin rounded-full border-4 border-primary border-t-transparent"})}),e.jsx("p",{className:"text-lg font-medium",children:"加载配置中..."}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:"正在读取现有配置"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"relative z-10 w-full max-w-4xl",children:[e.jsxs("div",{className:"mb-6 md:mb-8 text-center",children:[e.jsx("div",{className:"mx-auto mb-4 flex h-12 w-12 md:h-16 md:w-16 items-center justify-center rounded-2xl bg-primary/10",children:e.jsx(Rw,{className:"h-6 w-6 md:h-8 md:w-8 text-primary",strokeWidth:2,fill:"none"})}),e.jsx("h1",{className:"mb-2 text-2xl md:text-3xl font-bold",children:"首次配置向导"}),e.jsxs("p",{className:"text-sm md:text-base text-muted-foreground",children:["让我们一起完成 ",$m," 的初始配置"]})]}),e.jsxs("div",{className:"mb-6 md:mb-8",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between text-xs md:text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:["步骤 ",c+1," / ",T.length]}),e.jsxs("span",{className:"font-medium text-primary",children:[Math.round($),"%"]})]}),e.jsx(Bn,{value:$,className:"h-2"})]}),e.jsx("div",{className:"mb-6 md:mb-8 flex justify-between",children:T.map((le,fe)=>{const ge=le.icon;return e.jsxs("div",{className:B("flex flex-1 flex-col items-center gap-1 md:gap-2",fel({to:"/"}),className:"gap-2 w-full sm:w-auto",children:[e.jsx(Bo,{className:"h-4 w-4"}),"返回首页"]}),e.jsxs(C,{size:"lg",variant:"outline",onClick:()=>window.history.back(),className:"gap-2 w-full sm:w-auto",children:[e.jsx(Va,{className:"h-4 w-4"}),"返回上一页"]})]}),e.jsx("div",{className:"mt-12 pt-8 border-t border-border",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:"如果您认为这是一个错误,请联系系统管理员"})})]})})}const I2=Es.memo(function({config:n,onChange:i}){const c=n.platforms||[],u=n.alias_names||[],x=()=>{i({...n,platforms:[...c,""]})},h=v=>{i({...n,platforms:c.filter((b,w)=>w!==v)})},f=(v,b)=>{const w=[...c];w[v]=b,i({...n,platforms:w})},p=()=>{i({...n,alias_names:[...u,""]})},g=v=>{i({...n,alias_names:u.filter((b,w)=>w!==v)})},N=(v,b)=>{const w=[...u];w[v]=b,i({...n,alias_names:w})};return e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"基本信息"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"platform",children:"平台"}),e.jsx(ie,{id:"platform",value:n.platform,onChange:v=>i({...n,platform:v.target.value}),placeholder:"qq"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"qq_account",children:"QQ账号"}),e.jsx(ie,{id:"qq_account",value:n.qq_account,onChange:v=>i({...n,qq_account:v.target.value}),placeholder:"123456789"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"nickname",children:"昵称"}),e.jsx(ie,{id:"nickname",value:n.nickname,onChange:v=>i({...n,nickname:v.target.value}),placeholder:"麦麦"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:"其他平台账号"}),e.jsxs(C,{onClick:x,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加"]})]}),e.jsxs("div",{className:"space-y-2",children:[c.map((v,b)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{value:v,onChange:w=>f(b,w.target.value),placeholder:"wx:114514"}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除平台账号 "',v||"(空)",'" 吗?此操作无法撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>h(b),children:"删除"})]})]})]})]},b)),c.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无其他平台账号"})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:"别名"}),e.jsxs(C,{onClick:p,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加"]})]}),e.jsxs("div",{className:"space-y-2",children:[u.map((v,b)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{value:v,onChange:w=>N(b,w.target.value),placeholder:"小麦"}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除别名 "',v||"(空)",'" 吗?此操作无法撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>g(b),children:"删除"})]})]})]})]},b)),u.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无别名"})]})]})]})]})})}),P2=Es.memo(function({config:n,onChange:i}){const c=()=>{i({...n,states:[...n.states,""]})},u=h=>{i({...n,states:n.states.filter((f,p)=>p!==h)})},x=(h,f)=>{const p=[...n.states];p[h]=f,i({...n,states:p})};return e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"人格设置"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"personality",children:"人格特质"}),e.jsx(et,{id:"personality",value:n.personality,onChange:h=>i({...n,personality:h.target.value}),placeholder:"描述人格特质和身份特征(建议120字以内)",rows:3}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"建议120字以内,描述人格特质和身份特征"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"reply_style",children:"表达风格"}),e.jsx(et,{id:"reply_style",value:n.reply_style,onChange:h=>i({...n,reply_style:h.target.value}),placeholder:"描述说话的表达风格和习惯",rows:3})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"interest",children:"兴趣"}),e.jsx(et,{id:"interest",value:n.interest,onChange:h=>i({...n,interest:h.target.value}),placeholder:"会影响麦麦对什么话题进行回复",rows:2})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"plan_style",children:"说话规则与行为风格"}),e.jsx(et,{id:"plan_style",value:n.plan_style,onChange:h=>i({...n,plan_style:h.target.value}),placeholder:"麦麦的说话规则和行为风格",rows:5})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"visual_style",children:"识图规则"}),e.jsx(et,{id:"visual_style",value:n.visual_style,onChange:h=>i({...n,visual_style:h.target.value}),placeholder:"识图时的处理规则",rows:3})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"private_plan_style",children:"私聊规则"}),e.jsx(et,{id:"private_plan_style",value:n.private_plan_style,onChange:h=>i({...n,private_plan_style:h.target.value}),placeholder:"私聊的说话规则和行为风格",rows:4})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:"状态列表(人格多样性)"}),e.jsxs(C,{onClick:c,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加状态"]})]}),e.jsx("div",{className:"space-y-2",children:n.states.map((h,f)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(et,{value:h,onChange:p=>x(f,p.target.value),placeholder:"描述一个人格状态",rows:2}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsx(xs,{children:"确定要删除这个人格状态吗?此操作无法撤销。"})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>u(f),children:"删除"})]})]})]})]},f))})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"state_probability",children:"状态替换概率"}),e.jsx(ie,{id:"state_probability",type:"number",step:"0.1",min:"0",max:"1",value:n.state_probability,onChange:h=>i({...n,state_probability:parseFloat(h.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"每次构建人格时替换 personality 的概率(0.0-1.0)"})]})]})]})})}),Be=hw,$e=fw,Le=m.forwardRef(({className:l,children:n,...i},c)=>e.jsxs(Jg,{ref:c,className:B("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",l),...i,children:[n,e.jsx(ow,{asChild:!0,children:e.jsx($a,{className:"h-4 w-4 opacity-50"})})]}));Le.displayName=Jg.displayName;const Zj=m.forwardRef(({className:l,...n},i)=>e.jsx(Xg,{ref:i,className:B("flex cursor-default items-center justify-center py-1",l),...n,children:e.jsx(Dr,{className:"h-4 w-4"})}));Zj.displayName=Xg.displayName;const Wj=m.forwardRef(({className:l,...n},i)=>e.jsx(Zg,{ref:i,className:B("flex cursor-default items-center justify-center py-1",l),...n,children:e.jsx($a,{className:"h-4 w-4"})}));Wj.displayName=Zg.displayName;const Ue=m.forwardRef(({className:l,children:n,position:i="popper",...c},u)=>e.jsx(dw,{children:e.jsxs(Wg,{ref:u,className:B("relative z-[100] max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-hidden rounded-md border border-border bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",i==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",l),position:i,...c,children:[e.jsx(Zj,{}),e.jsx(uw,{className:B("p-1",i==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:n}),e.jsx(Wj,{})]})}));Ue.displayName=Wg.displayName;const H2=m.forwardRef(({className:l,...n},i)=>e.jsx(ej,{ref:i,className:B("px-2 py-1.5 text-sm font-semibold",l),...n}));H2.displayName=ej.displayName;const ae=m.forwardRef(({className:l,children:n,...i},c)=>e.jsxs(sj,{ref:c,className:B("relative flex w-full cursor-default select-none items-center rounded-sm py-2 pl-2 pr-8 text-sm outline-none bg-white dark:bg-gray-900 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-gray-800 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",l),...i,children:[e.jsx("span",{className:"absolute right-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(mw,{children:e.jsx(St,{className:"h-4 w-4"})})}),e.jsx(xw,{children:n})]}));ae.displayName=sj.displayName;const G2=m.forwardRef(({className:l,...n},i)=>e.jsx(tj,{ref:i,className:B("-mx-1 my-1 h-px bg-muted",l),...n}));G2.displayName=tj.displayName;const tl=C0,al=T0,Ka=m.forwardRef(({className:l,align:n="center",sideOffset:i=4,...c},u)=>e.jsx(k0,{children:e.jsx(Ug,{ref:u,align:n,sideOffset:i,className:B("z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-popover-content-transform-origin]",l),...c})}));Ka.displayName=Ug.displayName;const F2=Es.memo(function({value:n,onChange:i}){const c=m.useMemo(()=>{const w=n.split("-");if(w.length===2){const[y,R]=w,[D,k]=y.split(":"),[I,M]=R.split(":");return{startHour:D?D.padStart(2,"0"):"00",startMinute:k?k.padStart(2,"0"):"00",endHour:I?I.padStart(2,"0"):"23",endMinute:M?M.padStart(2,"0"):"59"}}return{startHour:"00",startMinute:"00",endHour:"23",endMinute:"59"}},[n]),[u,x]=m.useState(c.startHour),[h,f]=m.useState(c.startMinute),[p,g]=m.useState(c.endHour),[N,v]=m.useState(c.endMinute);m.useEffect(()=>{x(c.startHour),f(c.startMinute),g(c.endHour),v(c.endMinute)},[c]);const b=(w,y,R,D)=>{const k=`${w}:${y}-${R}:${D}`;i(k)};return e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",className:"w-full justify-start font-mono text-sm",children:[e.jsx(kl,{className:"h-4 w-4 mr-2"}),n||"选择时间段"]})}),e.jsx(Ka,{className:"w-72 sm:w-80",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-sm mb-3",children:"开始时间"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:gap-3",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-xs",children:"小时"}),e.jsxs(Be,{value:u,onValueChange:w=>{x(w),b(w,h,p,N)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:Array.from({length:24},(w,y)=>y).map(w=>e.jsx(ae,{value:w.toString().padStart(2,"0"),children:w.toString().padStart(2,"0")},w))})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-xs",children:"分钟"}),e.jsxs(Be,{value:h,onValueChange:w=>{f(w),b(u,w,p,N)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:Array.from({length:60},(w,y)=>y).map(w=>e.jsx(ae,{value:w.toString().padStart(2,"0"),children:w.toString().padStart(2,"0")},w))})]})]})]})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-sm mb-3",children:"结束时间"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:gap-3",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-xs",children:"小时"}),e.jsxs(Be,{value:p,onValueChange:w=>{g(w),b(u,h,w,N)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:Array.from({length:24},(w,y)=>y).map(w=>e.jsx(ae,{value:w.toString().padStart(2,"0"),children:w.toString().padStart(2,"0")},w))})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-xs",children:"分钟"}),e.jsxs(Be,{value:N,onValueChange:w=>{v(w),b(u,h,p,w)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:Array.from({length:60},(w,y)=>y).map(w=>e.jsx(ae,{value:w.toString().padStart(2,"0"),children:w.toString().padStart(2,"0")},w))})]})]})]})]})]})})]})}),q2=Es.memo(function({rule:n}){const i=`{ target = "${n.target}", time = "${n.time}", value = ${n.value.toFixed(1)} }`;return e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",children:[e.jsx(sa,{className:"h-4 w-4 mr-1"}),"预览"]})}),e.jsx(Ka,{className:"w-80 sm:w-96",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),e.jsx("div",{className:"rounded-md bg-muted p-3 font-mono text-xs break-all",children:i}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})}),V2=Es.memo(function({config:n,onChange:i}){const c=()=>{i({...n,talk_value_rules:[...n.talk_value_rules,{target:"",time:"00:00-23:59",value:1}]})},u=h=>{i({...n,talk_value_rules:n.talk_value_rules.filter((f,p)=>p!==h)})},x=(h,f,p)=>{const g=[...n.talk_value_rules];g[h]={...g[h],[f]:p},i({...n,talk_value_rules:g})};return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"聊天设置"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"talk_value",children:"聊天频率(基础值)"}),e.jsx(ie,{id:"talk_value",type:"number",step:"0.1",min:"0",max:"1",value:n.talk_value,onChange:h=>i({...n,talk_value:parseFloat(h.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"越小越沉默,范围 0-1"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"mentioned_bot_reply",checked:n.mentioned_bot_reply,onCheckedChange:h=>i({...n,mentioned_bot_reply:h})}),e.jsx(E,{htmlFor:"mentioned_bot_reply",className:"cursor-pointer",children:"启用提及必回复"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"max_context_size",children:"上下文长度"}),e.jsx(ie,{id:"max_context_size",type:"number",min:"1",value:n.max_context_size,onChange:h=>i({...n,max_context_size:parseInt(h.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"planner_smooth",children:"规划器平滑"}),e.jsx(ie,{id:"planner_smooth",type:"number",step:"1",min:"0",value:n.planner_smooth,onChange:h=>i({...n,planner_smooth:parseFloat(h.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"增大数值会减小 planner 负荷,推荐 1-5,0 为关闭"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_talk_value_rules",checked:n.enable_talk_value_rules,onCheckedChange:h=>i({...n,enable_talk_value_rules:h})}),e.jsx(E,{htmlFor:"enable_talk_value_rules",className:"cursor-pointer",children:"启用动态发言频率规则"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"include_planner_reasoning",checked:n.include_planner_reasoning,onCheckedChange:h=>i({...n,include_planner_reasoning:h})}),e.jsx(E,{htmlFor:"include_planner_reasoning",className:"cursor-pointer",children:"将 planner 推理加入 replyer"})]})]})]}),n.enable_talk_value_rules&&e.jsxs("div",{className:"border-t pt-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-base font-semibold",children:"动态发言频率规则"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"按时段或聊天流ID调整发言频率,优先匹配具体聊天,再匹配全局规则"})]}),e.jsxs(C,{onClick:c,size:"sm",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加规则"]})]}),n.talk_value_rules&&n.talk_value_rules.length>0?e.jsx("div",{className:"space-y-4",children:n.talk_value_rules.map((h,f)=>e.jsxs("div",{className:"rounded-lg border p-4 bg-muted/50 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-sm font-medium text-muted-foreground",children:["规则 #",f+1]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(q2,{rule:h}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{variant:"ghost",size:"sm",children:e.jsx(ls,{className:"h-4 w-4 text-destructive"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除规则 #",f+1," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>u(f),children:"删除"})]})]})]})]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"配置类型"}),e.jsxs(Be,{value:h.target===""?"global":"specific",onValueChange:p=>{p==="global"?x(f,"target",""):x(f,"target","qq::group")},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"global",children:"全局配置"}),e.jsx(ae,{value:"specific",children:"详细配置"})]})]})]}),h.target!==""&&(()=>{const p=h.target.split(":"),g=p[0]||"qq",N=p[1]||"",v=p[2]||"group";return e.jsxs("div",{className:"grid gap-4 p-3 sm:p-4 rounded-lg bg-muted/50",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"平台"}),e.jsxs(Be,{value:g,onValueChange:b=>{x(f,"target",`${b}:${N}:${v}`)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"qq",children:"QQ"}),e.jsx(ae,{value:"wx",children:"微信"})]})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"群 ID"}),e.jsx(ie,{value:N,onChange:b=>{x(f,"target",`${g}:${b.target.value}:${v}`)},placeholder:"输入群 ID",className:"font-mono text-sm"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"类型"}),e.jsxs(Be,{value:v,onValueChange:b=>{x(f,"target",`${g}:${N}:${b}`)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"group",children:"群组(group)"}),e.jsx(ae,{value:"private",children:"私聊(private)"})]})]})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["当前聊天流 ID:",h.target||"(未设置)"]})]})})(),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"时间段 (Time)"}),e.jsx(F2,{value:h.time,onChange:p=>x(f,"time",p)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"支持跨夜区间,例如 23:00-02:00"})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{htmlFor:`rule-value-${f}`,className:"text-xs font-medium",children:"发言频率值 (Value)"}),e.jsx(ie,{id:`rule-value-${f}`,type:"number",step:"0.01",min:"0.01",max:"1",value:h.value,onChange:p=>{const g=parseFloat(p.target.value);isNaN(g)||x(f,"value",Math.max(.01,Math.min(1,g)))},className:"w-20 h-8 text-xs"})]}),e.jsx(wa,{value:[h.value],onValueChange:p=>x(f,"value",p[0]),min:.01,max:1,step:.01,className:"w-full"}),e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:"0.01 (极少发言)"}),e.jsx("span",{children:"0.5"}),e.jsx("span",{children:"1.0 (正常)"})]})]})]})]},f))}):e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:e.jsx("p",{className:"text-sm",children:'暂无规则,点击"添加规则"按钮创建'})}),e.jsxs("div",{className:"mt-4 p-4 bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-800 rounded-lg",children:[e.jsx("h5",{className:"text-sm font-semibold text-blue-900 dark:text-blue-100 mb-2",children:"📝 规则说明"}),e.jsxs("ul",{className:"text-xs text-blue-800 dark:text-blue-200 space-y-1",children:[e.jsxs("li",{children:["• ",e.jsx("strong",{children:"Target 为空"}),":全局规则,对所有聊天生效"]}),e.jsxs("li",{children:["• ",e.jsx("strong",{children:"Target 指定"}),":仅对特定聊天流生效(格式:platform:id:type)"]}),e.jsxs("li",{children:["• ",e.jsx("strong",{children:"优先级"}),":先匹配具体聊天流规则,再匹配全局规则"]}),e.jsxs("li",{children:["• ",e.jsx("strong",{children:"时间支持跨夜"}),":例如 23:00-02:00 表示晚上11点到次日凌晨2点"]}),e.jsxs("li",{children:["• ",e.jsx("strong",{children:"数值范围"}),":建议 0-1,0 表示完全沉默,1 表示正常发言"]})]})]})]})]})}),K2=Es.memo(function({config:n,onChange:i}){const c=k=>{if(!k||!k.includes(":"))return{platform:"qq",userId:""};const[I,M]=k.split(":");return{platform:I,userId:M}},{platform:u,userId:x}=c(n.dream_send),[h,f]=m.useState(u),[p,g]=m.useState(x),N=k=>{const[I,M]=k.split("-");return{startTime:I||"09:00",endTime:M||"22:00"}},v=(k,I)=>{const M=I?`${k}:${I}`:"";i({...n,dream_send:M})},b=k=>{f(k),v(k,p)},w=k=>{g(k),v(h,k)},y=()=>{i({...n,dream_time_ranges:[...n.dream_time_ranges,"09:00-22:00"]})},R=k=>{i({...n,dream_time_ranges:n.dream_time_ranges.filter((I,M)=>M!==k)})},D=(k,I,M)=>{const S=[...n.dream_time_ranges],T=N(S[k]);I==="startTime"?T.startTime=M:T.endTime=M,S[k]=`${T.startTime}-${T.endTime}`,i({...n,dream_time_ranges:S})};return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"做梦配置"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"interval_minutes",children:"做梦时间间隔(分钟)"}),e.jsx(ie,{id:"interval_minutes",type:"number",min:"1",value:n.interval_minutes,onChange:k=>i({...n,interval_minutes:Number(k.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"默认30分钟"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"max_iterations",children:"做梦最大轮次"}),e.jsx(ie,{id:"max_iterations",type:"number",min:"1",value:n.max_iterations,onChange:k=>i({...n,max_iterations:Number(k.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"默认20轮"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"first_delay_seconds",children:"首次做梦延迟(秒)"}),e.jsx(ie,{id:"first_delay_seconds",type:"number",min:"0",value:n.first_delay_seconds,onChange:k=>i({...n,first_delay_seconds:Number(k.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"程序启动后首次做梦前的延迟时间,默认60秒"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"做梦结果推送目标"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(Be,{value:h,onValueChange:b,children:[e.jsx(Le,{className:"w-[120px]",children:e.jsx($e,{placeholder:"选择平台"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"qq",children:"QQ"}),e.jsx(ae,{value:"wx",children:"微信"}),e.jsx(ae,{value:"webui",children:"WebUI"})]})]}),e.jsx(ie,{type:"text",placeholder:"输入用户ID (例如: 123456)",value:p,onChange:k=>w(k.target.value),className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"选择平台并输入用户ID,做梦结束后将梦境发送给该用户。用户ID为空则不推送"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:"做梦时间段配置"}),e.jsx(C,{type:"button",size:"sm",onClick:y,children:"添加时间段"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"设置允许做梦的时间段,支持跨夜区间(如 23:00 到次日 02:00)。列表为空则全天允许做梦"}),e.jsxs("div",{className:"space-y-2",children:[n.dream_time_ranges.map((k,I)=>{const{startTime:M,endTime:S}=N(k);return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"time",value:M,onChange:T=>D(I,"startTime",T.target.value),className:"w-[140px]"}),e.jsx("span",{className:"text-muted-foreground",children:"至"}),e.jsx(ie,{type:"time",value:S,onChange:T=>D(I,"endTime",T.target.value),className:"w-[140px]"}),e.jsx(C,{type:"button",variant:"ghost",size:"icon",onClick:()=>R(I),children:e.jsx(_a,{className:"h-4 w-4"})})]},I)}),n.dream_time_ranges.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"当前配置为全天允许做梦"})]})]})]})}),Q2=Es.memo(function({config:n,onChange:i}){return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"LPMM 知识库设置"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{checked:n.enable,onCheckedChange:c=>i({...n,enable:c})}),e.jsx(E,{className:"cursor-pointer",children:"启用 LPMM 知识库"})]}),n.enable&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"LPMM 模式"}),e.jsxs(Be,{value:n.lpmm_mode,onValueChange:c=>i({...n,lpmm_mode:c}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择 LPMM 模式"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"classic",children:"经典模式"}),e.jsx(ae,{value:"agent",children:"Agent 模式"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"同义词搜索 TopK"}),e.jsx(ie,{type:"number",min:"1",value:n.rag_synonym_search_top_k,onChange:c=>i({...n,rag_synonym_search_top_k:parseInt(c.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"同义词阈值"}),e.jsx(ie,{type:"number",step:"0.1",min:"0",max:"1",value:n.rag_synonym_threshold,onChange:c=>i({...n,rag_synonym_threshold:parseFloat(c.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"实体提取线程数"}),e.jsx(ie,{type:"number",min:"1",value:n.info_extraction_workers,onChange:c=>i({...n,info_extraction_workers:parseInt(c.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"嵌入向量维度"}),e.jsx(ie,{type:"number",min:"1",value:n.embedding_dimension,onChange:c=>i({...n,embedding_dimension:parseInt(c.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"嵌入并发线程数"}),e.jsx(ie,{type:"number",min:"1",value:n.max_embedding_workers,onChange:c=>i({...n,max_embedding_workers:parseInt(c.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"每批嵌入条数"}),e.jsx(ie,{type:"number",min:"1",value:n.embedding_chunk_size,onChange:c=>i({...n,embedding_chunk_size:parseInt(c.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"同义实体数上限"}),e.jsx(ie,{type:"number",min:"1",value:n.max_synonym_entities,onChange:c=>i({...n,max_synonym_entities:parseInt(c.target.value)})})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{checked:n.enable_ppr,onCheckedChange:c=>i({...n,enable_ppr:c})}),e.jsx(E,{className:"cursor-pointer",children:"启用 PPR (低配机器可关闭)"})]})]})]})]})}),Y2=Es.memo(function({config:n,onChange:i}){const[c,u]=m.useState(""),[x,h]=m.useState("WARNING"),f=()=>{c&&!n.suppress_libraries.includes(c)&&(i({...n,suppress_libraries:[...n.suppress_libraries,c]}),u(""))},p=y=>{i({...n,suppress_libraries:n.suppress_libraries.filter(R=>R!==y)})},g=()=>{c&&!n.library_log_levels[c]&&(i({...n,library_log_levels:{...n.library_log_levels,[c]:x}}),u(""),h("WARNING"))},N=y=>{const R={...n.library_log_levels};delete R[y],i({...n,library_log_levels:R})},v=["DEBUG","INFO","WARNING","ERROR","CRITICAL"],b=["FULL","compact","lite"],w=["none","title","full"];return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"日志配置"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"日期格式"}),e.jsx(ie,{value:n.date_style,onChange:y=>i({...n,date_style:y.target.value}),placeholder:"例如: m-d H:i:s"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"m=月, d=日, H=时, i=分, s=秒"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"日志级别样式"}),e.jsxs(Be,{value:n.log_level_style,onValueChange:y=>i({...n,log_level_style:y}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:b.map(y=>e.jsx(ae,{value:y,children:y},y))})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"日志文本颜色"}),e.jsxs(Be,{value:n.color_text,onValueChange:y=>i({...n,color_text:y}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:w.map(y=>e.jsx(ae,{value:y,children:y},y))})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"全局日志级别"}),e.jsxs(Be,{value:n.log_level,onValueChange:y=>i({...n,log_level:y}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:v.map(y=>e.jsx(ae,{value:y,children:y},y))})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"控制台日志级别"}),e.jsxs(Be,{value:n.console_log_level,onValueChange:y=>i({...n,console_log_level:y}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:v.map(y=>e.jsx(ae,{value:y,children:y},y))})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"文件日志级别"}),e.jsxs(Be,{value:n.file_log_level,onValueChange:y=>i({...n,file_log_level:y}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsx(Ue,{children:v.map(y=>e.jsx(ae,{value:y,children:y},y))})]})]})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"mb-2 block",children:"完全屏蔽的库"}),e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx(ie,{value:c,onChange:y=>u(y.target.value),placeholder:"输入库名",className:"flex-1",onKeyDown:y=>{y.key==="Enter"&&(y.preventDefault(),f())}}),e.jsx(C,{onClick:f,size:"sm",className:"flex-shrink-0",children:e.jsx(it,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:n.suppress_libraries.map(y=>e.jsxs("div",{className:"flex items-center gap-1 bg-secondary px-3 py-1 rounded-md",children:[e.jsx("span",{className:"text-sm",children:y}),e.jsx(C,{variant:"ghost",size:"sm",className:"h-5 w-5 p-0",onClick:()=>p(y),children:e.jsx(ls,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]},y))})]}),e.jsxs("div",{children:[e.jsx(E,{className:"mb-2 block",children:"特定库的日志级别"}),e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx(ie,{value:c,onChange:y=>u(y.target.value),placeholder:"输入库名",className:"flex-1"}),e.jsxs(Be,{value:x,onValueChange:h,children:[e.jsx(Le,{className:"w-32",children:e.jsx($e,{})}),e.jsx(Ue,{children:v.map(y=>e.jsx(ae,{value:y,children:y},y))})]}),e.jsx(C,{onClick:g,size:"sm",children:e.jsx(it,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),e.jsx("div",{className:"space-y-2",children:Object.entries(n.library_log_levels).map(([y,R])=>e.jsxs("div",{className:"flex items-center justify-between bg-secondary px-3 py-2 rounded-md",children:[e.jsx("span",{className:"text-sm font-medium",children:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:R}),e.jsx(C,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0",onClick:()=>N(y),children:e.jsx(ls,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]})]},y))})]})]})}),J2=Es.memo(function({config:n,onChange:i}){return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"调试配置"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示 Prompt"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否在日志中显示提示词"})]}),e.jsx(Ge,{checked:n.show_prompt,onCheckedChange:c=>i({...n,show_prompt:c})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示回复器 Prompt"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示回复器的提示词"})]}),e.jsx(Ge,{checked:n.show_replyer_prompt,onCheckedChange:c=>i({...n,show_replyer_prompt:c})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示回复器推理"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示回复器的推理过程"})]}),e.jsx(Ge,{checked:n.show_replyer_reasoning,onCheckedChange:c=>i({...n,show_replyer_reasoning:c})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示 Jargon Prompt"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示术语相关的提示词"})]}),e.jsx(Ge,{checked:n.show_jargon_prompt,onCheckedChange:c=>i({...n,show_jargon_prompt:c})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示记忆检索 Prompt"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示记忆检索相关的提示词"})]}),e.jsx(Ge,{checked:n.show_memory_prompt,onCheckedChange:c=>i({...n,show_memory_prompt:c})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示 Planner Prompt"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示 Planner 的提示词和原始返回结果"})]}),e.jsx(Ge,{checked:n.show_planner_prompt,onCheckedChange:c=>i({...n,show_planner_prompt:c})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"显示 LPMM 相关文段"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否显示 LPMM 知识库找到的相关文段日志"})]}),e.jsx(Ge,{checked:n.show_lpmm_paragraph,onCheckedChange:c=>i({...n,show_lpmm_paragraph:c})})]})]})]})}),X2=Es.memo(function({config:n,onChange:i}){const[c,u]=m.useState(""),[x,h]=m.useState(""),f=()=>{c&&!n.auth_token.includes(c)&&(i({...n,auth_token:[...n.auth_token,c]}),u(""))},p=v=>{i({...n,auth_token:n.auth_token.filter((b,w)=>w!==v)})},g=()=>{x&&!n.api_server_allowed_api_keys.includes(x)&&(i({...n,api_server_allowed_api_keys:[...n.api_server_allowed_api_keys,x]}),h(""))},N=v=>{i({...n,api_server_allowed_api_keys:n.api_server_allowed_api_keys.filter((b,w)=>w!==v)})};return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"旧版 API 认证令牌"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-3",children:"用于旧版 API 验证,为空则不启用验证"}),e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx(ie,{value:c,onChange:v=>u(v.target.value),placeholder:"输入认证令牌",onKeyDown:v=>{v.key==="Enter"&&(v.preventDefault(),f())}}),e.jsx(C,{onClick:f,size:"sm",children:e.jsx(it,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),e.jsx("div",{className:"space-y-2",children:n.auth_token.map((v,b)=>e.jsxs("div",{className:"flex items-center justify-between bg-secondary px-3 py-2 rounded-md",children:[e.jsx("span",{className:"text-sm font-mono",children:v}),e.jsx(C,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0",onClick:()=>p(b),children:e.jsx(ls,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]},b))})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"新版 API Server 配置"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"启用新版 API Server"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"是否启用额外的新版 API Server(额外监听端口)"})]}),e.jsx(Ge,{checked:n.enable_api_server,onCheckedChange:v=>i({...n,enable_api_server:v})})]}),n.enable_api_server&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"主机地址"}),e.jsx(ie,{value:n.api_server_host,onChange:v=>i({...n,api_server_host:v.target.value}),placeholder:"0.0.0.0"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"端口号"}),e.jsx(ie,{type:"number",value:n.api_server_port,onChange:v=>i({...n,api_server_port:parseInt(v.target.value)}),placeholder:"8090"})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{checked:n.api_server_use_wss,onCheckedChange:v=>i({...n,api_server_use_wss:v})}),e.jsx(E,{children:"启用 WSS 安全连接"})]}),n.api_server_use_wss&&e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"SSL 证书文件路径"}),e.jsx(ie,{value:n.api_server_cert_file,onChange:v=>i({...n,api_server_cert_file:v.target.value}),placeholder:"cert.pem"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"SSL 密钥文件路径"}),e.jsx(ie,{value:n.api_server_key_file,onChange:v=>i({...n,api_server_key_file:v.target.value}),placeholder:"key.pem"})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"mb-2 block",children:"允许的 API Key 列表"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"为空则允许所有连接"}),e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx(ie,{value:x,onChange:v=>h(v.target.value),placeholder:"输入 API Key",onKeyDown:v=>{v.key==="Enter"&&(v.preventDefault(),g())}}),e.jsx(C,{onClick:g,size:"sm",children:e.jsx(it,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]}),e.jsx("div",{className:"space-y-2",children:n.api_server_allowed_api_keys.map((v,b)=>e.jsxs("div",{className:"flex items-center justify-between bg-secondary px-3 py-2 rounded-md",children:[e.jsx("span",{className:"text-sm font-mono",children:v}),e.jsx(C,{variant:"ghost",size:"sm",className:"h-6 w-6 p-0",onClick:()=>N(b),children:e.jsx(ls,{className:"h-3 w-3",strokeWidth:2,fill:"none"})})]},b))})]})]})]})]})]})}),Z2=Es.memo(function({config:n,onChange:i}){return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"统计信息"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:"启用统计信息发送"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"发送匿名统计信息,帮助我们了解全球有多少只麦麦在运行"})]}),e.jsx(Ge,{checked:n.enable,onCheckedChange:c=>i({...n,enable:c})})]})]})}),W2=Es.memo(function({emojiConfig:n,memoryConfig:i,toolConfig:c,voiceConfig:u,onEmojiChange:x,onMemoryChange:h,onToolChange:f,onVoiceChange:p}){return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"工具设置"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_tool",checked:c.enable_tool,onCheckedChange:g=>f({...c,enable_tool:g})}),e.jsx(E,{htmlFor:"enable_tool",className:"cursor-pointer",children:"启用工具系统"})]}),e.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"允许麦麦使用各种工具来增强功能"}),e.jsxs("div",{className:"flex items-center space-x-2 pt-2",children:[e.jsx(Ge,{id:"enable_asr",checked:u.enable_asr,onCheckedChange:g=>p({...u,enable_asr:g})}),e.jsx(E,{htmlFor:"enable_asr",className:"cursor-pointer",children:"启用语音识别"})]}),e.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"启用后麦麦可以识别语音消息,需要配置语音识别模型"})]})]})}),e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"记忆设置"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"max_agent_iterations",children:"记忆思考深度"}),e.jsx(ie,{id:"max_agent_iterations",type:"number",min:"1",value:i.max_agent_iterations,onChange:g=>h({...i,max_agent_iterations:parseInt(g.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"最低为 1(不深入思考)"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"agent_timeout_seconds",children:"最长回忆时间(秒)"}),e.jsx(ie,{id:"agent_timeout_seconds",type:"number",min:"1",step:"0.1",value:i.agent_timeout_seconds??120,onChange:g=>h({...i,agent_timeout_seconds:parseFloat(g.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"记忆检索的超时时间,避免过长的等待"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_jargon_detection",checked:i.enable_jargon_detection??!0,onCheckedChange:g=>h({...i,enable_jargon_detection:g})}),e.jsx(E,{htmlFor:"enable_jargon_detection",className:"cursor-pointer",children:"启用黑话识别"})]}),e.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"记忆检索过程中是否启用黑话识别"}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"global_memory",checked:i.global_memory??!1,onCheckedChange:g=>h({...i,global_memory:g})}),e.jsx(E,{htmlFor:"global_memory",className:"cursor-pointer",children:"全局记忆查询"})]}),e.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"允许记忆检索在所有聊天记录中进行全局查询(忽略当前聊天流)"})]})]})}),e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"表情包设置"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"emoji_chance",children:"表情包激活概率"}),e.jsx(ie,{id:"emoji_chance",type:"number",step:"0.1",min:"0",max:"1",value:n.emoji_chance,onChange:g=>x({...n,emoji_chance:parseFloat(g.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"范围 0-1,越大越容易发送表情包"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"max_reg_num",children:"最大注册数量"}),e.jsx(ie,{id:"max_reg_num",type:"number",min:"1",value:n.max_reg_num,onChange:g=>x({...n,max_reg_num:parseInt(g.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦最多可以注册的表情包数量"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"check_interval",children:"检查间隔(分钟)"}),e.jsx(ie,{id:"check_interval",type:"number",min:"1",value:n.check_interval,onChange:g=>x({...n,check_interval:parseInt(g.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"检查表情包(注册、破损、删除)的时间间隔"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"do_replace",checked:n.do_replace,onCheckedChange:g=>x({...n,do_replace:g})}),e.jsx(E,{htmlFor:"do_replace",className:"cursor-pointer",children:"达到最大数量时替换表情包"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"steal_emoji",checked:n.steal_emoji,onCheckedChange:g=>x({...n,steal_emoji:g})}),e.jsx(E,{htmlFor:"steal_emoji",className:"cursor-pointer",children:"偷取表情包"})]}),e.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"允许麦麦将看到的表情包据为己有"}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"content_filtration",checked:n.content_filtration,onCheckedChange:g=>x({...n,content_filtration:g})}),e.jsx(E,{htmlFor:"content_filtration",className:"cursor-pointer",children:"启用表情包过滤"})]}),n.content_filtration&&e.jsxs("div",{className:"grid gap-2 pl-6 border-l-2 border-primary/20",children:[e.jsx(E,{htmlFor:"filtration_prompt",children:"过滤要求"}),e.jsx(ie,{id:"filtration_prompt",value:n.filtration_prompt,onChange:g=>x({...n,filtration_prompt:g.target.value}),placeholder:"符合公序良俗"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"只有符合此要求的表情包才会被保存"})]})]})]})})]})}),e_=Es.memo(function({member:n,groupIndex:i,memberIndex:c,availableChatIds:u,onUpdate:x,onRemove:h}){const f=u.includes(n)||n==="*",[p,g]=m.useState(!f);return e.jsxs("div",{className:"flex gap-2",children:[e.jsx("div",{className:"flex-1 flex gap-2",children:p?e.jsxs(e.Fragment,{children:[e.jsx(ie,{value:n,onChange:N=>x(i,c,N.target.value),placeholder:'输入 "*" 或 "qq:123456:group"',className:"flex-1"}),u.length>0&&e.jsx(C,{size:"sm",variant:"outline",onClick:()=>g(!1),title:"切换到下拉选择",children:"下拉"})]}):e.jsxs(e.Fragment,{children:[e.jsxs(Be,{value:n,onValueChange:N=>x(i,c,N),children:[e.jsx(Le,{className:"flex-1",children:e.jsx($e,{placeholder:"选择聊天流"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"*",children:"* (全局共享)"}),u.map((N,v)=>e.jsx(ae,{value:N,children:N},v))]})]}),e.jsx(C,{size:"sm",variant:"outline",onClick:()=>g(!0),title:"切换到手动输入",children:"输入"})]})}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除组成员 "',n||"(空)",'" 吗?此操作无法撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>h(i,c),children:"删除"})]})]})]})]})}),s_=Es.memo(function({config:n,onChange:i}){const c=()=>{i({...n,learning_list:[...n.learning_list,["","enable","enable","1.0"]]})},u=b=>{i({...n,learning_list:n.learning_list.filter((w,y)=>y!==b)})},x=(b,w,y)=>{const R=[...n.learning_list];R[b][w]=y,i({...n,learning_list:R})},h=({rule:b})=>{const w=`["${b[0]}", "${b[1]}", "${b[2]}", "${b[3]}"]`;return e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",children:[e.jsx(sa,{className:"h-4 w-4 mr-1"}),"预览"]})}),e.jsx(Ka,{className:"w-80 sm:w-96",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),e.jsx("div",{className:"rounded-md bg-muted p-3 font-mono text-xs break-all",children:w}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})},f=()=>{i({...n,expression_groups:[...n.expression_groups,[]]})},p=b=>{i({...n,expression_groups:n.expression_groups.filter((w,y)=>y!==b)})},g=b=>{const w=[...n.expression_groups];w[b]=[...w[b],""],i({...n,expression_groups:w})},N=(b,w)=>{const y=[...n.expression_groups];y[b]=y[b].filter((R,D)=>D!==w),i({...n,expression_groups:y})},v=(b,w,y)=>{const R=[...n.expression_groups];R[b][w]=y,i({...n,expression_groups:R})};return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:"表达学习配置"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"配置麦麦如何学习和使用表达方式"})]}),e.jsxs(C,{onClick:c,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加规则"]})]}),e.jsxs("div",{className:"space-y-4",children:[n.learning_list.map((b,w)=>{const y=n.learning_list.some((S,T)=>T!==w&&S[0]===""),R=b[0]==="",D=b[0].split(":"),k=D[0]||"qq",I=D[1]||"",M=D[2]||"group";return e.jsxs("div",{className:"rounded-lg border p-4 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-sm font-medium",children:["规则 ",w+1," ",R&&"(全局配置)"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(h,{rule:b}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"sm",variant:"ghost",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除学习规则 ",w+1," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>u(w),children:"删除"})]})]})]})]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"配置类型"}),e.jsxs(Be,{value:R?"global":"specific",onValueChange:S=>{S==="global"?x(w,0,""):x(w,0,"qq::group")},disabled:y&&!R,children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"global",children:"全局配置"}),e.jsx(ae,{value:"specific",disabled:y&&!R,children:"详细配置"})]})]}),y&&!R&&e.jsx("p",{className:"text-xs text-amber-600",children:"已存在全局配置,无法创建新的全局配置"})]}),!R&&e.jsxs("div",{className:"grid gap-4 p-3 sm:p-4 rounded-lg bg-muted/50",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"平台"}),e.jsxs(Be,{value:k,onValueChange:S=>{x(w,0,`${S}:${I}:${M}`)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"qq",children:"QQ"}),e.jsx(ae,{value:"wx",children:"微信"})]})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"群 ID"}),e.jsx(ie,{value:I,onChange:S=>{x(w,0,`${k}:${S.target.value}:${M}`)},placeholder:"输入群 ID",className:"font-mono text-sm"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"类型"}),e.jsxs(Be,{value:M,onValueChange:S=>{x(w,0,`${k}:${I}:${S}`)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"group",children:"群组(group)"}),e.jsx(ae,{value:"private",children:"私聊(private)"})]})]})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["当前聊天流 ID:",b[0]||"(未设置)"]})]}),e.jsx("div",{className:"grid gap-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-xs font-medium",children:"使用学到的表达"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"允许麦麦使用从聊天中学到的表达方式"})]}),e.jsx(Ge,{checked:b[1]==="enable",onCheckedChange:S=>x(w,1,S?"enable":"disable")})]})}),e.jsx("div",{className:"grid gap-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-xs font-medium",children:"学习表达"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"允许麦麦从聊天中学习新的表达方式"})]}),e.jsx(Ge,{checked:b[2]==="enable",onCheckedChange:S=>x(w,2,S?"enable":"disable")})]})}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-xs font-medium",children:"学习强度"}),e.jsx(ie,{type:"number",step:"0.1",min:"0",max:"5",value:b[3],onChange:S=>{const T=parseFloat(S.target.value);isNaN(T)||x(w,3,Math.max(0,Math.min(5,T)).toFixed(1))},className:"w-20 h-8 text-xs"})]}),e.jsx(wa,{value:[parseFloat(b[3])||1],onValueChange:S=>x(w,3,S[0].toFixed(1)),min:0,max:5,step:.1,className:"w-full"}),e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:"0 (不学习)"}),e.jsx("span",{children:"2.5"}),e.jsx("span",{children:"5.0 (快速学习)"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"影响学习频率,最短学习间隔 = 300/学习强度(秒)"})]})]})]},w)}),n.learning_list.length===0&&e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无学习规则,点击"添加规则"开始配置'})]})]})}),e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:"表达反思配置"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"配置麦麦主动向管理员询问表达方式是否合适的功能"})]}),e.jsx(Ge,{checked:n.reflect,onCheckedChange:b=>i({...n,reflect:b})})]}),n.reflect&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border p-4 space-y-4",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-sm font-medium",children:"反思操作员"})}),e.jsx("div",{className:"space-y-4",children:(()=>{const w=(n.reflect_operator_id||"").split(":"),y=w[0]||"qq",R=w[1]||"",D=w[2]||"private";return e.jsxs("div",{className:"grid gap-4 p-3 sm:p-4 rounded-lg bg-muted/50",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"平台"}),e.jsxs(Be,{value:y,onValueChange:k=>{i({...n,reflect_operator_id:`${k}:${R}:${D}`})},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"qq",children:"QQ"}),e.jsx(ae,{value:"wx",children:"微信"})]})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"用户/群 ID"}),e.jsx(ie,{value:R,onChange:k=>{i({...n,reflect_operator_id:`${y}:${k.target.value}:${D}`})},placeholder:"输入 ID",className:"font-mono text-sm"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"类型"}),e.jsxs(Be,{value:D,onValueChange:k=>{i({...n,reflect_operator_id:`${y}:${R}:${k}`})},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"private",children:"私聊(private)"}),e.jsx(ae,{value:"group",children:"群组(group)"})]})]})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["当前操作员 ID:",n.reflect_operator_id||"(未设置)"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦会向此操作员询问表达方式是否合适"})]})})()})]}),e.jsxs("div",{className:"rounded-lg border p-4 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium",children:"允许反思的聊天流"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"只有在此列表中的聊天流才会提出问题并跟踪。如果列表为空,则所有聊天流都可以进行表达反思"})]}),e.jsxs(C,{onClick:()=>{i({...n,allow_reflect:[...n.allow_reflect||[],"qq::group"]})},size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加聊天流"]})]}),e.jsxs("div",{className:"space-y-2",children:[(n.allow_reflect||[]).map((b,w)=>{const y=b.split(":"),R=y[0]||"qq",D=y[1]||"",k=y[2]||"group";return e.jsxs("div",{className:"flex items-center gap-2 p-3 rounded-lg bg-muted/50",children:[e.jsxs(Be,{value:R,onValueChange:I=>{const M=[...n.allow_reflect];M[w]=`${I}:${D}:${k}`,i({...n,allow_reflect:M})},children:[e.jsx(Le,{className:"w-24",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"qq",children:"QQ"}),e.jsx(ae,{value:"wx",children:"微信"})]})]}),e.jsx(ie,{value:D,onChange:I=>{const M=[...n.allow_reflect];M[w]=`${R}:${I.target.value}:${k}`,i({...n,allow_reflect:M})},placeholder:"ID",className:"flex-1 font-mono text-sm"}),e.jsxs(Be,{value:k,onValueChange:I=>{const M=[...n.allow_reflect];M[w]=`${R}:${D}:${I}`,i({...n,allow_reflect:M})},children:[e.jsx(Le,{className:"w-32",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"group",children:"群组"}),e.jsx(ae,{value:"private",children:"私聊"})]})]}),e.jsx(C,{onClick:()=>{i({...n,allow_reflect:n.allow_reflect.filter((I,M)=>M!==w)})},size:"sm",variant:"ghost",children:e.jsx(ls,{className:"h-4 w-4"})})]},w)}),(!n.allow_reflect||n.allow_reflect.length===0)&&e.jsx("div",{className:"text-center py-4 text-muted-foreground text-sm",children:"列表为空,所有聊天流都可以进行表达反思"})]})]})]})]})}),e.jsx("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:"表达共享组配置"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"配置不同聊天流之间如何共享学到的表达方式"})]}),e.jsxs(C,{onClick:f,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加共享组"]})]}),e.jsxs("div",{className:"space-y-4",children:[n.expression_groups.map((b,w)=>{const y=n.learning_list.map(R=>R[0]).filter(R=>R!=="");return e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-sm font-medium",children:["共享组 ",w+1,b.length===1&&b[0]==="*"&&"(全局共享)"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(C,{onClick:()=>g(w),size:"sm",variant:"outline",children:e.jsx(it,{className:"h-4 w-4"})}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"sm",variant:"ghost",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除共享组 ",w+1," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>p(w),children:"删除"})]})]})]})]})]}),e.jsx("div",{className:"space-y-2",children:b.map((R,D)=>e.jsx(e_,{member:R,groupIndex:w,memberIndex:D,availableChatIds:y,onUpdate:v,onRemove:N},`${w}-${D}`))}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'提示:可以从下拉框选择已配置的聊天流,或手动输入。输入 "*" 启用全局共享'})]},w)}),n.expression_groups.length===0&&e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无共享组,点击"添加共享组"开始配置'})]})]})}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"黑话设置"}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"all_global_jargon",checked:n.all_global_jargon??!1,onCheckedChange:b=>i({...n,all_global_jargon:b})}),e.jsx(E,{htmlFor:"all_global_jargon",className:"cursor-pointer",children:"全局黑话模式"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"开启后,新增的黑话将默认设为全局(所有聊天流共享)。关闭后,已记录的全局黑话不会改变,需要手动删除。"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_jargon_explanation",checked:n.enable_jargon_explanation??!0,onCheckedChange:b=>i({...n,enable_jargon_explanation:b})}),e.jsx(E,{htmlFor:"enable_jargon_explanation",className:"cursor-pointer",children:"启用黑话解释"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"在回复前尝试对上下文中的黑话进行解释。关闭可减少一次LLM调用,仅影响回复前的黑话匹配与解释,不影响黑话学习。"})]}),e.jsxs("div",{children:[e.jsx(E,{htmlFor:"jargon_mode",children:"黑话解释来源模式"}),e.jsxs(Be,{value:n.jargon_mode??"context",onValueChange:b=>i({...n,jargon_mode:b}),children:[e.jsx(Le,{id:"jargon_mode",className:"mt-2",children:e.jsx($e,{placeholder:"选择黑话解释来源"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"context",children:"上下文模式(自动匹配黑话)"}),e.jsx(ae,{value:"planner",children:"Planner模式(使用unknown_words列表)"})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-2",children:["上下文模式:使用上下文自动匹配黑话并解释",e.jsx("br",{}),"Planner模式:仅使用Planner在reply动作中给出的unknown_words列表进行黑话检索"]})]})]})]})});function t_({regex:l,reaction:n,onRegexChange:i,onReactionChange:c}){const[u,x]=m.useState(!1),[h,f]=m.useState(""),[p,g]=m.useState(null),[N,v]=m.useState(""),[b,w]=m.useState({}),[y,R]=m.useState(""),D=m.useRef(null),[k,I]=m.useState("build"),M=A=>A.replace(/\(\?P<([^>]+)>/g,"(?<$1>"),S=(A,Q=0)=>{const G=D.current;if(!G)return;const de=G.selectionStart||0,oe=G.selectionEnd||0,ve=l.substring(0,de)+A+l.substring(oe);i(ve),setTimeout(()=>{const le=de+A.length+Q;G.setSelectionRange(le,le),G.focus()},0)};m.useEffect(()=>{if(!l||!h){p!==null&&g(null),Object.keys(b).length>0&&w({}),y!==n&&R(n),N!==""&&v("");return}try{const A=M(l),Q=new RegExp(A,"g"),G=h.match(Q);g(G),v("");const oe=new RegExp(A).exec(h);if(oe&&oe.groups){w(oe.groups);let ve=n;Object.entries(oe.groups).forEach(([le,fe])=>{ve=ve.replace(new RegExp(`\\[${le}\\]`,"g"),fe||"")}),R(ve)}else w({}),R(n)}catch(A){v(A.message),g(null),w({}),R(n)}},[l,h,n,p,b,y,N]);const T=()=>{if(!h||!p||p.length===0)return e.jsx("span",{className:"text-muted-foreground",children:h||"请输入测试文本"});try{const A=M(l),Q=new RegExp(A,"g");let G=0;const de=[];let oe;for(;(oe=Q.exec(h))!==null;)oe.index>G&&de.push(e.jsx("span",{children:h.substring(G,oe.index)},`text-${G}`)),de.push(e.jsx("span",{className:"bg-yellow-200 dark:bg-yellow-900 font-semibold",children:oe[0]},`match-${oe.index}`)),G=oe.index+oe[0].length;return G)",desc:"Python风格命名捕获组",moveCursor:-1},{label:"非捕获组",pattern:"(?:)",desc:"分组但不保存匹配结果",moveCursor:-1}]},{category:"字符类",items:[{label:"字符集",pattern:"[]",desc:"匹配括号内的任意字符",moveCursor:-1},{label:"排除字符",pattern:"[^]",desc:"匹配不在括号内的字符",moveCursor:-1},{label:"范围",pattern:"[a-z]",desc:"匹配a到z的字符"},{label:"中文字符",pattern:"[\\u4e00-\\u9fa5]",desc:"匹配中文汉字"}]},{category:"常用模板",items:[{label:"捕获词语",pattern:"(?P\\S+)",desc:"捕获一个词语"},{label:"捕获句子",pattern:"(?P.+)",desc:"捕获整个句子"},{label:"捕获数字",pattern:"(?P\\d+)",desc:"捕获一个或多个数字"},{label:"可选词语",pattern:"(?:词语1|词语2)",desc:"匹配多个可选项之一"}]}];return e.jsxs(Ks,{open:u,onOpenChange:x,children:[e.jsx(Ho,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",children:[e.jsx(Lm,{className:"h-4 w-4 mr-1"}),"正则编辑器"]})}),e.jsxs(Ps,{className:"max-w-[95vw] sm:max-w-[900px] max-h-[90vh]",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"正则表达式编辑器"}),e.jsx(ot,{className:"text-sm",children:"使用可视化工具构建正则表达式,并实时测试效果"})]}),e.jsx(es,{className:"max-h-[calc(90vh-120px)]",children:e.jsxs(ma,{value:k,onValueChange:A=>I(A),className:"w-full",children:[e.jsxs(ta,{className:"grid w-full grid-cols-2",children:[e.jsx(as,{value:"build",children:"🔧 构建器"}),e.jsx(as,{value:"test",children:"🧪 测试器"})]}),e.jsxs(ys,{value:"build",className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{className:"text-sm font-medium",children:"正则表达式"}),e.jsx(ie,{ref:D,value:l,onChange:A=>i(A.target.value),className:"font-mono text-sm",placeholder:"点击下方按钮构建正则表达式..."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{className:"text-sm font-medium",children:"Reaction 内容"}),e.jsx(et,{value:n,onChange:A=>c(A.target.value),placeholder:"使用 [捕获组名] 引用捕获的内容...",rows:3,className:"text-sm"})]}),e.jsxs("div",{className:"space-y-4 border-t pt-4",children:[$.map(A=>e.jsxs("div",{className:"space-y-2",children:[e.jsx("h5",{className:"text-xs font-semibold text-primary",children:A.category}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2",children:A.items.map(Q=>e.jsx(C,{variant:"outline",size:"sm",className:"justify-start h-auto py-2 px-3",onClick:()=>S(Q.pattern,Q.moveCursor||0),children:e.jsxs("div",{className:"flex flex-col items-start w-full",children:[e.jsxs("div",{className:"flex items-center gap-2 w-full",children:[e.jsx("span",{className:"text-xs font-medium",children:Q.label}),e.jsx("code",{className:"ml-auto text-xs bg-muted px-1.5 py-0.5 rounded font-mono",children:Q.pattern})]}),e.jsx("span",{className:"text-xs text-muted-foreground mt-0.5",children:Q.desc})]})},Q.label))})]},A.category)),e.jsxs("div",{className:"space-y-2 border-t pt-4",children:[e.jsx("h5",{className:"text-xs font-semibold text-primary",children:"完整示例模板"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(C,{variant:"outline",size:"sm",className:"w-full justify-start h-auto py-2 px-3",onClick:()=>i("^(?P\\S{1,20})是这样的$"),children:e.jsxs("div",{className:"flex flex-col items-start w-full",children:[e.jsxs("code",{className:"text-xs font-mono bg-muted px-2 py-1 rounded w-full overflow-x-auto",children:["^(?P\\S","{1,20}",")是这样的$"]}),e.jsx("span",{className:"text-xs text-muted-foreground mt-1",children:"匹配「某事物是这样的」并捕获事物名称"})]})}),e.jsx(C,{variant:"outline",size:"sm",className:"w-full justify-start h-auto py-2 px-3",onClick:()=>i("(?:[^,。.\\s]+,\\s*)?我(?:也)?[没沒]要求你\\s*(?P.+?)[.。,,]?$"),children:e.jsxs("div",{className:"flex flex-col items-start w-full",children:[e.jsx("code",{className:"text-xs font-mono bg-muted px-2 py-1 rounded w-full overflow-x-auto",children:"(?:[^,。.\\s]+,\\s*)?我(?:也)?[没沒]要求你\\s*(?P.+?)[.。,,]?$"}),e.jsx("span",{className:"text-xs text-muted-foreground mt-1",children:"匹配「我没要求你做某事」并捕获具体行为"})]})}),e.jsx(C,{variant:"outline",size:"sm",className:"w-full justify-start h-auto py-2 px-3",onClick:()=>i("(?P.+?)(?:是|为什么|怎么)"),children:e.jsxs("div",{className:"flex flex-col items-start w-full",children:[e.jsx("code",{className:"text-xs font-mono bg-muted px-2 py-1 rounded w-full overflow-x-auto",children:"(?P.+?)(?:是|为什么|怎么)"}),e.jsx("span",{className:"text-xs text-muted-foreground mt-1",children:"捕获问题主题词"})]})})]})]})]}),e.jsxs("div",{className:"rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3 space-y-1",children:[e.jsx("p",{className:"text-xs font-medium text-blue-900 dark:text-blue-100",children:"💡 使用提示"}),e.jsxs("ul",{className:"text-xs text-blue-700 dark:text-blue-300 space-y-1 list-disc list-inside",children:[e.jsx("li",{children:"点击输入框设置光标位置,然后点击按钮插入模式"}),e.jsxs("li",{children:["命名捕获组格式:",e.jsx("code",{className:"bg-blue-100 dark:bg-blue-900 px-1 rounded",children:"(?P<名称>模式)"})]}),e.jsxs("li",{children:["在 reaction 中使用 ",e.jsx("code",{className:"bg-blue-100 dark:bg-blue-900 px-1 rounded",children:"[名称]"})," 引用捕获的内容"]}),e.jsx("li",{children:"切换到测试器标签页验证正则表达式效果"})]})]})]}),e.jsxs(ys,{value:"test",className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{className:"text-sm font-medium",children:"当前正则表达式"}),e.jsx("div",{className:"rounded-md bg-muted p-3 font-mono text-xs break-all",children:l||"(未设置)"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"test-text",className:"text-sm font-medium",children:"测试文本"}),e.jsx(et,{id:"test-text",value:h,onChange:A=>f(A.target.value),placeholder:`在此输入要测试的文本... +例如:打游戏是这样的`,className:"min-h-[100px] text-sm"})]}),N&&e.jsxs("div",{className:"rounded-md bg-destructive/10 border border-destructive/20 p-3",children:[e.jsx("p",{className:"text-sm text-destructive font-medium",children:"正则表达式错误"}),e.jsx("p",{className:"text-xs text-destructive/80 mt-1",children:N})]}),!N&&h&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"flex items-center gap-2",children:p&&p.length>0?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-2 w-2 rounded-full bg-green-500"}),e.jsxs("span",{className:"text-sm font-medium text-green-600 dark:text-green-400",children:["匹配成功 (",p.length," 处)"]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-2 w-2 rounded-full bg-gray-400"}),e.jsx("span",{className:"text-sm font-medium text-muted-foreground",children:"无匹配"})]})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{className:"text-sm font-medium",children:"匹配高亮"}),e.jsx(es,{className:"h-40 rounded-md bg-muted p-3",children:e.jsx("div",{className:"text-sm break-words",children:T()})})]}),Object.keys(b).length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{className:"text-sm font-medium",children:"命名捕获组"}),e.jsx(es,{className:"h-32 rounded-md border p-3",children:e.jsx("div",{className:"space-y-2",children:Object.entries(b).map(([A,Q])=>e.jsxs("div",{className:"flex items-start gap-2 text-sm",children:[e.jsxs("span",{className:"font-mono font-semibold text-primary min-w-[80px]",children:["[",A,"]"]}),e.jsx("span",{className:"text-muted-foreground",children:"="}),e.jsx("span",{className:"font-mono bg-muted px-2 py-0.5 rounded",children:Q})]},A))})})]}),Object.keys(b).length>0&&n&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{className:"text-sm font-medium",children:"Reaction 替换预览"}),e.jsx(es,{className:"h-48 rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3",children:e.jsx("div",{className:"text-sm break-words",children:y})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"reaction 中的 [name] 已被替换为对应的捕获组值"})]})]}),e.jsxs("div",{className:"rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3 space-y-1",children:[e.jsx("p",{className:"text-xs font-medium text-blue-900 dark:text-blue-100",children:"💡 测试说明"}),e.jsxs("ul",{className:"text-xs text-blue-700 dark:text-blue-300 space-y-1 list-disc list-inside",children:[e.jsx("li",{children:"匹配的文本会以黄色背景高亮显示"}),e.jsx("li",{children:"命名捕获组的值会显示在下方列表中"}),e.jsx("li",{children:"Reaction 替换预览显示最终生成的反应内容"}),e.jsx("li",{children:"如需修改正则,切换回构建器标签页"})]})]})]})]})})]})]})}const a_=Es.memo(function({keywordReactionConfig:n,responsePostProcessConfig:i,chineseTypoConfig:c,responseSplitterConfig:u,onKeywordReactionChange:x,onResponsePostProcessChange:h,onChineseTypoChange:f,onResponseSplitterChange:p}){const g=()=>{x({...n,regex_rules:[...n.regex_rules,{regex:[""],reaction:""}]})},N=S=>{x({...n,regex_rules:n.regex_rules.filter((T,$)=>$!==S)})},v=(S,T,$)=>{const A=[...n.regex_rules];T==="regex"&&typeof $=="string"?A[S]={...A[S],regex:[$]}:T==="reaction"&&typeof $=="string"&&(A[S]={...A[S],reaction:$}),x({...n,regex_rules:A})},b=()=>{x({...n,keyword_rules:[...n.keyword_rules,{keywords:[],reaction:""}]})},w=S=>{x({...n,keyword_rules:n.keyword_rules.filter((T,$)=>$!==S)})},y=(S,T,$)=>{const A=[...n.keyword_rules];typeof $=="string"&&(A[S]={...A[S],reaction:$}),x({...n,keyword_rules:A})},R=S=>{const T=[...n.keyword_rules];T[S]={...T[S],keywords:[...T[S].keywords||[],""]},x({...n,keyword_rules:T})},D=(S,T)=>{const $=[...n.keyword_rules];$[S]={...$[S],keywords:($[S].keywords||[]).filter((A,Q)=>Q!==T)},x({...n,keyword_rules:$})},k=(S,T,$)=>{const A=[...n.keyword_rules],Q=[...A[S].keywords||[]];Q[T]=$,A[S]={...A[S],keywords:Q},x({...n,keyword_rules:A})},I=({rule:S})=>{const T=`{ regex = [${(S.regex||[]).map($=>`"${$}"`).join(", ")}], reaction = "${S.reaction}" }`;return e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",children:[e.jsx(sa,{className:"h-4 w-4 mr-1"}),"预览"]})}),e.jsx(Ka,{className:"w-[95vw] sm:w-[500px]",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),e.jsx(es,{className:"h-60 rounded-md bg-muted p-3",children:e.jsx("pre",{className:"font-mono text-xs break-all",children:T})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})},M=({rule:S})=>{const T=`[[keyword_reaction.keyword_rules]] +keywords = [${(S.keywords||[]).map($=>`"${$}"`).join(", ")}] +reaction = "${S.reaction}"`;return e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",children:[e.jsx(sa,{className:"h-4 w-4 mr-1"}),"预览"]})}),e.jsx(Ka,{className:"w-[95vw] sm:w-[500px]",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("h4",{className:"font-medium text-sm",children:"配置预览"}),e.jsx(es,{className:"h-60 rounded-md bg-muted p-3",children:e.jsx("pre",{className:"font-mono text-xs whitespace-pre-wrap break-all",children:T})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"这是保存到 bot_config.toml 文件中的格式"})]})})]})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"关键词反应配置"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"配置触发特定反应的关键词和正则表达式规则"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-base font-semibold",children:"正则表达式规则"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"使用正则表达式匹配消息内容"})]}),e.jsxs(C,{onClick:g,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加正则规则"]})]}),e.jsxs("div",{className:"space-y-3",children:[n.regex_rules.map((S,T)=>e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-sm font-medium",children:["正则规则 ",T+1]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(t_,{regex:S.regex&&S.regex[0]||"",reaction:S.reaction,onRegexChange:$=>v(T,"regex",$),onReactionChange:$=>v(T,"reaction",$)}),e.jsx(I,{rule:S}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"sm",variant:"ghost",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除正则规则 ",T+1," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>N(T),children:"删除"})]})]})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"正则表达式(Python 语法)"}),e.jsx(ie,{value:S.regex&&S.regex[0]||"",onChange:$=>v(T,"regex",$.target.value),placeholder:"例如:^(?P\\\\S{1,20})是这样的$ (点击正则编辑器按钮可视化构建)",className:"font-mono text-sm"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'支持命名捕获组 (?Ppattern),可在 reaction 中使用 [name] 引用。点击"正则编辑器"可视化构建和测试!'})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"反应内容"}),e.jsx(et,{value:S.reaction,onChange:$=>v(T,"reaction",$.target.value),placeholder:`触发后麦麦的反应... +可以使用 [捕获组名] 来引用正则表达式中的内容`,rows:3,className:"text-sm"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"使用 [捕获组名] 引用正则表达式中的命名捕获组,例如 [n] 会被替换为捕获的内容"})]})]})]},T)),n.regex_rules.length===0&&e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无正则规则,点击"添加正则规则"开始配置'})]})]}),e.jsxs("div",{className:"space-y-4 border-t pt-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-base font-semibold",children:"关键词规则"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"使用关键词列表匹配消息内容"})]}),e.jsxs(C,{onClick:b,size:"sm",variant:"outline",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加关键词规则"]})]}),e.jsxs("div",{className:"space-y-3",children:[n.keyword_rules.map((S,T)=>e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-sm font-medium",children:["关键词规则 ",T+1]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(M,{rule:S}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"sm",variant:"ghost",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除关键词规则 ",T+1," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>w(T),children:"删除"})]})]})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-xs font-medium",children:"关键词列表"}),e.jsxs(C,{onClick:()=>R(T),size:"sm",variant:"ghost",children:[e.jsx(it,{className:"h-3 w-3 mr-1"}),"添加关键词"]})]}),e.jsxs("div",{className:"space-y-2",children:[(S.keywords||[]).map(($,A)=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{value:$,onChange:Q=>k(T,A,Q.target.value),placeholder:"关键词",className:"flex-1"}),e.jsx(C,{onClick:()=>D(T,A),size:"sm",variant:"ghost",children:e.jsx(ls,{className:"h-4 w-4"})})]},A)),(!S.keywords||S.keywords.length===0)&&e.jsx("p",{className:"text-xs text-muted-foreground text-center py-2",children:'暂无关键词,点击"添加关键词"开始配置'})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-xs font-medium",children:"反应内容"}),e.jsx(et,{value:S.reaction,onChange:$=>y(T,"reaction",$.target.value),placeholder:"触发后麦麦的反应...",rows:3,className:"text-sm"})]})]})]},T)),n.keyword_rules.length===0&&e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:'暂无关键词规则,点击"添加关键词规则"开始配置'})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"回复后处理配置"}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_response_post_process",checked:i.enable_response_post_process,onCheckedChange:S=>h({...i,enable_response_post_process:S})}),e.jsx(E,{htmlFor:"enable_response_post_process",className:"cursor-pointer",children:"启用回复后处理"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"包括错别字生成器和回复分割器"})]}),i.enable_response_post_process&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"border-t pt-6 space-y-4",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-4",children:[e.jsx(Ge,{id:"enable_chinese_typo",checked:c.enable,onCheckedChange:S=>f({...c,enable:S})}),e.jsx(E,{htmlFor:"enable_chinese_typo",className:"cursor-pointer font-semibold",children:"中文错别字生成器"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mb-4",children:"为回复添加随机错别字,让麦麦的回复更自然"}),c.enable&&e.jsxs("div",{className:"grid gap-4 pl-6 border-l-2 border-primary/20",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"error_rate",className:"text-xs font-medium",children:"单字替换概率"}),e.jsx(ie,{id:"error_rate",type:"number",step:"0.001",min:"0",max:"1",value:c.error_rate,onChange:S=>f({...c,error_rate:parseFloat(S.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"min_freq",className:"text-xs font-medium",children:"最小字频阈值"}),e.jsx(ie,{id:"min_freq",type:"number",min:"0",value:c.min_freq,onChange:S=>f({...c,min_freq:parseInt(S.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"tone_error_rate",className:"text-xs font-medium",children:"声调错误概率"}),e.jsx(ie,{id:"tone_error_rate",type:"number",step:"0.01",min:"0",max:"1",value:c.tone_error_rate,onChange:S=>f({...c,tone_error_rate:parseFloat(S.target.value)})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"word_replace_rate",className:"text-xs font-medium",children:"整词替换概率"}),e.jsx(ie,{id:"word_replace_rate",type:"number",step:"0.001",min:"0",max:"1",value:c.word_replace_rate,onChange:S=>f({...c,word_replace_rate:parseFloat(S.target.value)})})]})]})]})}),e.jsx("div",{className:"border-t pt-6 space-y-4",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-4",children:[e.jsx(Ge,{id:"enable_response_splitter",checked:u.enable,onCheckedChange:S=>p({...u,enable:S})}),e.jsx(E,{htmlFor:"enable_response_splitter",className:"cursor-pointer font-semibold",children:"回复分割器"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mb-4",children:"控制回复的长度和句子数量"}),u.enable&&e.jsxs("div",{className:"grid gap-4 pl-6 border-l-2 border-primary/20",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"max_length",className:"text-xs font-medium",children:"最大长度"}),e.jsx(ie,{id:"max_length",type:"number",min:"1",value:u.max_length,onChange:S=>p({...u,max_length:parseInt(S.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"回复允许的最大字符数"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"max_sentence_num",className:"text-xs font-medium",children:"最大句子数"}),e.jsx(ie,{id:"max_sentence_num",type:"number",min:"1",value:u.max_sentence_num,onChange:S=>p({...u,max_sentence_num:parseInt(S.target.value)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"回复允许的最大句子数量"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_kaomoji_protection",checked:u.enable_kaomoji_protection,onCheckedChange:S=>p({...u,enable_kaomoji_protection:S})}),e.jsx(E,{htmlFor:"enable_kaomoji_protection",className:"cursor-pointer",children:"启用颜文字保护"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"enable_overflow_return_all",checked:u.enable_overflow_return_all,onCheckedChange:S=>p({...u,enable_overflow_return_all:S})}),e.jsx(E,{htmlFor:"enable_overflow_return_all",className:"cursor-pointer",children:"超出时一次性返回全部"})]}),e.jsx("p",{className:"text-xs text-muted-foreground -mt-2",children:"当句子数量超出限制时,合并后一次性返回所有内容"})]})]})})]})]})]})}),l_=Es.memo(function({config:n,onChange:i}){const[c,u]=m.useState(""),[x,h]=m.useState(""),[f,p]=m.useState(!1),g=n.allowed_ips?n.allowed_ips.split(",").map(k=>k.trim()).filter(k=>k):[],N=n.trusted_proxies?n.trusted_proxies.split(",").map(k=>k.trim()).filter(k=>k):[],v=()=>{if(!c.trim())return;const k=[...g,c.trim()];i({...n,allowed_ips:k.join(",")}),u("")},b=k=>{const I=g.filter((M,S)=>S!==k);i({...n,allowed_ips:I.join(",")})},w=()=>{if(!x.trim())return;const k=[...N,x.trim()];i({...n,trusted_proxies:k.join(",")}),h("")},y=k=>{const I=N.filter((M,S)=>S!==k);i({...n,trusted_proxies:I.join(",")})},R=k=>{!k&&n.enabled?p(!0):i({...n,enabled:k})},D=()=>{i({...n,enabled:!1}),p(!1)};return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"WebUI 服务配置"}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{checked:n.enabled,onCheckedChange:R}),e.jsx(E,{className:"cursor-pointer",children:"启用 WebUI"})]}),n.enabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"运行模式"}),e.jsxs(Be,{value:n.mode,onValueChange:k=>i({...n,mode:k}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择运行模式"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"development",children:"开发模式"}),e.jsx(ae,{value:"production",children:"生产模式"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"注意: WebUI 的监听地址和端口请在 .env 文件中配置 WEBUI_HOST 和 WEBUI_PORT"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"防爬虫模式"}),e.jsxs(Be,{value:n.anti_crawler_mode,onValueChange:k=>i({...n,anti_crawler_mode:k}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择防爬虫模式"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"false",children:"禁用"}),e.jsx(ae,{value:"basic",children:"基础(只记录不阻止)"}),e.jsx(ae,{value:"loose",children:"宽松"}),e.jsx(ae,{value:"strict",children:"严格"})]})]})]}),e.jsxs("div",{className:"grid gap-2 sm:col-span-2",children:[e.jsx(E,{children:"IP 白名单"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{value:c,onChange:k=>u(k.target.value),onKeyDown:k=>{k.key==="Enter"&&(k.preventDefault(),v())},placeholder:"输入IP地址后按回车或点击添加"}),e.jsx(C,{type:"button",size:"sm",onClick:v,disabled:!c.trim(),children:e.jsx(it,{className:"h-4 w-4"})})]}),g.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2 mt-2",children:g.map((k,I)=>e.jsxs(Ae,{variant:"secondary",className:"flex items-center gap-1",children:[k,e.jsx("button",{type:"button",onClick:()=>b(I),className:"ml-1 hover:bg-destructive/20 rounded-full p-0.5",children:e.jsx(_a,{className:"h-3 w-3"})})]},I))}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"支持精确IP、CIDR格式和通配符(如:127.0.0.1、192.168.1.0/24)"})]}),e.jsxs("div",{className:"grid gap-2 sm:col-span-2",children:[e.jsx(E,{children:"信任的代理 IP"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{value:x,onChange:k=>h(k.target.value),onKeyDown:k=>{k.key==="Enter"&&(k.preventDefault(),w())},placeholder:"输入代理IP后按回车或点击添加"}),e.jsx(C,{type:"button",size:"sm",onClick:w,disabled:!x.trim(),children:e.jsx(it,{className:"h-4 w-4"})})]}),N.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2 mt-2",children:N.map((k,I)=>e.jsxs(Ae,{variant:"secondary",className:"flex items-center gap-1",children:[k,e.jsx("button",{type:"button",onClick:()=>y(I),className:"ml-1 hover:bg-destructive/20 rounded-full p-0.5",children:e.jsx(_a,{className:"h-3 w-3"})})]},I))}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"只有来自这些IP的X-Forwarded-For头才被信任"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{checked:n.trust_xff,onCheckedChange:k=>i({...n,trust_xff:k})}),e.jsx(E,{className:"cursor-pointer",children:"启用 X-Forwarded-For 代理解析"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{checked:n.secure_cookie,onCheckedChange:k=>i({...n,secure_cookie:k})}),e.jsx(E,{className:"cursor-pointer",children:"启用安全 Cookie(仅 HTTPS)"})]})]})]}),e.jsx(ps,{open:f,onOpenChange:p,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"警告:即将关闭 WebUI"}),e.jsxs(xs,{children:["关闭 WebUI 后,在您下次重启麦麦之前,WebUI 界面将无法访问。",e.jsx("br",{}),e.jsx("br",{}),"您需要通过修改配置文件或命令行重新启用 WebUI 才能再次访问此界面。",e.jsx("br",{}),e.jsx("br",{}),"确定要关闭 WebUI 吗?"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{variant:"destructive",onClick:D,children:"确认关闭"})]})]})})]})}),un="/api/webui/config";async function ng(){const n=await(await we(`${un}/bot`)).json();if(!n.success)throw new Error("获取配置数据失败");return n.config}async function ln(){const n=await(await we(`${un}/model`)).json();if(!n.success)throw new Error("获取模型配置数据失败");return n.config}async function rg(l){const i=await(await we(`${un}/bot`,{method:"POST",body:JSON.stringify(l)})).json();if(!i.success)throw new Error(i.message||"保存配置失败")}async function n_(){const n=await(await we(`${un}/bot/raw`)).json();if(!n.success)throw new Error("获取配置源代码失败");return n.content}async function r_(l){const i=await(await we(`${un}/bot/raw`,{method:"POST",body:JSON.stringify({raw_content:l})})).json();if(!i.success)throw new Error(i.message||"保存配置失败")}async function Ii(l){const i=await(await we(`${un}/model`,{method:"POST",body:JSON.stringify(l)})).json();if(!i.success)throw new Error(i.message||"保存配置失败")}async function i_(l,n){const c=await(await we(`${un}/bot/section/${l}`,{method:"POST",body:JSON.stringify(n)})).json();if(!c.success)throw new Error(c.message||`保存配置节 ${l} 失败`)}async function Am(l,n){const c=await(await we(`${un}/model/section/${l}`,{method:"POST",body:JSON.stringify(n)})).json();if(!c.success)throw new Error(c.message||`保存配置节 ${l} 失败`)}async function c_(l,n="openai",i="/models"){const c=new URLSearchParams({provider_name:l,parser:n,endpoint:i}),u=await we(`/api/webui/models/list?${c}`);if(!u.ok){const h=await u.json().catch(()=>({}));throw new Error(h.detail||`获取模型列表失败 (${u.status})`)}const x=await u.json();if(!x.success)throw new Error("获取模型列表失败");return x.models}async function o_(l){const n=new URLSearchParams({provider_name:l}),i=await we(`/api/webui/models/test-connection-by-name?${n}`,{method:"POST"});if(!i.ok){const c=await i.json().catch(()=>({}));throw new Error(c.detail||`测试连接失败 (${i.status})`)}return await i.json()}const d_=Lr("relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),nt=m.forwardRef(({className:l,variant:n,...i},c)=>e.jsx("div",{ref:c,role:"alert",className:B(d_({variant:n}),l),...i}));nt.displayName="Alert";const An=m.forwardRef(({className:l,...n},i)=>e.jsx("h5",{ref:i,className:B("mb-1 font-medium leading-none tracking-tight",l),...n}));An.displayName="AlertTitle";const rt=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{ref:i,className:B("text-sm [&_p]:leading-relaxed",l),...n}));rt.displayName="AlertDescription";const u_={name:"toml",startState:function(){return{inString:!1,stringType:"",lhs:!0,inArray:0}},token:function(l,n){let i;if(!n.inString&&(i=l.match(/^('''|"""|'|")/))&&(n.stringType=i[0],n.inString=!0),l.sol()&&!n.inString&&n.inArray===0&&(n.lhs=!0),n.inString){for(;n.inString;)if(l.match(n.stringType))n.inString=!1;else if(l.peek()==="\\")l.next(),l.next();else{if(l.eol())break;l.match(/^.[^\\\"\']*/)}return n.lhs?"property":"string"}else{if(n.inArray&&l.peek()==="]")return l.next(),n.inArray--,"bracket";if(n.lhs&&l.peek()==="["&&l.skipTo("]"))return l.next(),l.peek()==="]"&&l.next(),"atom";if(l.peek()==="#")return l.skipToEnd(),"comment";if(l.eatSpace())return null;if(n.lhs&&l.eatWhile(function(c){return c!="="&&c!=" "}))return"property";if(n.lhs&&l.peek()==="=")return l.next(),n.lhs=!1,null;if(!n.lhs&&l.match(/^\d\d\d\d[\d\-\:\.T]*Z/))return"atom";if(!n.lhs&&(l.match("true")||l.match("false")))return"atom";if(!n.lhs&&l.peek()==="[")return n.inArray++,l.next(),"bracket";if(!n.lhs&&l.match(/^\-?\d+(?:\.\d+)?/))return"number";l.eatSpace()||l.next()}return null},languageData:{commentTokens:{line:"#"}}},m_={python:[r1()],json:[i1(),c1()],toml:[n1.define(u_)],text:[]};function ev({value:l,onChange:n,language:i="text",readOnly:c=!1,height:u="400px",minHeight:x,maxHeight:h,placeholder:f,theme:p="dark",className:g=""}){const[N,v]=m.useState(!1);if(m.useEffect(()=>{v(!0)},[]),!N)return e.jsx("div",{className:`rounded-md border bg-muted animate-pulse ${g}`,style:{height:u,minHeight:x,maxHeight:h}});const b=[...m_[i]||[],Yp.lineWrapping];return c&&b.push(Yp.editable.of(!1)),e.jsx("div",{className:`rounded-md overflow-hidden border ${g}`,children:e.jsx(o1,{value:l,height:u,minHeight:x,maxHeight:h,theme:p==="dark"?d1:void 0,extensions:b,onChange:n,placeholder:f,basicSetup:{lineNumbers:!0,highlightActiveLineGutter:!0,highlightSpecialChars:!0,history:!0,foldGutter:!0,drawSelection:!0,dropCursor:!0,allowMultipleSelections:!0,indentOnInput:!0,syntaxHighlighting:!0,bracketMatching:!0,closeBrackets:!0,autocompletion:!0,rectangularSelection:!0,crosshairCursor:!0,highlightActiveLine:!0,highlightSelectionMatches:!0,closeBracketsKeymap:!0,defaultKeymap:!0,searchKeymap:!0,historyKeymap:!0,foldKeymap:!0,completionKeymap:!0,lintKeymap:!0}})})}function x_({id:l,index:n,itemType:i,itemFields:c,value:u,onChange:x,onRemove:h,disabled:f,canRemove:p,placeholder:g}){const{attributes:N,listeners:v,setNodeRef:b,transform:w,transition:y,isDragging:R}=Uj({id:l,disabled:f}),D={transform:Bj.Transform.toString(w),transition:y};return e.jsxs("div",{ref:b,style:D,className:B("flex items-start gap-2 group",R&&"opacity-50 z-50"),children:[e.jsx("button",{type:"button",className:B("flex-shrink-0 p-2 cursor-grab active:cursor-grabbing","text-muted-foreground hover:text-foreground transition-colors","opacity-0 group-hover:opacity-100 focus:opacity-100",f&&"cursor-not-allowed opacity-30"),...N,...v,children:e.jsx(gj,{className:"h-4 w-4"})}),e.jsx("div",{className:"flex-1 min-w-0",children:i==="object"&&c?e.jsx(h_,{value:u,onChange:x,fields:c,disabled:f}):i==="number"?e.jsx(ie,{type:"number",value:u??"",onChange:k=>x(parseFloat(k.target.value)||0),placeholder:g??`第 ${n+1} 项`,disabled:f,className:"font-mono"}):e.jsx(ie,{type:"text",value:u??"",onChange:k=>x(k.target.value),placeholder:g??`第 ${n+1} 项`,disabled:f})}),e.jsx(C,{type:"button",variant:"ghost",size:"icon",onClick:h,disabled:f||!p,className:B("flex-shrink-0 text-muted-foreground hover:text-destructive","opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity"),children:e.jsx(ls,{className:"h-4 w-4"})})]})}function h_({value:l,onChange:n,fields:i,disabled:c}){const u=m.useCallback((h,f)=>{n({...l,[h]:f})},[l,n]),x=(h,f)=>{const p=l?.[h];if(f.type==="boolean"||f.type==="switch")return e.jsxs("div",{className:"flex items-center justify-between py-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:f.label??h}),e.jsx(Ge,{checked:!!(p??f.default),onCheckedChange:g=>u(h,g),disabled:c})]});if(f.type==="slider"||f.type==="number"&&f.min!=null&&f.max!=null){const g=p??f.default??f.min??0;return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:f.label??h}),e.jsx("span",{className:"text-xs text-muted-foreground",children:g})]}),e.jsx(wa,{value:[g],onValueChange:N=>u(h,N[0]),min:f.min??0,max:f.max??100,step:f.step??1,disabled:c,className:"py-1"})]})}return f.type==="select"&&f.choices?e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:f.label??h}),e.jsxs(Be,{value:String(p??f.default??""),onValueChange:g=>u(h,g),disabled:c,children:[e.jsx(Le,{className:"h-8 text-sm",children:e.jsx($e,{placeholder:f.placeholder??"请选择"})}),e.jsx(Ue,{children:f.choices.map(g=>e.jsx(ae,{value:String(g),children:String(g)},String(g)))})]})]}):f.type==="number"?e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:f.label??h}),e.jsx(ie,{type:"number",value:p??f.default??"",onChange:g=>u(h,parseFloat(g.target.value)||0),placeholder:f.placeholder,disabled:c,className:"h-8 text-sm"})]}):e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:f.label??h}),e.jsx(ie,{type:"text",value:p??f.default??"",onChange:g=>u(h,g.target.value),placeholder:f.placeholder,disabled:c,className:"h-8 text-sm"})]})};return e.jsx(De,{className:"p-3 space-y-2 bg-muted/30",children:Object.entries(i).map(([h,f])=>e.jsx("div",{children:x(h,f)},h))})}function f_({value:l,onChange:n,itemType:i="string",itemFields:c,minItems:u,maxItems:x,disabled:h,placeholder:f}){const p=m.useMemo(()=>Array.isArray(l)?l:typeof l=="string"&&l.trim()?l.split(",").map(M=>M.trim()):[],[l]),[g]=m.useState(()=>new Map),N=m.useCallback(M=>(g.has(M)||g.set(M,`item-${Date.now()}-${M}-${Math.random().toString(36).slice(2)}`),g.get(M)),[g]),v=m.useMemo(()=>{const M=[];for(let S=0;S{const{active:S,over:T}=M;if(T&&S.id!==T.id){const $=v.indexOf(S.id),A=v.indexOf(T.id),Q=Dj(p,$,A);n(Q)}},[p,v,n]),y=m.useCallback(()=>{if(x!=null&&p.length>=x)return;let M;i==="object"&&c?M=Object.fromEntries(Object.entries(c).map(([S,T])=>[S,T.default??""])):i==="number"?M=0:M="",n([...p,M])},[p,x,i,c,n]),R=m.useCallback((M,S)=>{const T=[...p];T[M]=S,n(T)},[p,n]),D=m.useCallback(M=>{if(u!=null&&p.length<=u)return;const S=p.filter((T,$)=>$!==M);g.delete(M),n(S)},[p,u,g,n]),k=x==null||p.lengthu;return e.jsxs("div",{className:"space-y-2",children:[p.length===0?e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground py-4 justify-center border border-dashed rounded-md",children:[e.jsx(Ct,{className:"h-4 w-4"}),e.jsx("span",{children:"暂无数据,点击下方按钮添加"})]}):e.jsx(Oj,{sensors:b,collisionDetection:Rj,onDragEnd:w,children:e.jsx(Lj,{items:v,strategy:u1,children:e.jsx("div",{className:"space-y-2",children:p.map((M,S)=>e.jsx(x_,{id:v[S],index:S,itemType:i,itemFields:c,value:M,onChange:T=>R(S,T),onRemove:()=>D(S),disabled:h,canRemove:I,placeholder:f},v[S]))})})}),e.jsxs(C,{type:"button",variant:"outline",size:"sm",onClick:y,disabled:h||!k,className:"w-full",children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加项目",x!==void 0&&e.jsxs("span",{className:"ml-2 text-xs text-muted-foreground",children:["(",p.length,"/",x,")"]})]}),(u!=null||x!=null)&&(u!==null||x!==null)&&e.jsx("p",{className:"text-xs text-muted-foreground text-center",children:u!=null&&x!=null?`允许 ${u} - ${x} 项`:u!=null?`至少 ${u} 项`:`最多 ${x} 项`})]})}function Im({content:l,className:n=""}){return e.jsx("div",{className:`prose prose-sm dark:prose-invert max-w-none ${n}`,children:e.jsx(g1,{remarkPlugins:[v1,N1],rehypePlugins:[j1],components:{code({inline:i,className:c,children:u,...x}){return i?e.jsx("code",{className:"bg-muted px-1.5 py-0.5 rounded text-sm font-mono",...x,children:u}):e.jsx("code",{className:`${c} block bg-muted p-4 rounded-lg overflow-x-auto`,...x,children:u})},table({children:i,...c}){return e.jsx("div",{className:"overflow-x-auto",children:e.jsx("table",{className:"border-collapse border border-border",...c,children:i})})},th({children:i,...c}){return e.jsx("th",{className:"border border-border bg-muted px-4 py-2 text-left font-semibold",...c,children:i})},td({children:i,...c}){return e.jsx("td",{className:"border border-border px-4 py-2",...c,children:i})},a({children:i,...c}){return e.jsx("a",{className:"text-primary hover:underline",target:"_blank",rel:"noopener noreferrer",...c,children:i})},blockquote({children:i,...c}){return e.jsx("blockquote",{className:"border-l-4 border-primary pl-4 italic text-muted-foreground",...c,children:i})},h1({children:i,...c}){return e.jsx("h1",{className:"text-3xl font-bold mt-6 mb-4",...c,children:i})},h2({children:i,...c}){return e.jsx("h2",{className:"text-2xl font-bold mt-5 mb-3",...c,children:i})},h3({children:i,...c}){return e.jsx("h3",{className:"text-xl font-bold mt-4 mb-2",...c,children:i})},h4({children:i,...c}){return e.jsx("h4",{className:"text-lg font-semibold mt-3 mb-2",...c,children:i})},ul({children:i,...c}){return e.jsx("ul",{className:"list-disc list-inside space-y-1 my-2",...c,children:i})},ol({children:i,...c}){return e.jsx("ol",{className:"list-decimal list-inside space-y-1 my-2",...c,children:i})},p({children:i,...c}){return e.jsx("p",{className:"my-2 leading-relaxed",...c,children:i})},hr({...i}){return e.jsx("hr",{className:"my-4 border-border",...i})}},children:l})})}function p_(l,n,i,c={}){const{debounceMs:u=2e3,onSaveSuccess:x,onSaveError:h}=c,f=m.useRef(null),p=m.useCallback(async(b,w)=>{try{n(!0),await i_(b,w),i(!1),x?.()}catch(y){console.error(`自动保存 ${b} 失败:`,y),i(!0),h?.(y instanceof Error?y:new Error(String(y)))}finally{n(!1)}},[n,i,x,h]),g=m.useCallback((b,w)=>{l||(i(!0),f.current&&clearTimeout(f.current),f.current=setTimeout(()=>{p(b,w)},u))},[l,i,p,u]),N=m.useCallback(async(b,w)=>{f.current&&(clearTimeout(f.current),f.current=null),await p(b,w)},[p]),v=m.useCallback(()=>{f.current&&(clearTimeout(f.current),f.current=null)},[]);return m.useEffect(()=>()=>{f.current&&clearTimeout(f.current)},[]),{triggerAutoSave:g,saveNow:N,cancelPendingAutoSave:v}}function Ut(l,n,i,c){m.useEffect(()=>{l&&!i&&c(n,l)},[l])}const g_=500;function j_(){return e.jsx(Pn,{children:e.jsx(v_,{})})}function v_(){const[l,n]=m.useState(!0),[i,c]=m.useState(!1),[u,x]=m.useState(!1),[h,f]=m.useState(!1),[p,g]=m.useState("visual"),[N,v]=m.useState(""),[b,w]=m.useState(!1),{toast:y}=Ws(),{triggerRestart:R,isRestarting:D}=dn(),[k,I]=m.useState(null),[M,S]=m.useState(null),[T,$]=m.useState(null),[A,Q]=m.useState(null),[G,de]=m.useState(null),[oe,ve]=m.useState(null),[le,fe]=m.useState(null),[ge,z]=m.useState(null),[V,U]=m.useState(null),[L,P]=m.useState(null),[_e,je]=m.useState(null),[Se,Y]=m.useState(null),[be,Z]=m.useState(null),[xe,Me]=m.useState(null),[J,ce]=m.useState(null),[Fe,q]=m.useState(null),[ee,ke]=m.useState(null),[Te,Oe]=m.useState(null),[me,ze]=m.useState(null),rs=m.useRef(!0),Kt=m.useRef({}),Qt=m.useCallback(Ee=>{Kt.current=Ee,I(Ee.bot),S(Ee.personality);const gs=Ee.chat;gs.talk_value_rules||(gs.talk_value_rules=[]),$(gs),Q(Ee.expression),de(Ee.emoji),ve(Ee.memory),fe(Ee.tool),z(Ee.voice),U(Ee.dream),P(Ee.lpmm_knowledge),je(Ee.keyword_reaction),Y(Ee.response_post_process),Z(Ee.chinese_typo),Me(Ee.response_splitter),ce(Ee.log),q(Ee.debug),ke(Ee.maim_message),Oe(Ee.telemetry),ze(Ee.webui)},[]),ka=m.useCallback(()=>({...Kt.current,bot:k,personality:M,chat:T,expression:A,emoji:G,memory:oe,tool:le,voice:ge,dream:V,lpmm_knowledge:L,keyword_reaction:_e,response_post_process:Se,chinese_typo:be,response_splitter:xe,log:J,debug:Fe,maim_message:ee,telemetry:Te,webui:me}),[k,M,T,A,G,oe,le,ge,V,L,_e,Se,be,xe,J,Fe,ee,Te,me]),yt=m.useCallback(async()=>{try{const gs=(await n_()).replace(/"([^"]*)"/g,(ts,Ze)=>`"${Ze.replace(/\\n/g,` +`).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\"/g,'"').replace(/\\\\/g,"\\")}"`);v(gs),w(!1)}catch(Ee){y({variant:"destructive",title:"加载失败",description:Ee instanceof Error?Ee.message:"加载源代码失败"})}},[y]),st=m.useCallback(async()=>{try{n(!0);const Ee=await ng();Qt(Ee),f(!1),rs.current=!1,await yt()}catch(Ee){console.error("加载配置失败:",Ee),y({title:"加载失败",description:"无法加载配置文件",variant:"destructive"})}finally{n(!1)}},[y,yt,Qt]);m.useEffect(()=>{st()},[st]);const{triggerAutoSave:F,cancelPendingAutoSave:qe}=p_(rs.current,x,f);Ut(k,"bot",rs.current,F),Ut(M,"personality",rs.current,F),Ut(T,"chat",rs.current,F),Ut(A,"expression",rs.current,F),Ut(G,"emoji",rs.current,F),Ut(oe,"memory",rs.current,F),Ut(le,"tool",rs.current,F),Ut(ge,"voice",rs.current,F),Ut(L,"lpmm_knowledge",rs.current,F),Ut(_e,"keyword_reaction",rs.current,F),Ut(Se,"response_post_process",rs.current,F),Ut(be,"chinese_typo",rs.current,F),Ut(xe,"response_splitter",rs.current,F),Ut(J,"log",rs.current,F),Ut(Fe,"debug",rs.current,F),Ut(ee,"maim_message",rs.current,F),Ut(Te,"telemetry",rs.current,F),Ut(me,"webui",rs.current,F);const Ie=async()=>{try{c(!0);const Ee=N.replace(/"([^"]*)"/g,(gs,ts)=>`"${ts.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r")}"`);await r_(Ee),f(!1),w(!1),y({title:"保存成功",description:"配置已保存"}),await st()}catch(Ee){w(!0),y({variant:"destructive",title:"保存失败",description:Ee instanceof Error?Ee.message:"保存配置失败"})}finally{c(!1)}},Ve=async Ee=>{if(h){y({variant:"destructive",title:"切换失败",description:"请先保存当前更改"});return}if(g(Ee),Ee==="source")await yt();else try{const gs=await ng();Qt(gs),f(!1)}catch(gs){console.error("加载配置失败:",gs),y({title:"加载失败",description:"无法加载配置文件",variant:"destructive"})}},Cs=async()=>{try{c(!0),qe(),await rg(ka()),f(!1),y({title:"保存成功",description:"麦麦主程序配置已保存"})}catch(Ee){console.error("保存配置失败:",Ee),y({title:"保存失败",description:Ee.message,variant:"destructive"})}finally{c(!1)}},ns=async()=>{await R()},Rs=async()=>{try{c(!0),qe(),await rg(ka()),f(!1),y({title:"保存成功",description:"配置已保存,即将重启麦麦..."}),await new Promise(Ee=>setTimeout(Ee,g_)),await ns()}catch(Ee){console.error("保存失败:",Ee),y({title:"保存失败",description:Ee.message,variant:"destructive"})}finally{c(!1)}};return l?e.jsx(es,{className:"h-full",children:e.jsx("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx("p",{className:"text-muted-foreground",children:"加载中..."})})})}):e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:gap-4",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-xl sm:text-2xl md:text-3xl font-bold",children:"麦麦主程序配置"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-xs sm:text-sm",children:"管理麦麦的核心功能和行为设置"})]}),e.jsxs("div",{className:"flex gap-2 flex-shrink-0",children:[e.jsxs(C,{onClick:p==="visual"?Cs:Ie,disabled:i||u||!h||D,size:"sm",variant:"outline",className:"w-20 sm:w-24",children:[e.jsx(Xi,{className:"h-4 w-4 flex-shrink-0",strokeWidth:2,fill:"none"}),e.jsx("span",{className:"ml-1 truncate text-xs sm:text-sm",children:i?"保存中":u?"自动":h?"保存":"已保存"})]}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{disabled:i||u||D,size:"sm",className:"w-20 sm:w-28",children:[e.jsx(Ji,{className:"h-4 w-4 flex-shrink-0"}),e.jsx("span",{className:"ml-1 truncate text-xs sm:text-sm",children:D?"重启中":h?"保存重启":"重启"})]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认重启麦麦?"}),e.jsx(xs,{asChild:!0,children:e.jsx("div",{children:e.jsx("p",{children:h?"当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。":"即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。"})})})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:h?Rs:ns,children:h?"保存并重启":"确认重启"})]})]})]})]})]}),e.jsx("div",{className:"flex",children:e.jsx(ma,{value:p,onValueChange:Ee=>Ve(Ee),className:"w-full",children:e.jsxs(ta,{className:"h-8 sm:h-9 w-full grid grid-cols-2",children:[e.jsxs(as,{value:"visual",className:"text-xs sm:text-sm",children:[e.jsx(jj,{className:"h-3 w-3 sm:h-4 sm:w-4 mr-1"}),"可视化编辑"]}),e.jsxs(as,{value:"source",className:"text-xs sm:text-sm",children:[e.jsx(vj,{className:"h-3 w-3 sm:h-4 sm:w-4 mr-1"}),"源代码编辑"]})]})})})]}),e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsxs(rt,{children:["配置更新后需要",e.jsx("strong",{children:"重启麦麦"}),'才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。']})]}),p==="source"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsxs(rt,{children:[e.jsx("strong",{children:"源代码模式(高级功能):"}),"直接编辑 TOML 配置文件。此功能仅适用于熟悉 TOML 语法的高级用户。保存时会在后端验证格式,只有格式完全正确才能保存。",b&&e.jsx("span",{className:"text-destructive font-semibold ml-2",children:"⚠️ 上次保存失败,请检查 TOML 格式"})]})]}),e.jsx(ev,{value:N,onChange:Ee=>{v(Ee),f(!0),b&&w(!1)},language:"toml",theme:"dark",height:"calc(100vh - 280px)",minHeight:"500px",placeholder:"TOML 配置内容"})]}),p==="visual"&&e.jsx(e.Fragment,{children:e.jsxs(ma,{defaultValue:"bot",className:"w-full",children:[e.jsxs(ta,{className:"flex flex-wrap h-auto gap-1 p-1 sm:grid sm:grid-cols-5 lg:grid-cols-10",children:[e.jsx(as,{value:"bot",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"基本信息"}),e.jsx(as,{value:"personality",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"人格"}),e.jsx(as,{value:"chat",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"聊天"}),e.jsx(as,{value:"expression",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"表达"}),e.jsx(as,{value:"features",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"功能"}),e.jsx(as,{value:"processing",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"处理"}),e.jsx(as,{value:"dream",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"做梦"}),e.jsx(as,{value:"lpmm",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"知识库"}),e.jsx(as,{value:"webui",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"WebUI"}),e.jsx(as,{value:"other",className:"text-xs px-2 py-1.5 sm:px-3 sm:py-2 data-[state=active]:shadow-sm",children:"其他"})]}),e.jsx(ys,{value:"bot",className:"space-y-4",children:k&&e.jsx(I2,{config:k,onChange:I})}),e.jsx(ys,{value:"personality",className:"space-y-4",children:M&&e.jsx(P2,{config:M,onChange:S})}),e.jsx(ys,{value:"chat",className:"space-y-4",children:T&&e.jsx(V2,{config:T,onChange:$})}),e.jsx(ys,{value:"expression",className:"space-y-4",children:A&&e.jsx(s_,{config:A,onChange:Q})}),e.jsx(ys,{value:"features",className:"space-y-4",children:G&&oe&&le&&ge&&e.jsx(W2,{emojiConfig:G,memoryConfig:oe,toolConfig:le,voiceConfig:ge,onEmojiChange:de,onMemoryChange:ve,onToolChange:fe,onVoiceChange:z})}),e.jsx(ys,{value:"processing",className:"space-y-4",children:_e&&Se&&be&&xe&&e.jsx(a_,{keywordReactionConfig:_e,responsePostProcessConfig:Se,chineseTypoConfig:be,responseSplitterConfig:xe,onKeywordReactionChange:je,onResponsePostProcessChange:Y,onChineseTypoChange:Z,onResponseSplitterChange:Me})}),e.jsx(ys,{value:"dream",className:"space-y-4",children:V&&e.jsx(K2,{config:V,onChange:U})}),e.jsx(ys,{value:"lpmm",className:"space-y-4",children:L&&e.jsx(Q2,{config:L,onChange:P})}),e.jsx(ys,{value:"webui",className:"space-y-4",children:me&&e.jsx(l_,{config:me,onChange:ze})}),e.jsxs(ys,{value:"other",className:"space-y-4",children:[J&&e.jsx(Y2,{config:J,onChange:ce}),Fe&&e.jsx(J2,{config:Fe,onChange:q}),ee&&e.jsx(X2,{config:ee,onChange:ke}),Te&&e.jsx(Z2,{config:Te,onChange:Oe})]})]})}),e.jsx(Hn,{})]})})}const El=m.forwardRef(({className:l,...n},i)=>e.jsx("div",{className:"relative w-full overflow-auto",children:e.jsx("table",{ref:i,className:B("w-full caption-bottom text-sm",l),...n})}));El.displayName="Table";const Ml=m.forwardRef(({className:l,...n},i)=>e.jsx("thead",{ref:i,className:B("[&_tr]:border-b",l),...n}));Ml.displayName="TableHeader";const Al=m.forwardRef(({className:l,...n},i)=>e.jsx("tbody",{ref:i,className:B("[&_tr:last-child]:border-0",l),...n}));Al.displayName="TableBody";const N_=m.forwardRef(({className:l,...n},i)=>e.jsx("tfoot",{ref:i,className:B("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",l),...n}));N_.displayName="TableFooter";const ct=m.forwardRef(({className:l,...n},i)=>e.jsx("tr",{ref:i,className:B("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",l),...n}));ct.displayName="TableRow";const Je=m.forwardRef(({className:l,...n},i)=>e.jsx("th",{ref:i,className:B("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",l),...n}));Je.displayName="TableHead";const He=m.forwardRef(({className:l,...n},i)=>e.jsx("td",{ref:i,className:B("px-4 py-3 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",l),...n}));He.displayName="TableCell";const b_=m.forwardRef(({className:l,...n},i)=>e.jsx("caption",{ref:i,className:B("mt-4 text-sm text-muted-foreground",l),...n}));b_.displayName="TableCaption";const Go=m.forwardRef(({className:l,...n},i)=>e.jsx(xa,{ref:i,className:B("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",l),...n}));Go.displayName=xa.displayName;const Fo=m.forwardRef(({className:l,...n},i)=>e.jsxs("div",{className:"flex items-center border-b px-3","cmdk-input-wrapper":"",children:[e.jsx(Vt,{className:"mr-2 h-4 w-4 shrink-0 opacity-50"}),e.jsx(xa.Input,{ref:i,className:B("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",l),...n})]}));Fo.displayName=xa.Input.displayName;const qo=m.forwardRef(({className:l,...n},i)=>e.jsx(xa.List,{ref:i,className:B("max-h-[300px] overflow-y-auto overflow-x-hidden",l),...n}));qo.displayName=xa.List.displayName;const Vo=m.forwardRef((l,n)=>e.jsx(xa.Empty,{ref:n,className:"py-6 text-center text-sm",...l}));Vo.displayName=xa.Empty.displayName;const qi=m.forwardRef(({className:l,...n},i)=>e.jsx(xa.Group,{ref:i,className:B("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",l),...n}));qi.displayName=xa.Group.displayName;const y_=m.forwardRef(({className:l,...n},i)=>e.jsx(xa.Separator,{ref:i,className:B("-mx-1 h-px bg-border",l),...n}));y_.displayName=xa.Separator.displayName;const Vi=m.forwardRef(({className:l,...n},i)=>e.jsx(xa.Item,{ref:i,className:B("relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",l),...n}));Vi.displayName=xa.Item.displayName;const Xs=m.forwardRef(({className:l,...n},i)=>e.jsx(aj,{ref:i,className:B("grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",l),...n,children:e.jsx(pw,{className:B("grid place-content-center text-current"),children:e.jsx(St,{className:"h-4 w-4"})})}));Xs.displayName=aj.displayName;const sv=m.createContext(null),tv="maibot-completed-tours";function w_(){try{const l=localStorage.getItem(tv);return l?new Set(JSON.parse(l)):new Set}catch{return new Set}}function ig(l){localStorage.setItem(tv,JSON.stringify([...l]))}function __({children:l}){const[n,i]=m.useState({activeTourId:null,stepIndex:0,isRunning:!1}),[c]=m.useState(()=>new Map),[u,x]=m.useState(w_),[,h]=m.useState(0),f=m.useCallback((M,S)=>{c.set(M,S),h(T=>T+1)},[c]),p=m.useCallback(M=>{c.delete(M),i(S=>S.activeTourId===M?{...S,activeTourId:null,isRunning:!1,stepIndex:0}:S)},[c]),g=m.useCallback((M,S=0)=>{c.has(M)&&i({activeTourId:M,stepIndex:S,isRunning:!0})},[c]),N=m.useCallback(()=>{i(M=>({...M,isRunning:!1}))},[]),v=m.useCallback(M=>{i(S=>({...S,stepIndex:M}))},[]),b=m.useCallback(()=>{i(M=>({...M,stepIndex:M.stepIndex+1}))},[]),w=m.useCallback(()=>{i(M=>({...M,stepIndex:Math.max(0,M.stepIndex-1)}))},[]),y=m.useCallback(()=>n.activeTourId?c.get(n.activeTourId)||[]:[],[n.activeTourId,c]),R=m.useCallback(M=>{x(S=>{const T=new Set(S);return T.add(M),ig(T),T})},[]),D=m.useCallback(M=>{const{action:S,index:T,status:$,type:A}=M,Q=["finished","skipped"];if(S==="close"){i(G=>({...G,isRunning:!1,stepIndex:0}));return}Q.includes($)?i(G=>($==="finished"&&G.activeTourId&&setTimeout(()=>R(G.activeTourId),0),{...G,isRunning:!1,stepIndex:0})):A==="step:after"&&(S==="next"?i(G=>({...G,stepIndex:T+1})):S==="prev"&&i(G=>({...G,stepIndex:T-1})))},[R]),k=m.useCallback(M=>u.has(M),[u]),I=m.useCallback(M=>{x(S=>{const T=new Set(S);return T.delete(M),ig(T),T})},[]);return e.jsx(sv.Provider,{value:{state:n,tours:c,registerTour:f,unregisterTour:p,startTour:g,stopTour:N,goToStep:v,nextStep:b,prevStep:w,getCurrentSteps:y,handleJoyrideCallback:D,isTourCompleted:k,markTourCompleted:R,resetTourCompleted:I},children:l})}function Pm(){const l=m.useContext(sv);if(!l)throw new Error("useTour must be used within a TourProvider");return l}const S_={options:{zIndex:1e4,primaryColor:"hsl(var(--primary))",textColor:"hsl(var(--foreground))",backgroundColor:"hsl(var(--background))",arrowColor:"hsl(var(--background))",overlayColor:"rgba(0, 0, 0, 0.5)"},tooltip:{borderRadius:"var(--radius)",padding:"1rem"},tooltipContainer:{textAlign:"left"},tooltipTitle:{fontSize:"1rem",fontWeight:600,marginBottom:"0.5rem"},tooltipContent:{fontSize:"0.875rem",padding:"0.5rem 0"},buttonNext:{backgroundColor:"hsl(var(--primary))",color:"hsl(var(--primary-foreground))",borderRadius:"calc(var(--radius) - 2px)",fontSize:"0.875rem",padding:"0.5rem 1rem"},buttonBack:{color:"hsl(var(--muted-foreground))",fontSize:"0.875rem",marginRight:"0.5rem"},buttonSkip:{color:"hsl(var(--muted-foreground))",fontSize:"0.875rem"},buttonClose:{color:"hsl(var(--muted-foreground))"},spotlight:{borderRadius:"var(--radius)"}},k_={back:"上一步",close:"关闭",last:"完成",next:"下一步",nextLabelWithProgress:"下一步 ({step}/{steps})",open:"打开对话框",skip:"跳过"};function C_(){const{state:l,getCurrentSteps:n,handleJoyrideCallback:i}=Pm(),c=n(),[u,x]=m.useState(!1),h=m.useRef(l.stepIndex),f=m.useRef(null);m.useEffect(()=>{h.current!==l.stepIndex&&(x(!1),h.current=l.stepIndex)},[l.stepIndex]),m.useEffect(()=>{if(!l.isRunning||c.length===0){x(!1);return}const v=c[l.stepIndex];if(!v){x(!1);return}const b=v.target;if(b==="body"){x(!0);return}x(!1);const w=setTimeout(()=>{const y=()=>{const I=document.querySelector(b);if(I){const M=I.getBoundingClientRect();if(M.width>0&&M.height>0)return!0}return!1};if(y()){setTimeout(()=>x(!0),100);return}const R=setInterval(()=>{y()&&(clearInterval(R),setTimeout(()=>x(!0),100))},100),D=setTimeout(()=>{clearInterval(R),x(!0)},5e3),k=()=>{clearInterval(R),clearTimeout(D)};f.current=k},150);return()=>{clearTimeout(w),f.current&&(f.current(),f.current=null)}},[l.isRunning,l.stepIndex,c]);const[p,g]=m.useState(null);if(m.useEffect(()=>{let v=document.getElementById("tour-portal-container");return v||(v=document.createElement("div"),v.id="tour-portal-container",v.style.cssText="position: fixed; top: 0; left: 0; z-index: 99999; pointer-events: none;",document.body.appendChild(v)),g(v),()=>{}},[]),!l.isRunning||c.length===0||!u)return null;const N=e.jsx(x1,{steps:c,stepIndex:l.stepIndex,run:l.isRunning,continuous:!0,showSkipButton:!0,showProgress:!0,disableOverlayClose:!0,disableScrolling:!1,disableScrollParentFix:!1,callback:i,styles:S_,locale:k_,scrollOffset:80,scrollToFirstStep:!0,floaterProps:{styles:{floater:{zIndex:99999}},disableAnimation:!0}},`tour-step-${l.stepIndex}`);return p?e0.createPortal(N,p):N}const el="model-assignment-tour",av=[{target:"body",content:"本引导旨在帮助你配置模型提供商和对应的模型,并为麦麦的各个组件分配合适的模型。",placement:"center",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="sidebar-model-provider"]',content:'第一步,你需要配置模型提供商。模型提供商决定了你要使用谁家的模型,无论是单一厂商(如 DeepSeek),还是模型平台(如 Siliconflow),都可以在这里进行配置。点击"下一步"进入配置页面。',placement:"right",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="add-provider-button"]',content:'点击"添加提供商"按钮,开始配置你的模型提供商。',placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!0,hideFooter:!0},{target:'[data-tour="provider-dialog"]',content:"在这里,你可以选择你想要配置的模型提供商,填写相关信息后保存即可。",placement:"left",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="provider-name-input"]',content:"这里的名称是你为这个模型提供商起的一个名字,方便你在后续使用时识别它。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="provider-apikey-input"]',content:"这里需要填写你从模型提供商那里获取的 API 密钥,用于验证和调用模型服务。对于不同的提供商,获取 API 密钥的方式可能有所不同,请参考对应提供商的文档。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="provider-url-input"]',content:"这里需要填写模型提供商的 API 访问地址,确保填写正确以便系统能够连接到模型服务。对于不同的提供商,API 地址可能有所不同,请参考对应提供商的文档。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="provider-template-select"]',content:"当然,如果你不知道如何填写这些信息,很多模型提供商在这里都提供了预设的模板供你选择,选择对应的模板后,相关信息会自动填充。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="provider-save-button"]',content:"填写完所有信息后,点击保存按钮,模型提供商就配置完成了。",placement:"top",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="provider-cancel-button"]',content:"因为这次咱们什么都没有填写,所以点击取消按钮退出吧。",placement:"top",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!0,hideFooter:!0},{target:'[data-tour="sidebar-model-management"]',content:'配置好模型提供商后,接下来我们需要为麦麦添加模型并分配功能。点击"下一步"进入模型管理页面。',placement:"right",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="add-model-button"]',content:'在为麦麦的组件分配模型之前,首先需要添加你想要分配的模型,点击"添加模型"按钮开始添加。',placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!0,hideFooter:!0},{target:'[data-tour="model-dialog"]',content:"在这里,你可以选择你之前配置好的模型提供商,然后选择对应的模型来添加。",placement:"left",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="model-name-input"]',content:"这里的模型名称是你为这个模型起的一个名字,方便你在后续使用时识别它。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="model-provider-select"]',content:"在这里选择你之前配置好的模型提供商,这样系统才能知道你要添加哪个提供商的模型。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="model-identifier-input"]',content:"这里需要填写你想要添加的模型的标识符,不同的模型提供商可能有不同的标识符格式,请参考对应提供商的文档。",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="model-save-button"]',content:"填写完所有信息后,点击保存按钮,模型就添加完成了。",placement:"top",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1},{target:'[data-tour="model-cancel-button"]',content:"当然,因为这次咱们什么都没有填写,所以直接点击取消按钮退出吧,等你准备好了再来添加模型。",placement:"top",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!0,hideFooter:!0},{target:'[data-tour="tasks-tab-trigger"]',content:'最后一步,添加好模型后,切换到"为模型分配功能"标签页,为麦麦的各个组件分配合适的模型。',placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!0,hideFooter:!0},{target:'[data-tour="task-model-select"]',content:"在这里,你可以为每个组件选择一个或多个合适的模型,选择完成后配置会自动保存。恭喜你完成了模型配置的学习!",placement:"bottom",disableBeacon:!0,disableOverlayClose:!0,hideCloseButton:!1,spotlightClicks:!1}],lv={0:"/config/model",1:"/config/model",2:"/config/modelProvider",3:"/config/modelProvider",4:"/config/modelProvider",5:"/config/modelProvider",6:"/config/modelProvider",7:"/config/modelProvider",8:"/config/modelProvider",9:"/config/modelProvider",10:"/config/modelProvider",11:"/config/model",12:"/config/model",13:"/config/model",14:"/config/model",15:"/config/model",16:"/config/model",17:"/config/model",18:"/config/model",19:"/config/model"},Li=[{id:"siliconflow",name:"SiliconFlow",base_url:"https://api.siliconflow.cn/v1",client_type:"openai",display_name:"硅基流动 (SiliconFlow)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"deepseek",name:"DeepSeek",base_url:"https://api.deepseek.com",client_type:"openai",display_name:"DeepSeek",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"rinkoai",name:"RinkoAI",base_url:"https://rinkoai.com/v1",client_type:"openai",display_name:"RinkoAI",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"zhipu",name:"ZhipuAI",base_url:"https://open.bigmodel.cn/api/paas/v4",client_type:"openai",display_name:"智谱 AI (ZhipuAI / GLM)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"moonshot",name:"Moonshot",base_url:"https://api.moonshot.cn/v1",client_type:"openai",display_name:"月之暗面 (Moonshot / Kimi)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"doubao",name:"Doubao",base_url:"https://ark.cn-beijing.volces.com/api/v3",client_type:"openai",display_name:"字节豆包 (Doubao)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"alibaba",name:"Alibaba",base_url:"https://dashscope.aliyuncs.com/compatible-mode/v1",client_type:"openai",display_name:"阿里云百炼 (Alibaba Qwen)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"baichuan",name:"Baichuan",base_url:"https://api.baichuan-ai.com/v1",client_type:"openai",display_name:"百川智能 (Baichuan)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"minimax",name:"MiniMax",base_url:"https://api.minimax.chat/v1",client_type:"openai",display_name:"MiniMax (海螺 AI)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"stepfun",name:"StepFun",base_url:"https://api.stepfun.com/v1",client_type:"openai",display_name:"阶跃星辰 (StepFun)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"lingyi",name:"Lingyi",base_url:"https://api.lingyiwanwu.com/v1",client_type:"openai",display_name:"零一万物 (Lingyi / Yi)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"openai",name:"OpenAI",base_url:"https://api.openai.com/v1",client_type:"openai",display_name:"OpenAI",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"xai",name:"xAI",base_url:"https://api.x.ai/v1",client_type:"openai",display_name:"xAI (Grok)",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"anthropic",name:"Anthropic",base_url:"https://api.anthropic.com/v1",client_type:"openai",display_name:"Anthropic (Claude)"},{id:"gemini",name:"Gemini",base_url:"https://generativelanguage.googleapis.com/v1beta",client_type:"gemini",display_name:"Google Gemini",modelFetcher:{endpoint:"/models",parser:"gemini"}},{id:"cohere",name:"Cohere",base_url:"https://api.cohere.ai/v1",client_type:"openai",display_name:"Cohere"},{id:"groq",name:"Groq",base_url:"https://api.groq.com/openai/v1",client_type:"openai",display_name:"Groq",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"together",name:"Together AI",base_url:"https://api.together.xyz/v1",client_type:"openai",display_name:"Together AI",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"fireworks",name:"Fireworks",base_url:"https://api.fireworks.ai/inference/v1",client_type:"openai",display_name:"Fireworks AI",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"mistral",name:"Mistral",base_url:"https://api.mistral.ai/v1",client_type:"openai",display_name:"Mistral AI",modelFetcher:{endpoint:"/models",parser:"openai"}},{id:"perplexity",name:"Perplexity",base_url:"https://api.perplexity.ai",client_type:"openai",display_name:"Perplexity AI"},{id:"custom",name:"",base_url:"",client_type:"openai",display_name:"自定义"}];function cg(l){return l?l.replace(/\/+$/,"").toLowerCase():""}function T_(l){if(!l)return null;const n=cg(l);return Li.find(i=>i.id!=="custom"&&cg(i.base_url)===n)||null}const vo=l=>({...l,max_retry:l.max_retry??2,timeout:l.timeout??30,retry_interval:l.retry_interval??10}),E_=l=>{const n={};return l?(l.name?.trim()||(n.name="请输入提供商名称"),l.base_url?.trim()||(n.base_url="请输入基础 URL"),l.api_key?.trim()||(n.api_key="请输入 API Key"),{isValid:Object.keys(n).length===0,errors:n}):{isValid:!1,errors:{name:"提供商数据为空"}}};function M_(){return e.jsx(Pn,{children:e.jsx(A_,{})})}function A_(){const[l,n]=m.useState([]),[i,c]=m.useState(!0),[u,x]=m.useState(!1),[h,f]=m.useState(!1),[p,g]=m.useState(!1),[N,v]=m.useState(!1),[b,w]=m.useState(null),[y,R]=m.useState(null),[D,k]=m.useState("custom"),[I,M]=m.useState(!1),[S,T]=m.useState(!1),[$,A]=m.useState(null),[Q,G]=m.useState(!1),[de,oe]=m.useState(""),[ve,le]=m.useState(new Set),[fe,ge]=m.useState(!1),[z,V]=m.useState(1),[U,L]=m.useState(20),[P,_e]=m.useState(""),[je,Se]=m.useState({isOpen:!1,providersToDelete:[],affectedModels:[],pendingProviders:[],context:"auto",oldProviders:[]}),[Y,be]=m.useState({}),[Z,xe]=m.useState(new Set),[Me,J]=m.useState(new Map),{toast:ce}=Ws(),Fe=aa(),{state:q,goToStep:ee,registerTour:ke}=Pm(),{triggerRestart:Te,isRestarting:Oe}=dn(),me=m.useRef(null),ze=m.useRef(!0);m.useEffect(()=>{ke(el,av)},[ke]),m.useEffect(()=>{if(q.activeTourId===el&&q.isRunning){const X=lv[q.stepIndex];X&&!window.location.pathname.endsWith(X.replace("/config/",""))&&Fe({to:X})}},[q.stepIndex,q.activeTourId,q.isRunning,Fe]);const rs=m.useRef(q.stepIndex);m.useEffect(()=>{if(q.activeTourId===el&&q.isRunning){const X=rs.current,ye=q.stepIndex;X>=3&&X<=9&&ye<3&&v(!1),X>=10&&ye>=3&&ye<=9&&(be({}),k("custom"),w({name:"",base_url:"",api_key:"",client_type:"openai",max_retry:2,timeout:30,retry_interval:10}),R(null),G(!1),v(!0)),rs.current=ye}},[q.stepIndex,q.activeTourId,q.isRunning]),m.useEffect(()=>{if(q.activeTourId!==el||!q.isRunning)return;const X=ye=>{const Ce=ye.target,Ls=q.stepIndex;Ls===2&&Ce.closest('[data-tour="add-provider-button"]')?setTimeout(()=>ee(3),300):Ls===9&&Ce.closest('[data-tour="provider-cancel-button"]')&&setTimeout(()=>ee(10),300)};return document.addEventListener("click",X,!0),()=>document.removeEventListener("click",X,!0)},[q,ee]),m.useEffect(()=>{Kt()},[]);const Kt=async()=>{try{c(!0);const X=await ln();n(X.api_providers||[]),g(!1),ze.current=!1}catch(X){console.error("加载配置失败:",X)}finally{c(!1)}},Qt=async()=>{await Te()},ka=async()=>{try{x(!0),me.current&&clearTimeout(me.current);const X=l.map(tt=>({...tt,max_retry:tt.max_retry??2,timeout:tt.timeout??30,retry_interval:tt.retry_interval??10})),{shouldProceed:ye}=await yt(X,"restart");if(!ye){x(!1);return}const Ce=await ln(),Ls=new Set(X.map(tt=>tt.name)),Jt=(Ce.models||[]).filter(tt=>Ls.has(tt.api_provider));Ce.api_providers=X,Ce.models=Jt,await Ii(Ce),g(!1),ce({title:"保存成功",description:"正在重启麦麦..."}),await Qt()}catch(X){console.error("保存配置失败:",X),ce({title:"保存失败",description:X.message,variant:"destructive"}),x(!1)}},yt=m.useCallback(async(X,ye="auto")=>{try{const Ce=await ln(),Ls=new Set(l.map(re=>re.name)),ha=new Set(X.map(re=>re.name)),Jt=Array.from(Ls).filter(re=>!ha.has(re));if(Jt.length===0)return{shouldProceed:!0,providers:X};const W=(Ce.models||[]).filter(re=>Jt.includes(re.api_provider));return W.length===0?{shouldProceed:!0,providers:X}:(Se({isOpen:!0,providersToDelete:Jt,affectedModels:W,pendingProviders:X,context:ye,oldProviders:[...l]}),{shouldProceed:!1,providers:X})}catch(Ce){return console.error("检查删除影响失败:",Ce),{shouldProceed:!0,providers:X}}},[l]),st=async()=>{try{(je.context==="auto"?f:x)(!0),Se(re=>({...re,isOpen:!1}));const ye=await ln(),Ce=je.pendingProviders.map(vo),Ls=new Set(Ce.map(re=>re.name)),Jt=(ye.models||[]).filter(re=>Ls.has(re.api_provider)),tt=new Set(je.affectedModels.map(re=>re.name)),W=ye.model_task_config;W&&Object.keys(W).forEach(re=>{const ss=W[re];ss&&Array.isArray(ss.model_list)&&(ss.model_list=ss.model_list.filter(Qs=>!tt.has(Qs)))}),ye.api_providers=Ce,ye.models=Jt,ye.model_task_config=W,await Ii(ye),n(je.pendingProviders),g(!1),ce({title:"删除成功",description:`已删除 ${je.providersToDelete.length} 个提供商和 ${je.affectedModels.length} 个关联模型`}),Se({isOpen:!1,providersToDelete:[],affectedModels:[],pendingProviders:[],context:"auto",oldProviders:[]}),le(new Set),je.context==="restart"&&await Qt()}catch(X){console.error("删除失败:",X),ce({title:"删除失败",description:X.message,variant:"destructive"})}finally{je.context==="auto"?f(!1):x(!1)}},F=()=>{je.oldProviders.length>0&&n(je.oldProviders),Se({isOpen:!1,providersToDelete:[],affectedModels:[],pendingProviders:[],context:"auto",oldProviders:[]}),g(!1)},qe=m.useCallback(async X=>{if(ze.current)return;const{shouldProceed:ye}=await yt(X,"auto");if(!ye){g(!0);return}try{f(!0);const Ce=X.map(vo);await Am("api_providers",Ce),g(!1)}catch(Ce){console.error("自动保存失败:",Ce),ce({title:"自动保存失败",description:Ce.message,variant:"destructive"}),g(!0)}finally{f(!1)}},[l,yt]);m.useEffect(()=>{if(!ze.current)return g(!0),me.current&&clearTimeout(me.current),me.current=setTimeout(()=>{qe(l)},2e3),()=>{me.current&&clearTimeout(me.current)}},[l,qe]);const Ie=async()=>{try{x(!0),me.current&&clearTimeout(me.current);const X=l.map(vo),{shouldProceed:ye}=await yt(X,"manual");if(!ye){x(!1);return}const Ce=await ln(),Ls=new Set(X.map(tt=>tt.name)),ha=Ce.models||[],Jt=ha.filter(tt=>{const W=Ls.has(tt.api_provider);return W||console.warn(`模型 "${tt.name}" 引用了已删除的提供商 "${tt.api_provider}",将被移除`),W});if(ha.length!==Jt.length){const tt=ha.length-Jt.length;ce({title:"注意",description:`已自动移除 ${tt} 个引用已删除提供商的模型`,variant:"default"})}console.log("发送的 providers 数据:",X),Ce.api_providers=X,Ce.models=Jt,console.log("完整配置数据:",Ce),await Ii(Ce),g(!1),ce({title:"保存成功",description:"模型提供商配置已保存"})}catch(X){console.error("保存配置失败:",X),ce({title:"保存失败",description:X.message,variant:"destructive"})}finally{x(!1)}},Ve=(X,ye)=>{if(be({}),X){const Ce=Li.find(Ls=>Ls.base_url===X.base_url&&Ls.client_type===X.client_type);k(Ce?.id||"custom"),w(X)}else k("custom"),w({name:"",base_url:"",api_key:"",client_type:"openai",max_retry:2,timeout:30,retry_interval:10});R(ye),G(!1),v(!0)},Cs=m.useCallback(X=>{k(X),M(!1);const ye=Li.find(Ce=>Ce.id===X);ye&&ye.id!=="custom"?w(Ce=>({...Ce,name:ye.name,base_url:ye.base_url,client_type:ye.client_type})):ye?.id==="custom"&&w(Ce=>({...Ce,name:"",base_url:"",client_type:"openai"}))},[]),ns=m.useMemo(()=>D!=="custom",[D]),Rs=m.useCallback(async()=>{if(b?.api_key)try{await navigator.clipboard.writeText(b.api_key),ce({title:"复制成功",description:"API Key 已复制到剪贴板"})}catch{ce({title:"复制失败",description:"无法访问剪贴板",variant:"destructive"})}},[b?.api_key,ce]),Ee=()=>{if(!b)return;const{isValid:X,errors:ye}=E_(b);if(!X){be(ye);return}be({});const Ce=vo(b);if(y!==null){const Ls=[...l];Ls[y]=Ce,n(Ls)}else n([...l,Ce]);v(!1),w(null),R(null)},gs=X=>{if(!X&&b){const ye={...b,max_retry:b.max_retry??2,timeout:b.timeout??30,retry_interval:b.retry_interval??10};w(ye)}v(X)},ts=X=>{A(X),T(!0)},Ze=async()=>{if($!==null){const X=l.filter((Ce,Ls)=>Ls!==$),{shouldProceed:ye}=await yt(X,"manual");ye&&(n(X),ce({title:"删除成功",description:"提供商已从列表中移除"}))}T(!1),A(null)},js=X=>{const ye=new Set(ve);ye.has(X)?ye.delete(X):ye.add(X),le(ye)},dt=()=>{if(ve.size===_s.length)le(new Set);else{const X=_s.map((ye,Ce)=>l.findIndex(Ls=>Ls===_s[Ce]));le(new Set(X))}},Ot=()=>{if(ve.size===0){ce({title:"提示",description:"请先选择要删除的提供商",variant:"default"});return}ge(!0)},ut=async()=>{const X=l.filter((Ce,Ls)=>!ve.has(Ls)),{shouldProceed:ye}=await yt(X,"manual");ye&&(n(X),le(new Set),ce({title:"批量删除成功",description:`已删除 ${ve.size} 个提供商`})),ge(!1)},_s=m.useMemo(()=>{if(!de)return l;const X=de.toLowerCase();return l.filter(ye=>ye.name.toLowerCase().includes(X)||ye.base_url.toLowerCase().includes(X)||ye.client_type.toLowerCase().includes(X))},[l,de]),{totalPages:Tt,paginatedProviders:Bt}=m.useMemo(()=>{const X=Math.ceil(_s.length/U),ye=_s.slice((z-1)*U,z*U);return{totalPages:X,paginatedProviders:ye}},[_s,z,U]),Ca=m.useCallback(()=>{const X=parseInt(P);X>=1&&X<=Tt&&(V(X),_e(""))},[P,Tt]),Ya=async X=>{xe(ye=>new Set(ye).add(X));try{const ye=await o_(X);J(Ce=>new Map(Ce).set(X,ye)),ye.network_ok?ye.api_key_valid===!0?ce({title:"连接正常",description:`${X} 网络连接正常,API Key 有效 (${ye.latency_ms}ms)`}):ye.api_key_valid===!1?ce({title:"连接正常但 Key 无效",description:`${X} 网络连接正常,但 API Key 无效或已过期`,variant:"destructive"}):ce({title:"网络连接正常",description:`${X} 可以访问 (${ye.latency_ms}ms)`}):ce({title:"连接失败",description:ye.error||"无法连接到提供商",variant:"destructive"})}catch(ye){ce({title:"测试失败",description:ye.message,variant:"destructive"})}finally{xe(ye=>{const Ce=new Set(ye);return Ce.delete(X),Ce})}},nl=async()=>{for(const X of l)await Ya(X.name)},Yt=X=>{const ye=Z.has(X),Ce=Me.get(X);return ye?e.jsxs(Ae,{variant:"secondary",className:"gap-1",children:[e.jsx(zs,{className:"h-3 w-3 animate-spin"}),"测试中"]}):Ce?Ce.network_ok?Ce.api_key_valid===!0?e.jsxs(Ae,{className:"gap-1 bg-green-600 hover:bg-green-700",children:[e.jsx(ea,{className:"h-3 w-3"}),"正常"]}):Ce.api_key_valid===!1?e.jsxs(Ae,{variant:"destructive",className:"gap-1",children:[e.jsx(Ct,{className:"h-3 w-3"}),"Key无效"]}):e.jsxs(Ae,{className:"gap-1 bg-blue-600 hover:bg-blue-700",children:[e.jsx(ea,{className:"h-3 w-3"}),"可访问"]}):e.jsxs(Ae,{variant:"destructive",className:"gap-1",children:[e.jsx(xj,{className:"h-3 w-3"}),"离线"]}):null};return i?e.jsx("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx("p",{className:"text-muted-foreground",children:"加载中..."})})}):e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"AI模型厂商配置"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理 AI 模型厂商的 API 配置"})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[ve.size>0&&e.jsxs(C,{onClick:Ot,size:"sm",variant:"destructive",className:"w-full sm:w-auto",children:[e.jsx(ls,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"批量删除 (",ve.size,")"]}),e.jsxs(C,{onClick:nl,size:"sm",variant:"outline",className:"w-full sm:w-auto",disabled:l.length===0||Z.size>0,children:[e.jsx(zn,{className:"mr-2 h-4 w-4"}),Z.size>0?`测试中 (${Z.size})`:"测试全部"]}),e.jsxs(C,{onClick:()=>Ve(null,null),size:"sm",className:"w-full sm:w-auto","data-tour":"add-provider-button",children:[e.jsx(it,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"添加提供商"]}),e.jsxs(C,{onClick:Ie,disabled:u||h||!p||Oe,size:"sm",variant:"outline",className:"w-full sm:w-auto sm:min-w-[120px]",children:[e.jsx(Xi,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),u?"保存中...":h?"自动保存中...":p?"保存配置":"已保存"]}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{disabled:u||h||Oe,size:"sm",className:"w-full sm:w-auto sm:min-w-[120px]",children:[e.jsx(Ji,{className:"mr-2 h-4 w-4"}),Oe?"重启中...":p?"保存并重启":"重启麦麦"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认重启麦麦?"}),e.jsx(xs,{asChild:!0,children:e.jsx("div",{children:e.jsx("p",{children:p?"当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。":"即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。"})})})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:p?ka:Qt,children:p?"保存并重启":"确认重启"})]})]})]})]})]}),e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsxs(rt,{children:["配置更新后需要",e.jsx("strong",{children:"重启麦麦"}),'才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。']})]}),e.jsxs(es,{className:"h-[calc(100vh-260px)]",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center gap-2 mb-4",children:[e.jsxs("div",{className:"relative w-full sm:flex-1 sm:max-w-sm",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索提供商名称、URL 或类型...",value:de,onChange:X=>oe(X.target.value),className:"pl-9"})]}),de&&e.jsxs("p",{className:"text-sm text-muted-foreground whitespace-nowrap",children:["找到 ",_s.length," 个结果"]})]}),e.jsx("div",{className:"md:hidden space-y-3",children:_s.length===0?e.jsx("div",{className:"text-center text-muted-foreground py-8 rounded-lg border bg-card",children:de?"未找到匹配的提供商":'暂无提供商配置,点击"添加提供商"开始配置'}):Bt.map((X,ye)=>{const Ce=l.findIndex(Ls=>Ls===X);return e.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("h3",{className:"font-semibold text-base truncate",children:X.name}),Yt(X.name)]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1 break-all",children:X.base_url})]}),e.jsxs("div",{className:"flex gap-1 flex-shrink-0",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>Ya(X.name),disabled:Z.has(X.name),title:"测试连接",children:Z.has(X.name)?e.jsx(zs,{className:"h-4 w-4 animate-spin"}):e.jsx(zn,{className:"h-4 w-4"})}),e.jsx(C,{variant:"default",size:"sm",onClick:()=>Ve(X,Ce),children:e.jsx(On,{className:"h-4 w-4",strokeWidth:2,fill:"none"})}),e.jsx(C,{size:"sm",onClick:()=>ts(Ce),className:"bg-red-600 hover:bg-red-700 text-white",children:e.jsx(ls,{className:"h-4 w-4",strokeWidth:2,fill:"none"})})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"客户端类型"}),e.jsx("p",{className:"font-medium",children:X.client_type})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"最大重试"}),e.jsx("p",{className:"font-medium",children:X.max_retry})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"超时(秒)"}),e.jsx("p",{className:"font-medium",children:X.timeout})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"重试间隔(秒)"}),e.jsx("p",{className:"font-medium",children:X.retry_interval})]})]})]},ye)})}),e.jsx("div",{className:"hidden md:block rounded-lg border bg-card overflow-hidden",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{className:"w-12",children:e.jsx(Xs,{checked:ve.size===_s.length&&_s.length>0,onCheckedChange:dt})}),e.jsx(Je,{children:"状态"}),e.jsx(Je,{children:"名称"}),e.jsx(Je,{children:"基础URL"}),e.jsx(Je,{children:"客户端类型"}),e.jsx(Je,{className:"text-right",children:"最大重试"}),e.jsx(Je,{className:"text-right",children:"超时(秒)"}),e.jsx(Je,{className:"text-right",children:"重试间隔(秒)"}),e.jsx(Je,{className:"text-right",children:"操作"})]})}),e.jsx(Al,{children:Bt.length===0?e.jsx(ct,{children:e.jsx(He,{colSpan:9,className:"text-center text-muted-foreground py-8",children:de?"未找到匹配的提供商":'暂无提供商配置,点击"添加提供商"开始配置'})}):Bt.map((X,ye)=>{const Ce=l.findIndex(Ls=>Ls===X);return e.jsxs(ct,{children:[e.jsx(He,{children:e.jsx(Xs,{checked:ve.has(Ce),onCheckedChange:()=>js(Ce)})}),e.jsx(He,{children:Yt(X.name)||e.jsx(Ae,{variant:"outline",className:"text-muted-foreground",children:"未测试"})}),e.jsx(He,{className:"font-medium",children:X.name}),e.jsx(He,{className:"max-w-xs truncate",title:X.base_url,children:X.base_url}),e.jsx(He,{children:X.client_type}),e.jsx(He,{className:"text-right",children:X.max_retry}),e.jsx(He,{className:"text-right",children:X.timeout}),e.jsx(He,{className:"text-right",children:X.retry_interval}),e.jsx(He,{className:"text-right",children:e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>Ya(X.name),disabled:Z.has(X.name),title:"测试连接",children:Z.has(X.name)?e.jsx(zs,{className:"h-4 w-4 animate-spin"}):e.jsx(zn,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"default",size:"sm",onClick:()=>Ve(X,Ce),children:[e.jsx(On,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),e.jsxs(C,{size:"sm",onClick:()=>ts(Ce),className:"bg-red-600 hover:bg-red-700 text-white",children:[e.jsx(ls,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})})]},ye)})})]})})}),_s.length>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{htmlFor:"page-size-provider",className:"text-sm whitespace-nowrap",children:"每页显示"}),e.jsxs(Be,{value:U.toString(),onValueChange:X=>{L(parseInt(X)),V(1),le(new Set)},children:[e.jsx(Le,{id:"page-size-provider",className:"w-20",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"10",children:"10"}),e.jsx(ae,{value:"20",children:"20"}),e.jsx(ae,{value:"50",children:"50"}),e.jsx(ae,{value:"100",children:"100"})]})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["显示 ",(z-1)*U+1," 到"," ",Math.min(z*U,_s.length)," 条,共 ",_s.length," 条"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>V(1),disabled:z===1,className:"hidden sm:flex",children:e.jsx(Ur,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>V(X=>Math.max(1,X-1)),disabled:z===1,children:[e.jsx(ll,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"number",value:P,onChange:X=>_e(X.target.value),onKeyDown:X=>X.key==="Enter"&&Ca(),placeholder:z.toString(),className:"w-16 h-8 text-center",min:1,max:Tt}),e.jsx(C,{variant:"outline",size:"sm",onClick:Ca,disabled:!P,className:"h-8",children:"跳转"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>V(X=>X+1),disabled:z>=Tt,children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>V(Tt),disabled:z>=Tt,className:"hidden sm:flex",children:e.jsx(Br,{className:"h-4 w-4"})})]})]})]}),e.jsx(Ks,{open:N,onOpenChange:gs,children:e.jsxs(Ps,{className:"max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto","data-tour":"provider-dialog",preventOutsideClose:q.isRunning,children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:y!==null?"编辑提供商":"添加提供商"}),e.jsx(ot,{children:"配置 API 提供商的连接信息和参数"})]}),e.jsxs("form",{onSubmit:X=>{X.preventDefault(),Ee()},autoComplete:"off",children:[e.jsxs("div",{className:"grid gap-4 py-4",children:[e.jsxs("div",{className:"grid gap-2","data-tour":"provider-template-select",children:[e.jsx(E,{htmlFor:"template",children:"提供商模板"}),e.jsxs(tl,{open:I,onOpenChange:M,children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",role:"combobox","aria-expanded":I,className:"w-full justify-between",children:[D?Li.find(X=>X.id===D)?.display_name:"选择提供商模板...",e.jsx(Um,{className:"ml-2 h-4 w-4 shrink-0 opacity-50"})]})}),e.jsx(Ka,{className:"p-0",align:"start",style:{width:"var(--radix-popover-trigger-width)"},children:e.jsxs(Go,{children:[e.jsx(Fo,{placeholder:"搜索提供商模板..."}),e.jsx(es,{className:"h-[300px]",children:e.jsxs(qo,{className:"max-h-none overflow-visible",children:[e.jsx(Vo,{children:"未找到匹配的模板"}),e.jsx(qi,{children:Li.map(X=>e.jsxs(Vi,{value:X.display_name,onSelect:()=>Cs(X.id),children:[e.jsx(St,{className:`mr-2 h-4 w-4 ${D===X.id?"opacity-100":"opacity-0"}`}),X.display_name]},X.id))})]})})]})})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"选择预设模板可自动填充 URL 和客户端类型,支持搜索"})]}),e.jsxs("div",{className:"grid gap-2","data-tour":"provider-name-input",children:[e.jsx(E,{htmlFor:"name",className:Y.name?"text-destructive":"",children:"名称 *"}),e.jsx(ie,{id:"name",value:b?.name||"",onChange:X=>{w(ye=>ye?{...ye,name:X.target.value}:null),Y.name&&be(ye=>({...ye,name:void 0}))},placeholder:"例如: DeepSeek, SiliconFlow",className:Y.name?"border-destructive focus-visible:ring-destructive":""}),Y.name&&e.jsx("p",{className:"text-xs text-destructive",children:Y.name})]}),e.jsxs("div",{className:"grid gap-2","data-tour":"provider-url-input",children:[e.jsx(E,{htmlFor:"base_url",className:Y.base_url?"text-destructive":"",children:"基础 URL *"}),e.jsx(ie,{id:"base_url",value:b?.base_url||"",onChange:X=>{w(ye=>ye?{...ye,base_url:X.target.value}:null),Y.base_url&&be(ye=>({...ye,base_url:void 0}))},placeholder:"https://api.example.com/v1",disabled:ns,className:`${ns?"bg-muted cursor-not-allowed":""} ${Y.base_url?"border-destructive focus-visible:ring-destructive":""}`}),Y.base_url&&e.jsx("p",{className:"text-xs text-destructive",children:Y.base_url}),ns&&!Y.base_url&&e.jsx("p",{className:"text-xs text-muted-foreground",children:'使用模板时 URL 不可编辑,切换到"自定义"以手动配置'})]}),e.jsxs("div",{className:"grid gap-2","data-tour":"provider-apikey-input",children:[e.jsx(E,{htmlFor:"api_key",className:Y.api_key?"text-destructive":"",children:"API Key *"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{id:"api_key",type:Q?"text":"password",value:b?.api_key||"",onChange:X=>{w(ye=>ye?{...ye,api_key:X.target.value}:null),Y.api_key&&be(ye=>({...ye,api_key:void 0}))},placeholder:"sk-...",className:`flex-1 ${Y.api_key?"border-destructive focus-visible:ring-destructive":""}`}),e.jsx(C,{type:"button",variant:"outline",size:"icon",onClick:()=>G(!Q),title:Q?"隐藏密钥":"显示密钥",children:Q?e.jsx(Hi,{className:"h-4 w-4"}):e.jsx(sa,{className:"h-4 w-4"})}),e.jsx(C,{type:"button",variant:"outline",size:"icon",onClick:Rs,title:"复制密钥",children:e.jsx(ko,{className:"h-4 w-4"})})]}),Y.api_key&&e.jsx("p",{className:"text-xs text-destructive",children:Y.api_key})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"client_type",children:"客户端类型"}),e.jsxs(Be,{value:b?.client_type||"openai",onValueChange:X=>w(ye=>ye?{...ye,client_type:X}:null),disabled:ns,children:[e.jsx(Le,{id:"client_type",className:ns?"bg-muted cursor-not-allowed":"",children:e.jsx($e,{placeholder:"选择客户端类型"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"openai",children:"OpenAI"}),e.jsx(ae,{value:"gemini",children:"Gemini"})]})]}),ns&&e.jsx("p",{className:"text-xs text-muted-foreground",children:'使用模板时客户端类型不可编辑,切换到"自定义"以手动配置'})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"max_retry",children:"最大重试"}),e.jsx(ie,{id:"max_retry",type:"number",min:"0",value:b?.max_retry??"",onChange:X=>{const ye=X.target.value===""?null:parseInt(X.target.value);w(Ce=>Ce?{...Ce,max_retry:ye}:null)},placeholder:"默认: 2"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"timeout",children:"超时(秒)"}),e.jsx(ie,{id:"timeout",type:"number",min:"1",value:b?.timeout??"",onChange:X=>{const ye=X.target.value===""?null:parseInt(X.target.value);w(Ce=>Ce?{...Ce,timeout:ye}:null)},placeholder:"默认: 30"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"retry_interval",children:"重试间隔(秒)"}),e.jsx(ie,{id:"retry_interval",type:"number",min:"1",value:b?.retry_interval??"",onChange:X=>{const ye=X.target.value===""?null:parseInt(X.target.value);w(Ce=>Ce?{...Ce,retry_interval:ye}:null)},placeholder:"默认: 10"})]})]})]}),e.jsxs(xt,{children:[e.jsx(C,{type:"button",variant:"outline",onClick:()=>v(!1),"data-tour":"provider-cancel-button",children:"取消"}),e.jsx(C,{type:"submit","data-tour":"provider-save-button",children:"保存"})]})]})]})}),e.jsx(ps,{open:S,onOpenChange:T,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除提供商 "',$!==null?l[$]?.name:"",'" 吗? 此操作无法撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:Ze,children:"删除"})]})]})}),e.jsx(ps,{open:fe,onOpenChange:ge,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认批量删除"}),e.jsxs(xs,{children:["确定要删除选中的 ",ve.size," 个提供商吗? 此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:ut,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"批量删除"})]})]})}),e.jsx(ps,{open:je.isOpen,onOpenChange:X=>Se(ye=>({...ye,isOpen:X})),children:e.jsxs(os,{className:"max-w-2xl",children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除提供商"}),e.jsx(xs,{asChild:!0,children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("p",{children:["您即将删除以下提供商:",e.jsx("strong",{className:"text-foreground ml-1",children:je.providersToDelete.join(", ")})]}),e.jsxs("p",{className:"text-yellow-600 dark:text-yellow-500 font-medium",children:["⚠️ 此操作将同时删除 ",je.affectedModels.length," 个关联的模型:"]}),e.jsx(es,{className:"h-32 w-full rounded border p-3",children:e.jsx("div",{className:"space-y-1",children:je.affectedModels.map((X,ye)=>e.jsxs("div",{className:"text-sm",children:[e.jsx("span",{className:"font-mono text-muted-foreground",children:"•"}),e.jsx("span",{className:"ml-2 font-medium",children:X.name}),e.jsxs("span",{className:"ml-2 text-xs text-muted-foreground",children:["(",X.model_identifier,")"]})]},ye))})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"这些模型将从模型列表和所有任务分配中移除。此操作无法撤销。"})]})})]}),e.jsxs(us,{children:[e.jsx(fs,{onClick:F,children:"取消"}),e.jsx(hs,{onClick:st,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认删除"})]})]})}),e.jsx(Hn,{})]})}function nv(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).substring(2,11)}`}function rv(l){return typeof l=="boolean"?"boolean":typeof l=="number"?"number":"string"}function z_(l,n){switch(n){case"boolean":return l==="true";case"number":{const i=parseFloat(l);return isNaN(i)?0:i}default:return l}}function og(l){return Object.entries(l).map(([n,i])=>({id:nv(),key:n,value:i,type:rv(i)}))}function jm(l){const n={};for(const i of l)i.key.trim()&&(n[i.key.trim()]=i.value);return n}function vm(l){if(!l.trim())return{valid:!0,parsed:{}};try{const n=JSON.parse(l);if(typeof n!="object"||n===null||Array.isArray(n))return{valid:!1,error:"必须是一个 JSON 对象 {}"};for(const[i,c]of Object.entries(n))if(c!==null&&!["string","number","boolean"].includes(typeof c))return{valid:!1,error:`键 "${i}" 的值类型不支持(仅支持 string/number/boolean)`};return{valid:!0,parsed:n}}catch{return{valid:!1,error:"JSON 格式错误"}}}function D_(l){switch(l){case"boolean":return"布尔";case"number":return"数字";default:return"字符串"}}function O_(l){switch(l){case"boolean":return"bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400";case"number":return"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400";default:return"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"}}function R_({value:l,onChange:n,className:i,placeholder:c="添加额外参数..."}){const[u,x]=m.useState("list"),h=m.useMemo(()=>og(l||{}),[l]),f=m.useMemo(()=>Object.keys(l||{}).length>0?JSON.stringify(l,null,2):"",[l]),[p,g]=m.useState(h),[N,v]=m.useState(f),[b,w]=m.useState(null);m.useEffect(()=>{g(h),v(f)},[h,f]);const y=m.useMemo(()=>{const S=vm(N);return S.valid&&S.parsed?{success:!0,data:S.parsed}:{success:!1,data:{}}},[N]),R=m.useCallback(S=>{const T=S;if(T==="json"&&u==="list"){const $=jm(p);v(Object.keys($).length>0?JSON.stringify($,null,2):""),w(null)}else if(T==="list"&&u==="json"){const $=vm(N);$.valid&&$.parsed&&(g(og($.parsed)),w(null))}x(T)},[u,p,N]),D=m.useCallback(()=>{const S={id:nv(),key:"",value:"",type:"string"},T=[...p,S];g(T)},[p]),k=m.useCallback(S=>{const T=p.filter($=>$.id!==S);g(T),n(jm(T))},[p,n]),I=m.useCallback((S,T,$)=>{const A=p.map(Q=>{if(Q.id!==S)return Q;if(T==="type"){const G=$;let de;return G==="boolean"?de=Q.value==="true"||Q.value===!0:G==="number"?de=typeof Q.value=="number"?Q.value:parseFloat(String(Q.value))||0:de=String(Q.value),{...Q,type:G,value:de}}else return T==="value"?{...Q,value:z_($,Q.type)}:{...Q,[T]:$}});g(A),n(jm(A))},[p,n]),M=m.useCallback(S=>{v(S);const T=vm(S);T.valid&&T.parsed?(w(null),n(T.parsed)):w(T.error||"JSON 格式错误")},[n]);return e.jsxs("div",{className:B("space-y-3",i),children:[e.jsx(E,{className:"text-sm font-medium",children:"额外参数"}),e.jsxs(ma,{value:u,onValueChange:R,className:"w-full",children:[e.jsxs(ta,{className:"h-8 p-0.5 bg-muted/60",children:[e.jsx(as,{value:"list",className:"h-7 px-3 text-xs data-[state=active]:bg-background data-[state=active]:shadow-sm",children:"键值对"}),e.jsx(as,{value:"json",className:"h-7 px-3 text-xs data-[state=active]:bg-background data-[state=active]:shadow-sm",children:"JSON"})]}),e.jsxs(ys,{value:"list",className:"mt-3 space-y-2",children:[p.length===0?e.jsx("div",{className:"text-sm text-muted-foreground text-center py-4 border border-dashed rounded-md",children:c}):e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"grid grid-cols-[1fr_1fr_90px_32px] gap-2 text-xs text-muted-foreground px-1",children:[e.jsx("span",{children:"键名"}),e.jsx("span",{children:"值"}),e.jsx("span",{children:"类型"}),e.jsx("span",{})]}),p.map(S=>e.jsxs("div",{className:"grid grid-cols-[1fr_1fr_90px_32px] gap-2 items-center",children:[e.jsx(ie,{value:S.key,onChange:T=>I(S.id,"key",T.target.value),placeholder:"key",className:"h-8 text-sm"}),S.type==="boolean"?e.jsxs("div",{className:"flex items-center h-8 px-3 border rounded-md bg-background",children:[e.jsx(Ge,{checked:S.value===!0,onCheckedChange:T=>I(S.id,"value",String(T))}),e.jsx("span",{className:"ml-2 text-sm text-muted-foreground",children:S.value?"true":"false"})]}):e.jsx(ie,{type:S.type==="number"?"number":"text",value:S.value,onChange:T=>I(S.id,"value",T.target.value),placeholder:"value",className:"h-8 text-sm",step:S.type==="number"?"any":void 0}),e.jsxs(Be,{value:S.type,onValueChange:T=>I(S.id,"type",T),children:[e.jsx(Le,{className:"h-8 text-xs",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"string",children:"字符串"}),e.jsx(ae,{value:"number",children:"数字"}),e.jsx(ae,{value:"boolean",children:"布尔"})]})]}),e.jsx(C,{type:"button",variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-destructive",onClick:()=>k(S.id),children:e.jsx(ls,{className:"h-4 w-4"})})]},S.id))]}),e.jsxs(C,{type:"button",variant:"outline",size:"sm",className:"w-full h-8",onClick:D,children:[e.jsx(it,{className:"h-4 w-4 mr-1"}),"添加参数"]})]}),e.jsx(ys,{value:"json",className:"mt-3",children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"编辑"}),b?e.jsxs("div",{className:"flex items-center gap-1 text-xs text-destructive",children:[e.jsx(Ct,{className:"h-3 w-3"}),e.jsx("span",{className:"truncate max-w-[150px]",children:b})]}):N.trim()&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-green-600 dark:text-green-400",children:[e.jsx(St,{className:"h-3 w-3"}),e.jsx("span",{children:"有效"})]})]}),e.jsx(et,{value:N,onChange:S=>M(S.target.value),placeholder:`{ + "key": "value" +}`,className:B("font-mono text-sm min-h-[140px] h-[140px] resize-y flex-1",b&&"border-destructive focus-visible:ring-destructive")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"支持 string、number、boolean 类型"})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"预览"}),e.jsx("div",{className:"min-h-[140px] h-[140px] flex-1 rounded-md border bg-muted/30 p-3 overflow-auto",children:y.success&&Object.keys(y.data).length>0?e.jsx("div",{className:"space-y-2",children:Object.entries(y.data).map(([S,T])=>{const $=rv(T);return e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("code",{className:"px-1.5 py-0.5 bg-background rounded text-xs font-medium",children:S}),e.jsx("span",{className:"text-muted-foreground",children:"="}),e.jsx("span",{className:B("font-mono",$==="boolean"&&(T?"text-green-600 dark:text-green-400":"text-red-600 dark:text-red-400"),$==="number"&&"text-blue-600 dark:text-blue-400",$==="string"&&"text-amber-600 dark:text-amber-400"),children:$==="string"?`"${T}"`:String(T)}),e.jsx(Ae,{variant:"secondary",className:B("h-5 text-[10px] px-1.5",O_($)),children:D_($)})]},S)})}):y.success?e.jsx("div",{className:"flex items-center justify-center h-full text-sm text-muted-foreground",children:"暂无参数"}):e.jsx("div",{className:"flex items-center justify-center h-full text-sm text-destructive",children:"JSON 格式错误"})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"实时预览解析结果"})]})]})})]})]})}const Ir="https://maibot-plugin-stats.maibot-webui.workers.dev";async function L_(l){const n=new URLSearchParams;l?.status&&n.set("status",l.status),l?.page&&n.set("page",l.page.toString()),l?.page_size&&n.set("page_size",l.page_size.toString()),l?.search&&n.set("search",l.search),l?.sort_by&&n.set("sort_by",l.sort_by),l?.sort_order&&n.set("sort_order",l.sort_order);const i=await fetch(`${Ir}/pack?${n.toString()}`);if(!i.ok)throw new Error(`获取 Pack 列表失败: ${i.status}`);return i.json()}async function U_(l){const n=await fetch(`${Ir}/pack/${l}`);if(!n.ok)throw new Error(`获取 Pack 失败: ${n.status}`);const i=await n.json();if(!i.success)throw new Error(i.error||"获取 Pack 失败");return i.pack}async function B_(l){const i=await(await fetch(`${Ir}/pack`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)})).json();if(!i.success)throw new Error(i.error||"创建 Pack 失败");return i}async function $_(l,n){await fetch(`${Ir}/pack/download`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pack_id:l,user_id:n})})}async function iv(l,n){const c=await(await fetch(`${Ir}/pack/like`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pack_id:l,user_id:n})})).json();if(!c.success)throw new Error(c.error||"点赞失败");return{likes:c.likes,liked:c.liked}}async function cv(l,n){return(await(await fetch(`${Ir}/pack/like/check?pack_id=${l}&user_id=${n}`)).json()).liked||!1}async function I_(l){const n=await we("/api/webui/config/model");if(!n.ok)throw new Error("获取当前模型配置失败");const i=await n.json(),c=i.config||i;console.log("=== Pack Conflict Detection ==="),console.log("Pack providers:",l.providers),console.log("Local providers:",c.api_providers);const u={existing_providers:[],new_providers:[],conflicting_models:[]},x=c.api_providers||[];for(const f of l.providers){console.log(` +Checking pack provider: ${f.name}`),console.log(` Pack URL: ${f.base_url}`),console.log(` Normalized: ${Nm(f.base_url)}`);const p=x.filter(g=>{const N=Nm(g.base_url),v=Nm(f.base_url);return console.log(` Comparing with local "${g.name}": ${g.base_url}`),console.log(` Local normalized: ${N}`),console.log(` Match: ${N===v}`),N===v});p.length>0?(console.log(` ✓ Matched with ${p.length} local provider(s):`,p.map(g=>g.name).join(", ")),u.existing_providers.push({pack_provider:f,local_providers:p.map(g=>({name:g.name,base_url:g.base_url}))})):(console.log(" ✗ No match found - will need API key"),u.new_providers.push(f))}const h=c.models||[];console.log(` +=== Model Conflict Detection ===`);for(const f of l.models){const p=h.find(g=>g.name===f.name);p&&(console.log(`Model conflict: ${f.name}`),u.conflicting_models.push({pack_model:f.name,local_model:p.name}))}return console.log(` +=== Detection Summary ===`),console.log(`Existing providers: ${u.existing_providers.length}`),console.log(`New providers: ${u.new_providers.length}`),console.log(`Conflicting models: ${u.conflicting_models.length}`),console.log(`=========================== +`),u}async function P_(l,n,i,c){const u=await we("/api/webui/config/model");if(!u.ok)throw new Error("获取当前模型配置失败");const x=await u.json(),h=x.config||x;if(n.apply_providers){const p=n.selected_providers?l.providers.filter(g=>n.selected_providers.includes(g.name)):l.providers;for(const g of p){if(i[g.name])continue;const N=c[g.name];if(!N)throw new Error(`提供商 "${g.name}" 缺少 API Key`);const v={...g,api_key:N},b=h.api_providers.findIndex(w=>w.name===g.name);b>=0?h.api_providers[b]=v:h.api_providers.push(v)}}if(n.apply_models){const p=n.selected_models?l.models.filter(g=>n.selected_models.includes(g.name)):l.models;for(const g of p){const N=i[g.api_provider]||g.api_provider,v={...g,api_provider:N},b=h.models.findIndex(w=>w.name===g.name);b>=0?h.models[b]=v:h.models.push(v)}}if(n.apply_task_config){const p=n.selected_tasks||Object.keys(l.task_config);for(const g of p){const N=l.task_config[g];if(!N)continue;const v=new Set(n.selected_models||l.models.map(y=>y.name)),b=N.model_list.filter(y=>v.has(y));if(b.length===0)continue;const w={...N,model_list:b};if(n.task_mode==="replace")h.model_task_config[g]=w;else{const y=h.model_task_config[g];if(y){const R=[...new Set([...y.model_list,...b])];h.model_task_config[g]={...y,model_list:R}}else h.model_task_config[g]=w}}}if(!(await we("/api/webui/config/model",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)})).ok)throw new Error("保存配置失败")}async function H_(l){const n=await we("/api/webui/config/model");if(!n.ok)throw new Error("获取当前模型配置失败");const i=await n.json();if(!i.success||!i.config)throw new Error("获取配置失败");const c=i.config;let u=(c.api_providers||[]).map(g=>({name:g.name,base_url:g.base_url,client_type:g.client_type,max_retry:g.max_retry,timeout:g.timeout,retry_interval:g.retry_interval}));l.selectedProviders&&(u=u.filter(g=>l.selectedProviders.includes(g.name)));let x=c.models||[];l.selectedModels&&(x=x.filter(g=>l.selectedModels.includes(g.name)));const h={},f=c.model_task_config||{},p=l.selectedTasks||Object.keys(f);for(const g of p)f[g]&&(h[g]=f[g]);return{providers:u,models:x,task_config:h}}function Nm(l){try{const n=new URL(l);return`${n.protocol}//${n.host}${n.pathname}`.replace(/\/$/,"").toLowerCase()}catch{return l.toLowerCase().replace(/\/$/,"")}}function ov(){const l="maibot_pack_user_id";let n=localStorage.getItem(l);return n||(n="pack_user_"+Math.random().toString(36).substring(2,15),localStorage.setItem(l,n)),n}const G_={utils:"通用工具",utils_small:"轻量工具",tool_use:"工具调用",replyer:"回复生成",planner:"规划推理",vlm:"视觉模型",voice:"语音处理",embedding:"向量嵌入",lpmm_entity_extract:"实体提取",lpmm_rdf_build:"RDF构建",lpmm_qa:"问答模型"},F_=["官方推荐","性价比","高性能","免费模型","国内可用","海外模型","OpenAI","Claude","Gemini","国产模型","多模态","轻量级"];function q_({trigger:l}){const[n,i]=m.useState(!1),[c,u]=m.useState(1),[x,h]=m.useState(!1),[f,p]=m.useState(!1),[g,N]=m.useState([]),[v,b]=m.useState([]),[w,y]=m.useState({}),[R,D]=m.useState(new Set),[k,I]=m.useState(new Set),[M,S]=m.useState(new Set),[T,$]=m.useState(""),[A,Q]=m.useState(""),[G,de]=m.useState(""),[oe,ve]=m.useState([]);m.useEffect(()=>{n&&c===1&&le()},[n,c]);const le=async()=>{h(!0);try{const Y=await H_({name:"",description:"",author:""});N(Y.providers),b(Y.models),y(Y.task_config),D(new Set(Y.providers.map(be=>be.name))),I(new Set(Y.models.map(be=>be.name))),S(new Set(Object.keys(Y.task_config)))}catch(Y){console.error("加载配置失败:",Y),Gt({title:"加载当前配置失败",variant:"destructive"})}finally{h(!1)}},fe=Y=>{const be=new Set(R),Z=new Set(k),xe=new Set(M);be.has(Y)?(be.delete(Y),v.filter(J=>J.api_provider===Y).forEach(J=>Z.delete(J.name)),Object.entries(w).forEach(([J,ce])=>{ce.model_list&&(ce.model_list.some(q=>Z.has(q))||xe.delete(J))})):(be.add(Y),v.filter(J=>J.api_provider===Y).forEach(J=>Z.add(J.name)),Object.entries(w).forEach(([J,ce])=>{ce.model_list&&ce.model_list.some(q=>{const ee=v.find(ke=>ke.name===q);return ee&&ee.api_provider===Y})&&xe.add(J)})),D(be),I(Z),S(xe)},ge=Y=>{const be=new Set(k),Z=new Set(M);be.has(Y)?(be.delete(Y),Object.entries(w).forEach(([xe,Me])=>{Me.model_list&&(Me.model_list.some(ce=>be.has(ce))||Z.delete(xe))})):(be.add(Y),Object.entries(w).forEach(([xe,Me])=>{Me.model_list&&Me.model_list.includes(Y)&&Z.add(xe)})),I(be),S(Z)},z=Y=>{const be=new Set(M);be.has(Y)?be.delete(Y):be.add(Y),S(be)},V=Y=>{oe.includes(Y)?ve(oe.filter(be=>be!==Y)):oe.length<5?ve([...oe,Y]):Gt({title:"最多选择 5 个标签",variant:"destructive"})},U=()=>{R.size===g.length?D(new Set):D(new Set(g.map(Y=>Y.name)))},L=()=>{k.size===v.length?I(new Set):I(new Set(v.map(Y=>Y.name)))},P=()=>{const Y=Object.keys(w);M.size===Y.length?S(new Set):S(new Set(Y))},_e=async()=>{if(!T.trim()){Gt({title:"请输入模板名称",variant:"destructive"});return}if(!A.trim()){Gt({title:"请输入模板描述",variant:"destructive"});return}if(!G.trim()){Gt({title:"请输入作者名称",variant:"destructive"});return}if(R.size===0&&k.size===0&&M.size===0){Gt({title:"请至少选择一项配置",variant:"destructive"});return}p(!0);try{const Y=g.filter(xe=>R.has(xe.name)),be=v.filter(xe=>k.has(xe.name)),Z={};for(const[xe,Me]of Object.entries(w))M.has(xe)&&(Z[xe]=Me);await B_({name:T.trim(),description:A.trim(),author:G.trim(),tags:oe,providers:Y,models:be,task_config:Z}),Gt({title:"模板已提交审核,审核通过后将显示在市场中"}),i(!1),je()}catch(Y){console.error("提交失败:",Y),Gt({title:Y instanceof Error?Y.message:"提交失败",variant:"destructive"})}finally{p(!1)}},je=()=>{u(1),$(""),Q(""),de(""),ve([]),D(new Set),I(new Set),S(new Set)},Se=2;return e.jsxs(Ks,{open:n,onOpenChange:i,children:[e.jsx(Ho,{asChild:!0,children:l||e.jsxs(C,{variant:"outline",children:[e.jsx(Nj,{className:"w-4 h-4 mr-2"}),"分享配置"]})}),e.jsxs(Ps,{className:"max-w-2xl max-h-[85vh] flex flex-col",children:[e.jsxs(Hs,{children:[e.jsxs(Gs,{className:"flex items-center gap-2",children:[e.jsx(Wt,{className:"w-5 h-5"}),"分享配置模板"]}),e.jsxs(ot,{children:["步骤 ",c," / ",Se,":",c===1&&"选择要分享的配置",c===2&&"填写模板信息"]})]}),e.jsx(es,{className:"h-[calc(85vh-220px)] pr-4",children:x?e.jsxs("div",{className:"py-8 text-center",children:[e.jsx(zs,{className:"w-8 h-8 mx-auto animate-spin text-primary"}),e.jsx("p",{className:"mt-4 text-muted-foreground",children:"正在加载当前配置..."})]}):e.jsxs(e.Fragment,{children:[c===1&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsx(An,{children:"安全提示"}),e.jsxs(rt,{children:["分享的配置将",e.jsx("strong",{children:"不包含"})," API Key,其他用户需要自行配置。"]})]}),e.jsxs(ma,{defaultValue:"providers",className:"w-full",children:[e.jsxs(ta,{className:"grid w-full grid-cols-3",children:[e.jsxs(as,{value:"providers",children:[e.jsx(Tl,{className:"w-4 h-4 mr-2"}),"API 提供商",e.jsxs(Ae,{variant:"secondary",className:"ml-2",children:[R.size,"/",g.length]})]}),e.jsxs(as,{value:"models",children:[e.jsx(Rn,{className:"w-4 h-4 mr-2"}),"模型配置",e.jsxs(Ae,{variant:"secondary",className:"ml-2",children:[k.size,"/",v.length]})]}),e.jsxs(as,{value:"tasks",children:[e.jsx(Ln,{className:"w-4 h-4 mr-2"}),"任务配置",e.jsxs(Ae,{variant:"secondary",className:"ml-2",children:[M.size,"/",Object.keys(w).length]})]})]}),e.jsx(ys,{value:"providers",className:"space-y-2 mt-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex justify-end",children:e.jsx(C,{variant:"ghost",size:"sm",onClick:U,children:R.size===g.length?"取消全选":"全选"})}),g.length===0?e.jsx("p",{className:"text-sm text-muted-foreground text-center py-2",children:"暂无提供商配置"}):g.map(Y=>e.jsxs("div",{className:"flex items-center space-x-2 p-2 rounded hover:bg-muted",children:[e.jsx(Xs,{id:`provider-${Y.name}`,checked:R.has(Y.name),onCheckedChange:()=>fe(Y.name)}),e.jsxs(E,{htmlFor:`provider-${Y.name}`,className:"flex-1 cursor-pointer",children:[e.jsx("span",{className:"font-medium",children:Y.name}),e.jsx("span",{className:"text-xs text-muted-foreground ml-2",children:Y.base_url})]}),e.jsx(Ae,{variant:"outline",className:"text-xs",children:Y.client_type})]},Y.name))]})}),e.jsx(ys,{value:"models",className:"space-y-2 mt-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex justify-end",children:e.jsx(C,{variant:"ghost",size:"sm",onClick:L,children:k.size===v.length?"取消全选":"全选"})}),v.length===0?e.jsx("p",{className:"text-sm text-muted-foreground text-center py-2",children:"暂无模型配置"}):v.map(Y=>e.jsxs("div",{className:"flex items-center space-x-2 p-2 rounded hover:bg-muted",children:[e.jsx(Xs,{id:`model-${Y.name}`,checked:k.has(Y.name),onCheckedChange:()=>ge(Y.name)}),e.jsxs(E,{htmlFor:`model-${Y.name}`,className:"flex-1 cursor-pointer",children:[e.jsx("span",{className:"font-medium",children:Y.name}),e.jsx("span",{className:"text-xs text-muted-foreground ml-2",children:Y.model_identifier})]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:Y.api_provider})]},Y.name))]})}),e.jsx(ys,{value:"tasks",className:"space-y-2 mt-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex justify-end",children:e.jsx(C,{variant:"ghost",size:"sm",onClick:P,children:M.size===Object.keys(w).length?"取消全选":"全选"})}),Object.keys(w).length===0?e.jsx("p",{className:"text-sm text-muted-foreground text-center py-2",children:"暂无任务配置"}):Object.entries(w).map(([Y,be])=>e.jsxs("div",{className:"space-y-2 p-2 rounded hover:bg-muted",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:`task-${Y}`,checked:M.has(Y),onCheckedChange:()=>z(Y)}),e.jsx(E,{htmlFor:`task-${Y}`,className:"flex-1 cursor-pointer",children:e.jsx("span",{className:"font-medium",children:G_[Y]||Y})}),e.jsxs(Ae,{variant:"outline",className:"text-xs",children:[be.model_list.length," 个模型"]})]}),be.model_list&&be.model_list.length>0&&e.jsx("div",{className:"ml-6 flex flex-wrap gap-1",children:be.model_list.map(Z=>{const xe=v.find(J=>J.name===Z),Me=k.has(Z);return e.jsxs(Ae,{variant:Me?"default":"outline",className:"text-xs cursor-pointer hover:opacity-80 transition-opacity",onClick:()=>ge(Z),children:[Z,xe&&e.jsxs("span",{className:"ml-1 opacity-70",children:["(",xe.api_provider,")"]})]},Z)})})]},Y))]})})]})]}),c===2&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex gap-4 text-sm p-3 bg-muted rounded-lg",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Tl,{className:"w-4 h-4"}),R.size," 个提供商"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Rn,{className:"w-4 h-4"}),k.size," 个模型"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Ln,{className:"w-4 h-4"}),M.size," 个任务"]})]}),e.jsx($r,{}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"pack-name",children:"模板名称 *"}),e.jsx(ie,{id:"pack-name",placeholder:"例如:高性价比国产模型配置",value:T,onChange:Y=>$(Y.target.value),maxLength:50}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[T.length,"/50"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"pack-description",children:"模板描述 *"}),e.jsx(et,{id:"pack-description",placeholder:"详细描述这个配置模板的特点、适用场景等...",value:A,onChange:Y=>Q(Y.target.value),rows:4,maxLength:500}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[A.length,"/500"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"pack-author",children:"作者名称 *"}),e.jsx(ie,{id:"pack-author",placeholder:"你的昵称或 ID",value:G,onChange:Y=>de(Y.target.value),maxLength:30})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"标签(可选,最多 5 个)"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:F_.map(Y=>e.jsxs(Ae,{variant:oe.includes(Y)?"default":"outline",className:"cursor-pointer transition-colors",onClick:()=>V(Y),children:[oe.includes(Y)&&e.jsx(St,{className:"w-3 h-3 mr-1"}),e.jsx($o,{className:"w-3 h-3 mr-1"}),Y]},Y))})]})]}),e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsx(An,{children:"审核说明"}),e.jsx(rt,{children:"提交后需要经过审核才能在市场中展示。审核通常在 1-3 个工作日内完成。"})]})]})]})}),e.jsxs(xt,{className:"flex justify-between pt-4 border-t",children:[e.jsx("div",{children:c>1&&e.jsx(C,{variant:"outline",onClick:()=>u(c-1),disabled:f,children:"上一步"})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(C,{variant:"outline",onClick:()=>{i(!1),je()},disabled:f,children:"取消"}),cu(c+1),disabled:x||R.size===0&&k.size===0&&M.size===0,children:"下一步"}):e.jsxs(C,{onClick:_e,disabled:f,children:[f&&e.jsx(zs,{className:"w-4 h-4 mr-2 animate-spin"}),"提交审核"]})]})]})]})]})}function V_({value:l,label:n,onRemove:i}){const{attributes:c,listeners:u,setNodeRef:x,transform:h,transition:f,isDragging:p}=Uj({id:l}),g={transform:Bj.Transform.toString(h),transition:f,opacity:p?.5:1},N=b=>{b.preventDefault(),b.stopPropagation(),i(l)},v=b=>{b.stopPropagation()};return e.jsx("div",{ref:x,style:g,className:B("inline-flex items-center gap-1",p&&"shadow-lg"),children:e.jsxs(Ae,{variant:"secondary",className:"cursor-move hover:bg-secondary/80 flex items-center gap-1",children:[e.jsx("div",{...c,...u,className:"cursor-grab active:cursor-grabbing flex items-center",children:e.jsx(gj,{className:"h-3 w-3 text-muted-foreground"})}),e.jsx("span",{children:n}),e.jsx("button",{type:"button",className:"ml-1 rounded-sm hover:bg-destructive/20 focus:outline-none focus:ring-1 focus:ring-destructive",onClick:N,onPointerDown:v,onMouseDown:b=>b.stopPropagation(),children:e.jsx(_a,{className:"h-3 w-3 cursor-pointer hover:text-destructive",strokeWidth:2,fill:"none"})})]})})}function K_({options:l,selected:n,onChange:i,placeholder:c="选择选项...",emptyText:u="未找到选项",className:x}){const[h,f]=m.useState(!1),p=Ej(Eo(zj,{activationConstraint:{distance:8}}),Eo(Aj,{coordinateGetter:Mj})),g=b=>{n.includes(b)?i(n.filter(w=>w!==b)):i([...n,b])},N=b=>{i(n.filter(w=>w!==b))},v=b=>{const{active:w,over:y}=b;if(y&&w.id!==y.id){const R=n.indexOf(w.id),D=n.indexOf(y.id);i(Dj(n,R,D))}};return e.jsxs(tl,{open:h,onOpenChange:f,children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",role:"combobox","aria-expanded":h,className:B("w-full justify-between min-h-10 h-auto",x),children:[e.jsx(Oj,{sensors:p,collisionDetection:Rj,onDragEnd:v,children:e.jsx(Lj,{items:n,strategy:m1,children:e.jsx("div",{className:"flex gap-1 flex-wrap flex-1",children:n.length===0?e.jsx("span",{className:"text-muted-foreground",children:c}):n.map(b=>{const w=l.find(y=>y.value===b);return e.jsx(V_,{value:b,label:w?.label||b,onRemove:N},b)})})})}),e.jsx(Um,{className:"ml-2 h-4 w-4 shrink-0 opacity-50",strokeWidth:2,fill:"none"})]})}),e.jsx(Ka,{className:"w-full p-0",align:"start",children:e.jsxs(Go,{children:[e.jsx(Fo,{placeholder:"搜索...",className:"h-9"}),e.jsxs(qo,{children:[e.jsx(Vo,{children:u}),e.jsx(qi,{children:l.map(b=>{const w=n.includes(b.value);return e.jsxs(Vi,{value:b.value,onSelect:()=>g(b.value),children:[e.jsx("div",{className:B("mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",w?"bg-primary text-primary-foreground":"opacity-50 [&_svg]:invisible"),children:e.jsx(St,{className:"h-3 w-3",strokeWidth:2,fill:"none"})}),e.jsx("span",{children:b.label})]},b.value)})})]})]})})]})}const Fa=Es.memo(function({title:n,description:i,taskConfig:c,modelNames:u,onChange:x,hideTemperature:h=!1,hideMaxTokens:f=!1,dataTour:p}){const g=N=>{x("model_list",N)};return e.jsxs("div",{className:"rounded-lg border bg-card p-4 sm:p-6 space-y-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"font-semibold text-base sm:text-lg",children:n}),e.jsx("p",{className:"text-xs sm:text-sm text-muted-foreground mt-1",children:i})]}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-2","data-tour":p,children:[e.jsx(E,{children:"模型列表"}),e.jsx(K_,{options:u.map(N=>({label:N,value:N})),selected:c.model_list||[],onChange:g,placeholder:"选择模型...",emptyText:"暂无可用模型"})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[!h&&e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:"温度"}),e.jsx(ie,{type:"number",step:"0.1",min:"0",max:"1",value:c.temperature??.3,onChange:N=>{const v=parseFloat(N.target.value);!isNaN(v)&&v>=0&&v<=1&&x("temperature",v)},className:"w-20 h-8 text-sm"})]}),e.jsx(wa,{value:[c.temperature??.3],onValueChange:N=>x("temperature",N[0]),min:0,max:1,step:.1,className:"w-full"})]}),!f&&e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{children:"最大 Token"}),e.jsx(ie,{type:"number",step:"1",min:"1",value:c.max_tokens??1024,onChange:N=>x("max_tokens",parseInt(N.target.value))})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:"慢请求阈值 (秒)"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"超时警告"})]}),e.jsx(ie,{type:"number",step:"1",min:"1",value:c.slow_threshold??15,onChange:N=>{const v=parseInt(N.target.value);!isNaN(v)&&v>=1&&x("slow_threshold",v)},placeholder:"15"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"模型响应时间超过此阈值将输出警告日志"})]})]})]})}),Q_=Es.memo(function({paginatedModels:n,allModels:i,onEdit:c,onDelete:u,isModelUsed:x,searchQuery:h}){return n.length===0?e.jsx("div",{className:"md:hidden text-center text-muted-foreground py-8 rounded-lg border bg-card",children:h?"未找到匹配的模型":"暂无模型配置"}):e.jsx("div",{className:"md:hidden space-y-3",children:n.map((f,p)=>{const g=i.findIndex(v=>v===f),N=x(f.name);return e.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h3",{className:"font-semibold text-base",children:f.name}),e.jsx(Ae,{variant:N?"default":"secondary",className:N?"bg-green-600 hover:bg-green-700":"",children:N?"已使用":"未使用"})]}),e.jsx("p",{className:"text-xs text-muted-foreground break-all",title:f.model_identifier,children:f.model_identifier})]}),e.jsxs("div",{className:"flex gap-1 flex-shrink-0",children:[e.jsxs(C,{variant:"default",size:"sm",onClick:()=>c(f,g),children:[e.jsx(On,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),e.jsxs(C,{size:"sm",onClick:()=>u(g),className:"bg-red-600 hover:bg-red-700 text-white",children:[e.jsx(ls,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"提供商"}),e.jsx("p",{className:"font-medium",children:f.api_provider})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"模型温度"}),e.jsx("p",{className:"font-medium",children:f.temperature!=null?f.temperature:e.jsx("span",{className:"text-muted-foreground",children:"默认"})})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"输入价格"}),e.jsxs("p",{className:"font-medium",children:["¥",f.price_in,"/M"]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:"输出价格"}),e.jsxs("p",{className:"font-medium",children:["¥",f.price_out,"/M"]})]})]})]},p)})})}),Y_=Es.memo(function({paginatedModels:n,allModels:i,filteredModels:c,selectedModels:u,onEdit:x,onDelete:h,onToggleSelection:f,onToggleSelectAll:p,isModelUsed:g,searchQuery:N}){return e.jsx("div",{className:"hidden md:block rounded-lg border bg-card overflow-hidden",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{className:"w-12",children:e.jsx(Xs,{checked:u.size===c.length&&c.length>0,onCheckedChange:p})}),e.jsx(Je,{className:"w-24",children:"使用状态"}),e.jsx(Je,{children:"模型名称"}),e.jsx(Je,{children:"模型标识符"}),e.jsx(Je,{children:"提供商"}),e.jsx(Je,{className:"text-center",children:"温度"}),e.jsx(Je,{className:"text-right",children:"输入价格"}),e.jsx(Je,{className:"text-right",children:"输出价格"}),e.jsx(Je,{className:"text-right",children:"操作"})]})}),e.jsx(Al,{children:n.length===0?e.jsx(ct,{children:e.jsx(He,{colSpan:9,className:"text-center text-muted-foreground py-8",children:N?"未找到匹配的模型":"暂无模型配置"})}):n.map((v,b)=>{const w=i.findIndex(R=>R===v),y=g(v.name);return e.jsxs(ct,{children:[e.jsx(He,{children:e.jsx(Xs,{checked:u.has(w),onCheckedChange:()=>f(w)})}),e.jsx(He,{children:e.jsx(Ae,{variant:y?"default":"secondary",className:y?"bg-green-600 hover:bg-green-700":"",children:y?"已使用":"未使用"})}),e.jsx(He,{className:"font-medium",children:v.name}),e.jsx(He,{className:"max-w-xs truncate",title:v.model_identifier,children:v.model_identifier}),e.jsx(He,{children:v.api_provider}),e.jsx(He,{className:"text-center",children:v.temperature!=null?v.temperature:e.jsx("span",{className:"text-muted-foreground",children:"-"})}),e.jsxs(He,{className:"text-right",children:["¥",v.price_in,"/M"]}),e.jsxs(He,{className:"text-right",children:["¥",v.price_out,"/M"]}),e.jsx(He,{className:"text-right",children:e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsxs(C,{variant:"default",size:"sm",onClick:()=>x(v,w),children:[e.jsx(On,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"编辑"]}),e.jsxs(C,{size:"sm",onClick:()=>h(w),className:"bg-red-600 hover:bg-red-700 text-white",children:[e.jsx(ls,{className:"h-4 w-4 mr-1",strokeWidth:2,fill:"none"}),"删除"]})]})})]},b)})})]})})})}),J_=300*1e3,dg=new Map,X_=[10,20,50,100],Z_=Es.memo(function({page:n,pageSize:i,totalItems:c,jumpToPage:u,onPageChange:x,onPageSizeChange:h,onJumpToPageChange:f,onJumpToPage:p,onSelectionClear:g}){const N=Math.ceil(c/i),v=w=>{h(parseInt(w)),x(1),g?.()},b=w=>{w.key==="Enter"&&p()};return c===0?null:e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{htmlFor:"page-size-model",className:"text-sm whitespace-nowrap",children:"每页显示"}),e.jsxs(Be,{value:i.toString(),onValueChange:v,children:[e.jsx(Le,{id:"page-size-model",className:"w-20",children:e.jsx($e,{})}),e.jsx(Ue,{children:X_.map(w=>e.jsx(ae,{value:w.toString(),children:w},w))})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["显示 ",(n-1)*i+1," 到"," ",Math.min(n*i,c)," 条,共 ",c," 条"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>x(1),disabled:n===1,className:"hidden sm:flex",children:e.jsx(Ur,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>x(Math.max(1,n-1)),disabled:n===1,children:[e.jsx(ll,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"number",value:u,onChange:w=>f(w.target.value),onKeyDown:b,placeholder:n.toString(),className:"w-16 h-8 text-center",min:1,max:N}),e.jsx(C,{variant:"outline",size:"sm",onClick:p,disabled:!u,className:"h-8",children:"跳转"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>x(n+1),disabled:n>=N,children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>x(N),disabled:n>=N,className:"hidden sm:flex",children:e.jsx(Br,{className:"h-4 w-4"})})]})]})});function W_(l){const{models:n,taskConfig:i,debounceMs:c=2e3,onSavingChange:u,onUnsavedChange:x}=l,h=m.useRef(null),f=m.useRef(null),p=m.useRef(!0),g=m.useCallback(()=>{h.current&&(clearTimeout(h.current),h.current=null),f.current&&(clearTimeout(f.current),f.current=null)},[]),N=m.useCallback(w=>{const y={model_identifier:w.model_identifier,name:w.name,api_provider:w.api_provider,price_in:w.price_in??0,price_out:w.price_out??0,force_stream_mode:w.force_stream_mode??!1,extra_params:w.extra_params??{}};return w.temperature!=null&&(y.temperature=w.temperature),w.max_tokens!=null&&(y.max_tokens=w.max_tokens),y},[]),v=m.useCallback(async w=>{try{u?.(!0);const y=w.map(N);await Am("models",y),x?.(!1)}catch(y){console.error("自动保存模型列表失败:",y),x?.(!0)}finally{u?.(!1)}},[u,x,N]),b=m.useCallback(async w=>{try{u?.(!0),await Am("model_task_config",w),x?.(!1)}catch(y){console.error("自动保存任务配置失败:",y),x?.(!0)}finally{u?.(!1)}},[u,x]);return m.useEffect(()=>{if(!p.current)return x?.(!0),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{v(n)},c),()=>{h.current&&clearTimeout(h.current)}},[n,v,c,x]),m.useEffect(()=>{if(!(p.current||!i))return x?.(!0),f.current&&clearTimeout(f.current),f.current=setTimeout(()=>{b(i)},c),()=>{f.current&&clearTimeout(f.current)}},[i,b,c,x]),m.useEffect(()=>()=>{g()},[g]),{clearTimers:g,initialLoadRef:p}}function eS(l={}){const{onCloseEditDialog:n}=l,i=aa(),{registerTour:c,startTour:u,state:x,goToStep:h}=Pm(),f=m.useRef(x.stepIndex);return m.useEffect(()=>{c(el,av)},[c]),m.useEffect(()=>{if(x.activeTourId===el&&x.isRunning){const g=lv[x.stepIndex];g&&!window.location.pathname.endsWith(g.replace("/config/",""))&&i({to:g})}},[x.stepIndex,x.activeTourId,x.isRunning,i]),m.useEffect(()=>{if(x.activeTourId===el&&x.isRunning){const g=f.current,N=x.stepIndex;g>=12&&g<=17&&N<12&&n?.(),f.current=N}},[x.stepIndex,x.activeTourId,x.isRunning,n]),m.useEffect(()=>{if(x.activeTourId!==el||!x.isRunning)return;const g=N=>{const v=N.target,b=x.stepIndex;b===2&&v.closest('[data-tour="add-provider-button"]')?setTimeout(()=>h(3),300):b===9&&v.closest('[data-tour="provider-cancel-button"]')?setTimeout(()=>h(10),300):b===11&&v.closest('[data-tour="add-model-button"]')?setTimeout(()=>h(12),300):b===17&&v.closest('[data-tour="model-cancel-button"]')?setTimeout(()=>h(18),300):b===18&&v.closest('[data-tour="tasks-tab-trigger"]')&&setTimeout(()=>h(19),300)};return document.addEventListener("click",g,!0),()=>document.removeEventListener("click",g,!0)},[x,h]),{startTour:m.useCallback(()=>{u(el)},[u]),isRunning:x.isRunning&&x.activeTourId===el,stepIndex:x.stepIndex}}function sS(l){const{getProviderConfig:n}=l,[i,c]=m.useState([]),[u,x]=m.useState(!1),[h,f]=m.useState(null),[p,g]=m.useState(null),N=m.useCallback(()=>{c([]),f(null),g(null)},[]),v=m.useCallback(async(b,w=!1)=>{const y=n(b);if(!y?.base_url){c([]),g(null),f('提供商配置不完整,请先在"模型提供商配置"中配置');return}if(!y.api_key){c([]),g(null),f('该提供商未配置 API Key,请先在"模型提供商配置"中填写');return}const R=T_(y.base_url);if(g(R),!R?.modelFetcher){c([]),f(null);return}const D=`${b}:${y.base_url}`,k=dg.get(D);if(!w&&k&&Date.now()-k.timestampM(!1)}),{clearTimers:Qt,initialLoadRef:ka}=W_({models:l,taskConfig:p,onSavingChange:R,onUnsavedChange:k}),yt=m.useCallback((W,re)=>{if(!W)return;const ss=new Set(re.map(pt=>pt.name)),Qs=[],vs=[],Ds=[{key:"utils",label:"工具模型"},{key:"utils_small",label:"轻量工具模型"},{key:"tool_use",label:"工具调用模型"},{key:"replyer",label:"回复模型"},{key:"planner",label:"规划器模型"},{key:"vlm",label:"视觉模型"},{key:"voice",label:"语音模型"},{key:"embedding",label:"嵌入模型"},{key:"lpmm_entity_extract",label:"LPMM实体抽取"},{key:"lpmm_rdf_build",label:"LPMM关系构建"},{key:"lpmm_qa",label:"LPMM问答"}];for(const{key:pt,label:fa}of Ds){const Dl=W[pt];if(!Dl)continue;if(!Dl.model_list||Dl.model_list.length===0){vs.push(fa);continue}const sc=Dl.model_list.filter(Wo=>!ss.has(Wo));sc.length>0&&Qs.push({taskName:fa,invalidModels:sc})}Fe(Qs),ee(vs)},[]),st=m.useCallback(async()=>{try{v(!0);const W=await ln(),re=W.models||[];n(re),f(re.map(Ds=>Ds.name));const ss=W.api_providers||[];c(ss.map(Ds=>Ds.name)),x(ss);const Qs=W.model_task_config||null;g(Qs),yt(Qs,re);const vs=Qs?.embedding?.model_list||[];Me.current=[...vs],k(!1),ka.current=!1}catch(W){console.error("加载配置失败:",W)}finally{v(!1)}},[ka,yt]);m.useEffect(()=>{st()},[st]);const F=m.useCallback(W=>u.find(re=>re.name===W),[u]),{availableModels:qe,fetchingModels:Ie,modelFetchError:Ve,matchedTemplate:Cs,fetchModelsForProvider:ns,clearModels:Rs}=sS({getProviderConfig:F});m.useEffect(()=>{I&&S?.api_provider&&ns(S.api_provider)},[I,S?.api_provider,ns]);const Ee=async()=>{await me()},gs=m.useCallback(()=>{if(!p)return;const W=new Set(l.map(Qs=>Qs.name)),re={...p},ss=Object.keys(re);for(const Qs of ss){const vs=re[Qs];vs&&vs.model_list&&(vs.model_list=vs.model_list.filter(Ds=>W.has(Ds)))}g(re),Fe([]),Oe({title:"清理完成",description:"已删除所有无效的模型引用"})},[p,l,Oe]),ts=W=>{const re={model_identifier:W.model_identifier,name:W.name,api_provider:W.api_provider,price_in:W.price_in??0,price_out:W.price_out??0,force_stream_mode:W.force_stream_mode??!1,extra_params:W.extra_params??{}};return W.temperature!=null&&(re.temperature=W.temperature),W.max_tokens!=null&&(re.max_tokens=W.max_tokens),re},Ze=async()=>{try{w(!0),Qt();const W=await ln();W.models=l.map(ts),W.model_task_config=p,await Ii(W),k(!1),Oe({title:"保存成功",description:"正在重启麦麦..."}),await Ee()}catch(W){console.error("保存配置失败:",W),Oe({title:"保存失败",description:W.message,variant:"destructive"}),w(!1)}},js=async()=>{try{w(!0),Qt();const W=await ln();W.models=l.map(ts),W.model_task_config=p,await Ii(W),k(!1),Oe({title:"保存成功",description:"模型配置已保存"}),await st()}catch(W){console.error("保存配置失败:",W),Oe({title:"保存失败",description:W.message,variant:"destructive"})}finally{w(!1)}},dt=(W,re)=>{Te({}),T(W||{model_identifier:"",name:"",api_provider:i[0]||"",price_in:0,price_out:0,temperature:null,max_tokens:null,force_stream_mode:!1,extra_params:{}}),A(re),M(!0)},Ot=()=>{if(!S)return;const W={};if(S.name?.trim()||(W.name="请输入模型名称"),S.api_provider?.trim()||(W.api_provider="请选择 API 提供商"),S.model_identifier?.trim()||(W.model_identifier="请输入模型标识符"),Object.keys(W).length>0){Te(W);return}Te({});const re={model_identifier:S.model_identifier,name:S.name,api_provider:S.api_provider,price_in:S.price_in??0,price_out:S.price_out??0,force_stream_mode:S.force_stream_mode??!1,extra_params:S.extra_params??{}};S.temperature!=null&&(re.temperature=S.temperature),S.max_tokens!=null&&(re.max_tokens=S.max_tokens);let ss,Qs=null;if($!==null?(Qs=l[$].name,ss=[...l],ss[$]=re):ss=[...l,re],n(ss),f(ss.map(vs=>vs.name)),Qs&&Qs!==re.name&&p){const vs=Ds=>Ds.map(pt=>pt===Qs?re.name:pt);g({...p,utils:{...p.utils,model_list:vs(p.utils?.model_list||[])},utils_small:{...p.utils_small,model_list:vs(p.utils_small?.model_list||[])},tool_use:{...p.tool_use,model_list:vs(p.tool_use?.model_list||[])},replyer:{...p.replyer,model_list:vs(p.replyer?.model_list||[])},planner:{...p.planner,model_list:vs(p.planner?.model_list||[])},vlm:{...p.vlm,model_list:vs(p.vlm?.model_list||[])},voice:{...p.voice,model_list:vs(p.voice?.model_list||[])},embedding:{...p.embedding,model_list:vs(p.embedding?.model_list||[])},lpmm_entity_extract:{...p.lpmm_entity_extract,model_list:vs(p.lpmm_entity_extract?.model_list||[])},lpmm_rdf_build:{...p.lpmm_rdf_build,model_list:vs(p.lpmm_rdf_build?.model_list||[])},lpmm_qa:{...p.lpmm_qa,model_list:vs(p.lpmm_qa?.model_list||[])}})}M(!1),T(null),A(null),Oe({title:$!==null?"模型已更新":"模型已添加",description:'配置将在 2 秒后自动保存,或点击右上角"保存配置"按钮立即保存'})},ut=W=>{if(!W&&S){const re={...S,price_in:S.price_in??0,price_out:S.price_out??0};T(re)}M(W)},_s=W=>{oe(W),G(!0)},Tt=()=>{if(de!==null){const W=l.filter((re,ss)=>ss!==de);n(W),f(W.map(re=>re.name)),yt(p,W),Oe({title:"删除成功",description:'配置将在 2 秒后自动保存,或点击右上角"保存配置"按钮立即保存'})}G(!1),oe(null)},Bt=W=>{const re=new Set(fe);re.has(W)?re.delete(W):re.add(W),ge(re)},Ca=()=>{if(fe.size===Ce.length)ge(new Set);else{const W=Ce.map((re,ss)=>l.findIndex(Qs=>Qs===Ce[ss]));ge(new Set(W))}},Ya=()=>{if(fe.size===0){Oe({title:"提示",description:"请先选择要删除的模型",variant:"default"});return}V(!0)},nl=()=>{const W=fe.size,re=l.filter((ss,Qs)=>!fe.has(Qs));n(re),f(re.map(ss=>ss.name)),yt(p,re),ge(new Set),V(!1),Oe({title:"批量删除成功",description:`已删除 ${W} 个模型,配置将在 2 秒后自动保存`})},Yt=(W,re,ss)=>{if(!p)return;if(W==="embedding"&&re==="model_list"&&Array.isArray(ss)){const vs=Me.current,Ds=ss;if((vs.length!==Ds.length||vs.some(fa=>!Ds.includes(fa))||Ds.some(fa=>!vs.includes(fa)))&&vs.length>0){J.current={field:re,value:ss},xe(!0);return}}const Qs={...p,[W]:{...p[W],[re]:ss}};g(Qs),yt(Qs,l),W==="embedding"&&re==="model_list"&&Array.isArray(ss)&&(Me.current=[...ss])},X=()=>{if(!p||!J.current)return;const{field:W,value:re}=J.current,ss={...p,embedding:{...p.embedding,[W]:re}};g(ss),yt(ss,l),W==="model_list"&&Array.isArray(re)&&(Me.current=[...re]),J.current=null,xe(!1),Oe({title:"嵌入模型已更新",description:"建议重新生成知识库向量以确保最佳匹配精度"})},ye=()=>{J.current=null,xe(!1)},Ce=l.filter(W=>{if(!ve)return!0;const re=ve.toLowerCase();return W.name.toLowerCase().includes(re)||W.model_identifier.toLowerCase().includes(re)||W.api_provider.toLowerCase().includes(re)}),Ls=Math.ceil(Ce.length/P),ha=Ce.slice((U-1)*P,U*P),Jt=()=>{const W=parseInt(je);W>=1&&W<=Ls&&(L(W),Se(""))},tt=W=>p?[p.utils?.model_list||[],p.utils_small?.model_list||[],p.tool_use?.model_list||[],p.replyer?.model_list||[],p.planner?.model_list||[],p.vlm?.model_list||[],p.voice?.model_list||[],p.embedding?.model_list||[],p.lpmm_entity_extract?.model_list||[],p.lpmm_rdf_build?.model_list||[],p.lpmm_qa?.model_list||[]].some(ss=>ss.includes(W)):!1;return N?e.jsx(es,{className:"h-full",children:e.jsx("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx("p",{className:"text-muted-foreground",children:"加载中..."})})})}):e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"模型管理与分配"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"添加模型并为模型分配功能"})]}),e.jsxs("div",{className:"flex gap-2 w-full sm:w-auto",children:[e.jsx(q_,{trigger:e.jsxs(C,{variant:"outline",size:"sm",className:"flex-1 sm:flex-none",children:[e.jsx(Nj,{className:"mr-2 h-4 w-4"}),"分享配置"]})}),e.jsxs(C,{onClick:js,disabled:b||y||!D||ze,size:"sm",variant:"outline",className:"flex-1 sm:flex-none sm:min-w-[120px]",children:[e.jsx(Xi,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),b?"保存中...":y?"自动保存中...":D?"保存配置":"已保存"]}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsxs(C,{disabled:b||y||ze,size:"sm",className:"flex-1 sm:flex-none sm:min-w-[120px]",children:[e.jsx(Ji,{className:"mr-2 h-4 w-4"}),ze?"重启中...":D?"保存并重启":"重启麦麦"]})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认重启麦麦?"}),e.jsx(xs,{asChild:!0,children:e.jsx("div",{children:e.jsx("p",{children:D?"当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。":"即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。"})})})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:D?Ze:Ee,children:D?"保存并重启":"确认重启"})]})]})]})]})]}),e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsxs(rt,{children:["配置更新后需要",e.jsx("strong",{children:"重启麦麦"}),'才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。']})]}),ce.length>0&&e.jsxs(nt,{variant:"destructive",children:[e.jsx(Ft,{className:"h-4 w-4"}),e.jsxs(rt,{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("strong",{children:"检测到无效的模型引用"}),e.jsx("div",{className:"mt-2 space-y-1",children:ce.map(({taskName:W,invalidModels:re})=>e.jsxs("div",{className:"text-sm",children:[e.jsx("strong",{children:W})," 引用了不存在的模型: ",re.join(", ")]},W))})]}),e.jsx(C,{variant:"outline",size:"sm",className:"shrink-0 bg-background hover:bg-accent",onClick:gs,children:"一键清理"})]})]}),q.length>0&&e.jsxs(nt,{variant:"default",className:"border-yellow-500/50 bg-yellow-500/10",children:[e.jsx(Ft,{className:"h-4 w-4 text-yellow-600"}),e.jsxs(rt,{children:[e.jsx("strong",{className:"text-yellow-600",children:"以下任务未配置模型"}),e.jsxs("div",{className:"mt-2 text-sm",children:[q.join("、")," 还未分配模型,这些功能将无法正常工作。"]})]})]}),e.jsxs(nt,{className:"hidden lg:flex border-primary/30 bg-primary/5 cursor-pointer hover:bg-primary/10 transition-colors",onClick:rs,children:[e.jsx(Bw,{className:"h-4 w-4 text-primary"}),e.jsxs(rt,{className:"flex items-center justify-between",children:[e.jsxs("span",{children:[e.jsx("strong",{className:"text-primary",children:"新手引导:"}),"不知道如何配置模型?点击这里开始学习如何为麦麦的组件分配模型。"]}),e.jsx(C,{variant:"outline",size:"sm",className:"ml-4 shrink-0",children:"开始引导"})]})]}),e.jsxs(ma,{defaultValue:"models",className:"w-full",children:[e.jsxs(ta,{className:"grid w-full max-w-full sm:max-w-md grid-cols-2",children:[e.jsx(as,{value:"models",children:"添加模型"}),e.jsx(as,{value:"tasks","data-tour":"tasks-tab-trigger",children:"为模型分配功能"})]}),e.jsxs(ys,{value:"models",className:"space-y-4 mt-0",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"配置可用的模型列表"}),e.jsxs("div",{className:"flex gap-2 w-full sm:w-auto",children:[fe.size>0&&e.jsxs(C,{onClick:Ya,size:"sm",variant:"destructive",className:"w-full sm:w-auto",children:[e.jsx(ls,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"批量删除 (",fe.size,")"]}),e.jsxs(C,{onClick:()=>dt(null,null),size:"sm",variant:"outline",className:"w-full sm:w-auto","data-tour":"add-model-button",children:[e.jsx(it,{className:"mr-2 h-4 w-4",strokeWidth:2,fill:"none"}),"添加模型"]})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center gap-2",children:[e.jsxs("div",{className:"relative w-full sm:flex-1 sm:max-w-sm",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索模型名称、标识符或提供商...",value:ve,onChange:W=>le(W.target.value),className:"pl-9"})]}),ve&&e.jsxs("p",{className:"text-sm text-muted-foreground whitespace-nowrap",children:["找到 ",Ce.length," 个结果"]})]}),e.jsx(Q_,{paginatedModels:ha,allModels:l,onEdit:dt,onDelete:_s,isModelUsed:tt,searchQuery:ve}),e.jsx(Y_,{paginatedModels:ha,allModels:l,filteredModels:Ce,selectedModels:fe,onEdit:dt,onDelete:_s,onToggleSelection:Bt,onToggleSelectAll:Ca,isModelUsed:tt,searchQuery:ve}),e.jsx(Z_,{page:U,pageSize:P,totalItems:Ce.length,jumpToPage:je,onPageChange:L,onPageSizeChange:_e,onJumpToPageChange:Se,onJumpToPage:Jt,onSelectionClear:()=>ge(new Set)})]}),e.jsxs(ys,{value:"tasks",className:"space-y-6 mt-0",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"为不同的任务配置使用的模型和参数"}),p&&e.jsxs("div",{className:"grid gap-4 sm:gap-6",children:[e.jsx(Fa,{title:"组件模型 (utils)",description:"用于表情包、取名、关系、情绪变化等组件",taskConfig:p.utils,modelNames:h,onChange:(W,re)=>Yt("utils",W,re),dataTour:"task-model-select"}),e.jsx(Fa,{title:"组件小模型 (utils_small)",description:"消耗量较大的组件,建议使用速度较快的小模型",taskConfig:p.utils_small,modelNames:h,onChange:(W,re)=>Yt("utils_small",W,re)}),e.jsx(Fa,{title:"工具调用模型 (tool_use)",description:"需要使用支持工具调用的模型",taskConfig:p.tool_use,modelNames:h,onChange:(W,re)=>Yt("tool_use",W,re)}),e.jsx(Fa,{title:"首要回复模型 (replyer)",description:"用于表达器和表达方式学习",taskConfig:p.replyer,modelNames:h,onChange:(W,re)=>Yt("replyer",W,re)}),e.jsx(Fa,{title:"决策模型 (planner)",description:"负责决定麦麦该什么时候回复",taskConfig:p.planner,modelNames:h,onChange:(W,re)=>Yt("planner",W,re)}),e.jsx(Fa,{title:"图像识别模型 (vlm)",description:"视觉语言模型",taskConfig:p.vlm,modelNames:h,onChange:(W,re)=>Yt("vlm",W,re),hideTemperature:!0}),e.jsx(Fa,{title:"语音识别模型 (voice)",description:"语音转文字",taskConfig:p.voice,modelNames:h,onChange:(W,re)=>Yt("voice",W,re),hideTemperature:!0,hideMaxTokens:!0}),e.jsx(Fa,{title:"嵌入模型 (embedding)",description:"用于向量化",taskConfig:p.embedding,modelNames:h,onChange:(W,re)=>Yt("embedding",W,re),hideTemperature:!0,hideMaxTokens:!0}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"LPMM 知识库模型"}),e.jsx(Fa,{title:"实体提取模型 (lpmm_entity_extract)",description:"从文本中提取实体",taskConfig:p.lpmm_entity_extract,modelNames:h,onChange:(W,re)=>Yt("lpmm_entity_extract",W,re)}),e.jsx(Fa,{title:"RDF 构建模型 (lpmm_rdf_build)",description:"构建知识图谱",taskConfig:p.lpmm_rdf_build,modelNames:h,onChange:(W,re)=>Yt("lpmm_rdf_build",W,re)}),e.jsx(Fa,{title:"问答模型 (lpmm_qa)",description:"知识库问答",taskConfig:p.lpmm_qa,modelNames:h,onChange:(W,re)=>Yt("lpmm_qa",W,re)})]})]})]})]}),e.jsx(Ks,{open:I,onOpenChange:ut,children:e.jsxs(Ps,{className:"max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto","data-tour":"model-dialog",preventOutsideClose:Kt,children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:$!==null?"编辑模型":"添加模型"}),e.jsx(ot,{children:"配置模型的基本信息和参数"})]}),e.jsxs("div",{className:"grid gap-4 py-4",children:[e.jsxs("div",{className:"grid gap-2","data-tour":"model-name-input",children:[e.jsx(E,{htmlFor:"model_name",className:ke.name?"text-destructive":"",children:"模型名称 *"}),e.jsx(ie,{id:"model_name",value:S?.name||"",onChange:W=>{T(re=>re?{...re,name:W.target.value}:null),ke.name&&Te(re=>({...re,name:void 0}))},placeholder:"例如: qwen3-30b",className:ke.name?"border-destructive focus-visible:ring-destructive":""}),ke.name?e.jsx("p",{className:"text-xs text-destructive",children:ke.name}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"用于在任务配置中引用此模型"})]}),e.jsxs("div",{className:"grid gap-2","data-tour":"model-provider-select",children:[e.jsx(E,{htmlFor:"api_provider",className:ke.api_provider?"text-destructive":"",children:"API 提供商 *"}),e.jsxs(Be,{value:S?.api_provider||"",onValueChange:W=>{T(re=>re?{...re,api_provider:W}:null),Rs(),ke.api_provider&&Te(re=>({...re,api_provider:void 0}))},children:[e.jsx(Le,{id:"api_provider",className:ke.api_provider?"border-destructive focus-visible:ring-destructive":"",children:e.jsx($e,{placeholder:"选择提供商"})}),e.jsx(Ue,{children:i.map(W=>e.jsx(ae,{value:W,children:W},W))})]}),ke.api_provider&&e.jsx("p",{className:"text-xs text-destructive",children:ke.api_provider})]}),e.jsxs("div",{className:"grid gap-2","data-tour":"model-identifier-input",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{htmlFor:"model_identifier",className:ke.model_identifier?"text-destructive":"",children:"模型标识符 *"}),Cs?.modelFetcher&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ae,{variant:"secondary",className:"text-xs",children:Cs.display_name}),e.jsx(C,{variant:"ghost",size:"sm",className:"h-6 px-2",onClick:()=>S?.api_provider&&ns(S.api_provider,!0),disabled:Ie,children:Ie?e.jsx(zs,{className:"h-3 w-3 animate-spin"}):e.jsx(kt,{className:"h-3 w-3"})})]})]}),Cs?.modelFetcher?e.jsxs(tl,{open:Y,onOpenChange:be,children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",role:"combobox","aria-expanded":Y,className:"w-full justify-between font-normal",disabled:Ie||!!Ve,children:[Ie?e.jsxs("span",{className:"flex items-center gap-2 text-muted-foreground",children:[e.jsx(zs,{className:"h-4 w-4 animate-spin"}),"正在获取模型列表..."]}):Ve?e.jsx("span",{className:"text-muted-foreground text-sm",children:"点击下方输入框手动填写"}):S?.model_identifier?e.jsx("span",{className:"truncate",children:S.model_identifier}):e.jsx("span",{className:"text-muted-foreground",children:"搜索或选择模型..."}),e.jsx(Um,{className:"ml-2 h-4 w-4 shrink-0 opacity-50"})]})}),e.jsx(Ka,{className:"p-0",align:"start",style:{width:"var(--radix-popover-trigger-width)"},children:e.jsxs(Go,{children:[e.jsx(Fo,{placeholder:"搜索模型..."}),e.jsx(es,{className:"h-[300px]",children:e.jsxs(qo,{className:"max-h-none overflow-visible",children:[e.jsx(Vo,{children:Ve?e.jsxs("div",{className:"py-4 px-2 text-center space-y-2",children:[e.jsx("p",{className:"text-sm text-destructive",children:Ve}),!Ve.includes("API Key")&&e.jsx(C,{variant:"link",size:"sm",onClick:()=>S?.api_provider&&ns(S.api_provider,!0),children:"重试"})]}):"未找到匹配的模型"}),e.jsx(qi,{heading:"可用模型",children:qe.map(W=>e.jsxs(Vi,{value:W.id,onSelect:()=>{T(re=>re?{...re,model_identifier:W.id}:null),be(!1)},children:[e.jsx(St,{className:`mr-2 h-4 w-4 ${S?.model_identifier===W.id?"opacity-100":"opacity-0"}`}),e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{children:W.id}),W.name!==W.id&&e.jsx("span",{className:"text-xs text-muted-foreground",children:W.name})]})]},W.id))}),e.jsx(qi,{heading:"手动输入",children:e.jsxs(Vi,{value:"__manual_input__",onSelect:()=>{be(!1)},children:[e.jsx(On,{className:"mr-2 h-4 w-4"}),"手动输入模型标识符..."]})})]})})]})})]}):e.jsx(ie,{id:"model_identifier",value:S?.model_identifier||"",onChange:W=>{T(re=>re?{...re,model_identifier:W.target.value}:null),ke.model_identifier&&Te(re=>({...re,model_identifier:void 0}))},placeholder:"Qwen/Qwen3-30B-A3B-Instruct-2507",className:ke.model_identifier?"border-destructive focus-visible:ring-destructive":""}),ke.model_identifier&&e.jsx("p",{className:"text-xs text-destructive",children:ke.model_identifier}),Ve&&Cs?.modelFetcher&&!ke.model_identifier&&e.jsxs(nt,{variant:"destructive",className:"mt-2 py-2",children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsx(rt,{className:"text-xs",children:Ve})]}),Cs?.modelFetcher&&e.jsx(ie,{value:S?.model_identifier||"",onChange:W=>{T(re=>re?{...re,model_identifier:W.target.value}:null),ke.model_identifier&&Te(re=>({...re,model_identifier:void 0}))},placeholder:"或手动输入模型标识符",className:`mt-2 ${ke.model_identifier?"border-destructive focus-visible:ring-destructive":""}`}),!ke.model_identifier&&e.jsx("p",{className:"text-xs text-muted-foreground",children:Ve?'请手动输入模型标识符,或前往"模型提供商配置"检查 API Key':Cs?.modelFetcher?`已识别为 ${Cs.display_name},支持自动获取模型列表`:"API 提供商提供的模型 ID"})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"price_in",children:"输入价格 (¥/M token)"}),e.jsx(ie,{id:"price_in",type:"number",step:"0.1",min:"0",value:S?.price_in??"",onChange:W=>{const re=W.target.value===""?null:parseFloat(W.target.value);T(ss=>ss?{...ss,price_in:re}:null)},placeholder:"默认: 0"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"price_out",children:"输出价格 (¥/M token)"}),e.jsx(ie,{id:"price_out",type:"number",step:"0.1",min:"0",value:S?.price_out??"",onChange:W=>{const re=W.target.value===""?null:parseFloat(W.target.value);T(ss=>ss?{...ss,price_out:re}:null)},placeholder:"默认: 0"})]})]}),e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{htmlFor:"enable_model_temperature",className:"cursor-pointer",children:"自定义模型温度"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"启用后将覆盖「为模型分配功能」中的任务温度配置"})]}),e.jsx(Ge,{id:"enable_model_temperature",checked:S?.temperature!=null,onCheckedChange:W=>{T(W?re=>re?{...re,temperature:.5}:null:re=>re?{...re,temperature:null}:null)}})]}),S?.temperature!=null&&e.jsxs("div",{className:"space-y-2 pt-2 border-t",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-sm",children:"温度值"}),e.jsx("span",{className:"text-sm font-medium tabular-nums",children:S.temperature.toFixed(1)})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"0"}),e.jsx(wa,{value:[S.temperature],onValueChange:W=>T(re=>re?{...re,temperature:W[0]}:null),min:0,max:1,step:.1,className:"flex-1"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"较低的温度(0.1-0.3)产生更确定的输出,较高的温度(0.7-1.0)产生更多样化的输出"})]})]}),e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{htmlFor:"enable_model_max_tokens",className:"cursor-pointer",children:"自定义最大 Token"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"启用后将覆盖「为模型分配功能」中的任务最大 Token 配置"})]}),e.jsx(Ge,{id:"enable_model_max_tokens",checked:S?.max_tokens!=null,onCheckedChange:W=>{T(W?re=>re?{...re,max_tokens:2048}:null:re=>re?{...re,max_tokens:null}:null)}})]}),S?.max_tokens!=null&&e.jsxs("div",{className:"space-y-2 pt-2 border-t",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{className:"text-sm",children:"最大 Token 数"}),e.jsx(ie,{type:"number",min:"1",max:"128000",value:S.max_tokens,onChange:W=>{const re=parseInt(W.target.value);!isNaN(re)&&re>=1&&T(ss=>ss?{...ss,max_tokens:re}:null)},className:"w-28 h-8 text-sm"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"限制模型单次输出的最大 token 数量,不同模型支持的上限不同"})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"force_stream_mode",checked:S?.force_stream_mode||!1,onCheckedChange:W=>T(re=>re?{...re,force_stream_mode:W}:null)}),e.jsx(E,{htmlFor:"force_stream_mode",className:"cursor-pointer",children:"强制流式输出模式"})]}),e.jsx(R_,{value:S?.extra_params||{},onChange:W=>T(re=>re?{...re,extra_params:W}:null),placeholder:"添加额外参数(如 enable_thinking、top_p 等)..."})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>M(!1),"data-tour":"model-cancel-button",children:"取消"}),e.jsx(C,{onClick:Ot,"data-tour":"model-save-button",children:"保存"})]})]})}),e.jsx(ps,{open:Q,onOpenChange:G,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除模型 "',de!==null?l[de]?.name:"",'" 吗? 此操作无法撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:Tt,children:"删除"})]})]})}),e.jsx(ps,{open:z,onOpenChange:V,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认批量删除"}),e.jsxs(xs,{children:["确定要删除选中的 ",fe.size," 个模型吗? 此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:nl,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"批量删除"})]})]})}),e.jsx(ps,{open:Z,onOpenChange:xe,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsxs(ms,{className:"flex items-center gap-2",children:[e.jsx(Ft,{className:"h-5 w-5 text-amber-500"}),"更换嵌入模型警告"]}),e.jsx(xs,{asChild:!0,children:e.jsxs("div",{className:"space-y-3 text-sm",children:[e.jsxs("p",{children:[e.jsx("strong",{className:"text-foreground",children:"注意:"}),"更换嵌入模型可能会影响知识库的匹配精度!"]}),e.jsxs("ul",{className:"space-y-2 ml-4 list-disc text-muted-foreground",children:[e.jsx("li",{children:"不同的嵌入模型会产生不同的向量表示"}),e.jsx("li",{children:"这可能导致现有知识库的检索结果不准确"}),e.jsx("li",{children:"建议更换嵌入模型后重新生成所有知识库的向量"})]}),e.jsx("p",{className:"text-foreground font-medium",children:"确定要更换嵌入模型吗?"})]})})]}),e.jsxs(us,{children:[e.jsx(fs,{onClick:ye,children:"取消"}),e.jsx(hs,{onClick:X,className:"bg-amber-600 hover:bg-amber-700",children:"确认更换"})]})]})}),e.jsx(Hn,{})]})})}const Ki=Bg,Qi=E0,Yi=M0,Ko="/api/webui/config";async function lS(){const n=await(await we(`${Ko}/adapter-config/path`)).json();return!n.success||!n.path?null:{path:n.path,lastModified:n.lastModified}}async function ug(l){const i=await(await we(`${Ko}/adapter-config/path`,{method:"POST",headers:Us(),body:JSON.stringify({path:l})})).json();if(!i.success)throw new Error(i.message||"保存路径失败")}async function mg(l){const i=await(await we(`${Ko}/adapter-config?path=${encodeURIComponent(l)}`)).json();if(!i.success)throw new Error("读取配置文件失败");return i.content}async function xg(l,n){const c=await(await we(`${Ko}/adapter-config`,{method:"POST",headers:Us(),body:JSON.stringify({path:l,content:n})})).json();if(!c.success)throw new Error(c.message||"保存配置失败")}const vt={inner:{version:"0.1.2"},nickname:{nickname:""},napcat_server:{host:"localhost",port:8095,token:"",heartbeat_interval:30},maibot_server:{host:"localhost",port:8e3},chat:{group_list_type:"whitelist",group_list:[],private_list_type:"whitelist",private_list:[],ban_user_id:[],ban_qq_bot:!1,enable_poke:!0},voice:{use_tts:!1},debug:{level:"INFO"}},bm={oneclick:{name:"一键包",description:"使用一键包部署的适配器配置",path:"../MaiBot-Napcat-Adapter/config.toml",icon:Wt},docker:{name:"Docker",description:"Docker Compose 部署的适配器配置",path:"/MaiMBot/adapters-config/config.toml",icon:$w}};function nS(l,n){let i=l.slice(0,n).split(/\r\n|\n|\r/g);return[i.length,i.pop().length+1]}function rS(l,n,i){let c=l.split(/\r\n|\n|\r/g),u="",x=(Math.log10(n+1)|0)+1;for(let h=n-1;h<=n+1;h++){let f=c[h-1];f&&(u+=h.toString().padEnd(x," "),u+=": ",u+=f,u+=` +`,h===n&&(u+=" ".repeat(x+i+2),u+=`^ +`))}return u}class ws extends Error{line;column;codeblock;constructor(n,i){const[c,u]=nS(i.toml,i.ptr),x=rS(i.toml,c,u);super(`Invalid TOML document: ${n} + +${x}`,i),this.line=c,this.column=u,this.codeblock=x}}function iS(l,n){let i=0;for(;l[n-++i]==="\\";);return--i&&i%2}function zo(l,n=0,i=l.length){let c=l.indexOf(` +`,n);return l[c-1]==="\r"&&c--,c<=i?c:-1}function Hm(l,n){for(let i=n;i-1&&i!=="'"&&iS(l,n));return n>-1&&(n+=c.length,c.length>1&&(l[n]===i&&n++,l[n]===i&&n++)),n}let cS=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}:\d{2}(?:\.\d+)?)?(Z|[-+]\d{2}:\d{2})?$/i;class Ar extends Date{#s=!1;#t=!1;#e=null;constructor(n){let i=!0,c=!0,u="Z";if(typeof n=="string"){let x=n.match(cS);x?(x[1]||(i=!1,n=`0000-01-01T${n}`),c=!!x[2],c&&n[10]===" "&&(n=n.replace(" ","T")),x[2]&&+x[2]>23?n="":(u=x[3]||null,n=n.toUpperCase(),!u&&c&&(n+="Z"))):n=""}super(n),isNaN(this.getTime())||(this.#s=i,this.#t=c,this.#e=u)}isDateTime(){return this.#s&&this.#t}isLocal(){return!this.#s||!this.#t||!this.#e}isDate(){return this.#s&&!this.#t}isTime(){return this.#t&&!this.#s}isValid(){return this.#s||this.#t}toISOString(){let n=super.toISOString();if(this.isDate())return n.slice(0,10);if(this.isTime())return n.slice(11,23);if(this.#e===null)return n.slice(0,-1);if(this.#e==="Z")return n;let i=+this.#e.slice(1,3)*60+ +this.#e.slice(4,6);return i=this.#e[0]==="-"?i:-i,new Date(this.getTime()-i*6e4).toISOString().slice(0,-1)+this.#e}static wrapAsOffsetDateTime(n,i="Z"){let c=new Ar(n);return c.#e=i,c}static wrapAsLocalDateTime(n){let i=new Ar(n);return i.#e=null,i}static wrapAsLocalDate(n){let i=new Ar(n);return i.#t=!1,i.#e=null,i}static wrapAsLocalTime(n){let i=new Ar(n);return i.#s=!1,i.#e=null,i}}let oS=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,dS=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,uS=/^[+-]?0[0-9_]/,mS=/^[0-9a-f]{4,8}$/i,fg={b:"\b",t:" ",n:` +`,f:"\f",r:"\r",'"':'"',"\\":"\\"};function uv(l,n=0,i=l.length){let c=l[n]==="'",u=l[n++]===l[n]&&l[n]===l[n+1];u&&(i-=2,l[n+=2]==="\r"&&n++,l[n]===` +`&&n++);let x=0,h,f="",p=n;for(;n-1&&(Hm(l,x),u=u.slice(0,x));let h=u.trimEnd();if(!c){let f=u.indexOf(` +`,h.length);if(f>-1)throw new ws("newlines are not allowed in inline tables",{toml:l,ptr:n+f})}return[h,x]}function Gm(l,n,i,c,u){if(c===0)throw new ws("document contains excessively nested structures. aborting.",{toml:l,ptr:n});let x=l[n];if(x==="["||x==="{"){let[p,g]=x==="["?gS(l,n,c,u):pS(l,n,c,u),N=i?hg(l,g,",",i):g;if(g-N&&i==="}"){let v=zo(l,g,N);if(v>-1)throw new ws("newlines are not allowed in inline tables",{toml:l,ptr:v})}return[p,N]}let h;if(x==='"'||x==="'"){h=dv(l,n);let p=uv(l,n,h);if(i){if(h=Cl(l,h,i!=="]"),l[h]&&l[h]!==","&&l[h]!==i&&l[h]!==` +`&&l[h]!=="\r")throw new ws("unexpected character encountered",{toml:l,ptr:h});h+=+(l[h]===",")}return[p,h]}h=hg(l,n,",",i);let f=hS(l,n,h-+(l[h-1]===","),i==="]");if(!f[0])throw new ws("incomplete key-value declaration: no value specified",{toml:l,ptr:n});return i&&f[1]>-1&&(h=Cl(l,n+f[1]),h+=+(l[h]===",")),[xS(f[0],l,n,u),h]}let fS=/^[a-zA-Z0-9-_]+[ \t]*$/;function zm(l,n,i="="){let c=n-1,u=[],x=l.indexOf(i,n);if(x<0)throw new ws("incomplete key-value: cannot find end of key",{toml:l,ptr:n});do{let h=l[n=++c];if(h!==" "&&h!==" ")if(h==='"'||h==="'"){if(h===l[n+1]&&h===l[n+2])throw new ws("multiline strings are not allowed in keys",{toml:l,ptr:n});let f=dv(l,n);if(f<0)throw new ws("unfinished string encountered",{toml:l,ptr:n});c=l.indexOf(".",f);let p=l.slice(f,c<0||c>x?x:c),g=zo(p);if(g>-1)throw new ws("newlines are not allowed in keys",{toml:l,ptr:n+c+g});if(p.trimStart())throw new ws("found extra tokens after the string part",{toml:l,ptr:f});if(xx?x:c);if(!fS.test(f))throw new ws("only letter, numbers, dashes and underscores are allowed in keys",{toml:l,ptr:n});u.push(f.trimEnd())}}while(c+1&&cu===""||u===null||u===void 0?x:u,i={inner:{version:n(l.inner.version,vt.inner.version)},nickname:{nickname:n(l.nickname.nickname,vt.nickname.nickname)},napcat_server:{host:n(l.napcat_server.host,vt.napcat_server.host),port:n(l.napcat_server.port||0,vt.napcat_server.port),token:n(l.napcat_server.token,vt.napcat_server.token),heartbeat_interval:n(l.napcat_server.heartbeat_interval||0,vt.napcat_server.heartbeat_interval)},maibot_server:{host:n(l.maibot_server.host,vt.maibot_server.host),port:n(l.maibot_server.port||0,vt.maibot_server.port)},chat:{group_list_type:n(l.chat.group_list_type,vt.chat.group_list_type),group_list:l.chat.group_list||[],private_list_type:n(l.chat.private_list_type,vt.chat.private_list_type),private_list:l.chat.private_list||[],ban_user_id:l.chat.ban_user_id||[],ban_qq_bot:l.chat.ban_qq_bot??vt.chat.ban_qq_bot,enable_poke:l.chat.enable_poke??vt.chat.enable_poke},voice:{use_tts:l.voice.use_tts??vt.voice.use_tts},debug:{level:n(l.debug.level,vt.debug.level)}};let c=yS(i);return c=wS(c),c}catch(n){throw console.error("TOML 生成失败:",n),new Error(`无法生成 TOML 文件: ${n instanceof Error?n.message:"未知错误"}`)}}function wS(l){const n=l.split(` +`),i=[];for(let c=0;c"|?*\x00-\x1F]/.test(l)?{valid:!1,error:"路径包含非法字符"}:{valid:!0,error:""}}function _S(){const[l,n]=m.useState("upload"),[i,c]=m.useState(null),[u,x]=m.useState(""),[h,f]=m.useState(""),[p,g]=m.useState("oneclick"),[N,v]=m.useState(""),[b,w]=m.useState(!1),[y,R]=m.useState(!1),[D,k]=m.useState(!1),[I,M]=m.useState(!1),[S,T]=m.useState(null),[$,A]=m.useState(!1),Q=m.useRef(null),{toast:G}=Ws(),de=m.useRef(null),oe=Z=>{if(f(Z),Z.trim()){const xe=_m(Z);v(xe.error)}else v("")},ve=m.useCallback(async Z=>{const xe=bm[Z];R(!0);try{const Me=await mg(xe.path),J=ym(Me);c(J),g(Z),f(xe.path),await ug(xe.path),G({title:"加载成功",description:`已从${xe.name}预设加载配置`})}catch(Me){console.error("加载预设配置失败:",Me),G({title:"加载失败",description:Me instanceof Error?Me.message:"无法读取预设配置文件",variant:"destructive"})}finally{R(!1)}},[G]),le=m.useCallback(async Z=>{const xe=_m(Z);if(!xe.valid){v(xe.error),G({title:"路径无效",description:xe.error,variant:"destructive"});return}v(""),R(!0);try{const Me=await mg(Z),J=ym(Me);c(J),f(Z),await ug(Z),G({title:"加载成功",description:"已从配置文件加载"})}catch(Me){console.error("加载配置失败:",Me),G({title:"加载失败",description:Me instanceof Error?Me.message:"无法读取配置文件",variant:"destructive"})}finally{R(!1)}},[G]);m.useEffect(()=>{(async()=>{try{const xe=await lS();if(xe&&xe.path){f(xe.path);const Me=Object.entries(bm).find(([,J])=>J.path===xe.path);Me?(n("preset"),g(Me[0]),await ve(Me[0])):(n("path"),await le(xe.path))}}catch(xe){console.error("加载保存的路径失败:",xe)}})()},[le,ve]);const fe=m.useCallback(Z=>{l!=="path"&&l!=="preset"||!h||(de.current&&clearTimeout(de.current),de.current=setTimeout(async()=>{w(!0);try{const xe=wm(Z);await xg(h,xe),G({title:"自动保存成功",description:"配置已保存到文件"})}catch(xe){console.error("自动保存失败:",xe),G({title:"自动保存失败",description:xe instanceof Error?xe.message:"保存配置失败",variant:"destructive"})}finally{w(!1)}},1e3))},[l,h,G]),ge=async()=>{if(!i||!h)return;const Z=_m(h);if(!Z.valid){G({title:"保存失败",description:Z.error,variant:"destructive"});return}w(!0);try{const xe=wm(i);await xg(h,xe),G({title:"保存成功",description:"配置已保存到文件"})}catch(xe){console.error("保存失败:",xe),G({title:"保存失败",description:xe instanceof Error?xe.message:"保存配置失败",variant:"destructive"})}finally{w(!1)}},z=async()=>{h&&await le(h)},V=Z=>{if(Z!==l){if(i){T(Z),k(!0);return}U(Z)}},U=Z=>{c(null),x(""),v(""),n(Z),Z==="preset"&&ve("oneclick"),G({title:"已切换模式",description:{upload:"现在可以上传配置文件",path:"现在可以指定配置文件路径",preset:"现在可以使用预设配置"}[Z]})},L=()=>{S&&(U(S),T(null)),k(!1)},P=()=>{if(i){M(!0);return}_e()},_e=()=>{f(""),c(null),v(""),G({title:"已清空",description:"路径和配置已清空"})},je=()=>{_e(),M(!1)},Se=Z=>{const xe=Z.target.files?.[0];if(!xe)return;const Me=new FileReader;Me.onload=J=>{try{const ce=J.target?.result,Fe=ym(ce);c(Fe),x(xe.name),G({title:"上传成功",description:`已加载配置文件:${xe.name}`})}catch(ce){console.error("解析配置文件失败:",ce),G({title:"解析失败",description:"配置文件格式错误,请检查文件内容",variant:"destructive"})}},Me.readAsText(xe)},Y=()=>{if(!i)return;const Z=wm(i),xe=new Blob([Z],{type:"text/plain;charset=utf-8"}),Me=URL.createObjectURL(xe),J=document.createElement("a");J.href=Me,J.download=u||"config.toml",document.body.appendChild(J),J.click(),document.body.removeChild(J),URL.revokeObjectURL(Me),G({title:"下载成功",description:"配置文件已下载,请手动覆盖并重启适配器"})},be=()=>{c(JSON.parse(JSON.stringify(vt))),x("config.toml"),G({title:"已加载默认配置",description:"可以开始编辑配置"})};return e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"麦麦适配器配置"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理麦麦的 QQ 适配器的配置文件"})]})}),e.jsxs("div",{className:"flex items-start gap-2 p-3 rounded-lg border border-amber-500/50 bg-amber-500/10 text-amber-700 dark:text-amber-400",children:[e.jsx(Ct,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("p",{className:"text-sm",children:"适配器配置保存之后使用 WebUI 的重启功能适配器并不会重启,需要手动重启适配器。"})]}),e.jsx(Ki,{open:$,onOpenChange:A,children:e.jsxs(De,{children:[e.jsx(Xe,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(We,{children:"工作模式"}),e.jsx(Is,{children:"选择配置文件的管理方式"})]}),e.jsx(Qi,{asChild:!0,children:e.jsxs(C,{variant:"ghost",size:"sm",className:"w-9 p-0",children:[e.jsx($a,{className:`h-4 w-4 transition-transform duration-200 ${$?"transform rotate-180":""}`}),e.jsx("span",{className:"sr-only",children:"切换"})]})})]})}),e.jsx(Yi,{children:e.jsxs(Qe,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-3 md:gap-4",children:[e.jsx("div",{className:`border-2 rounded-lg p-3 md:p-4 cursor-pointer transition-all ${l==="preset"?"border-primary bg-primary/5":"border-muted hover:border-primary/50 active:border-primary/70"}`,onClick:()=>V("preset"),children:e.jsxs("div",{className:"flex items-start gap-2 md:gap-3",children:[e.jsx(Wt,{className:"h-4 w-4 md:h-5 md:w-5 mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h3",{className:"font-semibold text-sm md:text-base",children:"预设模式"}),e.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-1 line-clamp-2",children:"使用预设的部署配置"})]})]})}),e.jsx("div",{className:`border-2 rounded-lg p-3 md:p-4 cursor-pointer transition-all ${l==="upload"?"border-primary bg-primary/5":"border-muted hover:border-primary/50 active:border-primary/70"}`,onClick:()=>V("upload"),children:e.jsxs("div",{className:"flex items-start gap-2 md:gap-3",children:[e.jsx(Gi,{className:"h-4 w-4 md:h-5 md:w-5 mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h3",{className:"font-semibold text-sm md:text-base",children:"上传文件模式"}),e.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-1 line-clamp-2",children:"上传配置文件,编辑后下载并手动覆盖"})]})]})}),e.jsx("div",{className:`border-2 rounded-lg p-3 md:p-4 cursor-pointer transition-all ${l==="path"?"border-primary bg-primary/5":"border-muted hover:border-primary/50 active:border-primary/70"}`,onClick:()=>V("path"),children:e.jsxs("div",{className:"flex items-start gap-2 md:gap-3",children:[e.jsx(Iw,{className:"h-4 w-4 md:h-5 md:w-5 mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h3",{className:"font-semibold text-sm md:text-base",children:"指定路径模式"}),e.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-1 line-clamp-2",children:"指定配置文件路径,自动加载和保存"})]})]})})]}),l==="preset"&&e.jsxs("div",{className:"space-y-3 pt-2 border-t",children:[e.jsx(E,{className:"text-sm md:text-base",children:"选择部署方式"}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:Object.entries(bm).map(([Z,xe])=>{const Me=xe.icon,J=p===Z;return e.jsx("div",{className:`border-2 rounded-lg p-3 cursor-pointer transition-all ${J?"border-primary bg-primary/5":"border-muted hover:border-primary/50"}`,onClick:()=>{g(Z),ve(Z)},children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Me,{className:"h-5 w-5 mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h4",{className:"font-semibold text-sm",children:xe.name}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:xe.description}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1 font-mono break-all",children:xe.path})]})]})},Z)})})]}),l==="path"&&e.jsxs("div",{className:"space-y-3 pt-2 border-t",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"config-path",className:"text-sm md:text-base",children:"配置文件路径"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsxs("div",{className:"flex-1 space-y-1",children:[e.jsx(ie,{id:"config-path",value:h,onChange:Z=>oe(Z.target.value),placeholder:"例: C:\\Adapter\\config.toml",className:`text-sm ${N?"border-destructive":""}`}),N&&e.jsx("p",{className:"text-xs text-destructive",children:N})]}),e.jsx(C,{onClick:()=>le(h),disabled:y||!h||!!N,className:"w-full sm:w-auto",children:y?e.jsxs(e.Fragment,{children:[e.jsx(kt,{className:"h-4 w-4 animate-spin mr-2"}),e.jsx("span",{className:"sm:hidden",children:"加载中..."})]}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"sm:hidden",children:"加载配置"}),e.jsx("span",{className:"hidden sm:inline",children:"加载"})]})})]})]}),e.jsxs("details",{className:"rounded-lg bg-muted/50 p-3 group",children:[e.jsxs("summary",{className:"text-xs font-medium cursor-pointer select-none list-none flex items-center justify-between",children:[e.jsx("span",{children:"路径格式说明"}),e.jsx("svg",{className:"h-4 w-4 transition-transform group-open:rotate-180",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),e.jsxs("div",{className:"mt-2 space-y-2 text-xs text-muted-foreground",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{className:"font-mono bg-background px-1.5 py-0.5 rounded text-[10px] md:text-xs whitespace-nowrap",children:"Windows"})}),e.jsxs("div",{className:"pl-2 space-y-0.5 text-[10px] md:text-xs break-all",children:[e.jsx("div",{children:"C:\\Adapter\\config.toml"}),e.jsx("div",{className:"hidden sm:block",children:"D:\\MaiBot\\adapter\\config.toml"}),e.jsx("div",{className:"hidden sm:block",children:"\\\\server\\share\\config.toml"})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{className:"font-mono bg-background px-1.5 py-0.5 rounded text-[10px] md:text-xs whitespace-nowrap",children:"Linux"})}),e.jsxs("div",{className:"pl-2 space-y-0.5 text-[10px] md:text-xs break-all",children:[e.jsx("div",{children:"/opt/adapter/config.toml"}),e.jsx("div",{className:"hidden sm:block",children:"/home/user/adapter/config.toml"}),e.jsx("div",{className:"hidden sm:block",children:"~/adapter/config.toml"})]})]}),e.jsx("p",{className:"pt-1 border-t text-[10px] md:text-xs",children:"💡 配置会自动保存到指定文件,修改后 1 秒自动保存"})]})]})]})]})})]})}),e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsx(rt,{children:l==="preset"?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"预设模式:"}),"选择预设的部署方式,配置会自动加载,修改后 1 秒自动保存",b&&" (正在保存...)"]}):l==="upload"?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"上传文件模式:"}),"上传配置文件 → 在线编辑 → 下载文件 → 手动覆盖并重启适配器"]}):e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"指定路径模式:"}),"指定配置文件路径后,配置会自动加载,修改后 1 秒自动保存",b&&" (正在保存...)"]})})]}),l==="upload"&&!i&&e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 w-full",children:[e.jsx("input",{ref:Q,type:"file",accept:".toml",className:"hidden",onChange:Se}),e.jsxs(C,{onClick:()=>Q.current?.click(),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[e.jsx(Gi,{className:"mr-2 h-4 w-4"}),"上传配置"]}),e.jsxs(C,{onClick:be,size:"sm",className:"w-full sm:w-auto",children:[e.jsx(qa,{className:"mr-2 h-4 w-4"}),"使用默认配置"]})]}),l==="upload"&&i&&e.jsx("div",{className:"flex gap-2",children:e.jsxs(C,{onClick:Y,size:"sm",className:"w-full sm:w-auto",children:[e.jsx(Xt,{className:"mr-2 h-4 w-4"}),"下载配置"]})}),(l==="preset"||l==="path")&&i&&e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsxs(C,{onClick:ge,size:"sm",disabled:b||!!N,className:"w-full sm:w-auto",children:[e.jsx(Xi,{className:"mr-2 h-4 w-4"}),b?"保存中...":"立即保存"]}),e.jsxs(C,{onClick:z,size:"sm",variant:"outline",disabled:y,className:"w-full sm:w-auto",children:[e.jsx(kt,{className:`mr-2 h-4 w-4 ${y?"animate-spin":""}`}),"刷新"]}),l==="path"&&e.jsxs(C,{onClick:P,size:"sm",variant:"destructive",className:"w-full sm:w-auto",children:[e.jsx(ls,{className:"mr-2 h-4 w-4"}),"清空路径"]})]}),i?e.jsxs(ma,{defaultValue:"napcat",className:"w-full",children:[e.jsx("div",{className:"overflow-x-auto -mx-4 px-4 sm:mx-0 sm:px-0",children:e.jsxs(ta,{className:"inline-flex w-auto min-w-full sm:grid sm:w-full sm:grid-cols-5",children:[e.jsxs(as,{value:"napcat",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[e.jsx("span",{className:"hidden sm:inline",children:"Napcat 连接"}),e.jsx("span",{className:"sm:hidden",children:"Napcat"})]}),e.jsxs(as,{value:"maibot",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[e.jsx("span",{className:"hidden sm:inline",children:"麦麦连接"}),e.jsx("span",{className:"sm:hidden",children:"麦麦"})]}),e.jsxs(as,{value:"chat",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[e.jsx("span",{className:"hidden sm:inline",children:"聊天控制"}),e.jsx("span",{className:"sm:hidden",children:"聊天"})]}),e.jsxs(as,{value:"voice",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:[e.jsx("span",{className:"hidden sm:inline",children:"语音设置"}),e.jsx("span",{className:"sm:hidden",children:"语音"})]}),e.jsx(as,{value:"debug",className:"flex-shrink-0 text-xs sm:text-sm whitespace-nowrap",children:"调试"})]})}),e.jsx(ys,{value:"napcat",className:"space-y-4",children:e.jsx(SS,{config:i,onChange:Z=>{c(Z),fe(Z)}})}),e.jsx(ys,{value:"maibot",className:"space-y-4",children:e.jsx(kS,{config:i,onChange:Z=>{c(Z),fe(Z)}})}),e.jsx(ys,{value:"chat",className:"space-y-4",children:e.jsx(CS,{config:i,onChange:Z=>{c(Z),fe(Z)}})}),e.jsx(ys,{value:"voice",className:"space-y-4",children:e.jsx(TS,{config:i,onChange:Z=>{c(Z),fe(Z)}})}),e.jsx(ys,{value:"debug",className:"space-y-4",children:e.jsx(ES,{config:i,onChange:Z=>{c(Z),fe(Z)}})})]}):e.jsx("div",{className:"rounded-lg border bg-card p-6 md:p-12",children:e.jsxs("div",{className:"text-center space-y-3 md:space-y-4",children:[e.jsx(qa,{className:"h-12 w-12 md:h-16 md:w-16 mx-auto text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-base md:text-lg font-semibold",children:"尚未加载配置"}),e.jsx("p",{className:"text-xs md:text-sm text-muted-foreground mt-2 px-4",children:l==="preset"?"请选择预设的部署方式":l==="upload"?"请上传现有配置文件,或使用默认配置开始编辑":"请指定配置文件路径并点击加载按钮"})]})]})}),e.jsx(ps,{open:D,onOpenChange:k,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认切换模式"}),e.jsxs(xs,{children:["切换模式将清空当前配置,确定要继续吗?",e.jsx("br",{}),e.jsx("span",{className:"text-destructive font-medium",children:"请确保已保存重要配置"})]})]}),e.jsxs(us,{children:[e.jsx(fs,{onClick:()=>{k(!1),T(null)},children:"取消"}),e.jsx(hs,{onClick:L,children:"确认切换"})]})]})}),e.jsx(ps,{open:I,onOpenChange:M,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认清空路径"}),e.jsxs(xs,{children:["清空路径将清除当前配置,确定要继续吗?",e.jsx("br",{}),e.jsx("span",{className:"text-muted-foreground text-sm",children:"此操作不会删除配置文件,只是清除界面中的配置"})]})]}),e.jsxs(us,{children:[e.jsx(fs,{onClick:()=>M(!1),children:"取消"}),e.jsx(hs,{onClick:je,className:"bg-destructive hover:bg-destructive/90",children:"确认清空"})]})]})})]})})}function SS({config:l,onChange:n}){return e.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"Napcat WebSocket 服务设置"}),e.jsxs("div",{className:"grid gap-3 md:gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"napcat-host",className:"text-sm md:text-base",children:"主机地址"}),e.jsx(ie,{id:"napcat-host",value:l.napcat_server.host,onChange:i=>n({...l,napcat_server:{...l.napcat_server,host:i.target.value}}),placeholder:"localhost",className:"text-sm md:text-base"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Napcat 设定的主机地址"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"napcat-port",className:"text-sm md:text-base",children:"端口"}),e.jsx(ie,{id:"napcat-port",type:"number",value:l.napcat_server.port||"",onChange:i=>n({...l,napcat_server:{...l.napcat_server,port:i.target.value?parseInt(i.target.value):0}}),placeholder:"8095",className:"text-sm md:text-base"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Napcat 设定的端口(留空使用默认值 8095)"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"napcat-token",className:"text-sm md:text-base",children:"访问令牌(Token)"}),e.jsx(ie,{id:"napcat-token",type:"password",value:l.napcat_server.token,onChange:i=>n({...l,napcat_server:{...l.napcat_server,token:i.target.value}}),placeholder:"留空表示无需令牌",className:"text-sm md:text-base"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Napcat 设定的访问令牌,若无则留空"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"napcat-heartbeat",className:"text-sm md:text-base",children:"心跳间隔(秒)"}),e.jsx(ie,{id:"napcat-heartbeat",type:"number",value:l.napcat_server.heartbeat_interval||"",onChange:i=>n({...l,napcat_server:{...l.napcat_server,heartbeat_interval:i.target.value?parseInt(i.target.value):0}}),placeholder:"30",className:"text-sm md:text-base"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"与 Napcat 设置的心跳间隔保持一致(留空使用默认值 30)"})]})]})]})})}function kS({config:l,onChange:n}){return e.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"麦麦 WebSocket 服务设置"}),e.jsxs("div",{className:"grid gap-3 md:gap-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"maibot-host",className:"text-sm md:text-base",children:"主机地址"}),e.jsx(ie,{id:"maibot-host",value:l.maibot_server.host,onChange:i=>n({...l,maibot_server:{...l.maibot_server,host:i.target.value}}),placeholder:"localhost",className:"text-sm md:text-base"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦在 .env 文件中设置的 HOST 字段"})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{htmlFor:"maibot-port",className:"text-sm md:text-base",children:"端口"}),e.jsx(ie,{id:"maibot-port",type:"number",value:l.maibot_server.port||"",onChange:i=>n({...l,maibot_server:{...l.maibot_server,port:i.target.value?parseInt(i.target.value):0}}),placeholder:"8000",className:"text-sm md:text-base"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦在 .env 文件中设置的 PORT 字段(留空使用默认值 8000)"})]})]})]})})}function CS({config:l,onChange:n}){const i=x=>{const h={...l};x==="group"?h.chat.group_list=[...h.chat.group_list,0]:x==="private"?h.chat.private_list=[...h.chat.private_list,0]:h.chat.ban_user_id=[...h.chat.ban_user_id,0],n(h)},c=(x,h)=>{const f={...l};x==="group"?f.chat.group_list=f.chat.group_list.filter((p,g)=>g!==h):x==="private"?f.chat.private_list=f.chat.private_list.filter((p,g)=>g!==h):f.chat.ban_user_id=f.chat.ban_user_id.filter((p,g)=>g!==h),n(f)},u=(x,h,f)=>{const p={...l};x==="group"?p.chat.group_list[h]=f:x==="private"?p.chat.private_list[h]=f:p.chat.ban_user_id[h]=f,n(p)};return e.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"聊天黑白名单功能"}),e.jsxs("div",{className:"grid gap-4 md:gap-6",children:[e.jsxs("div",{className:"space-y-3 md:space-y-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-sm md:text-base",children:"群组名单类型"}),e.jsxs(Be,{value:l.chat.group_list_type,onValueChange:x=>n({...l,chat:{...l.chat,group_list_type:x}}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"whitelist",children:"白名单(仅名单内可聊天)"}),e.jsx(ae,{value:"blacklist",children:"黑名单(名单内禁止聊天)"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-0",children:[e.jsx(E,{className:"text-sm md:text-base",children:"群组列表"}),e.jsxs(C,{onClick:()=>i("group"),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[e.jsx(qa,{className:"mr-1 h-4 w-4"}),"添加群号"]})]}),l.chat.group_list.map((x,h)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{type:"number",value:x,onChange:f=>u("group",h,parseInt(f.target.value)||0),placeholder:"输入群号",className:"text-sm md:text-base"}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除群号 ",x," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>c("group",h),children:"删除"})]})]})]})]},h)),l.chat.group_list.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无群组"})]})]}),e.jsxs("div",{className:"space-y-3 md:space-y-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-sm md:text-base",children:"私聊名单类型"}),e.jsxs(Be,{value:l.chat.private_list_type,onValueChange:x=>n({...l,chat:{...l.chat,private_list_type:x}}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"whitelist",children:"白名单(仅名单内可聊天)"}),e.jsx(ae,{value:"blacklist",children:"黑名单(名单内禁止聊天)"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-0",children:[e.jsx(E,{className:"text-sm md:text-base",children:"私聊列表"}),e.jsxs(C,{onClick:()=>i("private"),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[e.jsx(qa,{className:"mr-1 h-4 w-4"}),"添加用户"]})]}),l.chat.private_list.map((x,h)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{type:"number",value:x,onChange:f=>u("private",h,parseInt(f.target.value)||0),placeholder:"输入QQ号",className:"text-sm md:text-base"}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要删除用户 ",x," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>c("private",h),children:"删除"})]})]})]})]},h)),l.chat.private_list.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无用户"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-0",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-sm md:text-base",children:"全局禁止名单"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"名单中的用户无法进行任何聊天"})]}),e.jsxs(C,{onClick:()=>i("ban"),size:"sm",variant:"outline",className:"w-full sm:w-auto",children:[e.jsx(qa,{className:"mr-1 h-4 w-4"}),"添加用户"]})]}),l.chat.ban_user_id.map((x,h)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{type:"number",value:x,onChange:f=>u("ban",h,parseInt(f.target.value)||0),placeholder:"输入QQ号",className:"text-sm md:text-base"}),e.jsxs(ps,{children:[e.jsx(bt,{asChild:!0,children:e.jsx(C,{size:"icon",variant:"outline",children:e.jsx(ls,{className:"h-4 w-4"})})}),e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:["确定要从全局禁止名单中删除用户 ",x," 吗?此操作无法撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>c("ban",h),children:"删除"})]})]})]})]},h)),l.chat.ban_user_id.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"暂无禁止用户"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-sm md:text-base",children:"屏蔽QQ官方机器人"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"是否屏蔽来自QQ官方机器人的消息"})]}),e.jsx(Ge,{checked:l.chat.ban_qq_bot,onCheckedChange:x=>n({...l,chat:{...l.chat,ban_qq_bot:x}})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-sm md:text-base",children:"启用戳一戳功能"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"是否响应戳一戳消息"})]}),e.jsx(Ge,{checked:l.chat.enable_poke,onCheckedChange:x=>n({...l,chat:{...l.chat,enable_poke:x}})})]})]})]})})}function TS({config:l,onChange:n}){return e.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"发送语音设置"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-sm md:text-base",children:"使用 TTS 语音"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"请确保已配置 TTS 并有对应的适配器"})]}),e.jsx(Ge,{checked:l.voice.use_tts,onCheckedChange:i=>n({...l,voice:{use_tts:i}})})]})]})})}function ES({config:l,onChange:n}){return e.jsx("div",{className:"rounded-lg border bg-card p-4 md:p-6 space-y-4 md:space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-base md:text-lg font-semibold mb-3 md:mb-4",children:"调试设置"}),e.jsx("div",{className:"grid gap-3 md:gap-4",children:e.jsxs("div",{className:"grid gap-2",children:[e.jsx(E,{className:"text-sm md:text-base",children:"日志等级"}),e.jsxs(Be,{value:l.debug.level,onValueChange:i=>n({...l,debug:{level:i}}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"DEBUG",children:"DEBUG(调试)"}),e.jsx(ae,{value:"INFO",children:"INFO(信息)"}),e.jsx(ae,{value:"WARNING",children:"WARNING(警告)"}),e.jsx(ae,{value:"ERROR",children:"ERROR(错误)"}),e.jsx(ae,{value:"CRITICAL",children:"CRITICAL(严重)"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"设置适配器的日志输出等级"})]})})]})})}const MS=["defaultChecked","defaultValue","suppressContentEditableWarning","suppressHydrationWarning","dangerouslySetInnerHTML","accessKey","className","contentEditable","contextMenu","dir","draggable","hidden","id","lang","placeholder","slot","spellCheck","style","tabIndex","title","translate","radioGroup","role","about","datatype","inlist","prefix","property","resource","typeof","vocab","autoCapitalize","autoCorrect","autoSave","color","itemProp","itemScope","itemType","itemID","itemRef","results","security","unselectable","inputMode","is","onCopy","onCopyCapture","onCut","onCutCapture","onPaste","onPasteCapture","onCompositionEnd","onCompositionEndCapture","onCompositionStart","onCompositionStartCapture","onCompositionUpdate","onCompositionUpdateCapture","onFocus","onFocusCapture","onBlur","onBlurCapture","onChange","onChangeCapture","onBeforeInput","onBeforeInputCapture","onInput","onInputCapture","onReset","onResetCapture","onSubmit","onSubmitCapture","onInvalid","onInvalidCapture","onLoad","onLoadCapture","onError","onErrorCapture","onKeyDown","onKeyDownCapture","onKeyPress","onKeyPressCapture","onKeyUp","onKeyUpCapture","onAbort","onAbortCapture","onCanPlay","onCanPlayCapture","onCanPlayThrough","onCanPlayThroughCapture","onDurationChange","onDurationChangeCapture","onEmptied","onEmptiedCapture","onEncrypted","onEncryptedCapture","onEnded","onEndedCapture","onLoadedData","onLoadedDataCapture","onLoadedMetadata","onLoadedMetadataCapture","onLoadStart","onLoadStartCapture","onPause","onPauseCapture","onPlay","onPlayCapture","onPlaying","onPlayingCapture","onProgress","onProgressCapture","onRateChange","onRateChangeCapture","onSeeked","onSeekedCapture","onSeeking","onSeekingCapture","onStalled","onStalledCapture","onSuspend","onSuspendCapture","onTimeUpdate","onTimeUpdateCapture","onVolumeChange","onVolumeChangeCapture","onWaiting","onWaitingCapture","onAuxClick","onAuxClickCapture","onClick","onClickCapture","onContextMenu","onContextMenuCapture","onDoubleClick","onDoubleClickCapture","onDrag","onDragCapture","onDragEnd","onDragEndCapture","onDragEnter","onDragEnterCapture","onDragExit","onDragExitCapture","onDragLeave","onDragLeaveCapture","onDragOver","onDragOverCapture","onDragStart","onDragStartCapture","onDrop","onDropCapture","onMouseDown","onMouseDownCapture","onMouseEnter","onMouseLeave","onMouseMove","onMouseMoveCapture","onMouseOut","onMouseOutCapture","onMouseOver","onMouseOverCapture","onMouseUp","onMouseUpCapture","onSelect","onSelectCapture","onTouchCancel","onTouchCancelCapture","onTouchEnd","onTouchEndCapture","onTouchMove","onTouchMoveCapture","onTouchStart","onTouchStartCapture","onPointerDown","onPointerDownCapture","onPointerMove","onPointerMoveCapture","onPointerUp","onPointerUpCapture","onPointerCancel","onPointerCancelCapture","onPointerEnter","onPointerEnterCapture","onPointerLeave","onPointerLeaveCapture","onPointerOver","onPointerOverCapture","onPointerOut","onPointerOutCapture","onGotPointerCapture","onGotPointerCaptureCapture","onLostPointerCapture","onLostPointerCaptureCapture","onScroll","onScrollCapture","onWheel","onWheelCapture","onAnimationStart","onAnimationStartCapture","onAnimationEnd","onAnimationEndCapture","onAnimationIteration","onAnimationIterationCapture","onTransitionEnd","onTransitionEndCapture"],AS=/^(aria-|data-)/,hv=l=>Object.fromEntries(Object.entries(l).filter(([n])=>AS.test(n)||MS.includes(n)));function zS(l,n){const i=hv(l);return Object.keys(l).some(c=>!Object.hasOwn(i,c)&&l[c]!==n[c])}class DS extends m.Component{container;plugin;componentDidMount(){this.installPlugin()}componentDidUpdate(n){if(n.uppy!==this.props.uppy)this.uninstallPlugin(n),this.installPlugin();else if(zS(this.props,n)){const{uppy:i,...c}={...this.props,target:this.container};this.plugin.setOptions(c)}}componentWillUnmount(){this.uninstallPlugin()}installPlugin(){const{uppy:n,...i}={id:"Dashboard",...this.props,inline:!0,target:this.container};n.use(f1,i),this.plugin=n.getPlugin(i.id)}uninstallPlugin(n=this.props){const{uppy:i}=n;i.removePlugin(this.plugin)}render(){return m.createElement("div",{className:"uppy-Container",ref:n=>{this.container=n},...hv(this.props)})}}function OS({src:l,alt:n="表情包",className:i,maxRetries:c=5,retryInterval:u=1500}){const[x,h]=m.useState("loading"),[f,p]=m.useState(0),[g,N]=m.useState(null),[v,b]=m.useState(l);l!==v&&(h("loading"),p(0),N(null),b(l));const w=m.useCallback(async()=>{try{const y=await fetch(l,{credentials:"include"});if(y.status===202){h("generating"),f{p(k=>k+1)},u):h("error");return}if(!y.ok){h("error");return}const R=await y.blob(),D=URL.createObjectURL(R);N(D),h("loaded")}catch(y){console.error("加载缩略图失败:",y),h("error")}},[l,f,c,u]);return m.useEffect(()=>{w()},[w]),m.useEffect(()=>()=>{g&&URL.revokeObjectURL(g)},[g]),x==="loading"||x==="generating"?e.jsx(Js,{className:B("w-full h-full",i)}):x==="error"||!g?e.jsx("div",{className:B("w-full h-full flex items-center justify-center bg-muted",i),children:e.jsx(bj,{className:"h-8 w-8 text-muted-foreground"})}):e.jsx("img",{src:g,alt:n,className:B("w-full h-full object-contain",i)})}function RS({children:l,className:n}){return e.jsx(Im,{content:l,className:n})}const Ia="/api/webui/emoji";async function LS(l){const n=new URLSearchParams;l.page&&n.append("page",l.page.toString()),l.page_size&&n.append("page_size",l.page_size.toString()),l.search&&n.append("search",l.search),l.is_registered!==void 0&&n.append("is_registered",l.is_registered.toString()),l.is_banned!==void 0&&n.append("is_banned",l.is_banned.toString()),l.format&&n.append("format",l.format),l.sort_by&&n.append("sort_by",l.sort_by),l.sort_order&&n.append("sort_order",l.sort_order);const i=await we(`${Ia}/list?${n}`,{});if(!i.ok)throw new Error(`获取表情包列表失败: ${i.statusText}`);return i.json()}async function US(l){const n=await we(`${Ia}/${l}`,{});if(!n.ok)throw new Error(`获取表情包详情失败: ${n.statusText}`);return n.json()}async function BS(l,n){const i=await we(`${Ia}/${l}`,{method:"PATCH",body:JSON.stringify(n)});if(!i.ok)throw new Error(`更新表情包失败: ${i.statusText}`);return i.json()}async function $S(l){const n=await we(`${Ia}/${l}`,{method:"DELETE"});if(!n.ok)throw new Error(`删除表情包失败: ${n.statusText}`);return n.json()}async function IS(){const l=await we(`${Ia}/stats/summary`,{});if(!l.ok)throw new Error(`获取统计数据失败: ${l.statusText}`);return l.json()}async function PS(l){const n=await we(`${Ia}/${l}/register`,{method:"POST"});if(!n.ok)throw new Error(`注册表情包失败: ${n.statusText}`);return n.json()}async function HS(l){const n=await we(`${Ia}/${l}/ban`,{method:"POST"});if(!n.ok)throw new Error(`封禁表情包失败: ${n.statusText}`);return n.json()}function GS(l,n=!1){return n?`${Ia}/${l}/thumbnail?original=true`:`${Ia}/${l}/thumbnail`}function FS(l){return`${Ia}/${l}/thumbnail?original=true`}async function qS(l){const n=await we(`${Ia}/batch/delete`,{method:"POST",body:JSON.stringify({emoji_ids:l})});if(!n.ok){const i=await n.json();throw new Error(i.detail||"批量删除失败")}return n.json()}function VS(){return`${Ia}/upload`}function KS(){const[l,n]=m.useState([]),[i,c]=m.useState(null),[u,x]=m.useState(!1),[h,f]=m.useState(1),[p,g]=m.useState(0),[N,v]=m.useState(20),[b,w]=m.useState("all"),[y,R]=m.useState("all"),[D,k]=m.useState("all"),[I,M]=m.useState("usage_count"),[S,T]=m.useState("desc"),[$,A]=m.useState(null),[Q,G]=m.useState(!1),[de,oe]=m.useState(!1),[ve,le]=m.useState(!1),[fe,ge]=m.useState(new Set),[z,V]=m.useState(!1),[U,L]=m.useState(""),[P,_e]=m.useState("medium"),[je,Se]=m.useState(!1),{toast:Y}=Ws(),be=m.useCallback(async()=>{try{x(!0);const me=await LS({page:h,page_size:N,is_registered:b==="all"?void 0:b==="registered",is_banned:y==="all"?void 0:y==="banned",format:D==="all"?void 0:D,sort_by:I,sort_order:S});n(me.data),g(me.total)}catch(me){const ze=me instanceof Error?me.message:"加载表情包列表失败";Y({title:"错误",description:ze,variant:"destructive"})}finally{x(!1)}},[h,N,b,y,D,I,S,Y]),Z=async()=>{try{const me=await IS();c(me.data)}catch(me){console.error("加载统计数据失败:",me)}};m.useEffect(()=>{be()},[be]),m.useEffect(()=>{Z()},[]);const xe=async me=>{try{const ze=await US(me.id);A(ze.data),G(!0)}catch(ze){const rs=ze instanceof Error?ze.message:"加载详情失败";Y({title:"错误",description:rs,variant:"destructive"})}},Me=me=>{A(me),oe(!0)},J=me=>{A(me),le(!0)},ce=async()=>{if($)try{await $S($.id),Y({title:"成功",description:"表情包已删除"}),le(!1),A(null),be(),Z()}catch(me){const ze=me instanceof Error?me.message:"删除失败";Y({title:"错误",description:ze,variant:"destructive"})}},Fe=async me=>{try{await PS(me.id),Y({title:"成功",description:"表情包已注册"}),be(),Z()}catch(ze){const rs=ze instanceof Error?ze.message:"注册失败";Y({title:"错误",description:rs,variant:"destructive"})}},q=async me=>{try{await HS(me.id),Y({title:"成功",description:"表情包已封禁"}),be(),Z()}catch(ze){const rs=ze instanceof Error?ze.message:"封禁失败";Y({title:"错误",description:rs,variant:"destructive"})}},ee=me=>{const ze=new Set(fe);ze.has(me)?ze.delete(me):ze.add(me),ge(ze)},ke=async()=>{try{const me=await qS(Array.from(fe));Y({title:"批量删除完成",description:me.message}),ge(new Set),V(!1),be(),Z()}catch(me){Y({title:"批量删除失败",description:me instanceof Error?me.message:"批量删除失败",variant:"destructive"})}},Te=()=>{const me=parseInt(U),ze=Math.ceil(p/N);me>=1&&me<=ze?(f(me),L("")):Y({title:"无效的页码",description:`请输入1-${ze}之间的页码`,variant:"destructive"})},Oe=i?.formats?Object.keys(i.formats):[];return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsxs("div",{className:"mb-4 sm:mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"表情包管理"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"管理麦麦的表情包资源"})]}),e.jsxs(C,{onClick:()=>Se(!0),className:"gap-2",children:[e.jsx(Gi,{className:"h-4 w-4"}),"上传表情包"]})]}),e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[i&&e.jsxs("div",{className:"grid gap-4 grid-cols-2 lg:grid-cols-4",children:[e.jsx(De,{children:e.jsxs(Xe,{className:"pb-2",children:[e.jsx(Is,{children:"总数"}),e.jsx(We,{className:"text-2xl",children:i.total})]})}),e.jsx(De,{children:e.jsxs(Xe,{className:"pb-2",children:[e.jsx(Is,{children:"已注册"}),e.jsx(We,{className:"text-2xl text-green-600",children:i.registered})]})}),e.jsx(De,{children:e.jsxs(Xe,{className:"pb-2",children:[e.jsx(Is,{children:"已封禁"}),e.jsx(We,{className:"text-2xl text-red-600",children:i.banned})]})}),e.jsx(De,{children:e.jsxs(Xe,{className:"pb-2",children:[e.jsx(Is,{children:"未注册"}),e.jsx(We,{className:"text-2xl text-gray-600",children:i.unregistered})]})})]}),e.jsxs(De,{children:[e.jsx(Xe,{children:e.jsxs(We,{className:"flex items-center gap-2",children:[e.jsx(yo,{className:"h-5 w-5"}),"筛选和排序"]})}),e.jsxs(Qe,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"排序方式"}),e.jsxs(Be,{value:`${I}-${S}`,onValueChange:me=>{const[ze,rs]=me.split("-");M(ze),T(rs),f(1)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"usage_count-desc",children:"使用次数 (多→少)"}),e.jsx(ae,{value:"usage_count-asc",children:"使用次数 (少→多)"}),e.jsx(ae,{value:"register_time-desc",children:"注册时间 (新→旧)"}),e.jsx(ae,{value:"register_time-asc",children:"注册时间 (旧→新)"}),e.jsx(ae,{value:"record_time-desc",children:"记录时间 (新→旧)"}),e.jsx(ae,{value:"record_time-asc",children:"记录时间 (旧→新)"}),e.jsx(ae,{value:"last_used_time-desc",children:"最后使用 (新→旧)"}),e.jsx(ae,{value:"last_used_time-asc",children:"最后使用 (旧→新)"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"注册状态"}),e.jsxs(Be,{value:b,onValueChange:me=>{w(me),f(1)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部"}),e.jsx(ae,{value:"registered",children:"已注册"}),e.jsx(ae,{value:"unregistered",children:"未注册"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"封禁状态"}),e.jsxs(Be,{value:y,onValueChange:me=>{R(me),f(1)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部"}),e.jsx(ae,{value:"banned",children:"已封禁"}),e.jsx(ae,{value:"unbanned",children:"未封禁"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"格式"}),e.jsxs(Be,{value:D,onValueChange:me=>{k(me),f(1)},children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部"}),Oe.map(me=>e.jsxs(ae,{value:me,children:[me.toUpperCase()," (",i?.formats[me],")"]},me))]})]})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[fe.size>0&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["已选择 ",fe.size," 个表情包"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{className:"text-sm whitespace-nowrap",children:"卡片大小"}),e.jsxs(Be,{value:P,onValueChange:me=>_e(me),children:[e.jsx(Le,{className:"w-24",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"small",children:"小"}),e.jsx(ae,{value:"medium",children:"中"}),e.jsx(ae,{value:"large",children:"大"})]})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{htmlFor:"emoji-page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),e.jsxs(Be,{value:N.toString(),onValueChange:me=>{v(parseInt(me)),f(1),ge(new Set)},children:[e.jsx(Le,{id:"emoji-page-size",className:"w-20",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"20",children:"20"}),e.jsx(ae,{value:"40",children:"40"}),e.jsx(ae,{value:"60",children:"60"}),e.jsx(ae,{value:"100",children:"100"})]})]}),fe.size>0&&e.jsxs(e.Fragment,{children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>ge(new Set),children:"取消选择"}),e.jsxs(C,{variant:"destructive",size:"sm",onClick:()=>V(!0),children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]})]}),e.jsx("div",{className:"flex justify-end pt-4 border-t",children:e.jsxs(C,{variant:"outline",size:"sm",onClick:be,disabled:u,children:[e.jsx(kt,{className:`h-4 w-4 mr-2 ${u?"animate-spin":""}`}),"刷新"]})})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"表情包列表"}),e.jsxs(Is,{children:["共 ",p," 个表情包,当前第 ",h," 页"]})]}),e.jsxs(Qe,{children:[l.length===0?e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:"暂无数据"}):e.jsx("div",{className:`grid gap-3 ${P==="small"?"grid-cols-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10":P==="medium"?"grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8":"grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"}`,children:l.map(me=>e.jsxs("div",{className:`group relative rounded-lg border bg-card overflow-hidden hover:ring-2 hover:ring-primary transition-all cursor-pointer ${fe.has(me.id)?"ring-2 ring-primary bg-primary/5":""}`,onClick:()=>ee(me.id),children:[e.jsx("div",{className:`absolute top-1 left-1 z-10 transition-opacity ${fe.has(me.id)?"opacity-100":"opacity-0 group-hover:opacity-100"}`,children:e.jsx("div",{className:`w-5 h-5 rounded-full border-2 flex items-center justify-center ${fe.has(me.id)?"bg-primary border-primary text-primary-foreground":"bg-background/80 border-muted-foreground/50"}`,children:fe.has(me.id)&&e.jsx(ea,{className:"h-3 w-3"})})}),e.jsxs("div",{className:"absolute top-1 right-1 z-10 flex flex-col gap-0.5",children:[me.is_registered&&e.jsx(Ae,{variant:"default",className:"bg-green-600 text-[10px] px-1 py-0",children:"已注册"}),me.is_banned&&e.jsx(Ae,{variant:"destructive",className:"text-[10px] px-1 py-0",children:"已封禁"})]}),e.jsx("div",{className:`aspect-square bg-muted flex items-center justify-center overflow-hidden ${P==="small"?"p-1":P==="medium"?"p-2":"p-3"}`,children:e.jsx(OS,{src:GS(me.id),alt:"表情包"})}),e.jsxs("div",{className:`border-t bg-card ${P==="small"?"p-1":"p-2"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1 text-xs text-muted-foreground mb-1",children:[e.jsx(Ae,{variant:"outline",className:"text-[10px] px-1 py-0",children:me.format.toUpperCase()}),e.jsxs("span",{className:"font-mono",children:[me.usage_count,"次"]})]}),e.jsxs("div",{className:`flex gap-1 justify-center opacity-0 group-hover:opacity-100 transition-opacity ${P==="small"?"flex-wrap":""}`,children:[e.jsx(C,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:ze=>{ze.stopPropagation(),Me(me)},title:"编辑",children:e.jsx(Un,{className:"h-3 w-3"})}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:ze=>{ze.stopPropagation(),xe(me)},title:"详情",children:e.jsx(qt,{className:"h-3 w-3"})}),!me.is_registered&&e.jsx(C,{variant:"ghost",size:"icon",className:"h-6 w-6 text-green-600 hover:text-green-700",onClick:ze=>{ze.stopPropagation(),Fe(me)},title:"注册",children:e.jsx(ea,{className:"h-3 w-3"})}),!me.is_banned&&e.jsx(C,{variant:"ghost",size:"icon",className:"h-6 w-6 text-orange-600 hover:text-orange-700",onClick:ze=>{ze.stopPropagation(),q(me)},title:"封禁",children:e.jsx(Pw,{className:"h-3 w-3"})}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-6 w-6 text-red-600 hover:text-red-700",onClick:ze=>{ze.stopPropagation(),J(me)},title:"删除",children:e.jsx(ls,{className:"h-3 w-3"})})]})]})]},me.id))}),p>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[e.jsxs("div",{className:"text-sm text-muted-foreground",children:["显示 ",(h-1)*N+1," 到"," ",Math.min(h*N,p)," 条,共 ",p," 条"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(1),disabled:h===1,className:"hidden sm:flex",children:e.jsx(Ur,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(me=>Math.max(1,me-1)),disabled:h===1,children:[e.jsx(ll,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"number",value:U,onChange:me=>L(me.target.value),onKeyDown:me=>me.key==="Enter"&&Te(),placeholder:h.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(p/N)}),e.jsx(C,{variant:"outline",size:"sm",onClick:Te,disabled:!U,className:"h-8",children:"跳转"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(me=>me+1),disabled:h>=Math.ceil(p/N),children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(Math.ceil(p/N)),disabled:h>=Math.ceil(p/N),className:"hidden sm:flex",children:e.jsx(Br,{className:"h-4 w-4"})})]})]})]})]}),e.jsx(QS,{emoji:$,open:Q,onOpenChange:G}),e.jsx(YS,{emoji:$,open:de,onOpenChange:oe,onSuccess:()=>{be(),Z()}}),e.jsx(JS,{open:je,onOpenChange:Se,onSuccess:()=>{be(),Z()}})]})}),e.jsx(ps,{open:z,onOpenChange:V,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认批量删除"}),e.jsxs(xs,{children:["你确定要删除选中的 ",fe.size," 个表情包吗?此操作不可撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:ke,children:"确认删除"})]})]})}),e.jsx(Ks,{open:ve,onOpenChange:le,children:e.jsxs(Ps,{children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"确认删除"}),e.jsx(ot,{children:"确定要删除这个表情包吗?此操作无法撤销。"})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>le(!1),children:"取消"}),e.jsx(C,{variant:"destructive",onClick:ce,children:"删除"})]})]})})]})}function QS({emoji:l,open:n,onOpenChange:i}){if(!l)return null;const c=u=>u?new Date(u*1e3).toLocaleString("zh-CN"):"-";return e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[90vh]",children:[e.jsx(Hs,{children:e.jsx(Gs,{children:"表情包详情"})}),e.jsx(es,{className:"max-h-[calc(90vh-8rem)] pr-4",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex justify-center",children:e.jsx("div",{className:"w-32 h-32 bg-muted rounded-lg flex items-center justify-center overflow-hidden",children:e.jsx("img",{src:FS(l.id),alt:l.description||"表情包",className:"w-full h-full object-cover",onError:u=>{const x=u.target;x.style.display="none";const h=x.parentElement;h&&(h.innerHTML='')}})})}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"ID"}),e.jsx("div",{className:"mt-1 font-mono",children:l.id})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"格式"}),e.jsx("div",{className:"mt-1",children:e.jsx(Ae,{variant:"outline",children:l.format.toUpperCase()})})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"文件路径"}),e.jsx("div",{className:"mt-1 font-mono text-sm break-all bg-muted p-2 rounded",children:l.full_path})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"哈希值"}),e.jsx("div",{className:"mt-1 font-mono text-sm break-all bg-muted p-2 rounded",children:l.emoji_hash})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"描述"}),l.description?e.jsx("div",{className:"mt-1 rounded-lg border bg-muted/50 p-3",children:e.jsx(RS,{className:"prose-sm",children:l.description})}):e.jsx("div",{className:"mt-1 text-sm text-muted-foreground",children:"-"})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"情绪"}),e.jsx("div",{className:"mt-1",children:l.emotion?e.jsx("span",{className:"text-sm",children:l.emotion}):e.jsx("span",{className:"text-sm text-muted-foreground",children:"-"})})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"状态"}),e.jsxs("div",{className:"mt-2 flex gap-2",children:[l.is_registered&&e.jsx(Ae,{variant:"default",className:"bg-green-600",children:"已注册"}),l.is_banned&&e.jsx(Ae,{variant:"destructive",children:"已封禁"}),!l.is_registered&&!l.is_banned&&e.jsx(Ae,{variant:"outline",children:"未注册"})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"使用次数"}),e.jsx("div",{className:"mt-1 font-mono text-lg",children:l.usage_count})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"记录时间"}),e.jsx("div",{className:"mt-1 text-sm",children:c(l.record_time)})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"注册时间"}),e.jsx("div",{className:"mt-1 text-sm",children:c(l.register_time)})]})]}),e.jsxs("div",{children:[e.jsx(E,{className:"text-muted-foreground",children:"最后使用"}),e.jsx("div",{className:"mt-1 text-sm",children:c(l.last_used_time)})]})]})})]})})}function YS({emoji:l,open:n,onOpenChange:i,onSuccess:c}){const[u,x]=m.useState(""),[h,f]=m.useState(!1),[p,g]=m.useState(!1),[N,v]=m.useState(!1),{toast:b}=Ws();m.useEffect(()=>{l&&(x(l.emotion||""),f(l.is_registered),g(l.is_banned))},[l]);const w=async()=>{if(l)try{v(!0);const y=u.split(/[,,]/).map(R=>R.trim()).filter(Boolean).join(",");await BS(l.id,{emotion:y||void 0,is_registered:h,is_banned:p}),b({title:"成功",description:"表情包信息已更新"}),i(!1),c()}catch(y){const R=y instanceof Error?y.message:"保存失败";b({title:"错误",description:R,variant:"destructive"})}finally{v(!1)}};return l?e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"编辑表情包"}),e.jsx(ot,{children:"修改表情包的情绪和状态信息"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(E,{children:"情绪"}),e.jsx(et,{value:u,onChange:y=>x(y.target.value),placeholder:"输入情绪描述...",rows:2,className:"mt-1"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"输入情绪相关的文本描述"})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"is_registered",checked:h,onCheckedChange:y=>{y===!0?(f(!0),g(!1)):f(!1)}}),e.jsx(E,{htmlFor:"is_registered",className:"cursor-pointer",children:"已注册"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"is_banned",checked:p,onCheckedChange:y=>{y===!0?(g(!0),f(!1)):g(!1)}}),e.jsx(E,{htmlFor:"is_banned",className:"cursor-pointer",children:"已封禁"})]})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>i(!1),children:"取消"}),e.jsx(C,{onClick:w,disabled:N,children:N?"保存中...":"保存"})]})]})}):null}function JS({open:l,onOpenChange:n,onSuccess:i}){const[c,u]=m.useState("select"),[x,h]=m.useState([]),[f,p]=m.useState(null),[g,N]=m.useState(!1),{toast:v}=Ws(),b=m.useMemo(()=>new p1({id:"emoji-uploader",autoProceed:!1,restrictions:{maxFileSize:10485760,allowedFileTypes:["image/jpeg","image/png","image/gif","image/webp"],maxNumberOfFiles:20},locale:{pluralize:()=>0,strings:{addMoreFiles:"添加更多文件",addingMoreFiles:"正在添加更多文件",allowedFileTypes:"允许的文件类型:%{types}",cancel:"取消",closeModal:"关闭",complete:"完成",connectedToInternet:"已连接到互联网",copyLink:"复制链接",copyLinkToClipboardFallback:"复制下方链接",copyLinkToClipboardSuccess:"链接已复制到剪贴板",dashboardTitle:"选择文件",dashboardWindowTitle:"文件选择窗口(按 ESC 关闭)",done:"完成",dropHereOr:"拖放文件到这里或 %{browse}",dropHint:"将文件拖放到此处",dropPasteFiles:"将文件拖放到这里或 %{browseFiles}",dropPasteFolders:"将文件拖放到这里或 %{browseFolders}",dropPasteBoth:"将文件拖放到这里,%{browseFiles} 或 %{browseFolders}",dropPasteImportFiles:"将文件拖放到这里,%{browseFiles} 或从以下位置导入:",dropPasteImportFolders:"将文件拖放到这里,%{browseFolders} 或从以下位置导入:",dropPasteImportBoth:"将文件拖放到这里,%{browseFiles},%{browseFolders} 或从以下位置导入:",editFile:"编辑文件",editing:"正在编辑 %{file}",emptyFolderAdded:"未从空文件夹添加文件",exceedsSize:"%{file} 超过了最大允许大小 %{size}",failedToUpload:"上传 %{file} 失败",fileSource:"文件来源:%{name}",filesUploadedOfTotal:{0:"已上传 %{complete} / %{smart_count} 个文件",1:"已上传 %{complete} / %{smart_count} 个文件"},filter:"筛选",finishEditingFile:"完成编辑文件",folderAdded:{0:"已从 %{folder} 添加 %{smart_count} 个文件",1:"已从 %{folder} 添加 %{smart_count} 个文件"},generatingThumbnails:"正在生成缩略图...",import:"导入",importFiles:"从以下位置导入文件:",importFrom:"从 %{name} 导入",loading:"加载中...",logOut:"登出",myDevice:"我的设备",noFilesFound:"这里没有文件或文件夹",noInternetConnection:"无网络连接",openFolderNamed:"打开文件夹 %{name}",pause:"暂停",pauseUpload:"暂停上传",paused:"已暂停",poweredBy:"技术支持:%{uppy}",processingXFiles:{0:"正在处理 %{smart_count} 个文件",1:"正在处理 %{smart_count} 个文件"},recording:"录制中",removeFile:"移除文件",resetFilter:"重置筛选",resume:"继续",resumeUpload:"继续上传",retry:"重试",retryUpload:"重试上传",save:"保存",saveChanges:"保存更改",selectFileNamed:"选择文件 %{name}",selectX:{0:"选择 %{smart_count}",1:"选择 %{smart_count}"},smile:"笑一个!",startRecording:"开始录制视频",stopRecording:"停止录制视频",takePicture:"拍照",timedOut:"上传已停滞 %{seconds} 秒,正在中止。",upload:"下一步",uploadComplete:"上传完成",uploadFailed:"上传失败",uploadPaused:"上传已暂停",uploadXFiles:{0:"下一步(%{smart_count} 个文件)",1:"下一步(%{smart_count} 个文件)"},uploadXNewFiles:{0:"下一步(+%{smart_count} 个文件)",1:"下一步(+%{smart_count} 个文件)"},uploading:"正在上传",uploadingXFiles:{0:"正在上传 %{smart_count} 个文件",1:"正在上传 %{smart_count} 个文件"},xFilesSelected:{0:"已选择 %{smart_count} 个文件",1:"已选择 %{smart_count} 个文件"},xMoreFilesAdded:{0:"又添加了 %{smart_count} 个文件",1:"又添加了 %{smart_count} 个文件"},xTimeLeft:"剩余 %{time}",youCanOnlyUploadFileTypes:"您只能上传:%{types}",youCanOnlyUploadX:{0:"您只能上传 %{smart_count} 个文件",1:"您只能上传 %{smart_count} 个文件"},youHaveToAtLeastSelectX:{0:"您至少需要选择 %{smart_count} 个文件",1:"您至少需要选择 %{smart_count} 个文件"},browseFiles:"浏览文件",browseFolders:"浏览文件夹",cancelUpload:"取消上传",addMore:"添加更多",back:"返回",editFileWithFilename:"编辑文件 %{file}"}}}),[]);m.useEffect(()=>{const $=()=>{const A=b.getFiles();if(A.length===0)return;const Q=A.map(G=>({id:G.id,name:G.name,previewUrl:G.preview||URL.createObjectURL(G.data),emotion:"",description:"",isRegistered:!0,file:G.data}));h(Q),A.length===1?(p(Q[0].id),u("edit-single")):u("edit-multiple")};return b.on("upload",$),()=>{b.off("upload",$)}},[b]),m.useEffect(()=>{l||(b.cancelAll(),u("select"),h([]),p(null),N(!1))},[l,b]);const w=m.useCallback(($,A)=>{h(Q=>Q.map(G=>G.id===$?{...G,...A}:G))},[]),y=m.useCallback($=>$.emotion.trim().length>0,[]),R=m.useMemo(()=>x.length>0&&x.every(y),[x,y]),D=m.useMemo(()=>x.find($=>$.id===f)||null,[x,f]),k=m.useCallback(()=>{(c==="edit-single"||c==="edit-multiple")&&(u("select"),h([]),p(null))},[c]),I=m.useCallback(async()=>{if(!R){v({title:"请填写必填项",description:"每个表情包的情感标签都是必填的",variant:"destructive"});return}N(!0);let $=0,A=0;try{for(const Q of x){const G=new FormData;G.append("file",Q.file),G.append("emotion",Q.emotion),G.append("description",Q.description),G.append("is_registered",Q.isRegistered.toString());try{(await we(VS(),{method:"POST",body:G})).ok?$++:A++}catch{A++}}A===0?(v({title:"上传成功",description:`成功上传 ${$} 个表情包`}),n(!1),i()):(v({title:"部分上传失败",description:`成功 ${$} 个,失败 ${A} 个`,variant:"destructive"}),i())}finally{N(!1)}},[R,x,v,n,i]),M=()=>e.jsx("div",{className:"space-y-4",children:e.jsx("div",{className:"border rounded-lg overflow-hidden w-full",children:e.jsx(DS,{uppy:b,proudlyDisplayPoweredByUppy:!1,hideProgressDetails:!0,height:350,width:"100%",theme:"auto",note:"支持 JPG、PNG、GIF、WebP 格式,最多 20 个文件"})})}),S=()=>{const $=x[0];return $?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(C,{variant:"ghost",size:"sm",onClick:k,children:[e.jsx(Va,{className:"h-4 w-4 mr-1"}),"返回"]}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"编辑表情包信息"})]}),e.jsxs("div",{className:"flex gap-6",children:[e.jsxs("div",{className:"flex-shrink-0",children:[e.jsx("div",{className:"w-32 h-32 rounded-lg border overflow-hidden bg-muted flex items-center justify-center",children:e.jsx("img",{src:$.previewUrl,alt:$.name,className:"max-w-full max-h-full object-contain"})}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2 text-center truncate max-w-32",children:$.name})]}),e.jsxs("div",{className:"flex-1 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"single-emotion",children:["情感标签 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(ie,{id:"single-emotion",value:$.emotion,onChange:A=>w($.id,{emotion:A.target.value}),placeholder:"多个标签用逗号分隔,如:开心,高兴",className:$.emotion.trim()?"":"border-destructive"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"用于情感匹配,多个标签用逗号分隔"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"single-description",children:"描述"}),e.jsx(ie,{id:"single-description",value:$.description,onChange:A=>w($.id,{description:A.target.value}),placeholder:"输入表情包描述..."})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"single-is-registered",checked:$.isRegistered,onCheckedChange:A=>w($.id,{isRegistered:A===!0})}),e.jsx(E,{htmlFor:"single-is-registered",className:"cursor-pointer",children:"上传后立即注册(可被麦麦使用)"})]})]})]}),e.jsx(xt,{children:e.jsx(C,{onClick:I,disabled:!R||g,children:g?"上传中...":"上传"})})]}):null},T=()=>{const $=x.filter(y).length,A=x.length;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(C,{variant:"ghost",size:"sm",onClick:k,children:[e.jsx(Va,{className:"h-4 w-4 mr-1"}),"返回"]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["编辑表情包信息(",$,"/",A," 已完成)"]})]}),e.jsx(Ae,{variant:R?"default":"secondary",children:R?e.jsxs(e.Fragment,{children:[e.jsx(St,{className:"h-3 w-3 mr-1"}),"全部完成"]}):e.jsxs(e.Fragment,{children:[e.jsx(_a,{className:"h-3 w-3 mr-1"}),"未完成"]})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsx(es,{className:"h-[350px] pr-2",children:e.jsx("div",{className:"space-y-2",children:x.map(Q=>{const G=y(Q),de=f===Q.id;return e.jsxs("div",{onClick:()=>p(Q.id),className:` + flex items-center gap-3 p-3 rounded-lg border-2 cursor-pointer transition-all + ${de?"ring-2 ring-primary":""} + ${G?"border-green-500 bg-green-50 dark:bg-green-950/20":"border-border hover:border-muted-foreground/50"} + `,children:[e.jsx("div",{className:"w-12 h-12 rounded border overflow-hidden bg-muted flex-shrink-0 flex items-center justify-center",children:e.jsx("img",{src:Q.previewUrl,alt:Q.name,className:"max-w-full max-h-full object-contain"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium truncate",children:Q.name}),e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:Q.emotion||"未填写情感标签"})]}),G?e.jsx(ea,{className:"h-5 w-5 text-green-500 flex-shrink-0"}):e.jsx("div",{className:"h-5 w-5 rounded-full border-2 border-muted-foreground/30 flex-shrink-0"})]},Q.id)})})}),e.jsx("div",{className:"border rounded-lg p-4",children:D?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-16 h-16 rounded border overflow-hidden bg-muted flex items-center justify-center",children:e.jsx("img",{src:D.previewUrl,alt:D.name,className:"max-w-full max-h-full object-contain"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-medium truncate",children:D.name}),y(D)&&e.jsxs(Ae,{variant:"outline",className:"text-green-600 border-green-600",children:[e.jsx(St,{className:"h-3 w-3 mr-1"}),"已完成"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"multi-emotion",children:["情感标签 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(ie,{id:"multi-emotion",value:D.emotion,onChange:Q=>w(D.id,{emotion:Q.target.value}),placeholder:"多个标签用逗号分隔,如:开心,高兴",className:D.emotion.trim()?"":"border-destructive"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"multi-description",children:"描述"}),e.jsx(ie,{id:"multi-description",value:D.description,onChange:Q=>w(D.id,{description:Q.target.value}),placeholder:"输入表情包描述..."})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"multi-is-registered",checked:D.isRegistered,onCheckedChange:Q=>w(D.id,{isRegistered:Q===!0})}),e.jsx(E,{htmlFor:"multi-is-registered",className:"cursor-pointer text-sm",children:"上传后立即注册"})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center text-muted-foreground",children:e.jsxs("div",{className:"text-center",children:[e.jsx(bj,{className:"h-12 w-12 mx-auto mb-2 opacity-50"}),e.jsx("p",{children:"点击左侧卡片编辑"})]})})})]}),e.jsx(xt,{children:e.jsx(C,{onClick:I,disabled:!R||g,children:g?"上传中...":`上传全部 (${A})`})})]})};return e.jsx(Ks,{open:l,onOpenChange:n,children:e.jsxs(Ps,{className:"max-w-3xl max-h-[90vh] overflow-hidden",children:[e.jsxs(Hs,{children:[e.jsxs(Gs,{className:"flex items-center gap-2",children:[e.jsx(Gi,{className:"h-5 w-5"}),c==="select"&&"上传表情包 - 选择文件",c==="edit-single"&&"上传表情包 - 填写信息",c==="edit-multiple"&&"上传表情包 - 批量编辑"]}),e.jsxs(ot,{children:[c==="select"&&"支持 JPG、PNG、GIF、WebP 格式,单个文件最大 10MB,可同时上传多个文件",c==="edit-single"&&"请填写表情包的情感标签(必填)和描述",c==="edit-multiple"&&"点击左侧卡片编辑每个表情包的信息,情感标签为必填项"]})]}),e.jsxs("div",{className:"overflow-y-auto pr-1",children:[c==="select"&&M(),c==="edit-single"&&S(),c==="edit-multiple"&&T()]})]})})}const mn="/api/webui/expression";async function XS(){const l=await we(`${mn}/chats`,{});if(!l.ok){const n=await l.json();throw new Error(n.detail||"获取聊天列表失败")}return l.json()}async function ZS(l){const n=new URLSearchParams;l.page&&n.append("page",l.page.toString()),l.page_size&&n.append("page_size",l.page_size.toString()),l.search&&n.append("search",l.search),l.chat_id&&n.append("chat_id",l.chat_id);const i=await we(`${mn}/list?${n}`,{});if(!i.ok){const c=await i.json();throw new Error(c.detail||"获取表达方式列表失败")}return i.json()}async function WS(l){const n=await we(`${mn}/${l}`,{});if(!n.ok){const i=await n.json();throw new Error(i.detail||"获取表达方式详情失败")}return n.json()}async function e4(l){const n=await we(`${mn}/`,{method:"POST",body:JSON.stringify(l)});if(!n.ok){const i=await n.json();throw new Error(i.detail||"创建表达方式失败")}return n.json()}async function s4(l,n){const i=await we(`${mn}/${l}`,{method:"PATCH",body:JSON.stringify(n)});if(!i.ok){const c=await i.json();throw new Error(c.detail||"更新表达方式失败")}return i.json()}async function t4(l){const n=await we(`${mn}/${l}`,{method:"DELETE"});if(!n.ok){const i=await n.json();throw new Error(i.detail||"删除表达方式失败")}return n.json()}async function a4(l){const n=await we(`${mn}/batch/delete`,{method:"POST",body:JSON.stringify({ids:l})});if(!n.ok){const i=await n.json();throw new Error(i.detail||"批量删除表达方式失败")}return n.json()}async function l4(){const l=await we(`${mn}/stats/summary`,{});if(!l.ok){const n=await l.json();throw new Error(n.detail||"获取统计数据失败")}return l.json()}function n4(){const[l,n]=m.useState([]),[i,c]=m.useState(!0),[u,x]=m.useState(0),[h,f]=m.useState(1),[p,g]=m.useState(20),[N,v]=m.useState(""),[b,w]=m.useState(null),[y,R]=m.useState(!1),[D,k]=m.useState(!1),[I,M]=m.useState(!1),[S,T]=m.useState(null),[$,A]=m.useState(new Set),[Q,G]=m.useState(!1),[de,oe]=m.useState(""),[ve,le]=m.useState({total:0,recent_7days:0,chat_count:0,top_chats:{}}),[fe,ge]=m.useState([]),[z,V]=m.useState(new Map),{toast:U}=Ws(),L=async()=>{try{c(!0);const ce=await ZS({page:h,page_size:p,search:N||void 0});n(ce.data),x(ce.total)}catch(ce){U({title:"加载失败",description:ce instanceof Error?ce.message:"无法加载表达方式",variant:"destructive"})}finally{c(!1)}},P=async()=>{try{const ce=await l4();ce?.data&&le(ce.data)}catch(ce){console.error("加载统计数据失败:",ce)}},_e=async()=>{try{const ce=await XS();if(ce?.data){ge(ce.data);const Fe=new Map;ce.data.forEach(q=>{Fe.set(q.chat_id,q.chat_name)}),V(Fe)}}catch(ce){console.error("加载聊天列表失败:",ce)}},je=ce=>z.get(ce)||ce;m.useEffect(()=>{L(),P(),_e()},[h,p,N]);const Se=async ce=>{try{const Fe=await WS(ce.id);w(Fe.data),R(!0)}catch(Fe){U({title:"加载详情失败",description:Fe instanceof Error?Fe.message:"无法加载表达方式详情",variant:"destructive"})}},Y=ce=>{w(ce),k(!0)},be=async ce=>{try{await t4(ce.id),U({title:"删除成功",description:`已删除表达方式: ${ce.situation}`}),T(null),L(),P()}catch(Fe){U({title:"删除失败",description:Fe instanceof Error?Fe.message:"无法删除表达方式",variant:"destructive"})}},Z=ce=>{const Fe=new Set($);Fe.has(ce)?Fe.delete(ce):Fe.add(ce),A(Fe)},xe=()=>{$.size===l.length&&l.length>0?A(new Set):A(new Set(l.map(ce=>ce.id)))},Me=async()=>{try{await a4(Array.from($)),U({title:"批量删除成功",description:`已删除 ${$.size} 个表达方式`}),A(new Set),G(!1),L(),P()}catch(ce){U({title:"批量删除失败",description:ce instanceof Error?ce.message:"无法批量删除表达方式",variant:"destructive"})}},J=()=>{const ce=parseInt(de),Fe=Math.ceil(u/p);ce>=1&&ce<=Fe?(f(ce),oe("")):U({title:"无效的页码",description:`请输入1-${Fe}之间的页码`,variant:"destructive"})};return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsx("div",{className:"mb-4 sm:mb-6",children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(on,{className:"h-8 w-8",strokeWidth:2}),"表达方式管理"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"管理麦麦的表达方式和话术模板"})]}),e.jsxs(C,{onClick:()=>M(!0),className:"gap-2",children:[e.jsx(it,{className:"h-4 w-4"}),"新增表达方式"]})]})}),e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"总数量"}),e.jsx("div",{className:"text-2xl font-bold mt-1",children:ve.total})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"近7天新增"}),e.jsx("div",{className:"text-2xl font-bold mt-1 text-green-600",children:ve.recent_7days})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"关联聊天数"}),e.jsx("div",{className:"text-2xl font-bold mt-1 text-blue-600",children:ve.chat_count})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx(E,{htmlFor:"search",children:"搜索"}),e.jsx("div",{className:"flex flex-col sm:flex-row gap-2 mt-1.5",children:e.jsxs("div",{className:"flex-1 relative",children:[e.jsx(Vt,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{id:"search",placeholder:"搜索情境、风格或上下文...",value:N,onChange:ce=>v(ce.target.value),className:"pl-9"})]})}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mt-4 pt-4 border-t",children:[e.jsx("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:$.size>0&&e.jsxs("span",{children:["已选择 ",$.size," 个表达方式"]})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{htmlFor:"page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),e.jsxs(Be,{value:p.toString(),onValueChange:ce=>{g(parseInt(ce)),f(1),A(new Set)},children:[e.jsx(Le,{id:"page-size",className:"w-20",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"10",children:"10"}),e.jsx(ae,{value:"20",children:"20"}),e.jsx(ae,{value:"50",children:"50"}),e.jsx(ae,{value:"100",children:"100"})]})]}),$.size>0&&e.jsxs(e.Fragment,{children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>A(new Set),children:"取消选择"}),e.jsxs(C,{variant:"destructive",size:"sm",onClick:()=>G(!0),children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsx("div",{className:"hidden md:block",children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{className:"w-12",children:e.jsx(Xs,{checked:$.size===l.length&&l.length>0,onCheckedChange:xe})}),e.jsx(Je,{children:"情境"}),e.jsx(Je,{children:"风格"}),e.jsx(Je,{children:"聊天"}),e.jsx(Je,{className:"text-right",children:"操作"})]})}),e.jsx(Al,{children:i?e.jsx(ct,{children:e.jsx(He,{colSpan:5,className:"text-center py-8 text-muted-foreground",children:"加载中..."})}):l.length===0?e.jsx(ct,{children:e.jsx(He,{colSpan:5,className:"text-center py-8 text-muted-foreground",children:"暂无数据"})}):l.map(ce=>e.jsxs(ct,{children:[e.jsx(He,{children:e.jsx(Xs,{checked:$.has(ce.id),onCheckedChange:()=>Z(ce.id)})}),e.jsx(He,{className:"font-medium max-w-xs truncate",children:ce.situation}),e.jsx(He,{className:"max-w-xs truncate",children:ce.style}),e.jsx(He,{className:"max-w-[200px] truncate",title:je(ce.chat_id),style:{wordBreak:"keep-all"},children:e.jsx("span",{className:"whitespace-nowrap overflow-hidden text-ellipsis block",children:je(ce.chat_id)})}),e.jsx(He,{className:"text-right",children:e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsxs(C,{variant:"default",size:"sm",onClick:()=>Y(ce),children:[e.jsx(Un,{className:"h-4 w-4 mr-1"}),"编辑"]}),e.jsx(C,{variant:"outline",size:"icon",className:"h-8 w-8",onClick:()=>Se(ce),title:"查看详情",children:e.jsx(sa,{className:"h-4 w-4"})}),e.jsxs(C,{size:"sm",onClick:()=>T(ce),className:"bg-red-600 hover:bg-red-700 text-white",children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"删除"]})]})})]},ce.id))})]})}),e.jsx("div",{className:"md:hidden space-y-3 p-4",children:i?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):l.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"暂无数据"}):l.map(ce=>e.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3 overflow-hidden",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Xs,{checked:$.has(ce.id),onCheckedChange:()=>Z(ce.id),className:"mt-1"}),e.jsxs("div",{className:"min-w-0 flex-1 overflow-hidden space-y-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"情境"}),e.jsx("h3",{className:"font-semibold text-sm line-clamp-2 w-full break-all",title:ce.situation,children:ce.situation})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"风格"}),e.jsx("p",{className:"text-sm line-clamp-2 w-full break-all",title:ce.style,children:ce.style})]})]})]}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"聊天"}),e.jsx("p",{className:"text-sm truncate",title:je(ce.chat_id),style:{wordBreak:"keep-all"},children:je(ce.chat_id)})]}),e.jsxs("div",{className:"flex flex-wrap gap-1 pt-2 border-t overflow-hidden",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>Y(ce),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[e.jsx(Un,{className:"h-3 w-3 mr-1"}),"编辑"]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>Se(ce),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:e.jsx(sa,{className:"h-3 w-3"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>T(ce),className:"text-xs px-2 py-1 h-auto flex-shrink-0 text-destructive hover:text-destructive",children:[e.jsx(ls,{className:"h-3 w-3 mr-1"}),"删除"]})]})]},ce.id))}),u>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 px-4 py-3 border-t",children:[e.jsxs("div",{className:"text-sm text-muted-foreground",children:["共 ",u," 条记录,第 ",h," / ",Math.ceil(u/p)," 页"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(1),disabled:h===1,className:"hidden sm:flex",children:e.jsx(Ur,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(h-1),disabled:h===1,children:[e.jsx(ll,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"number",value:de,onChange:ce=>oe(ce.target.value),onKeyDown:ce=>ce.key==="Enter"&&J(),placeholder:h.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(u/p)}),e.jsx(C,{variant:"outline",size:"sm",onClick:J,disabled:!de,className:"h-8",children:"跳转"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(h+1),disabled:h>=Math.ceil(u/p),children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(Math.ceil(u/p)),disabled:h>=Math.ceil(u/p),className:"hidden sm:flex",children:e.jsx(Br,{className:"h-4 w-4"})})]})]})]})]})}),e.jsx(r4,{expression:b,open:y,onOpenChange:R,chatNameMap:z}),e.jsx(i4,{open:I,onOpenChange:M,chatList:fe,onSuccess:()=>{L(),P(),M(!1)}}),e.jsx(c4,{expression:b,open:D,onOpenChange:k,chatList:fe,onSuccess:()=>{L(),P(),k(!1)}}),e.jsx(ps,{open:!!S,onOpenChange:()=>T(null),children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除表达方式 "',S?.situation,'" 吗? 此操作不可撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>S&&be(S),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"删除"})]})]})}),e.jsx(o4,{open:Q,onOpenChange:G,onConfirm:Me,count:$.size})]})}function r4({expression:l,open:n,onOpenChange:i,chatNameMap:c}){if(!l)return null;const u=h=>h?new Date(h*1e3).toLocaleString("zh-CN"):"-",x=h=>c.get(h)||h;return e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"表达方式详情"}),e.jsx(ot,{children:"查看表达方式的完整信息"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsx(Oi,{label:"情境",value:l.situation}),e.jsx(Oi,{label:"风格",value:l.style}),e.jsx(Oi,{label:"聊天",value:x(l.chat_id)}),e.jsx(Oi,{icon:Or,label:"记录ID",value:l.id.toString(),mono:!0})]}),e.jsx("div",{className:"grid grid-cols-2 gap-4",children:e.jsx(Oi,{icon:kl,label:"创建时间",value:u(l.create_date)})})]}),e.jsx(xt,{children:e.jsx(C,{onClick:()=>i(!1),children:"关闭"})})]})})}function Oi({icon:l,label:n,value:i,mono:c=!1}){return e.jsxs("div",{className:"space-y-1",children:[e.jsxs(E,{className:"text-xs text-muted-foreground flex items-center gap-1",children:[l&&e.jsx(l,{className:"h-3 w-3"}),n]}),e.jsx("div",{className:B("text-sm",c&&"font-mono",!i&&"text-muted-foreground"),children:i||"-"})]})}function i4({open:l,onOpenChange:n,chatList:i,onSuccess:c}){const[u,x]=m.useState({situation:"",style:"",chat_id:""}),[h,f]=m.useState(!1),{toast:p}=Ws(),g=async()=>{if(!u.situation||!u.style||!u.chat_id){p({title:"验证失败",description:"请填写必填字段:情境、风格和聊天",variant:"destructive"});return}try{f(!0),await e4(u),p({title:"创建成功",description:"表达方式已创建"}),x({situation:"",style:"",chat_id:""}),c()}catch(N){p({title:"创建失败",description:N instanceof Error?N.message:"无法创建表达方式",variant:"destructive"})}finally{f(!1)}};return e.jsx(Ks,{open:l,onOpenChange:n,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"新增表达方式"}),e.jsx(ot,{children:"创建新的表达方式记录"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"situation",children:["情境 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(ie,{id:"situation",value:u.situation,onChange:N=>x({...u,situation:N.target.value}),placeholder:"描述使用场景"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"style",children:["风格 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(ie,{id:"style",value:u.style,onChange:N=>x({...u,style:N.target.value}),placeholder:"描述表达风格"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"chat_id",children:["聊天 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsxs(Be,{value:u.chat_id,onValueChange:N=>x({...u,chat_id:N}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择关联的聊天"})}),e.jsx(Ue,{children:i.map(N=>e.jsx(ae,{value:N.chat_id,children:e.jsxs("span",{className:"truncate",style:{wordBreak:"keep-all"},children:[N.chat_name,N.is_group&&e.jsx("span",{className:"text-muted-foreground ml-1",children:"(群聊)"})]})},N.chat_id))})]})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>n(!1),children:"取消"}),e.jsx(C,{onClick:g,disabled:h,children:h?"创建中...":"创建"})]})]})})}function c4({expression:l,open:n,onOpenChange:i,chatList:c,onSuccess:u}){const[x,h]=m.useState({}),[f,p]=m.useState(!1),{toast:g}=Ws();m.useEffect(()=>{l&&h({situation:l.situation,style:l.style,chat_id:l.chat_id})},[l]);const N=async()=>{if(l)try{p(!0),await s4(l.id,x),g({title:"保存成功",description:"表达方式已更新"}),u()}catch(v){g({title:"保存失败",description:v instanceof Error?v.message:"无法更新表达方式",variant:"destructive"})}finally{p(!1)}};return l?e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"编辑表达方式"}),e.jsx(ot,{children:"修改表达方式的信息"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit_situation",children:"情境"}),e.jsx(ie,{id:"edit_situation",value:x.situation||"",onChange:v=>h({...x,situation:v.target.value}),placeholder:"描述使用场景"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit_style",children:"风格"}),e.jsx(ie,{id:"edit_style",value:x.style||"",onChange:v=>h({...x,style:v.target.value}),placeholder:"描述表达风格"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit_chat_id",children:"聊天"}),e.jsxs(Be,{value:x.chat_id||"",onValueChange:v=>h({...x,chat_id:v}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择关联的聊天"})}),e.jsx(Ue,{children:c.map(v=>e.jsx(ae,{value:v.chat_id,children:e.jsxs("span",{className:"truncate",style:{wordBreak:"keep-all"},children:[v.chat_name,v.is_group&&e.jsx("span",{className:"text-muted-foreground ml-1",children:"(群聊)"})]})},v.chat_id))})]})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>i(!1),children:"取消"}),e.jsx(C,{onClick:N,disabled:f,children:f?"保存中...":"保存"})]})]})}):null}function o4({open:l,onOpenChange:n,onConfirm:i,count:c}){return e.jsx(ps,{open:l,onOpenChange:n,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认批量删除"}),e.jsxs(xs,{children:["您即将删除 ",c," 个表达方式,此操作无法撤销。确定要继续吗?"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:i,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认删除"})]})]})})}const zl="/api/webui/jargon";async function d4(){const l=await we(`${zl}/chats`,{});if(!l.ok){const n=await l.json();throw new Error(n.detail||"获取聊天列表失败")}return l.json()}async function u4(l){const n=new URLSearchParams;l.page&&n.append("page",l.page.toString()),l.page_size&&n.append("page_size",l.page_size.toString()),l.search&&n.append("search",l.search),l.chat_id&&n.append("chat_id",l.chat_id),l.is_jargon!==void 0&&l.is_jargon!==null&&n.append("is_jargon",l.is_jargon.toString()),l.is_global!==void 0&&n.append("is_global",l.is_global.toString());const i=await we(`${zl}/list?${n}`,{});if(!i.ok){const c=await i.json();throw new Error(c.detail||"获取黑话列表失败")}return i.json()}async function m4(l){const n=await we(`${zl}/${l}`,{});if(!n.ok){const i=await n.json();throw new Error(i.detail||"获取黑话详情失败")}return n.json()}async function x4(l){const n=await we(`${zl}/`,{method:"POST",body:JSON.stringify(l)});if(!n.ok){const i=await n.json();throw new Error(i.detail||"创建黑话失败")}return n.json()}async function h4(l,n){const i=await we(`${zl}/${l}`,{method:"PATCH",body:JSON.stringify(n)});if(!i.ok){const c=await i.json();throw new Error(c.detail||"更新黑话失败")}return i.json()}async function f4(l){const n=await we(`${zl}/${l}`,{method:"DELETE"});if(!n.ok){const i=await n.json();throw new Error(i.detail||"删除黑话失败")}return n.json()}async function p4(l){const n=await we(`${zl}/batch/delete`,{method:"POST",body:JSON.stringify({ids:l})});if(!n.ok){const i=await n.json();throw new Error(i.detail||"批量删除黑话失败")}return n.json()}async function g4(){const l=await we(`${zl}/stats/summary`,{});if(!l.ok){const n=await l.json();throw new Error(n.detail||"获取黑话统计失败")}return l.json()}async function j4(l,n){const i=new URLSearchParams;l.forEach(u=>i.append("ids",u.toString())),i.append("is_jargon",n.toString());const c=await we(`${zl}/batch/set-jargon?${i}`,{method:"POST"});if(!c.ok){const u=await c.json();throw new Error(u.detail||"批量设置黑话状态失败")}return c.json()}function v4(){const[l,n]=m.useState([]),[i,c]=m.useState(!0),[u,x]=m.useState(0),[h,f]=m.useState(1),[p,g]=m.useState(20),[N,v]=m.useState(""),[b,w]=m.useState("all"),[y,R]=m.useState("all"),[D,k]=m.useState(null),[I,M]=m.useState(!1),[S,T]=m.useState(!1),[$,A]=m.useState(!1),[Q,G]=m.useState(null),[de,oe]=m.useState(new Set),[ve,le]=m.useState(!1),[fe,ge]=m.useState(""),[z,V]=m.useState({total:0,confirmed_jargon:0,confirmed_not_jargon:0,pending:0,global_count:0,complete_count:0,chat_count:0,top_chats:{}}),[U,L]=m.useState([]),{toast:P}=Ws(),_e=async()=>{try{c(!0);const ee=await u4({page:h,page_size:p,search:N||void 0,chat_id:b==="all"?void 0:b,is_jargon:y==="all"?void 0:y==="true"?!0:y==="false"?!1:void 0});n(ee.data),x(ee.total)}catch(ee){P({title:"加载失败",description:ee instanceof Error?ee.message:"无法加载黑话列表",variant:"destructive"})}finally{c(!1)}},je=async()=>{try{const ee=await g4();ee?.data&&V(ee.data)}catch(ee){console.error("加载统计数据失败:",ee)}},Se=async()=>{try{const ee=await d4();ee?.data&&L(ee.data)}catch(ee){console.error("加载聊天列表失败:",ee)}};m.useEffect(()=>{_e(),je(),Se()},[h,p,N,b,y]);const Y=async ee=>{try{const ke=await m4(ee.id);k(ke.data),M(!0)}catch(ke){P({title:"加载详情失败",description:ke instanceof Error?ke.message:"无法加载黑话详情",variant:"destructive"})}},be=ee=>{k(ee),T(!0)},Z=async ee=>{try{await f4(ee.id),P({title:"删除成功",description:`已删除黑话: ${ee.content}`}),G(null),_e(),je()}catch(ke){P({title:"删除失败",description:ke instanceof Error?ke.message:"无法删除黑话",variant:"destructive"})}},xe=ee=>{const ke=new Set(de);ke.has(ee)?ke.delete(ee):ke.add(ee),oe(ke)},Me=()=>{de.size===l.length&&l.length>0?oe(new Set):oe(new Set(l.map(ee=>ee.id)))},J=async()=>{try{await p4(Array.from(de)),P({title:"批量删除成功",description:`已删除 ${de.size} 个黑话`}),oe(new Set),le(!1),_e(),je()}catch(ee){P({title:"批量删除失败",description:ee instanceof Error?ee.message:"无法批量删除黑话",variant:"destructive"})}},ce=async ee=>{try{await j4(Array.from(de),ee),P({title:"操作成功",description:`已将 ${de.size} 个词条设为${ee?"黑话":"非黑话"}`}),oe(new Set),_e(),je()}catch(ke){P({title:"操作失败",description:ke instanceof Error?ke.message:"批量设置失败",variant:"destructive"})}},Fe=()=>{const ee=parseInt(fe),ke=Math.ceil(u/p);ee>=1&&ee<=ke?(f(ee),ge("")):P({title:"无效的页码",description:`请输入1-${ke}之间的页码`,variant:"destructive"})},q=ee=>ee===!0?e.jsxs(Ae,{variant:"default",className:"bg-green-600 hover:bg-green-700",children:[e.jsx(St,{className:"h-3 w-3 mr-1"}),"是黑话"]}):ee===!1?e.jsxs(Ae,{variant:"secondary",children:[e.jsx(_a,{className:"h-3 w-3 mr-1"}),"非黑话"]}):e.jsxs(Ae,{variant:"outline",children:[e.jsx(pj,{className:"h-3 w-3 mr-1"}),"未判定"]});return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsx("div",{className:"mb-4 sm:mb-6",children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(Hw,{className:"h-8 w-8",strokeWidth:2}),"黑话管理"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"管理麦麦学习到的黑话和俚语"})]}),e.jsxs(C,{onClick:()=>A(!0),className:"gap-2",children:[e.jsx(it,{className:"h-4 w-4"}),"新增黑话"]})]})}),e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-7 gap-3",children:[e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"总数量"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1",children:z.total})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"已确认黑话"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1 text-green-600",children:z.confirmed_jargon})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"确认非黑话"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1 text-gray-500",children:z.confirmed_not_jargon})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"待判定"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1 text-yellow-600",children:z.pending})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"全局黑话"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1 text-blue-600",children:z.global_count})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"推断完成"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1 text-purple-600",children:z.complete_count})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-3 sm:p-4",children:[e.jsx("div",{className:"text-xs sm:text-sm text-muted-foreground",children:"关联聊天数"}),e.jsx("div",{className:"text-xl sm:text-2xl font-bold mt-1",children:z.chat_count})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(E,{htmlFor:"search",children:"搜索"}),e.jsxs("div",{className:"relative",children:[e.jsx(Vt,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{id:"search",placeholder:"搜索内容、含义...",value:N,onChange:ee=>v(ee.target.value),className:"pl-9"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(E,{children:"聊天筛选"}),e.jsxs(Be,{value:b,onValueChange:w,children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"全部聊天"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部聊天"}),U.map(ee=>e.jsx(ae,{value:ee.chat_id,children:ee.chat_name},ee.chat_id))]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(E,{children:"状态筛选"}),e.jsxs(Be,{value:y,onValueChange:R,children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"全部状态"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部状态"}),e.jsx(ae,{value:"true",children:"是黑话"}),e.jsx(ae,{value:"false",children:"非黑话"})]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(E,{htmlFor:"page-size",children:"每页显示"}),e.jsxs(Be,{value:p.toString(),onValueChange:ee=>{g(parseInt(ee)),f(1),oe(new Set)},children:[e.jsx(Le,{id:"page-size",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"10",children:"10"}),e.jsx(ae,{value:"20",children:"20"}),e.jsx(ae,{value:"50",children:"50"}),e.jsx(ae,{value:"100",children:"100"})]})]})]})]}),de.size>0&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 mt-4 pt-4 border-t",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:["已选择 ",de.size," 个"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>ce(!0),children:[e.jsx(St,{className:"h-4 w-4 mr-1"}),"标记为黑话"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>ce(!1),children:[e.jsx(_a,{className:"h-4 w-4 mr-1"}),"标记为非黑话"]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>oe(new Set),children:"取消选择"}),e.jsxs(C,{variant:"destructive",size:"sm",onClick:()=>le(!0),children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsx("div",{className:"hidden md:block",children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{className:"w-12",children:e.jsx(Xs,{checked:de.size===l.length&&l.length>0,onCheckedChange:Me})}),e.jsx(Je,{children:"内容"}),e.jsx(Je,{children:"含义"}),e.jsx(Je,{children:"聊天"}),e.jsx(Je,{children:"状态"}),e.jsx(Je,{className:"text-center",children:"次数"}),e.jsx(Je,{className:"text-right",children:"操作"})]})}),e.jsx(Al,{children:i?e.jsx(ct,{children:e.jsx(He,{colSpan:7,className:"text-center py-8 text-muted-foreground",children:"加载中..."})}):l.length===0?e.jsx(ct,{children:e.jsx(He,{colSpan:7,className:"text-center py-8 text-muted-foreground",children:"暂无数据"})}):l.map(ee=>e.jsxs(ct,{children:[e.jsx(He,{children:e.jsx(Xs,{checked:de.has(ee.id),onCheckedChange:()=>xe(ee.id)})}),e.jsx(He,{className:"font-medium max-w-[200px]",children:e.jsxs("div",{className:"flex items-center gap-2",children:[ee.is_global&&e.jsx("span",{title:"全局黑话",children:e.jsx(Co,{className:"h-4 w-4 text-blue-500 flex-shrink-0"})}),e.jsx("span",{className:"truncate",title:ee.content,children:ee.content})]})}),e.jsx(He,{className:"max-w-[200px] truncate",title:ee.meaning||"",children:ee.meaning||e.jsx("span",{className:"text-muted-foreground",children:"-"})}),e.jsx(He,{className:"max-w-[150px] truncate",title:ee.chat_name||ee.chat_id,children:ee.chat_name||ee.chat_id}),e.jsx(He,{children:q(ee.is_jargon)}),e.jsx(He,{className:"text-center",children:ee.count}),e.jsx(He,{className:"text-right",children:e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsxs(C,{variant:"default",size:"sm",onClick:()=>be(ee),children:[e.jsx(Un,{className:"h-4 w-4 mr-1"}),"编辑"]}),e.jsx(C,{variant:"outline",size:"icon",className:"h-8 w-8",onClick:()=>Y(ee),title:"查看详情",children:e.jsx(sa,{className:"h-4 w-4"})}),e.jsxs(C,{size:"sm",onClick:()=>G(ee),className:"bg-red-600 hover:bg-red-700 text-white",children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"删除"]})]})})]},ee.id))})]})}),e.jsx("div",{className:"md:hidden space-y-3 p-4",children:i?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):l.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"暂无数据"}):l.map(ee=>e.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Xs,{checked:de.has(ee.id),onCheckedChange:()=>xe(ee.id),className:"mt-1"}),e.jsxs("div",{className:"min-w-0 flex-1 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[ee.is_global&&e.jsx(Co,{className:"h-4 w-4 text-blue-500 flex-shrink-0"}),e.jsx("h3",{className:"font-semibold text-sm break-all",children:ee.content})]}),ee.meaning&&e.jsx("p",{className:"text-sm text-muted-foreground break-all",children:ee.meaning}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs",children:[q(ee.is_jargon),e.jsxs("span",{className:"text-muted-foreground",children:["次数: ",ee.count]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground truncate",children:["聊天: ",ee.chat_name||ee.chat_id]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-1 pt-2 border-t",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>be(ee),className:"text-xs px-2 py-1 h-auto",children:[e.jsx(Un,{className:"h-3 w-3 mr-1"}),"编辑"]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>Y(ee),className:"text-xs px-2 py-1 h-auto",children:e.jsx(sa,{className:"h-3 w-3"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>G(ee),className:"text-xs px-2 py-1 h-auto text-destructive hover:text-destructive",children:[e.jsx(ls,{className:"h-3 w-3 mr-1"}),"删除"]})]})]},ee.id))}),u>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 px-4 py-3 border-t",children:[e.jsxs("div",{className:"text-sm text-muted-foreground",children:["共 ",u," 条记录,第 ",h," / ",Math.ceil(u/p)," 页"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(1),disabled:h===1,className:"hidden sm:flex",children:e.jsx(Ur,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(h-1),disabled:h===1,children:[e.jsx(ll,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"number",value:fe,onChange:ee=>ge(ee.target.value),onKeyDown:ee=>ee.key==="Enter"&&Fe(),placeholder:h.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(u/p)}),e.jsx(C,{variant:"outline",size:"sm",onClick:Fe,disabled:!fe,className:"h-8",children:"跳转"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(h+1),disabled:h>=Math.ceil(u/p),children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(Math.ceil(u/p)),disabled:h>=Math.ceil(u/p),className:"hidden sm:flex",children:e.jsx(Br,{className:"h-4 w-4"})})]})]})]})]})}),e.jsx(N4,{jargon:D,open:I,onOpenChange:M}),e.jsx(b4,{open:$,onOpenChange:A,chatList:U,onSuccess:()=>{_e(),je(),A(!1)}}),e.jsx(y4,{jargon:D,open:S,onOpenChange:T,chatList:U,onSuccess:()=>{_e(),je(),T(!1)}}),e.jsx(ps,{open:!!Q,onOpenChange:()=>G(null),children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除黑话 "',Q?.content,'" 吗?此操作不可撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>Q&&Z(Q),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"删除"})]})]})}),e.jsx(ps,{open:ve,onOpenChange:le,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认批量删除"}),e.jsxs(xs,{children:["您即将删除 ",de.size," 个黑话,此操作无法撤销。确定要继续吗?"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:J,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认删除"})]})]})})]})}function N4({jargon:l,open:n,onOpenChange:i}){return l?e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] grid grid-rows-[auto_1fr_auto] overflow-hidden",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"黑话详情"}),e.jsx(ot,{children:"查看黑话的完整信息"})]}),e.jsx(es,{className:"h-full pr-4",children:e.jsxs("div",{className:"space-y-4 pb-2",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsx(Sm,{icon:Or,label:"记录ID",value:l.id.toString(),mono:!0}),e.jsx(Sm,{label:"使用次数",value:l.count.toString()})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"内容"}),e.jsx("div",{className:"text-sm p-2 bg-muted rounded break-all whitespace-pre-wrap",children:l.content})]}),l.raw_content&&e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"原始内容"}),e.jsx("div",{className:"text-sm p-2 bg-muted rounded break-all",children:(()=>{try{const c=JSON.parse(l.raw_content);return Array.isArray(c)?c.map((u,x)=>e.jsxs("div",{children:[x>0&&e.jsx("hr",{className:"my-3 border-border"}),e.jsx("div",{className:"whitespace-pre-wrap",children:u})]},x)):e.jsx("div",{className:"whitespace-pre-wrap",children:l.raw_content})}catch{return e.jsx("div",{className:"whitespace-pre-wrap",children:l.raw_content})}})()})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"含义"}),e.jsx("div",{className:"text-sm p-2 bg-muted rounded break-all",children:l.meaning?e.jsx(Im,{content:l.meaning}):"-"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsx(Sm,{label:"聊天",value:l.chat_name||l.chat_id}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"状态"}),e.jsxs("div",{className:"flex items-center gap-2",children:[l.is_jargon===!0&&e.jsx(Ae,{variant:"default",className:"bg-green-600",children:"是黑话"}),l.is_jargon===!1&&e.jsx(Ae,{variant:"secondary",children:"非黑话"}),l.is_jargon===null&&e.jsx(Ae,{variant:"outline",children:"未判定"}),l.is_global&&e.jsx(Ae,{variant:"outline",className:"border-blue-500 text-blue-500",children:"全局"}),l.is_complete&&e.jsx(Ae,{variant:"outline",className:"border-purple-500 text-purple-500",children:"推断完成"})]})]})]}),l.inference_with_context&&e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"上下文推断结果"}),e.jsx("div",{className:"p-2 bg-muted rounded break-all whitespace-pre-wrap font-mono text-xs max-h-[200px] overflow-y-auto",children:l.inference_with_context})]}),l.inference_content_only&&e.jsxs("div",{className:"space-y-1",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"纯词条推断结果"}),e.jsx("div",{className:"p-2 bg-muted rounded break-all whitespace-pre-wrap font-mono text-xs max-h-[200px] overflow-y-auto",children:l.inference_content_only})]})]})}),e.jsx(xt,{className:"flex-shrink-0",children:e.jsx(C,{onClick:()=>i(!1),children:"关闭"})})]})}):null}function Sm({icon:l,label:n,value:i,mono:c=!1}){return e.jsxs("div",{className:"space-y-1",children:[e.jsxs(E,{className:"text-xs text-muted-foreground flex items-center gap-1",children:[l&&e.jsx(l,{className:"h-3 w-3"}),n]}),e.jsx("div",{className:B("text-sm",c&&"font-mono",!i&&"text-muted-foreground"),children:i||"-"})]})}function b4({open:l,onOpenChange:n,chatList:i,onSuccess:c}){const[u,x]=m.useState({content:"",meaning:"",chat_id:"",is_global:!1}),[h,f]=m.useState(!1),{toast:p}=Ws(),g=async()=>{if(!u.content||!u.chat_id){p({title:"验证失败",description:"请填写必填字段:内容和聊天",variant:"destructive"});return}try{f(!0),await x4(u),p({title:"创建成功",description:"黑话已创建"}),x({content:"",meaning:"",chat_id:"",is_global:!1}),c()}catch(N){p({title:"创建失败",description:N instanceof Error?N.message:"无法创建黑话",variant:"destructive"})}finally{f(!1)}};return e.jsx(Ks,{open:l,onOpenChange:n,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"新增黑话"}),e.jsx(ot,{children:"创建新的黑话记录"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"content",children:["内容 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(ie,{id:"content",value:u.content,onChange:N=>x({...u,content:N.target.value}),placeholder:"输入黑话内容"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"meaning",children:"含义"}),e.jsx(et,{id:"meaning",value:u.meaning||"",onChange:N=>x({...u,meaning:N.target.value}),placeholder:"输入黑话含义(可选)",rows:3})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{htmlFor:"chat_id",children:["聊天 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsxs(Be,{value:u.chat_id,onValueChange:N=>x({...u,chat_id:N}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择关联的聊天"})}),e.jsx(Ue,{children:i.map(N=>e.jsx(ae,{value:N.chat_id,children:N.chat_name},N.chat_id))})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"is_global",checked:u.is_global,onCheckedChange:N=>x({...u,is_global:N})}),e.jsx(E,{htmlFor:"is_global",children:"设为全局黑话"})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>n(!1),children:"取消"}),e.jsx(C,{onClick:g,disabled:h,children:h?"创建中...":"创建"})]})]})})}function y4({jargon:l,open:n,onOpenChange:i,chatList:c,onSuccess:u}){const[x,h]=m.useState({}),[f,p]=m.useState(!1),{toast:g}=Ws();m.useEffect(()=>{l&&h({content:l.content,meaning:l.meaning||"",chat_id:l.stream_id||l.chat_id,is_global:l.is_global,is_jargon:l.is_jargon})},[l]);const N=async()=>{if(l)try{p(!0),await h4(l.id,x),g({title:"保存成功",description:"黑话已更新"}),u()}catch(v){g({title:"保存失败",description:v instanceof Error?v.message:"无法更新黑话",variant:"destructive"})}finally{p(!1)}};return l?e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"编辑黑话"}),e.jsx(ot,{children:"修改黑话的信息"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit_content",children:"内容"}),e.jsx(ie,{id:"edit_content",value:x.content||"",onChange:v=>h({...x,content:v.target.value}),placeholder:"输入黑话内容"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit_meaning",children:"含义"}),e.jsx(et,{id:"edit_meaning",value:x.meaning||"",onChange:v=>h({...x,meaning:v.target.value}),placeholder:"输入黑话含义",rows:3})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit_chat_id",children:"聊天"}),e.jsxs(Be,{value:x.chat_id||"",onValueChange:v=>h({...x,chat_id:v}),children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择关联的聊天"})}),e.jsx(Ue,{children:c.map(v=>e.jsx(ae,{value:v.chat_id,children:v.chat_name},v.chat_id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"黑话状态"}),e.jsxs(Be,{value:x.is_jargon===null?"null":x.is_jargon?.toString()||"null",onValueChange:v=>h({...x,is_jargon:v==="null"?null:v==="true"}),children:[e.jsx(Le,{children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"null",children:"未判定"}),e.jsx(ae,{value:"true",children:"是黑话"}),e.jsx(ae,{value:"false",children:"非黑话"})]})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"edit_is_global",checked:x.is_global,onCheckedChange:v=>h({...x,is_global:v})}),e.jsx(E,{htmlFor:"edit_is_global",children:"全局黑话"})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>i(!1),children:"取消"}),e.jsx(C,{onClick:N,disabled:f,children:f?"保存中...":"保存"})]})]})}):null}const Pr="/api/webui/person";async function w4(l){const n=new URLSearchParams;l.page&&n.append("page",l.page.toString()),l.page_size&&n.append("page_size",l.page_size.toString()),l.search&&n.append("search",l.search),l.is_known!==void 0&&n.append("is_known",l.is_known.toString()),l.platform&&n.append("platform",l.platform);const i=await we(`${Pr}/list?${n}`,{headers:Us()});if(!i.ok){const c=await i.json();throw new Error(c.detail||"获取人物列表失败")}return i.json()}async function _4(l){const n=await we(`${Pr}/${l}`,{headers:Us()});if(!n.ok){const i=await n.json();throw new Error(i.detail||"获取人物详情失败")}return n.json()}async function S4(l,n){const i=await we(`${Pr}/${l}`,{method:"PATCH",headers:Us(),body:JSON.stringify(n)});if(!i.ok){const c=await i.json();throw new Error(c.detail||"更新人物信息失败")}return i.json()}async function k4(l){const n=await we(`${Pr}/${l}`,{method:"DELETE",headers:Us()});if(!n.ok){const i=await n.json();throw new Error(i.detail||"删除人物信息失败")}return n.json()}async function C4(){const l=await we(`${Pr}/stats/summary`,{headers:Us()});if(!l.ok){const n=await l.json();throw new Error(n.detail||"获取统计数据失败")}return l.json()}async function T4(l){const n=await we(`${Pr}/batch/delete`,{method:"POST",headers:Us(),body:JSON.stringify({person_ids:l})});if(!n.ok){const i=await n.json();throw new Error(i.detail||"批量删除失败")}return n.json()}function E4(){const[l,n]=m.useState([]),[i,c]=m.useState(!0),[u,x]=m.useState(0),[h,f]=m.useState(1),[p,g]=m.useState(20),[N,v]=m.useState(""),[b,w]=m.useState(void 0),[y,R]=m.useState(void 0),[D,k]=m.useState(null),[I,M]=m.useState(!1),[S,T]=m.useState(!1),[$,A]=m.useState(null),[Q,G]=m.useState({total:0,known:0,unknown:0,platforms:{}}),[de,oe]=m.useState(new Set),[ve,le]=m.useState(!1),[fe,ge]=m.useState(""),{toast:z}=Ws(),V=async()=>{try{c(!0);const J=await w4({page:h,page_size:p,search:N||void 0,is_known:b,platform:y});n(J.data),x(J.total)}catch(J){z({title:"加载失败",description:J instanceof Error?J.message:"无法加载人物信息",variant:"destructive"})}finally{c(!1)}},U=async()=>{try{const J=await C4();J?.data&&G(J.data)}catch(J){console.error("加载统计数据失败:",J)}};m.useEffect(()=>{V(),U()},[h,p,N,b,y]);const L=async J=>{try{const ce=await _4(J.person_id);k(ce.data),M(!0)}catch(ce){z({title:"加载详情失败",description:ce instanceof Error?ce.message:"无法加载人物详情",variant:"destructive"})}},P=J=>{k(J),T(!0)},_e=async J=>{try{await k4(J.person_id),z({title:"删除成功",description:`已删除人物信息: ${J.person_name||J.nickname||J.user_id}`}),A(null),V(),U()}catch(ce){z({title:"删除失败",description:ce instanceof Error?ce.message:"无法删除人物信息",variant:"destructive"})}},je=m.useMemo(()=>Object.keys(Q.platforms),[Q.platforms]),Se=J=>{const ce=new Set(de);ce.has(J)?ce.delete(J):ce.add(J),oe(ce)},Y=()=>{de.size===l.length&&l.length>0?oe(new Set):oe(new Set(l.map(J=>J.person_id)))},be=()=>{if(de.size===0){z({title:"未选择任何人物",description:"请先选择要删除的人物",variant:"destructive"});return}le(!0)},Z=async()=>{try{const J=await T4(Array.from(de));z({title:"批量删除完成",description:J.message}),oe(new Set),le(!1),V(),U()}catch(J){z({title:"批量删除失败",description:J instanceof Error?J.message:"批量删除失败",variant:"destructive"})}},xe=()=>{const J=parseInt(fe),ce=Math.ceil(u/p);J>=1&&J<=ce?(f(J),ge("")):z({title:"无效的页码",description:`请输入1-${ce}之间的页码`,variant:"destructive"})},Me=J=>J?new Date(J*1e3).toLocaleString("zh-CN"):"-";return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsx("div",{className:"mb-4 sm:mb-6",children:e.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(Tm,{className:"h-8 w-8",strokeWidth:2}),"人物信息管理"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"管理麦麦认识的所有人物信息"})]})})}),e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"总人数"}),e.jsx("div",{className:"text-2xl font-bold mt-1",children:Q.total})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"已认识"}),e.jsx("div",{className:"text-2xl font-bold mt-1 text-green-600",children:Q.known})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"未认识"}),e.jsx("div",{className:"text-2xl font-bold mt-1 text-muted-foreground",children:Q.unknown})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"sm:col-span-2",children:[e.jsx(E,{htmlFor:"search",children:"搜索"}),e.jsxs("div",{className:"relative mt-1.5",children:[e.jsx(Vt,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{id:"search",placeholder:"搜索名称、昵称或用户ID...",value:N,onChange:J=>v(J.target.value),className:"pl-9"})]})]}),e.jsxs("div",{children:[e.jsx(E,{htmlFor:"filter-known",children:"认识状态"}),e.jsxs(Be,{value:b===void 0?"all":b.toString(),onValueChange:J=>{w(J==="all"?void 0:J==="true"),f(1)},children:[e.jsx(Le,{id:"filter-known",className:"mt-1.5",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部"}),e.jsx(ae,{value:"true",children:"已认识"}),e.jsx(ae,{value:"false",children:"未认识"})]})]})]}),e.jsxs("div",{children:[e.jsx(E,{htmlFor:"filter-platform",children:"平台"}),e.jsxs(Be,{value:y||"all",onValueChange:J=>{R(J==="all"?void 0:J),f(1)},children:[e.jsx(Le,{id:"filter-platform",className:"mt-1.5",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部平台"}),je.map(J=>e.jsxs(ae,{value:J,children:[J," (",Q.platforms[J],")"]},J))]})]})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mt-4 pt-4 border-t",children:[e.jsx("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:de.size>0&&e.jsxs("span",{children:["已选择 ",de.size," 个人物"]})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{htmlFor:"page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),e.jsxs(Be,{value:p.toString(),onValueChange:J=>{g(parseInt(J)),f(1),oe(new Set)},children:[e.jsx(Le,{id:"page-size",className:"w-20",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"10",children:"10"}),e.jsx(ae,{value:"20",children:"20"}),e.jsx(ae,{value:"50",children:"50"}),e.jsx(ae,{value:"100",children:"100"})]})]}),de.size>0&&e.jsxs(e.Fragment,{children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>oe(new Set),children:"取消选择"}),e.jsxs(C,{variant:"destructive",size:"sm",onClick:be,children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsx("div",{className:"hidden md:block",children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{className:"w-12",children:e.jsx(Xs,{checked:l.length>0&&de.size===l.length,onCheckedChange:Y,"aria-label":"全选"})}),e.jsx(Je,{children:"状态"}),e.jsx(Je,{children:"名称"}),e.jsx(Je,{children:"昵称"}),e.jsx(Je,{children:"平台"}),e.jsx(Je,{children:"用户ID"}),e.jsx(Je,{children:"最后更新"}),e.jsx(Je,{className:"text-right",children:"操作"})]})}),e.jsx(Al,{children:i?e.jsx(ct,{children:e.jsx(He,{colSpan:8,className:"text-center py-8 text-muted-foreground",children:"加载中..."})}):l.length===0?e.jsx(ct,{children:e.jsx(He,{colSpan:8,className:"text-center py-8 text-muted-foreground",children:"暂无数据"})}):l.map(J=>e.jsxs(ct,{children:[e.jsx(He,{children:e.jsx(Xs,{checked:de.has(J.person_id),onCheckedChange:()=>Se(J.person_id),"aria-label":`选择 ${J.person_name||J.nickname||J.user_id}`})}),e.jsx(He,{children:e.jsx("div",{className:B("inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium",J.is_known?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400"),children:J.is_known?"已认识":"未认识"})}),e.jsx(He,{className:"font-medium",children:J.person_name||e.jsx("span",{className:"text-muted-foreground",children:"-"})}),e.jsx(He,{children:J.nickname||"-"}),e.jsx(He,{children:J.platform}),e.jsx(He,{className:"font-mono text-sm",children:J.user_id}),e.jsx(He,{className:"text-sm text-muted-foreground",children:Me(J.last_know)}),e.jsx(He,{className:"text-right",children:e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsxs(C,{variant:"default",size:"sm",onClick:()=>L(J),children:[e.jsx(sa,{className:"h-4 w-4 mr-1"}),"详情"]}),e.jsxs(C,{variant:"default",size:"sm",onClick:()=>P(J),children:[e.jsx(Un,{className:"h-4 w-4 mr-1"}),"编辑"]}),e.jsxs(C,{size:"sm",onClick:()=>A(J),className:"bg-red-600 hover:bg-red-700 text-white",children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"删除"]})]})})]},J.id))})]})}),e.jsx("div",{className:"md:hidden space-y-3 p-4",children:i?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):l.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"暂无数据"}):l.map(J=>e.jsxs("div",{className:"rounded-lg border bg-card p-4 space-y-3 overflow-hidden",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Xs,{checked:de.has(J.person_id),onCheckedChange:()=>Se(J.person_id),className:"mt-1"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:B("inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium mb-2",J.is_known?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400"),children:J.is_known?"已认识":"未认识"}),e.jsx("h3",{className:"font-semibold text-sm line-clamp-1 w-full break-all",children:J.person_name||e.jsx("span",{className:"text-muted-foreground",children:"未命名"})}),J.nickname&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1 line-clamp-1 w-full break-all",children:["昵称: ",J.nickname]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"平台"}),e.jsx("p",{className:"font-medium text-xs",children:J.platform})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"用户ID"}),e.jsx("p",{className:"font-mono text-xs truncate",title:J.user_id,children:J.user_id})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"最后更新"}),e.jsx("p",{className:"text-xs",children:Me(J.last_know)})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-1 pt-2 border-t overflow-hidden",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>L(J),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[e.jsx(sa,{className:"h-3 w-3 mr-1"}),"查看"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>P(J),className:"text-xs px-2 py-1 h-auto flex-shrink-0",children:[e.jsx(Un,{className:"h-3 w-3 mr-1"}),"编辑"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>A(J),className:"text-xs px-2 py-1 h-auto flex-shrink-0 text-destructive hover:text-destructive",children:[e.jsx(ls,{className:"h-3 w-3 mr-1"}),"删除"]})]})]},J.id))}),u>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 px-4 py-3 border-t",children:[e.jsxs("div",{className:"text-sm text-muted-foreground",children:["共 ",u," 条记录,第 ",h," / ",Math.ceil(u/p)," 页"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(1),disabled:h===1,className:"hidden sm:flex",children:e.jsx(Ur,{className:"h-4 w-4"})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(h-1),disabled:h===1,children:[e.jsx(ll,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{type:"number",value:fe,onChange:J=>ge(J.target.value),onKeyDown:J=>J.key==="Enter"&&xe(),placeholder:h.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(u/p)}),e.jsx(C,{variant:"outline",size:"sm",onClick:xe,disabled:!fe,className:"h-8",children:"跳转"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>f(h+1),disabled:h>=Math.ceil(u/p),children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>f(Math.ceil(u/p)),disabled:h>=Math.ceil(u/p),className:"hidden sm:flex",children:e.jsx(Br,{className:"h-4 w-4"})})]})]})]})]})}),e.jsx(M4,{person:D,open:I,onOpenChange:M}),e.jsx(A4,{person:D,open:S,onOpenChange:T,onSuccess:()=>{V(),U(),T(!1)}}),e.jsx(ps,{open:!!$,onOpenChange:()=>A(null),children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认删除"}),e.jsxs(xs,{children:['确定要删除人物信息 "',$?.person_name||$?.nickname||$?.user_id,'" 吗? 此操作不可撤销。']})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:()=>$&&_e($),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"删除"})]})]})}),e.jsx(ps,{open:ve,onOpenChange:le,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"确认批量删除"}),e.jsxs(xs,{children:["确定要删除选中的 ",de.size," 个人物信息吗? 此操作不可撤销。"]})]}),e.jsxs(us,{children:[e.jsx(fs,{children:"取消"}),e.jsx(hs,{onClick:Z,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"批量删除"})]})]})})]})}function M4({person:l,open:n,onOpenChange:i}){if(!l)return null;const c=u=>u?new Date(u*1e3).toLocaleString("zh-CN"):"-";return e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"人物详情"}),e.jsxs(ot,{children:["查看 ",l.person_name||l.nickname||l.user_id," 的完整信息"]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsx(_l,{icon:Dn,label:"人物名称",value:l.person_name}),e.jsx(_l,{icon:on,label:"昵称",value:l.nickname}),e.jsx(_l,{icon:Or,label:"用户ID",value:l.user_id,mono:!0}),e.jsx(_l,{icon:Or,label:"人物ID",value:l.person_id,mono:!0}),e.jsx(_l,{label:"平台",value:l.platform}),e.jsx(_l,{label:"状态",value:l.is_known?"已认识":"未认识"})]}),l.name_reason&&e.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"名称设定原因"}),e.jsx("p",{className:"mt-1 text-sm",children:l.name_reason})]}),l.memory_points&&e.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"个人印象"}),e.jsx("p",{className:"mt-1 text-sm whitespace-pre-wrap",children:l.memory_points})]}),l.group_nick_name&&l.group_nick_name.length>0&&e.jsxs("div",{className:"rounded-lg border bg-muted/50 p-3",children:[e.jsx(E,{className:"text-xs text-muted-foreground",children:"群昵称"}),e.jsx("div",{className:"mt-2 space-y-1",children:l.group_nick_name.map((u,x)=>e.jsxs("div",{className:"text-sm flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:u.group_id}),e.jsx("span",{children:"→"}),e.jsx("span",{children:u.group_nick_name})]},x))})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsx(_l,{icon:kl,label:"认识时间",value:c(l.know_times)}),e.jsx(_l,{icon:kl,label:"首次记录",value:c(l.know_since)}),e.jsx(_l,{icon:kl,label:"最后更新",value:c(l.last_know)})]})]}),e.jsx(xt,{children:e.jsx(C,{onClick:()=>i(!1),children:"关闭"})})]})})}function _l({icon:l,label:n,value:i,mono:c=!1}){return e.jsxs("div",{className:"space-y-1",children:[e.jsxs(E,{className:"text-xs text-muted-foreground flex items-center gap-1",children:[l&&e.jsx(l,{className:"h-3 w-3"}),n]}),e.jsx("div",{className:B("text-sm",c&&"font-mono",!i&&"text-muted-foreground"),children:i||"-"})]})}function A4({person:l,open:n,onOpenChange:i,onSuccess:c}){const[u,x]=m.useState({}),[h,f]=m.useState(!1),{toast:p}=Ws();m.useEffect(()=>{l&&x({person_name:l.person_name||"",name_reason:l.name_reason||"",nickname:l.nickname||"",is_known:l.is_known})},[l]);const g=async()=>{if(l)try{f(!0),await S4(l.person_id,u),p({title:"保存成功",description:"人物信息已更新"}),c()}catch(N){p({title:"保存失败",description:N instanceof Error?N.message:"无法更新人物信息",variant:"destructive"})}finally{f(!1)}};return l?e.jsx(Ks,{open:n,onOpenChange:i,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"编辑人物信息"}),e.jsxs(ot,{children:["修改 ",l.person_name||l.nickname||l.user_id," 的信息"]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"person_name",children:"人物名称"}),e.jsx(ie,{id:"person_name",value:u.person_name||"",onChange:N=>x({...u,person_name:N.target.value}),placeholder:"为这个人设置一个名称"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"nickname",children:"昵称"}),e.jsx(ie,{id:"nickname",value:u.nickname||"",onChange:N=>x({...u,nickname:N.target.value}),placeholder:"昵称"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"name_reason",children:"名称设定原因"}),e.jsx(et,{id:"name_reason",value:u.name_reason||"",onChange:N=>x({...u,name_reason:N.target.value}),placeholder:"为什么这样称呼这个人?",rows:2})]}),e.jsxs("div",{className:"flex items-center justify-between rounded-lg border p-3",children:[e.jsxs("div",{children:[e.jsx(E,{htmlFor:"is_known",className:"text-base font-medium",children:"已认识"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"标记是否已经认识这个人"})]}),e.jsx(Ge,{id:"is_known",checked:u.is_known,onCheckedChange:N=>x({...u,is_known:N})})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>i(!1),children:"取消"}),e.jsx(C,{onClick:g,disabled:h,children:h?"保存中...":"保存"})]})]})}):null}var z4=b1();const gg=d0(z4),Km="/api/webui";async function D4(l=100,n="all"){const i=`${Km}/knowledge/graph?limit=${l}&node_type=${n}`,c=await fetch(i);if(!c.ok)throw new Error(`获取知识图谱失败: ${c.status}`);return c.json()}async function O4(){const l=await fetch(`${Km}/knowledge/stats`);if(!l.ok)throw new Error("获取知识图谱统计信息失败");return l.json()}async function R4(l){const n=await fetch(`${Km}/knowledge/search?query=${encodeURIComponent(l)}`);if(!n.ok)throw new Error("搜索知识节点失败");return n.json()}const fv=m.memo(({data:l})=>e.jsxs("div",{className:"px-4 py-2 shadow-md rounded-lg bg-gradient-to-br from-blue-500 to-blue-600 border-2 border-blue-700 min-w-[120px]",children:[e.jsx(Mo,{type:"target",position:Ao.Top}),e.jsx("div",{className:"font-semibold text-white text-sm truncate max-w-[200px]",title:l.content,children:l.label}),e.jsx(Mo,{type:"source",position:Ao.Bottom})]}));fv.displayName="EntityNode";const pv=m.memo(({data:l})=>e.jsxs("div",{className:"px-3 py-2 shadow-md rounded-md bg-gradient-to-br from-green-500 to-green-600 border-2 border-green-700 min-w-[100px]",children:[e.jsx(Mo,{type:"target",position:Ao.Top}),e.jsx("div",{className:"font-medium text-white text-xs truncate max-w-[150px]",title:l.content,children:l.label}),e.jsx(Mo,{type:"source",position:Ao.Bottom})]}));pv.displayName="ParagraphNode";const L4={entity:fv,paragraph:pv};function U4(l,n){const i=new gg.graphlib.Graph;i.setDefaultEdgeLabel(()=>({})),i.setGraph({rankdir:"TB",ranksep:100,nodesep:80});const c=[],u=[];return l.forEach(x=>{i.setNode(x.id,{width:150,height:50})}),n.forEach(x=>{i.setEdge(x.source,x.target)}),gg.layout(i),l.forEach(x=>{const h=i.node(x.id);c.push({id:x.id,type:x.type,position:{x:h.x-75,y:h.y-25},data:{label:x.content.slice(0,20)+(x.content.length>20?"...":""),content:x.content}})}),n.forEach((x,h)=>{const f={id:`edge-${h}`,source:x.source,target:x.target,animated:l.length<=200&&x.weight>5,style:{strokeWidth:Math.min(x.weight/2,5),opacity:.6}};x.weight>10&&l.length<100&&(f.label=`${x.weight.toFixed(0)}`),u.push(f)}),{nodes:c,edges:u}}function B4(){const l=aa(),[n,i]=m.useState(!1),[c,u]=m.useState(null),[x,h]=m.useState(""),[f,p]=m.useState("all"),[g,N]=m.useState(50),[v,b]=m.useState("50"),[w,y]=m.useState(!1),[R,D]=m.useState(!0),[k,I]=m.useState(!1),[M,S]=m.useState(!1),[T,$,A]=y1([]),[Q,G,de]=w1([]),[oe,ve]=m.useState(0),[le,fe]=m.useState(null),[ge,z]=m.useState(null),{toast:V}=Ws(),U=m.useCallback(Z=>Z.type==="entity"?"#6366f1":Z.type==="paragraph"?"#10b981":"#6b7280",[]),L=m.useCallback(async(Z=!1)=>{try{if(!Z&&g>200){S(!0);return}i(!0);const[xe,Me]=await Promise.all([D4(g,f),O4()]);if(u(Me),xe.nodes.length===0){V({title:"提示",description:"知识库为空,请先导入知识数据"}),$([]),G([]);return}const{nodes:J,edges:ce}=U4(xe.nodes,xe.edges);$(J),G(ce),ve(J.length),Me&&Me.total_nodes>g&&V({title:"提示",description:`知识图谱包含 ${Me.total_nodes} 个节点,当前显示 ${J.length} 个`}),V({title:"加载成功",description:`已加载 ${J.length} 个节点,${ce.length} 条边`})}catch(xe){console.error("加载知识图谱失败:",xe),V({title:"加载失败",description:xe instanceof Error?xe.message:"未知错误",variant:"destructive"})}finally{i(!1)}},[g,f,V]),P=m.useCallback(async()=>{if(!x.trim()){V({title:"提示",description:"请输入搜索关键词"});return}try{const Z=await R4(x);if(Z.length===0){V({title:"未找到",description:"没有找到匹配的节点"});return}const xe=new Set(Z.map(Me=>Me.id));$(Me=>Me.map(J=>({...J,style:{...J.style,opacity:xe.has(J.id)?1:.3,filter:xe.has(J.id)?"brightness(1.2)":"brightness(0.8)"}}))),V({title:"搜索完成",description:`找到 ${Z.length} 个匹配节点`})}catch(Z){console.error("搜索失败:",Z),V({title:"搜索失败",description:Z instanceof Error?Z.message:"未知错误",variant:"destructive"})}},[x,V]),_e=m.useCallback(()=>{$(Z=>Z.map(xe=>({...xe,style:{...xe.style,opacity:1,filter:"brightness(1)"}})))},[]),je=m.useCallback(()=>{D(!1),I(!0),L()},[L]),Se=m.useCallback(()=>{S(!1),setTimeout(()=>{L(!0)},0)},[L]),Y=m.useCallback((Z,xe)=>{T.find(J=>J.id===xe.id)&&fe({id:xe.id,type:xe.type,content:xe.data.content})},[T]);m.useEffect(()=>{R||k&&L()},[g,f,R,k]);const be=m.useCallback((Z,xe)=>{const Me=T.find(Fe=>Fe.id===xe.source),J=T.find(Fe=>Fe.id===xe.target),ce=Q.find(Fe=>Fe.id===xe.id);Me&&J&&ce&&z({source:{id:Me.id,type:Me.type,content:Me.data.content},target:{id:J.id,type:J.type,content:J.data.content},edge:{source:xe.source,target:xe.target,weight:parseFloat(xe.label||"0")}})},[T,Q]);return e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"flex-shrink-0 p-4 border-b bg-background",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"麦麦知识库图谱"}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"可视化知识实体与关系网络"})]}),c&&e.jsxs("div",{className:"flex gap-2 flex-wrap",children:[e.jsxs(Ae,{variant:"outline",className:"gap-1",children:[e.jsx(zr,{className:"h-3 w-3"}),"节点: ",c.total_nodes]}),e.jsxs(Ae,{variant:"outline",className:"gap-1",children:[e.jsx(yj,{className:"h-3 w-3"}),"边: ",c.total_edges]}),e.jsxs(Ae,{variant:"outline",className:"gap-1",children:[e.jsx(qt,{className:"h-3 w-3"}),"实体: ",c.entity_nodes]}),e.jsxs(Ae,{variant:"outline",className:"gap-1",children:[e.jsx(qa,{className:"h-3 w-3"}),"段落: ",c.paragraph_nodes]})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 mt-4",children:[e.jsxs("div",{className:"flex-1 flex gap-2",children:[e.jsx(ie,{placeholder:"搜索节点内容...",value:x,onChange:Z=>h(Z.target.value),onKeyDown:Z=>Z.key==="Enter"&&P(),className:"flex-1"}),e.jsx(C,{onClick:P,size:"sm",children:e.jsx(Vt,{className:"h-4 w-4"})}),e.jsx(C,{onClick:_e,variant:"outline",size:"sm",children:"重置"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(Be,{value:f,onValueChange:Z=>p(Z),children:[e.jsx(Le,{className:"w-[120px]",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部节点"}),e.jsx(ae,{value:"entity",children:"仅实体"}),e.jsx(ae,{value:"paragraph",children:"仅段落"})]})]}),e.jsxs(Be,{value:g===1e4?"all":w?"custom":g.toString(),onValueChange:Z=>{Z==="custom"?(y(!0),b(g.toString())):Z==="all"?(y(!1),N(1e4)):(y(!1),N(Number(Z)))},children:[e.jsx(Le,{className:"w-[120px]",children:e.jsx($e,{})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"50",children:"50 节点"}),e.jsx(ae,{value:"100",children:"100 节点"}),e.jsx(ae,{value:"200",children:"200 节点"}),e.jsx(ae,{value:"500",children:"500 节点"}),e.jsx(ae,{value:"1000",children:"1000 节点"}),e.jsx(ae,{value:"all",children:"全部 (最多10000)"}),e.jsx(ae,{value:"custom",children:"自定义..."})]})]}),w&&e.jsx(ie,{type:"number",min:"50",value:v,onChange:Z=>b(Z.target.value),onBlur:()=>{const Z=parseInt(v);!isNaN(Z)&&Z>=50?N(Z):(b("50"),N(50))},onKeyDown:Z=>{if(Z.key==="Enter"){const xe=parseInt(v);!isNaN(xe)&&xe>=50?N(xe):(b("50"),N(50))}},placeholder:"最少50个",className:"w-[120px]"}),e.jsx(C,{onClick:()=>L(),variant:"outline",size:"sm",disabled:n,children:e.jsx(kt,{className:B("h-4 w-4",n&&"animate-spin")})})]})]})]}),e.jsx("div",{className:"flex-1 relative",children:n?e.jsx("div",{className:"absolute inset-0 flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx(kt,{className:"h-8 w-8 animate-spin mx-auto mb-2 text-muted-foreground"}),e.jsx("p",{className:"text-muted-foreground",children:"加载知识图谱中..."})]})}):T.length===0?e.jsx("div",{className:"absolute inset-0 flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx(zr,{className:"h-12 w-12 mx-auto mb-4 text-muted-foreground"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"知识库为空"}),e.jsx("p",{className:"text-muted-foreground",children:"请先导入知识数据"})]})}):e.jsxs(_1,{nodes:T,edges:Q,onNodesChange:A,onEdgesChange:de,onNodeClick:Y,onEdgeClick:be,nodeTypes:L4,fitView:!0,minZoom:.05,maxZoom:1.5,defaultViewport:{x:0,y:0,zoom:.5},elevateNodesOnSelect:oe<=500,nodesDraggable:oe<=1e3,attributionPosition:"bottom-left",children:[e.jsx(S1,{variant:k1.Dots,gap:12,size:1}),e.jsx(C1,{}),oe<=500&&e.jsx(T1,{nodeColor:U,nodeBorderRadius:8,pannable:!0,zoomable:!0}),e.jsxs(E1,{position:"top-right",className:"bg-background/95 backdrop-blur-sm rounded-lg border p-3 shadow-lg",children:[e.jsx("div",{className:"text-sm font-semibold mb-2",children:"图例"}),e.jsxs("div",{className:"space-y-2 text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-4 h-4 rounded bg-gradient-to-br from-blue-500 to-blue-600 border-2 border-blue-700"}),e.jsx("span",{children:"实体节点"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-4 h-4 rounded bg-gradient-to-br from-green-500 to-green-600 border-2 border-green-700"}),e.jsx("span",{children:"段落节点"})]}),oe>200&&e.jsxs("div",{className:"mt-2 pt-2 border-t text-yellow-600 dark:text-yellow-500",children:[e.jsx("div",{className:"font-semibold",children:"性能模式"}),e.jsx("div",{children:"已禁用动画"}),oe>500&&e.jsx("div",{children:"已禁用缩略图"})]})]})]})]})}),e.jsx(Ks,{open:!!le,onOpenChange:Z=>!Z&&fe(null),children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsx(Hs,{children:e.jsx(Gs,{children:"节点详情"})}),le&&e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"grid grid-cols-2 gap-4",children:e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-muted-foreground",children:"类型"}),e.jsx("div",{className:"mt-1",children:e.jsx(Ae,{variant:le.type==="entity"?"default":"secondary",children:le.type==="entity"?"🏷️ 实体":"📄 段落"})})]})}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-muted-foreground",children:"ID"}),e.jsx("code",{className:"mt-1 block p-2 bg-muted rounded text-xs break-all",children:le.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-muted-foreground",children:"内容"}),e.jsx(es,{className:"mt-1 h-40 p-3 bg-muted rounded",children:e.jsx("p",{className:"text-sm whitespace-pre-wrap",children:le.content})})]})]})]})}),e.jsx(Ks,{open:!!ge,onOpenChange:Z=>!Z&&z(null),children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-hidden flex flex-col",children:[e.jsx(Hs,{children:e.jsx(Gs,{children:"边详情"})}),ge&&e.jsx(es,{className:"flex-1 pr-4",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0 p-3 bg-blue-50 dark:bg-blue-950 rounded border-2 border-blue-200 dark:border-blue-800",children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"源节点"}),e.jsx("div",{className:"font-medium text-sm mb-2 truncate",children:ge.source.content}),e.jsxs("code",{className:"text-xs text-muted-foreground truncate block",children:[ge.source.id.slice(0,40),"..."]})]}),e.jsx("div",{className:"text-2xl text-muted-foreground flex-shrink-0",children:"→"}),e.jsxs("div",{className:"flex-1 min-w-0 p-3 bg-green-50 dark:bg-green-950 rounded border-2 border-green-200 dark:border-green-800",children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"目标节点"}),e.jsx("div",{className:"font-medium text-sm mb-2 truncate",children:ge.target.content}),e.jsxs("code",{className:"text-xs text-muted-foreground truncate block",children:[ge.target.id.slice(0,40),"..."]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-muted-foreground",children:"权重"}),e.jsx("div",{className:"mt-1",children:e.jsx(Ae,{variant:"outline",className:"text-base font-mono",children:ge.edge.weight.toFixed(4)})})]})]})})]})}),e.jsx(ps,{open:R,onOpenChange:D,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"加载知识图谱"}),e.jsxs(xs,{children:["知识图谱的动态展示会消耗较多系统资源。",e.jsx("br",{}),"确定要加载知识图谱吗?"]})]}),e.jsxs(us,{children:[e.jsx(fs,{onClick:()=>l({to:"/"}),children:"取消 (返回首页)"}),e.jsx(hs,{onClick:je,children:"确认加载"})]})]})}),e.jsx(ps,{open:M,onOpenChange:S,children:e.jsxs(os,{children:[e.jsxs(ds,{children:[e.jsx(ms,{children:"⚠️ 节点数量较多"}),e.jsx(xs,{asChild:!0,children:e.jsxs("div",{children:[e.jsxs("p",{children:["您正在尝试加载 ",e.jsx("strong",{className:"text-orange-600",children:g>=1e4?"全部 (最多10000个)":g})," 个节点。"]}),e.jsx("p",{className:"mt-4",children:"节点数量过多可能导致:"}),e.jsxs("ul",{className:"list-disc list-inside mt-2 space-y-1",children:[e.jsx("li",{children:"页面加载时间较长"}),e.jsx("li",{children:"浏览器卡顿或崩溃"}),e.jsx("li",{children:"系统资源占用过高"})]}),e.jsx("p",{className:"mt-4",children:"建议先选择较少的节点数量 (50-200 个)。"})]})})]}),e.jsxs(us,{children:[e.jsx(fs,{onClick:()=>{S(!1),g>200&&(N(50),y(!1))},children:"取消"}),e.jsx(hs,{onClick:Se,className:"bg-orange-600 hover:bg-orange-700",children:"我了解风险,继续加载"})]})]})})]})}function $4(){return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsx("div",{className:"flex-none border-b bg-card/50 px-6 py-4",children:e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"麦麦知识库管理"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"管理和组织麦麦的知识库内容"})]})})}),e.jsx("div",{className:"flex-1 overflow-auto p-6",children:e.jsx("div",{className:"mx-auto max-w-4xl",children:e.jsxs(De,{children:[e.jsxs(Xe,{className:"text-center",children:[e.jsx("div",{className:"mx-auto mb-4 flex h-20 w-20 items-center justify-center rounded-full bg-primary/10",children:e.jsx(zr,{className:"h-10 w-10 text-primary"})}),e.jsx(We,{className:"text-2xl",children:"麦麦知识库管理"}),e.jsx(Is,{className:"text-base",children:"功能开发中,敬请期待"})]}),e.jsx(Qe,{className:"text-center text-sm text-muted-foreground",children:e.jsx("p",{children:"此功能将提供知识库的创建、编辑、导入和管理能力"})})]})})})]})}function jg({className:l,classNames:n,showOutsideDays:i=!0,captionLayout:c="label",buttonVariant:u="ghost",formatters:x,components:h,...f}){const p=$j();return e.jsx(h1,{showOutsideDays:i,className:B("bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,l),captionLayout:c,formatters:{formatMonthDropdown:g=>g.toLocaleString("default",{month:"short"}),...x},classNames:{root:B("w-fit",p.root),months:B("relative flex flex-col gap-4 md:flex-row",p.months),month:B("flex w-full flex-col gap-4",p.month),nav:B("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",p.nav),button_previous:B(Rr({variant:u}),"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",p.button_previous),button_next:B(Rr({variant:u}),"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",p.button_next),month_caption:B("flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",p.month_caption),dropdowns:B("flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",p.dropdowns),dropdown_root:B("has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",p.dropdown_root),dropdown:B("bg-popover absolute inset-0 opacity-0",p.dropdown),caption_label:B("select-none font-medium",c==="label"?"text-sm":"[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",p.caption_label),table:"w-full border-collapse",weekdays:B("flex",p.weekdays),weekday:B("text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",p.weekday),week:B("mt-2 flex w-full",p.week),week_number_header:B("w-[--cell-size] select-none",p.week_number_header),week_number:B("text-muted-foreground select-none text-[0.8rem]",p.week_number),day:B("group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",p.day),range_start:B("bg-accent rounded-l-md",p.range_start),range_middle:B("rounded-none",p.range_middle),range_end:B("bg-accent rounded-r-md",p.range_end),today:B("bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",p.today),outside:B("text-muted-foreground aria-selected:text-muted-foreground",p.outside),disabled:B("text-muted-foreground opacity-50",p.disabled),hidden:B("invisible",p.hidden),...n},components:{Root:({className:g,rootRef:N,...v})=>e.jsx("div",{"data-slot":"calendar",ref:N,className:B(g),...v}),Chevron:({className:g,orientation:N,...v})=>N==="left"?e.jsx(ll,{className:B("size-4",g),...v}):N==="right"?e.jsx(Sa,{className:B("size-4",g),...v}):e.jsx($a,{className:B("size-4",g),...v}),DayButton:I4,WeekNumber:({children:g,...N})=>e.jsx("td",{...N,children:e.jsx("div",{className:"flex size-[--cell-size] items-center justify-center text-center",children:g})}),...h},...f})}function I4({className:l,day:n,modifiers:i,...c}){const u=$j(),x=m.useRef(null);return m.useEffect(()=>{i.focused&&x.current?.focus()},[i.focused]),e.jsx(C,{ref:x,variant:"ghost",size:"icon","data-day":n.date.toLocaleDateString(),"data-selected-single":i.selected&&!i.range_start&&!i.range_end&&!i.range_middle,"data-range-start":i.range_start,"data-range-end":i.range_end,"data-range-middle":i.range_middle,className:B("data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",u.day,l),...c})}const No={xs:{label:"小",rowHeight:28,class:"text-[10px] sm:text-xs"},sm:{label:"中",rowHeight:36,class:"text-xs sm:text-sm"},base:{label:"大",rowHeight:44,class:"text-sm sm:text-base"}};function P4(){const[l,n]=m.useState([]),[i,c]=m.useState(""),[u,x]=m.useState("all"),[h,f]=m.useState("all"),[p,g]=m.useState(void 0),[N,v]=m.useState(void 0),[b,w]=m.useState(!0),[y,R]=m.useState(!1),[D,k]=m.useState("xs"),[I,M]=m.useState(4),[S,T]=m.useState(!1),$=m.useRef(null);m.useEffect(()=>{const P=Mn.getAllLogs();n(P);const _e=Mn.onLog(()=>{n(Mn.getAllLogs())}),je=Mn.onConnectionChange(Se=>{R(Se)});return()=>{_e(),je()}},[]);const A=m.useMemo(()=>{const P=new Set(l.map(_e=>_e.module).filter(_e=>_e&&_e.trim()!==""));return Array.from(P).sort()},[l]),Q=P=>{switch(P){case"DEBUG":return"text-muted-foreground";case"INFO":return"text-blue-500 dark:text-blue-400";case"WARNING":return"text-yellow-600 dark:text-yellow-500";case"ERROR":return"text-red-600 dark:text-red-500";case"CRITICAL":return"text-red-700 dark:text-red-400 font-bold";default:return"text-foreground"}},G=P=>{switch(P){case"DEBUG":return"bg-gray-800/30 dark:bg-gray-800/50";case"INFO":return"bg-blue-900/20 dark:bg-blue-500/20";case"WARNING":return"bg-yellow-900/20 dark:bg-yellow-500/20";case"ERROR":return"bg-red-900/20 dark:bg-red-500/20";case"CRITICAL":return"bg-red-900/30 dark:bg-red-600/30";default:return"bg-gray-800/20 dark:bg-gray-800/30"}},de=()=>{window.location.reload()},oe=()=>{Mn.clearLogs(),n([])},ve=()=>{const P=ge.map(Y=>`${Y.timestamp} [${Y.level.padEnd(8)}] [${Y.module}] ${Y.message}`).join(` +`),_e=new Blob([P],{type:"text/plain;charset=utf-8"}),je=URL.createObjectURL(_e),Se=document.createElement("a");Se.href=je,Se.download=`logs-${cm(new Date,"yyyy-MM-dd-HHmmss")}.txt`,Se.click(),URL.revokeObjectURL(je)},le=()=>{w(!b)},fe=()=>{g(void 0),v(void 0)},ge=m.useMemo(()=>l.filter(P=>{const _e=i===""||P.message.toLowerCase().includes(i.toLowerCase())||P.module.toLowerCase().includes(i.toLowerCase()),je=u==="all"||P.level===u,Se=h==="all"||P.module===h;let Y=!0;if(p||N){const be=new Date(P.timestamp);if(p){const Z=new Date(p);Z.setHours(0,0,0,0),Y=Y&&be>=Z}if(N){const Z=new Date(N);Z.setHours(23,59,59,999),Y=Y&&be<=Z}}return _e&&je&&Se&&Y}),[l,i,u,h,p,N]),z=No[D].rowHeight+I,V=s0({count:ge.length,getScrollElement:()=>$.current,estimateSize:()=>z,overscan:50}),U=m.useRef(!1),L=m.useRef(ge.length);return m.useEffect(()=>{const P=$.current;if(!P)return;const _e=()=>{if(U.current)return;const{scrollTop:je,scrollHeight:Se,clientHeight:Y}=P,be=Se-je-Y;be>100&&b?w(!1):be<50&&!b&&w(!0)};return P.addEventListener("scroll",_e,{passive:!0}),()=>P.removeEventListener("scroll",_e)},[b]),m.useEffect(()=>{const P=ge.length>L.current;L.current=ge.length,b&&ge.length>0&&P&&(U.current=!0,V.scrollToIndex(ge.length-1,{align:"end",behavior:"auto"}),requestAnimationFrame(()=>{requestAnimationFrame(()=>{U.current=!1})}))},[ge.length,b,V]),e.jsxs("div",{className:"h-full flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"flex-shrink-0 space-y-2 sm:space-y-3 p-2 sm:p-3 lg:p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-lg sm:text-xl lg:text-2xl font-bold",children:"日志查看器"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5 hidden sm:block",children:"实时查看和分析麦麦运行日志"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:B("h-2 w-2 sm:h-2.5 sm:w-2.5 rounded-full",y?"bg-green-500 animate-pulse":"bg-red-500")}),e.jsx("span",{className:"text-xs text-muted-foreground",children:y?"已连接":"未连接"})]})]}),e.jsx(De,{className:"p-2 sm:p-3",children:e.jsx(Ki,{open:S,onOpenChange:T,children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"flex-1 relative min-w-0",children:[e.jsx(Vt,{className:"absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索日志...",value:i,onChange:P=>c(P.target.value),className:"pl-8 h-8 text-xs sm:text-sm"})]}),e.jsxs("div",{className:"flex gap-1 flex-shrink-0",children:[e.jsxs(C,{variant:b?"default":"outline",size:"sm",onClick:le,className:"h-8 px-2",title:b?"自动滚动":"已暂停",children:[b?e.jsx(Gw,{className:"h-3.5 w-3.5"}):e.jsx(Fw,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"ml-1 text-xs hidden sm:inline",children:b?"滚动":"暂停"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:oe,className:"h-8 px-2",title:"清空日志",children:[e.jsx(ls,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"ml-1 text-xs hidden md:inline",children:"清空"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:ve,className:"h-8 px-2 hidden sm:flex",title:"导出日志",children:[e.jsx(Xt,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"ml-1 text-xs hidden lg:inline",children:"导出"})]}),e.jsx(Qi,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",className:"h-8 px-2",title:S?"收起筛选":"展开筛选",children:[e.jsx(yo,{className:"h-3.5 w-3.5"}),S?e.jsx(Dr,{className:"h-3.5 w-3.5 ml-1"}):e.jsx($a,{className:"h-3.5 w-3.5 ml-1"})]})})]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground text-center sm:text-right -mt-1",children:[e.jsxs("span",{className:"font-mono",children:[ge.length," / ",l.length]}),e.jsx("span",{className:"ml-1",children:"条日志"})]}),e.jsxs(Yi,{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:gap-2",children:[e.jsxs(Be,{value:u,onValueChange:x,children:[e.jsxs(Le,{className:"w-full sm:flex-1 h-8 text-xs",children:[e.jsx(yo,{className:"h-3.5 w-3.5 mr-1.5"}),e.jsx($e,{placeholder:"级别"})]}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部级别"}),e.jsx(ae,{value:"DEBUG",children:"DEBUG"}),e.jsx(ae,{value:"INFO",children:"INFO"}),e.jsx(ae,{value:"WARNING",children:"WARNING"}),e.jsx(ae,{value:"ERROR",children:"ERROR"}),e.jsx(ae,{value:"CRITICAL",children:"CRITICAL"})]})]}),e.jsxs(Be,{value:h,onValueChange:f,children:[e.jsxs(Le,{className:"w-full sm:flex-1 h-8 text-xs",children:[e.jsx(yo,{className:"h-3.5 w-3.5 mr-1.5"}),e.jsx($e,{placeholder:"模块"})]}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部模块"}),A.map(P=>e.jsx(ae,{value:P,children:P},P))]})]})]}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:gap-2",children:[e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",className:B("w-full sm:flex-1 justify-start text-left font-normal h-8",!p&&"text-muted-foreground"),children:[e.jsx(Vp,{className:"mr-1.5 h-3.5 w-3.5"}),e.jsx("span",{className:"text-xs",children:p?cm(p,"PP",{locale:jo}):"开始日期"})]})}),e.jsx(Ka,{className:"w-auto p-0",align:"start",children:e.jsx(jg,{mode:"single",selected:p,onSelect:g,initialFocus:!0,locale:jo})})]}),e.jsxs(tl,{children:[e.jsx(al,{asChild:!0,children:e.jsxs(C,{variant:"outline",size:"sm",className:B("w-full sm:flex-1 justify-start text-left font-normal h-8",!N&&"text-muted-foreground"),children:[e.jsx(Vp,{className:"mr-1.5 h-3.5 w-3.5"}),e.jsx("span",{className:"text-xs",children:N?cm(N,"PP",{locale:jo}):"结束日期"})]})}),e.jsx(Ka,{className:"w-auto p-0",align:"start",children:e.jsx(jg,{mode:"single",selected:N,onSelect:v,initialFocus:!0,locale:jo})})]}),(p||N)&&e.jsxs(C,{variant:"outline",size:"sm",onClick:fe,className:"w-full sm:w-auto h-8",children:[e.jsx(_a,{className:"h-3.5 w-3.5 sm:mr-1"}),e.jsx("span",{className:"text-xs",children:"清除"})]})]}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3 pt-2 border-t border-border/50",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[e.jsx(qw,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:"字号"})]}),e.jsx("div",{className:"flex gap-1",children:Object.keys(No).map(P=>e.jsx(C,{variant:D===P?"default":"outline",size:"sm",onClick:()=>k(P),className:"h-6 px-2 text-xs",children:No[P].label},P))})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-1 max-w-[200px]",children:[e.jsx("span",{className:"text-xs text-muted-foreground whitespace-nowrap",children:"行距"}),e.jsx(wa,{value:[I],onValueChange:([P])=>M(P),min:0,max:12,step:2,className:"flex-1"}),e.jsxs("span",{className:"text-xs text-muted-foreground w-7",children:[I,"px"]})]}),e.jsxs("div",{className:"flex gap-2 sm:hidden",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:de,className:"flex-1 h-8",children:[e.jsx(kt,{className:"h-3.5 w-3.5 mr-1"}),e.jsx("span",{className:"text-xs",children:"刷新"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:ve,className:"flex-1 h-8",children:[e.jsx(Xt,{className:"h-3.5 w-3.5 mr-1"}),e.jsx("span",{className:"text-xs",children:"导出"})]})]})]})]})]})})})]}),e.jsx("div",{className:"flex-1 min-h-0 px-2 sm:px-3 lg:px-4 pb-2 sm:pb-3 lg:pb-4",children:e.jsx(De,{className:"bg-black dark:bg-gray-950 border-gray-800 dark:border-gray-900 h-full overflow-hidden",children:e.jsx("div",{ref:$,className:B("h-full overflow-auto","[&::-webkit-scrollbar]:w-2.5","[&::-webkit-scrollbar-track]:bg-transparent","[&::-webkit-scrollbar-thumb]:bg-border [&::-webkit-scrollbar-thumb]:rounded-full","[&::-webkit-scrollbar-thumb:hover]:bg-border/80"),children:e.jsx("div",{className:B("p-2 sm:p-3 font-mono relative",No[D].class),style:{height:`${V.getTotalSize()}px`},children:ge.length===0?e.jsx("div",{className:"text-gray-500 dark:text-gray-600 text-center py-8 text-xs sm:text-sm",children:"暂无日志数据"}):V.getVirtualItems().map(P=>{const _e=ge[P.index];return e.jsxs("div",{"data-index":P.index,ref:V.measureElement,className:B("absolute top-0 left-0 w-full px-2 sm:px-3 rounded hover:bg-white/5 transition-colors",G(_e.level)),style:{transform:`translateY(${P.start}px)`,paddingTop:`${I/2}px`,paddingBottom:`${I/2}px`},children:[e.jsxs("div",{className:"flex flex-col gap-0.5 sm:hidden",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-gray-500 dark:text-gray-600 text-[10px]",children:_e.timestamp}),e.jsxs("span",{className:B("font-semibold text-[10px]",Q(_e.level)),children:["[",_e.level,"]"]})]}),e.jsx("div",{className:"text-cyan-400 dark:text-cyan-500 truncate text-[10px]",children:_e.module}),e.jsx("div",{className:"text-gray-300 dark:text-gray-400 whitespace-pre-wrap break-words text-[10px]",children:_e.message})]}),e.jsxs("div",{className:"hidden sm:flex gap-2 items-start",children:[e.jsx("span",{className:"text-gray-500 dark:text-gray-600 flex-shrink-0 w-[130px] lg:w-[160px]",children:_e.timestamp}),e.jsxs("span",{className:B("flex-shrink-0 w-[65px] lg:w-[75px] font-semibold",Q(_e.level)),children:["[",_e.level,"]"]}),e.jsx("span",{className:"text-cyan-400 dark:text-cyan-500 flex-shrink-0 w-[100px] lg:w-[130px] truncate",children:_e.module}),e.jsx("span",{className:"text-gray-300 dark:text-gray-400 flex-1 whitespace-pre-wrap break-words",children:_e.message})]})]},P.key)})})})})})]})}const H4="Mai-with-u",G4="plugin-repo",F4="main",q4="plugin_details.json";async function V4(){try{const l=await we("/api/webui/plugins/fetch-raw",{method:"POST",body:JSON.stringify({owner:H4,repo:G4,branch:F4,file_path:q4})});if(!l.ok)throw new Error(`HTTP error! status: ${l.status}`);const n=await l.json();if(!n.success||!n.data)throw new Error(n.error||"获取插件列表失败");return JSON.parse(n.data).filter(u=>!u?.id||!u?.manifest?(console.warn("跳过无效插件数据:",u),!1):!u.manifest.name||!u.manifest.version?(console.warn("跳过缺少必需字段的插件:",u.id),!1):!0).map(u=>({id:u.id,manifest:{manifest_version:u.manifest.manifest_version||1,name:u.manifest.name,version:u.manifest.version,description:u.manifest.description||"",author:u.manifest.author||{name:"Unknown"},license:u.manifest.license||"Unknown",host_application:u.manifest.host_application||{min_version:"0.0.0"},homepage_url:u.manifest.homepage_url,repository_url:u.manifest.repository_url,keywords:u.manifest.keywords||[],categories:u.manifest.categories||[],default_locale:u.manifest.default_locale||"zh-CN",locales_path:u.manifest.locales_path},downloads:0,rating:0,review_count:0,installed:!1,published_at:new Date().toISOString(),updated_at:new Date().toISOString()}))}catch(l){throw console.error("Failed to fetch plugin list:",l),l}}async function gv(){try{const l=await we("/api/webui/plugins/git-status");if(!l.ok)throw new Error(`HTTP error! status: ${l.status}`);return await l.json()}catch(l){return console.error("Failed to check Git status:",l),{installed:!1,error:"无法检测 Git 安装状态"}}}async function jv(){try{const l=await we("/api/webui/plugins/version");if(!l.ok)throw new Error(`HTTP error! status: ${l.status}`);return await l.json()}catch(l){return console.error("Failed to get Maimai version:",l),{version:"0.0.0",version_major:0,version_minor:0,version_patch:0}}}function vv(l,n,i){const c=l.split(".").map(f=>parseInt(f)||0),u=c[0]||0,x=c[1]||0,h=c[2]||0;if(i.version_majorparseInt(v)||0),p=f[0]||0,g=f[1]||0,N=f[2]||0;if(i.version_major>p||i.version_major===p&&i.version_minor>g||i.version_major===p&&i.version_minor===g&&i.version_patch>N)return!1}return!0}async function K4(){try{const l=await we("/api/webui/ws-token");if(!l.ok)return console.error("获取 WebSocket token 失败:",l.status),null;const n=await l.json();return n.success&&n.token?n.token:null}catch(l){return console.error("获取 WebSocket token 失败:",l),null}}async function Q4(l,n){const i=await K4();if(!i)return console.warn("无法获取 WebSocket token,可能未登录"),null;const c=window.location.protocol==="https:"?"wss:":"ws:",u=window.location.host,x=`${c}//${u}/api/webui/ws/plugin-progress?token=${encodeURIComponent(i)}`;try{const h=new WebSocket(x);return h.onopen=()=>{console.log("Plugin progress WebSocket connected");const f=setInterval(()=>{h.readyState===WebSocket.OPEN?h.send("ping"):clearInterval(f)},3e4)},h.onmessage=f=>{try{if(f.data==="pong")return;const p=JSON.parse(f.data);l(p)}catch(p){console.error("Failed to parse progress data:",p)}},h.onerror=f=>{console.error("Plugin progress WebSocket error:",f),n?.(f)},h.onclose=()=>{console.log("Plugin progress WebSocket disconnected")},h}catch(h){return console.error("创建 WebSocket 连接失败:",h),null}}async function Sl(){try{const l=await we("/api/webui/plugins/installed",{headers:Us()});if(!l.ok)throw new Error(`HTTP error! status: ${l.status}`);const n=await l.json();if(!n.success)throw new Error(n.message||"获取已安装插件列表失败");return n.plugins||[]}catch(l){return console.error("Failed to get installed plugins:",l),[]}}function nn(l,n){return n.some(i=>i.id===l)}function rn(l,n){const i=n.find(c=>c.id===l);if(i)return i.manifest?.version||i.version}async function Nv(l,n,i="main"){const c=await we("/api/webui/plugins/install",{method:"POST",body:JSON.stringify({plugin_id:l,repository_url:n,branch:i})});if(!c.ok){const u=await c.json();throw new Error(u.detail||"安装失败")}return await c.json()}async function bv(l){const n=await we("/api/webui/plugins/uninstall",{method:"POST",body:JSON.stringify({plugin_id:l})});if(!n.ok){const i=await n.json();throw new Error(i.detail||"卸载失败")}return await n.json()}async function yv(l,n,i="main"){const c=await we("/api/webui/plugins/update",{method:"POST",body:JSON.stringify({plugin_id:l,repository_url:n,branch:i})});if(!c.ok){const u=await c.json();throw new Error(u.detail||"更新失败")}return await c.json()}async function Y4(l){const n=await we(`/api/webui/plugins/config/${l}/schema`,{headers:Us()});if(!n.ok){const c=await n.text();try{const u=JSON.parse(c);throw new Error(u.detail||"获取配置 Schema 失败")}catch{throw new Error(`获取配置 Schema 失败 (${n.status})`)}}const i=await n.json();if(!i.success)throw new Error(i.message||"获取配置 Schema 失败");return i.schema}async function J4(l){const n=await we(`/api/webui/plugins/config/${l}`,{headers:Us()});if(!n.ok){const c=await n.text();try{const u=JSON.parse(c);throw new Error(u.detail||"获取配置失败")}catch{throw new Error(`获取配置失败 (${n.status})`)}}const i=await n.json();if(!i.success)throw new Error(i.message||"获取配置失败");return i.config}async function X4(l){const n=await we(`/api/webui/plugins/config/${l}/raw`,{headers:Us()});if(!n.ok){const c=await n.text();try{const u=JSON.parse(c);throw new Error(u.detail||"获取配置失败")}catch{throw new Error(`获取配置失败 (${n.status})`)}}const i=await n.json();if(!i.success)throw new Error(i.message||"获取配置失败");return i.config}async function Z4(l,n){const i=await we(`/api/webui/plugins/config/${l}`,{method:"PUT",headers:Us(),body:JSON.stringify({config:n})});if(!i.ok){const c=await i.json();throw new Error(c.detail||"保存配置失败")}return await i.json()}async function W4(l,n){const i=await we(`/api/webui/plugins/config/${l}/raw`,{method:"PUT",headers:Us(),body:JSON.stringify({config:n})});if(!i.ok){const c=await i.json();throw new Error(c.detail||"保存配置失败")}return await i.json()}async function ek(l){const n=await we(`/api/webui/plugins/config/${l}/reset`,{method:"POST",headers:Us()});if(!n.ok){const i=await n.json();throw new Error(i.detail||"重置配置失败")}return await n.json()}async function sk(l){const n=await we(`/api/webui/plugins/config/${l}/toggle`,{method:"POST",headers:Us()});if(!n.ok){const i=await n.json();throw new Error(i.detail||"切换状态失败")}return await n.json()}const Wi="https://maibot-plugin-stats.maibot-webui.workers.dev";async function wv(l){try{const n=await fetch(`${Wi}/stats/${l}`);return n.ok?await n.json():(console.error("Failed to fetch plugin stats:",n.statusText),null)}catch(n){return console.error("Error fetching plugin stats:",n),null}}async function tk(l,n){try{const i=n||Qm(),c=await fetch(`${Wi}/stats/like`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:l,user_id:i})}),u=await c.json();return c.status===429?{success:!1,error:"操作过于频繁,请稍后再试"}:c.ok?{success:!0,...u}:{success:!1,error:u.error||"点赞失败"}}catch(i){return console.error("Error liking plugin:",i),{success:!1,error:"网络错误"}}}async function ak(l,n){try{const i=n||Qm(),c=await fetch(`${Wi}/stats/dislike`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:l,user_id:i})}),u=await c.json();return c.status===429?{success:!1,error:"操作过于频繁,请稍后再试"}:c.ok?{success:!0,...u}:{success:!1,error:u.error||"点踩失败"}}catch(i){return console.error("Error disliking plugin:",i),{success:!1,error:"网络错误"}}}async function lk(l,n,i,c){if(n<1||n>5)return{success:!1,error:"评分必须在 1-5 之间"};try{const u=c||Qm(),x=await fetch(`${Wi}/stats/rate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:l,rating:n,comment:i,user_id:u})}),h=await x.json();return x.status===429?{success:!1,error:"每天最多评分 3 次"}:x.ok?{success:!0,...h}:{success:!1,error:h.error||"评分失败"}}catch(u){return console.error("Error rating plugin:",u),{success:!1,error:"网络错误"}}}async function _v(l){try{const n=await fetch(`${Wi}/stats/download`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({plugin_id:l})}),i=await n.json();return n.status===429?(console.warn("Download recording rate limited"),{success:!0}):n.ok?{success:!0,...i}:(console.error("Failed to record download:",i.error),{success:!1,error:i.error})}catch(n){return console.error("Error recording download:",n),{success:!1,error:"网络错误"}}}function nk(){const l=navigator,n=[navigator.userAgent,navigator.language,navigator.languages?.join(",")||"",navigator.platform,navigator.hardwareConcurrency||0,screen.width,screen.height,screen.colorDepth,screen.pixelDepth,new Date().getTimezoneOffset(),Intl.DateTimeFormat().resolvedOptions().timeZone,navigator.maxTouchPoints||0,l.deviceMemory||0].join("|");let i=0;for(let c=0;c{const ee=q.map(async Oe=>{try{const me=await wv(Oe.id);return{id:Oe.id,stats:me}}catch(me){return console.warn(`Failed to load stats for ${Oe.id}:`,me),{id:Oe.id,stats:null}}}),ke=await Promise.all(ee),Te={};ke.forEach(({id:Oe,stats:me})=>{me&&(Te[Oe]=me)}),G(Te)};m.useEffect(()=>{let q=null,ee=!1;return(async()=>{if(q=await Q4(Te=>{ee||(S(Te),Te.stage==="success"?setTimeout(()=>{ee||S(null)},2e3):Te.stage==="error"&&(y(!1),D(Te.error||"加载失败")))},Te=>{console.error("WebSocket error:",Te),ee||je({title:"WebSocket 连接失败",description:"无法实时显示加载进度",variant:"destructive"})}),await new Promise(Te=>{if(!q){Te();return}const Oe=()=>{q&&q.readyState===WebSocket.OPEN?(console.log("WebSocket connected, starting to load plugins"),Te()):q&&q.readyState===WebSocket.CLOSED?(console.warn("WebSocket closed before loading plugins"),Te()):setTimeout(Oe,100)};Oe()}),!ee){const Te=await gv();I(Te),Te.installed||je({title:"Git 未安装",description:Te.error||"请先安装 Git 才能使用插件安装功能",variant:"destructive"})}if(!ee){const Te=await jv();$(Te)}if(!ee)try{y(!0),D(null);const Te=await V4();if(!ee){const Oe=await Sl();A(Oe);const me=Te.map(ze=>{const rs=nn(ze.id,Oe),Kt=rn(ze.id,Oe);return{...ze,installed:rs,installed_version:Kt}});for(const ze of Oe)!me.some(Kt=>Kt.id===ze.id)&&ze.manifest&&me.push({id:ze.id,manifest:{manifest_version:ze.manifest.manifest_version||1,name:ze.manifest.name,version:ze.manifest.version,description:ze.manifest.description||"",author:ze.manifest.author,license:ze.manifest.license||"Unknown",host_application:ze.manifest.host_application,homepage_url:ze.manifest.homepage_url,repository_url:ze.manifest.repository_url,keywords:ze.manifest.keywords||[],categories:ze.manifest.categories||[],default_locale:ze.manifest.default_locale||"zh-CN",locales_path:ze.manifest.locales_path},downloads:0,rating:0,review_count:0,installed:!0,installed_version:ze.manifest.version,published_at:new Date().toISOString(),updated_at:new Date().toISOString()});b(me),Se(me)}}catch(Te){if(!ee){const Oe=Te instanceof Error?Te.message:"加载插件列表失败";D(Oe),je({title:"加载失败",description:Oe,variant:"destructive"})}}finally{ee||y(!1)}})(),()=>{ee=!0,q&&q.close()}},[je]);const Y=q=>{if(!q.installed&&T&&!be(q))return e.jsxs(Ae,{variant:"destructive",className:"gap-1",children:[e.jsx(Ct,{className:"h-3 w-3"}),"不兼容"]});if(q.installed){const ee=q.installed_version?.trim(),ke=q.manifest.version?.trim();if(ee!==ke){const Te=ee?.split(".").map(Number)||[0,0,0],Oe=ke?.split(".").map(Number)||[0,0,0];for(let me=0;me<3;me++){if((Oe[me]||0)>(Te[me]||0))return e.jsxs(Ae,{variant:"outline",className:"gap-1 text-orange-600 border-orange-600",children:[e.jsx(Ct,{className:"h-3 w-3"}),"可更新"]});if((Oe[me]||0)<(Te[me]||0))break}}return e.jsxs(Ae,{variant:"default",className:"gap-1",children:[e.jsx(ea,{className:"h-3 w-3"}),"已安装"]})}return null},be=q=>!T||!q.manifest?.host_application?!0:vv(q.manifest.host_application.min_version,q.manifest.host_application.max_version,T),Z=q=>{if(!q.installed||!q.installed_version||!q.manifest?.version)return!1;const ee=q.installed_version.trim(),ke=q.manifest.version.trim();if(ee===ke)return!1;const Te=ee.split(".").map(Number),Oe=ke.split(".").map(Number);for(let me=0;me<3;me++){if((Oe[me]||0)>(Te[me]||0))return!0;if((Oe[me]||0)<(Te[me]||0))return!1}return!1},xe=v.filter(q=>{if(!q.manifest)return console.warn("[过滤] 跳过无 manifest 的插件:",q.id),!1;const ee=c===""||q.manifest.name?.toLowerCase().includes(c.toLowerCase())||q.manifest.description?.toLowerCase().includes(c.toLowerCase())||q.manifest.keywords&&q.manifest.keywords.some(me=>me.toLowerCase().includes(c.toLowerCase())),ke=x==="all"||q.manifest.categories&&q.manifest.categories.includes(x);let Te=!0;f==="installed"?Te=q.installed===!0:f==="updates"&&(Te=q.installed===!0&&Z(q));const Oe=!g||!T||be(q);return ee&&ke&&Te&&Oe}),Me=q=>{if(!k?.installed){je({title:"无法安装",description:"Git 未安装",variant:"destructive"});return}if(T&&!be(q)){je({title:"无法安装",description:"插件与当前麦麦版本不兼容",variant:"destructive"});return}le(q),ge("main"),V(""),L("preset"),_e(!1),oe(!0)},J=async()=>{if(!ve)return;const q=U==="custom"?z:fe;if(!q||q.trim()===""){je({title:"分支名称不能为空",variant:"destructive"});return}try{oe(!1),await Nv(ve.id,ve.manifest.repository_url||"",q),_v(ve.id).catch(ke=>{console.warn("Failed to record download:",ke)}),je({title:"安装成功",description:`${ve.manifest.name} 已成功安装`});const ee=await Sl();A(ee),b(ke=>ke.map(Te=>{if(Te.id===ve.id){const Oe=nn(Te.id,ee),me=rn(Te.id,ee);return{...Te,installed:Oe,installed_version:me}}return Te}))}catch(ee){je({title:"安装失败",description:ee instanceof Error?ee.message:"未知错误",variant:"destructive"})}finally{le(null)}},ce=async q=>{try{await bv(q.id),je({title:"卸载成功",description:`${q.manifest.name} 已成功卸载`});const ee=await Sl();A(ee),b(ke=>ke.map(Te=>{if(Te.id===q.id){const Oe=nn(Te.id,ee),me=rn(Te.id,ee);return{...Te,installed:Oe,installed_version:me}}return Te}))}catch(ee){je({title:"卸载失败",description:ee instanceof Error?ee.message:"未知错误",variant:"destructive"})}},Fe=async q=>{if(!k?.installed){je({title:"无法更新",description:"Git 未安装",variant:"destructive"});return}try{const ee=await yv(q.id,q.manifest.repository_url||"","main");je({title:"更新成功",description:`${q.manifest.name} 已从 ${ee.old_version} 更新到 ${ee.new_version}`});const ke=await Sl();A(ke),b(Te=>Te.map(Oe=>{if(Oe.id===q.id){const me=nn(Oe.id,ke),ze=rn(Oe.id,ke);return{...Oe,installed:me,installed_version:ze}}return Oe}))}catch(ee){je({title:"更新失败",description:ee instanceof Error?ee.message:"未知错误",variant:"destructive"})}};return e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件市场"}),e.jsx("p",{className:"text-muted-foreground mt-2",children:"浏览和管理麦麦的插件"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(C,{variant:"outline",onClick:()=>n(),disabled:i,children:[e.jsx(wj,{className:`h-4 w-4 mr-2 ${i?"animate-spin":""}`}),"重启麦麦"]}),e.jsxs(C,{onClick:()=>l({to:"/plugin-mirrors"}),children:[e.jsx(Vw,{className:"h-4 w-4 mr-2"}),"配置镜像源"]})]})]}),e.jsx(De,{className:"border-blue-200 bg-blue-50 dark:bg-blue-950/20 dark:border-blue-900",children:e.jsx(Qe,{className:"py-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(qt,{className:"h-4 w-4 text-blue-600 flex-shrink-0"}),e.jsxs("p",{className:"text-sm text-blue-800 dark:text-blue-200",children:["安装、卸载或更新插件后,需要",e.jsx("span",{className:"font-semibold",children:"重启麦麦"}),"才能使更改生效"]})]})})}),k&&!k.installed&&e.jsxs(De,{className:"border-orange-600 bg-orange-50 dark:bg-orange-950/20",children:[e.jsx(Xe,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ft,{className:"h-5 w-5 text-orange-600"}),e.jsxs("div",{children:[e.jsx(We,{className:"text-lg text-orange-900 dark:text-orange-100",children:"Git 未安装"}),e.jsx(Is,{className:"text-orange-800 dark:text-orange-200",children:k.error||"请先安装 Git 才能使用插件安装功能"})]})]})}),e.jsx(Qe,{children:e.jsxs("p",{className:"text-sm text-orange-800 dark:text-orange-200",children:["您可以从 ",e.jsx("a",{href:"https://git-scm.com/downloads",target:"_blank",rel:"noopener noreferrer",className:"underline font-medium",children:"git-scm.com"})," 下载并安装 Git。 安装完成后,请重启麦麦应用。"]})})]}),e.jsx(De,{className:"p-4",children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[e.jsxs("div",{className:"flex-1 relative",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索插件...",value:c,onChange:q=>u(q.target.value),className:"pl-9"})]}),e.jsxs(Be,{value:x,onValueChange:h,children:[e.jsx(Le,{className:"w-full sm:w-[200px]",children:e.jsx($e,{placeholder:"选择分类"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"all",children:"全部分类"}),e.jsx(ae,{value:"Group Management",children:"群组管理"}),e.jsx(ae,{value:"Entertainment & Interaction",children:"娱乐互动"}),e.jsx(ae,{value:"Utility Tools",children:"实用工具"}),e.jsx(ae,{value:"Content Generation",children:"内容生成"}),e.jsx(ae,{value:"Multimedia",children:"多媒体"}),e.jsx(ae,{value:"External Integration",children:"外部集成"}),e.jsx(ae,{value:"Data Analysis & Insights",children:"数据分析与洞察"}),e.jsx(ae,{value:"Other",children:"其他"})]})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"compatible-only",checked:g,onCheckedChange:q=>N(q===!0)}),e.jsx("label",{htmlFor:"compatible-only",className:"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer",children:"只显示兼容当前版本的插件"})]})]})}),e.jsx(ma,{value:f,onValueChange:p,className:"w-full",children:e.jsxs(ta,{className:"grid w-full grid-cols-3",children:[e.jsxs(as,{value:"all",children:["全部插件 (",v.filter(q=>{if(!q.manifest)return!1;const ee=c===""||q.manifest.name?.toLowerCase().includes(c.toLowerCase())||q.manifest.description?.toLowerCase().includes(c.toLowerCase())||q.manifest.keywords&&q.manifest.keywords.some(Oe=>Oe.toLowerCase().includes(c.toLowerCase())),ke=x==="all"||q.manifest.categories&&q.manifest.categories.includes(x),Te=!g||!T||be(q);return ee&&ke&&Te}).length,")"]}),e.jsxs(as,{value:"installed",children:["已安装 (",v.filter(q=>{if(!q.manifest)return!1;const ee=c===""||q.manifest.name?.toLowerCase().includes(c.toLowerCase())||q.manifest.description?.toLowerCase().includes(c.toLowerCase())||q.manifest.keywords&&q.manifest.keywords.some(Oe=>Oe.toLowerCase().includes(c.toLowerCase())),ke=x==="all"||q.manifest.categories&&q.manifest.categories.includes(x),Te=!g||!T||be(q);return q.installed&&ee&&ke&&Te}).length,")"]}),e.jsxs(as,{value:"updates",children:["可更新 (",v.filter(q=>{if(!q.manifest)return!1;const ee=c===""||q.manifest.name?.toLowerCase().includes(c.toLowerCase())||q.manifest.description?.toLowerCase().includes(c.toLowerCase())||q.manifest.keywords&&q.manifest.keywords.some(Oe=>Oe.toLowerCase().includes(c.toLowerCase())),ke=x==="all"||q.manifest.categories&&q.manifest.categories.includes(x),Te=!g||!T||be(q);return q.installed&&Z(q)&&ee&&ke&&Te}).length,")"]})]})}),M&&M.stage==="loading"&&M.operation==="fetch"&&e.jsx(De,{className:"p-4",children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(zs,{className:"h-4 w-4 animate-spin"}),e.jsx("span",{className:"text-sm font-medium",children:"加载插件列表"})]}),e.jsxs("span",{className:"text-sm font-medium",children:[M.progress,"%"]})]}),e.jsx(Bn,{value:M.progress,className:"h-2"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:M.message}),M.total_plugins>0&&e.jsxs("div",{className:"text-xs text-muted-foreground text-center",children:["已加载 ",M.loaded_plugins," / ",M.total_plugins," 个插件"]})]})}),M&&M.stage==="error"&&M.error&&e.jsx(De,{className:"border-destructive bg-destructive/10",children:e.jsx(Xe,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ft,{className:"h-5 w-5 text-destructive"}),e.jsxs("div",{children:[e.jsx(We,{className:"text-lg text-destructive",children:"加载失败"}),e.jsx(Is,{className:"text-destructive/80",children:M.error})]})]})})}),w?e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx(zs,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-3 text-muted-foreground",children:"加载插件列表中..."})]}):R?e.jsx(De,{className:"p-6",children:e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[e.jsx(Ft,{className:"h-12 w-12 text-destructive mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"加载失败"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:R}),e.jsx(C,{onClick:()=>window.location.reload(),children:"重新加载"})]})}):xe.length===0?e.jsx(De,{className:"p-6",children:e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[e.jsx(Vt,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未找到插件"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:c||x!=="all"?"尝试调整搜索条件或筛选器":"暂无可用插件"})]})}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:xe.map(q=>e.jsxs(De,{className:"flex flex-col hover:shadow-lg transition-shadow h-full",children:[e.jsxs(Xe,{children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsx(We,{className:"text-xl",children:q.manifest?.name||q.id}),e.jsxs("div",{className:"flex flex-col gap-1",children:[q.manifest?.categories&&q.manifest.categories[0]&&e.jsx(Ae,{variant:"secondary",className:"text-xs whitespace-nowrap",children:rk[q.manifest.categories[0]]||q.manifest.categories[0]}),Y(q)]})]}),e.jsx(Is,{className:"line-clamp-2",children:q.manifest?.description||"无描述"})]}),e.jsx(Qe,{className:"flex-1",children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(Xt,{className:"h-4 w-4"}),e.jsx("span",{children:(Q[q.id]?.downloads??q.downloads??0).toLocaleString()})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(an,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),e.jsx("span",{children:(Q[q.id]?.rating??q.rating??0).toFixed(1)})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[q.manifest?.keywords&&q.manifest.keywords.slice(0,3).map(ee=>e.jsx(Ae,{variant:"outline",className:"text-xs",children:ee},ee)),q.manifest?.keywords&&q.manifest.keywords.length>3&&e.jsxs(Ae,{variant:"outline",className:"text-xs",children:["+",q.manifest.keywords.length-3]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground pt-2 border-t space-y-1",children:[e.jsxs("div",{children:["v",q.manifest?.version||"unknown"," · ",q.manifest?.author?.name||"Unknown"]}),q.manifest?.host_application&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{children:"支持:"}),e.jsxs("span",{className:"font-medium",children:[q.manifest.host_application.min_version,q.manifest.host_application.max_version?` - ${q.manifest.host_application.max_version}`:" - 最新版本"]})]})]})]})}),e.jsx(Io,{className:"pt-4",children:e.jsxs("div",{className:"flex items-center justify-end gap-2 w-full",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>l({to:"/plugin-detail",search:{pluginId:q.id}}),children:"查看详情"}),q.installed?Z(q)?e.jsxs(C,{size:"sm",disabled:!k?.installed,title:k?.installed?void 0:"Git 未安装",onClick:()=>Fe(q),children:[e.jsx(kt,{className:"h-4 w-4 mr-1"}),"更新"]}):e.jsxs(C,{variant:"destructive",size:"sm",disabled:!k?.installed,title:k?.installed?void 0:"Git 未安装",onClick:()=>ce(q),children:[e.jsx(ls,{className:"h-4 w-4 mr-1"}),"卸载"]}):e.jsxs(C,{size:"sm",disabled:!k?.installed||M?.operation==="install"||T!==null&&!be(q),title:k?.installed?T!==null&&!be(q)?`不兼容当前版本 (需要 ${q.manifest?.host_application?.min_version||"未知"}${q.manifest?.host_application?.max_version?` - ${q.manifest.host_application.max_version}`:"+"},当前 ${T?.version})`:void 0:"Git 未安装",onClick:()=>Me(q),children:[e.jsx(Xt,{className:"h-4 w-4 mr-1"}),M?.operation==="install"&&M?.plugin_id===q.id?"安装中...":"安装"]})]})}),M&&(M.stage==="loading"||M.stage==="success"||M.stage==="error")&&M.operation!=="fetch"&&M.plugin_id===q.id&&e.jsx("div",{className:"px-6 pb-4 -mt-2",children:e.jsxs("div",{className:`space-y-2 p-3 rounded-lg border ${M.stage==="success"?"bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900":M.stage==="error"?"bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900":"bg-muted/50"}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[M.stage==="loading"?e.jsx(zs,{className:"h-3 w-3 animate-spin"}):M.stage==="success"?e.jsx(ea,{className:"h-3 w-3 text-green-600"}):e.jsx(Ct,{className:"h-3 w-3 text-red-600"}),e.jsx("span",{className:`text-xs font-medium ${M.stage==="success"?"text-green-700 dark:text-green-300":M.stage==="error"?"text-red-700 dark:text-red-300":""}`,children:M.stage==="loading"?e.jsxs(e.Fragment,{children:[M.operation==="install"&&"正在安装",M.operation==="uninstall"&&"正在卸载",M.operation==="update"&&"正在更新"]}):M.stage==="success"?e.jsxs(e.Fragment,{children:[M.operation==="install"&&"安装完成",M.operation==="uninstall"&&"卸载完成",M.operation==="update"&&"更新完成"]}):e.jsxs(e.Fragment,{children:[M.operation==="install"&&"安装失败",M.operation==="uninstall"&&"卸载失败",M.operation==="update"&&"更新失败"]})})]}),M.stage!=="error"&&e.jsxs("span",{className:`text-xs font-medium ${M.stage==="success"?"text-green-700 dark:text-green-300":""}`,children:[M.progress,"%"]})]}),M.stage!=="error"&&e.jsx(Bn,{value:M.progress,className:`h-1.5 ${M.stage==="success"?"[&>div]:bg-green-500":""}`}),e.jsx("div",{className:`text-xs ${M.stage==="success"?"text-green-600 dark:text-green-400 truncate":M.stage==="error"?"text-red-600 dark:text-red-400":"text-muted-foreground truncate"}`,children:M.stage==="error"?M.error||M.message||"操作失败":M.message})]})})]},q.id))}),e.jsx(Ks,{open:de,onOpenChange:oe,children:e.jsxs(Ps,{children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"安装插件"}),e.jsxs(ot,{children:["安装 ",ve?.manifest.name]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["版本: ",ve?.manifest.version]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["作者: ",typeof ve?.manifest.author=="string"?ve.manifest.author:ve?.manifest.author?.name]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"advanced-options",checked:P,onCheckedChange:q=>_e(q)}),e.jsx("label",{htmlFor:"advanced-options",className:"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",children:"高级选项"})]}),P&&e.jsx("div",{className:"space-y-4 p-4 border rounded-lg",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium",children:"分支选择"}),e.jsxs(ma,{value:U,onValueChange:q=>L(q),children:[e.jsxs(ta,{className:"grid w-full grid-cols-2",children:[e.jsx(as,{value:"preset",className:"text-xs",children:"预设分支"}),e.jsx(as,{value:"custom",className:"text-xs",children:"自定义分支"})]}),U==="preset"&&e.jsx("div",{className:"mt-3",children:e.jsxs(Be,{value:fe,onValueChange:ge,children:[e.jsx(Le,{children:e.jsx($e,{placeholder:"选择分支"})}),e.jsxs(Ue,{children:[e.jsx(ae,{value:"main",children:"main (默认)"}),e.jsx(ae,{value:"master",children:"master"}),e.jsx(ae,{value:"dev",children:"dev (开发版)"}),e.jsx(ae,{value:"develop",children:"develop"}),e.jsx(ae,{value:"beta",children:"beta (测试版)"}),e.jsx(ae,{value:"stable",children:"stable (稳定版)"})]})]})}),U==="custom"&&e.jsxs("div",{className:"space-y-2 mt-3",children:[e.jsx("input",{type:"text",className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",placeholder:"输入分支名称,例如: feature/new-feature",value:z,onChange:q=>V(q.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"输入 Git 分支名称、标签或提交哈希"})]})]})]})}),!P&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"将从默认分支 (main) 安装插件"})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>oe(!1),children:"取消"}),e.jsxs(C,{onClick:J,children:[e.jsx(Xt,{className:"h-4 w-4 mr-2"}),"安装"]})]})]})}),e.jsx(Hn,{})]})})}function ok(){return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsx("div",{className:"mb-4 sm:mb-6",children:e.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(_j,{className:"h-8 w-8",strokeWidth:2}),"模型分配预设市场"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"浏览和下载社区共享的模型分配预设配置"})]})})}),e.jsx(es,{className:"flex-1",children:e.jsx("div",{className:"flex items-center justify-center h-[calc(100vh-12rem)]",children:e.jsxs(De,{className:"max-w-2xl w-full border-dashed",children:[e.jsxs(Xe,{className:"text-center",children:[e.jsx("div",{className:"flex justify-center mb-4",children:e.jsx(Wt,{className:"h-16 w-16 text-muted-foreground"})}),e.jsx(We,{className:"text-2xl",children:"功能开发中"}),e.jsx(Is,{className:"text-base",children:"模型分配预设市场功能正在开发中,敬请期待!"})]}),e.jsx(Qe,{children:e.jsxs("div",{className:"space-y-3 text-sm text-muted-foreground",children:[e.jsx("p",{className:"font-medium text-foreground",children:"📦 即将推出的功能:"}),e.jsxs("ul",{className:"space-y-2 ml-6",children:[e.jsxs("li",{className:"flex items-start",children:[e.jsx("span",{className:"mr-2",children:"•"}),e.jsx("span",{children:"浏览社区共享的模型分配预设配置"})]}),e.jsxs("li",{className:"flex items-start",children:[e.jsx("span",{className:"mr-2",children:"•"}),e.jsx("span",{children:"一键下载和应用预设配置"})]}),e.jsxs("li",{className:"flex items-start",children:[e.jsx("span",{className:"mr-2",children:"•"}),e.jsx("span",{children:"分享自己的模型分配方案"})]}),e.jsxs("li",{className:"flex items-start",children:[e.jsx("span",{className:"mr-2",children:"•"}),e.jsx("span",{children:"预设配置评分和评论系统"})]}),e.jsxs("li",{className:"flex items-start",children:[e.jsx("span",{className:"mr-2",children:"•"}),e.jsx("span",{children:"根据使用场景智能推荐配置"})]})]})]})})]})})})]})}function dk({field:l,value:n,onChange:i}){const[c,u]=m.useState(!1);switch(l.ui_type){case"switch":return e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(E,{children:l.label}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]}),e.jsx(Ge,{checked:!!n,onCheckedChange:i,disabled:l.disabled})]});case"number":return e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:l.label}),e.jsx(ie,{type:"number",value:n??l.default,onChange:x=>i(parseFloat(x.target.value)||0),min:l.min,max:l.max,step:l.step??1,placeholder:l.placeholder,disabled:l.disabled}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]});case"slider":return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(E,{children:l.label}),e.jsx("span",{className:"text-sm text-muted-foreground",children:n??l.default})]}),e.jsx(wa,{value:[n??l.default],onValueChange:x=>i(x[0]),min:l.min??0,max:l.max??100,step:l.step??1,disabled:l.disabled}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]});case"select":return e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:l.label}),e.jsxs(Be,{value:String(n??l.default),onValueChange:i,disabled:l.disabled,children:[e.jsx(Le,{children:e.jsx($e,{placeholder:l.placeholder??"请选择"})}),e.jsx(Ue,{children:l.choices?.map(x=>e.jsx(ae,{value:String(x),children:String(x)},String(x)))})]}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]});case"textarea":return e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:l.label}),e.jsx(et,{value:n??l.default,onChange:x=>i(x.target.value),placeholder:l.placeholder,rows:l.rows??3,disabled:l.disabled}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]});case"password":return e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:l.label}),e.jsxs("div",{className:"relative",children:[e.jsx(ie,{type:c?"text":"password",value:n??"",onChange:x=>i(x.target.value),placeholder:l.placeholder,disabled:l.disabled,className:"pr-10"}),e.jsx(C,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-3",onClick:()=>u(!c),children:c?e.jsx(Hi,{className:"h-4 w-4"}):e.jsx(sa,{className:"h-4 w-4"})})]}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]});case"list":return e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:l.label}),e.jsx(f_,{value:Array.isArray(n)?n:[],onChange:x=>i(x),itemType:l.item_type??"string",itemFields:l.item_fields,minItems:l.min_items,maxItems:l.max_items,disabled:l.disabled,placeholder:l.placeholder}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]});case"text":default:return e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:l.label}),e.jsx(ie,{type:"text",value:n??l.default??"",onChange:x=>i(x.target.value),placeholder:l.placeholder,maxLength:l.max_length,disabled:l.disabled}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground",children:l.hint})]})}}function vg({section:l,config:n,onChange:i}){const[c,u]=m.useState(!l.collapsed),x=Object.entries(l.fields).filter(([,h])=>!h.hidden).sort(([,h],[,f])=>h.order-f.order);return e.jsx(Ki,{open:c,onOpenChange:u,children:e.jsxs(De,{children:[e.jsx(Qi,{asChild:!0,children:e.jsxs(Xe,{className:"cursor-pointer hover:bg-muted/50 transition-colors",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[c?e.jsx($a,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(Sa,{className:"h-4 w-4 text-muted-foreground"}),e.jsx(We,{className:"text-lg",children:l.title})]}),e.jsxs(Ae,{variant:"secondary",className:"text-xs",children:[x.length," 项"]})]}),l.description&&e.jsx(Is,{className:"ml-6",children:l.description})]})}),e.jsx(Yi,{children:e.jsx(Qe,{className:"space-y-4 pt-0",children:x.map(([h,f])=>e.jsx(dk,{field:f,value:n[l.name]?.[h],onChange:p=>i(l.name,h,p),sectionName:l.name},h))})})]})})}function uk({plugin:l,onBack:n}){const{toast:i}=Ws(),{triggerRestart:c,isRestarting:u}=dn(),[x,h]=m.useState("visual"),[f,p]=m.useState(null),[g,N]=m.useState({}),[v,b]=m.useState({}),[w,y]=m.useState(""),[R,D]=m.useState(""),[k,I]=m.useState(!0),[M,S]=m.useState(!1),[T,$]=m.useState(!1),[A,Q]=m.useState(!1),[G,de]=m.useState(!1),oe=m.useCallback(async()=>{I(!0);try{const[U,L,P]=await Promise.all([Y4(l.id),J4(l.id),X4(l.id)]);p(U),N(L),b(JSON.parse(JSON.stringify(L))),y(P),D(P)}catch(U){i({title:"加载配置失败",description:U instanceof Error?U.message:"未知错误",variant:"destructive"})}finally{I(!1)}},[l.id,i]);m.useEffect(()=>{oe()},[oe]),m.useEffect(()=>{$(x==="visual"?JSON.stringify(g)!==JSON.stringify(v):w!==R)},[g,v,w,R,x]);const ve=(U,L,P)=>{N(_e=>({..._e,[U]:{..._e[U]||{},[L]:P}}))},le=async()=>{S(!0);try{if(x==="source"){try{mv(w)}catch(U){Q(!0),i({title:"TOML 格式错误",description:U instanceof Error?U.message:"无法解析 TOML 配置,请检查语法",variant:"destructive"}),S(!1);return}await W4(l.id,w),D(w),Q(!1)}else await Z4(l.id,g),b(JSON.parse(JSON.stringify(g)));i({title:"配置已保存",description:"更改将在插件重新加载后生效"})}catch(U){i({title:"保存失败",description:U instanceof Error?U.message:"未知错误",variant:"destructive"})}finally{S(!1)}},fe=async()=>{try{await ek(l.id),i({title:"配置已重置",description:"下次加载插件时将使用默认配置"}),de(!1),oe()}catch(U){i({title:"重置失败",description:U instanceof Error?U.message:"未知错误",variant:"destructive"})}},ge=async()=>{try{const U=await sk(l.id);i({title:U.message,description:U.note}),oe()}catch(U){i({title:"切换状态失败",description:U instanceof Error?U.message:"未知错误",variant:"destructive"})}};if(k)return e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(zs,{className:"h-8 w-8 animate-spin text-muted-foreground"})});if(!f)return e.jsxs("div",{className:"flex flex-col items-center justify-center h-64 space-y-4",children:[e.jsx(Ct,{className:"h-12 w-12 text-muted-foreground"}),e.jsx("p",{className:"text-muted-foreground",children:"无法加载配置"}),e.jsxs(C,{onClick:n,variant:"outline",children:[e.jsx(Va,{className:"h-4 w-4 mr-2"}),"返回"]})]});const z=Object.values(f.sections).sort((U,L)=>U.order-L.order),V=g.plugin?.enabled!==!1;return e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(C,{variant:"ghost",size:"icon",onClick:n,children:e.jsx(Va,{className:"h-5 w-5"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:f.plugin_info.name||l.manifest.name}),e.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[e.jsx(Ae,{variant:V?"default":"secondary",children:V?"已启用":"已禁用"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["v",f.plugin_info.version||l.manifest.version]})]})]})]}),e.jsxs("div",{className:"flex gap-2 ml-10 sm:ml-0",children:[e.jsx(C,{variant:"outline",size:"sm",onClick:()=>h(x==="visual"?"source":"visual"),children:x==="visual"?e.jsxs(e.Fragment,{children:[e.jsx(vj,{className:"h-4 w-4 mr-2"}),"源代码"]}):e.jsxs(e.Fragment,{children:[e.jsx(jj,{className:"h-4 w-4 mr-2"}),"可视化"]})}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>c(),disabled:u,children:[e.jsx(wj,{className:`h-4 w-4 mr-2 ${u?"animate-spin":""}`}),"重启麦麦"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:ge,children:[e.jsx(Ji,{className:"h-4 w-4 mr-2"}),V?"禁用":"启用"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>de(!0),children:[e.jsx(Pi,{className:"h-4 w-4 mr-2"}),"重置"]}),e.jsxs(C,{size:"sm",onClick:le,disabled:!T||M,children:[M?e.jsx(zs,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Xi,{className:"h-4 w-4 mr-2"}),"保存"]})]})]}),T&&e.jsx(De,{className:"border-orange-200 bg-orange-50 dark:bg-orange-950/20 dark:border-orange-900",children:e.jsx(Qe,{className:"py-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(qt,{className:"h-4 w-4 text-orange-600"}),e.jsx("p",{className:"text-sm text-orange-800 dark:text-orange-200",children:"有未保存的更改"})]})})}),x==="source"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs(nt,{children:[e.jsx(Ct,{className:"h-4 w-4"}),e.jsxs(rt,{children:[e.jsx("strong",{children:"源代码模式(高级功能):"}),"直接编辑 TOML 配置文件。保存时会验证格式,只有格式正确才能保存。",A&&e.jsx("span",{className:"text-destructive font-semibold ml-2",children:"⚠️ 上次保存失败,请检查 TOML 格式"})]})]}),e.jsx(ev,{value:w,onChange:U=>{y(U),A&&Q(!1)},language:"toml",theme:"dark",height:"calc(100vh - 350px)",minHeight:"500px",placeholder:"TOML 配置内容"})]}),x==="visual"&&e.jsxs(e.Fragment,{children:[e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsxs(rt,{children:[e.jsx("strong",{children:"提示:"}),"如果插件当前未加载或未启用,WebUI 适配器的高级插件可视化编辑功能可能会不可用。 请确保插件已启用并成功加载后,再进行配置编辑。"]})]}),f.layout.type==="tabs"&&f.layout.tabs.length>0?e.jsxs(ma,{defaultValue:f.layout.tabs[0]?.id,children:[e.jsx(ta,{children:f.layout.tabs.map(U=>e.jsxs(as,{value:U.id,children:[U.title,U.badge&&e.jsx(Ae,{variant:"secondary",className:"ml-2 text-xs",children:U.badge})]},U.id))}),f.layout.tabs.map(U=>e.jsx(ys,{value:U.id,className:"space-y-4 mt-4",children:U.sections.map(L=>{const P=f.sections[L];return P?e.jsx(vg,{section:P,config:g,onChange:ve},L):null})},U.id))]}):e.jsx("div",{className:"space-y-4",children:z.map(U=>e.jsx(vg,{section:U,config:g,onChange:ve},U.name))})]}),e.jsx(Ks,{open:G,onOpenChange:de,children:e.jsxs(Ps,{children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"确认重置配置"}),e.jsx(ot,{children:"这将删除当前配置文件,下次加载插件时将使用默认配置。此操作不可撤销。"})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>de(!1),children:"取消"}),e.jsx(C,{variant:"destructive",onClick:fe,children:"确认重置"})]})]})})]})}function mk(){return e.jsx(Pn,{children:e.jsx(xk,{})})}function xk(){const{toast:l}=Ws(),[n,i]=m.useState([]),[c,u]=m.useState(!0),[x,h]=m.useState(""),[f,p]=m.useState(null),g=async()=>{u(!0);try{const y=await Sl();i(y)}catch(y){l({title:"加载插件列表失败",description:y instanceof Error?y.message:"未知错误",variant:"destructive"})}finally{u(!1)}};m.useEffect(()=>{g()},[]);const v=n.filter(y=>{const R=x.toLowerCase();return y.id.toLowerCase().includes(R)||y.manifest.name.toLowerCase().includes(R)||y.manifest.description?.toLowerCase().includes(R)}).filter((y,R,D)=>R===D.findIndex(k=>k.id===y.id)),b=n.length,w=0;return f?e.jsxs(e.Fragment,{children:[e.jsx(es,{className:"h-full",children:e.jsx("div",{className:"p-4 sm:p-6",children:e.jsx(uk,{plugin:f,onBack:()=>p(null)})})}),e.jsx(Hn,{})]}):e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件配置"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:"管理和配置已安装的插件"})]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:g,children:[e.jsx(kt,{className:`h-4 w-4 mr-2 ${c?"animate-spin":""}`}),"刷新"]})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-1 xs:grid-cols-2 lg:grid-cols-3",children:[e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"已安装插件"}),e.jsx(Wt,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(Qe,{children:[e.jsx("div",{className:"text-2xl font-bold",children:n.length}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:c?"正在加载...":"个插件"})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"已启用"}),e.jsx(ea,{className:"h-4 w-4 text-green-600"})]}),e.jsxs(Qe,{children:[e.jsx("div",{className:"text-2xl font-bold",children:b}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"运行中的插件"})]})]}),e.jsxs(De,{children:[e.jsxs(Xe,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(We,{className:"text-sm font-medium",children:"已禁用"}),e.jsx(Ct,{className:"h-4 w-4 text-orange-600"})]}),e.jsxs(Qe,{children:[e.jsx("div",{className:"text-2xl font-bold",children:w}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"未激活的插件"})]})]})]}),e.jsxs("div",{className:"relative",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索插件...",value:x,onChange:y=>h(y.target.value),className:"pl-9"})]}),e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"已安装的插件"}),e.jsx(Is,{children:"点击插件查看和编辑配置"})]}),e.jsx(Qe,{children:c?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(zs,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):v.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 space-y-4",children:[e.jsx(Wt,{className:"h-16 w-16 text-muted-foreground/50"}),e.jsxs("div",{className:"text-center space-y-2",children:[e.jsx("p",{className:"text-lg font-medium text-muted-foreground",children:x?"没有找到匹配的插件":"暂无已安装的插件"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:x?"尝试其他搜索关键词":"前往插件市场安装插件"})]})]}):e.jsx("div",{className:"space-y-2",children:v.map(y=>e.jsxs("div",{className:"flex items-center justify-between p-4 rounded-lg border hover:bg-muted/50 cursor-pointer transition-colors",onClick:()=>p(y),children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx("div",{className:"h-10 w-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0",children:e.jsx(Wt,{className:"h-5 w-5 text-primary"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-medium truncate",children:y.manifest.name}),e.jsxs(Ae,{variant:"secondary",className:"text-xs flex-shrink-0",children:["v",y.manifest.version]})]}),e.jsx("p",{className:"text-sm text-muted-foreground truncate",children:y.manifest.description||"暂无描述"})]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[e.jsx(C,{variant:"ghost",size:"sm",children:e.jsx(In,{className:"h-4 w-4"})}),e.jsx(Sa,{className:"h-4 w-4 text-muted-foreground"})]})]},y.id))})})]})]})})}function hk(){const l=aa(),{toast:n}=Ws(),[i,c]=m.useState([]),[u,x]=m.useState(!0),[h,f]=m.useState(null),[p,g]=m.useState(null),[N,v]=m.useState(!1),[b,w]=m.useState(!1),[y,R]=m.useState({id:"",name:"",raw_prefix:"",clone_prefix:"",enabled:!0,priority:1}),D=m.useCallback(async()=>{try{x(!0),f(null);const A=await we("/api/webui/plugins/mirrors");if(!A.ok)throw new Error("获取镜像源列表失败");const Q=await A.json();c(Q.mirrors||[])}catch(A){const Q=A instanceof Error?A.message:"加载镜像源失败";f(Q),n({title:"加载失败",description:Q,variant:"destructive"})}finally{x(!1)}},[n]);m.useEffect(()=>{D()},[D]);const k=async()=>{try{const A=await we("/api/webui/plugins/mirrors",{method:"POST",body:JSON.stringify(y)});if(!A.ok){const Q=await A.json();throw new Error(Q.detail||"添加镜像源失败")}n({title:"添加成功",description:"镜像源已添加"}),v(!1),R({id:"",name:"",raw_prefix:"",clone_prefix:"",enabled:!0,priority:1}),D()}catch(A){n({title:"添加失败",description:A instanceof Error?A.message:"未知错误",variant:"destructive"})}},I=async()=>{if(p)try{if(!(await we(`/api/webui/plugins/mirrors/${p.id}`,{method:"PUT",body:JSON.stringify({name:y.name,raw_prefix:y.raw_prefix,clone_prefix:y.clone_prefix,enabled:y.enabled,priority:y.priority})})).ok)throw new Error("更新镜像源失败");n({title:"更新成功",description:"镜像源已更新"}),w(!1),g(null),D()}catch(A){n({title:"更新失败",description:A instanceof Error?A.message:"未知错误",variant:"destructive"})}},M=async A=>{if(confirm("确定要删除这个镜像源吗?"))try{if(!(await we(`/api/webui/plugins/mirrors/${A}`,{method:"DELETE"})).ok)throw new Error("删除镜像源失败");n({title:"删除成功",description:"镜像源已删除"}),D()}catch(Q){n({title:"删除失败",description:Q instanceof Error?Q.message:"未知错误",variant:"destructive"})}},S=async A=>{try{if(!(await we(`/api/webui/plugins/mirrors/${A.id}`,{method:"PUT",body:JSON.stringify({enabled:!A.enabled})})).ok)throw new Error("更新状态失败");D()}catch(Q){n({title:"更新失败",description:Q instanceof Error?Q.message:"未知错误",variant:"destructive"})}},T=A=>{g(A),R({id:A.id,name:A.name,raw_prefix:A.raw_prefix,clone_prefix:A.clone_prefix,enabled:A.enabled,priority:A.priority}),w(!0)},$=async(A,Q)=>{const G=Q==="up"?A.priority-1:A.priority+1;if(!(G<1))try{if(!(await we(`/api/webui/plugins/mirrors/${A.id}`,{method:"PUT",body:JSON.stringify({priority:G})})).ok)throw new Error("更新优先级失败");D()}catch(de){n({title:"更新失败",description:de instanceof Error?de.message:"未知错误",variant:"destructive"})}};return e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(C,{variant:"ghost",size:"icon",onClick:()=>l({to:"/plugins"}),children:e.jsx(Va,{className:"h-5 w-5"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"镜像源配置"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"管理 Git 克隆和文件下载的镜像源"})]})]}),e.jsxs(C,{onClick:()=>v(!0),children:[e.jsx(it,{className:"h-4 w-4 mr-2"}),"添加镜像源"]})]}),u?e.jsx(De,{className:"p-6",children:e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(zs,{className:"h-8 w-8 animate-spin text-primary"})})}):h?e.jsx(De,{className:"p-6",children:e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[e.jsx(Ft,{className:"h-12 w-12 text-destructive mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"加载失败"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:h}),e.jsx(C,{onClick:D,children:"重新加载"})]})}):e.jsxs(De,{children:[e.jsx("div",{className:"hidden md:block",children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{children:"状态"}),e.jsx(Je,{children:"名称"}),e.jsx(Je,{children:"ID"}),e.jsx(Je,{children:"优先级"}),e.jsx(Je,{className:"text-right",children:"操作"})]})}),e.jsx(Al,{children:i.map(A=>e.jsxs(ct,{children:[e.jsx(He,{children:e.jsx(Ge,{checked:A.enabled,onCheckedChange:()=>S(A)})}),e.jsx(He,{children:e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:A.name}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1",children:["Raw: ",A.raw_prefix]})]})}),e.jsx(He,{children:e.jsx(Ae,{variant:"outline",children:A.id})}),e.jsx(He,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono",children:A.priority}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(C,{variant:"ghost",size:"icon",className:"h-5 w-5",onClick:()=>$(A,"up"),disabled:A.priority===1,children:e.jsx(Dr,{className:"h-3 w-3"})}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-5 w-5",onClick:()=>$(A,"down"),children:e.jsx($a,{className:"h-3 w-3"})})]})]})}),e.jsx(He,{className:"text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx(C,{variant:"ghost",size:"icon",onClick:()=>T(A),children:e.jsx(On,{className:"h-4 w-4"})}),e.jsx(C,{variant:"ghost",size:"icon",onClick:()=>M(A.id),children:e.jsx(ls,{className:"h-4 w-4 text-destructive"})})]})})]},A.id))})]})}),e.jsx("div",{className:"md:hidden p-4 space-y-4",children:i.map(A=>e.jsx(De,{className:"p-4",children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-semibold",children:A.name}),A.enabled&&e.jsx(Ae,{variant:"default",className:"text-xs",children:"启用"})]}),e.jsx(Ae,{variant:"outline",className:"mt-1 text-xs",children:A.id})]}),e.jsx(Ge,{checked:A.enabled,onCheckedChange:()=>S(A)})]}),e.jsxs("div",{className:"text-sm space-y-1",children:[e.jsxs("div",{className:"text-muted-foreground",children:[e.jsx("span",{className:"font-medium",children:"Raw: "}),e.jsx("span",{className:"break-all",children:A.raw_prefix})]}),e.jsxs("div",{className:"text-muted-foreground",children:[e.jsx("span",{className:"font-medium",children:"优先级: "}),e.jsx("span",{className:"font-mono",children:A.priority})]})]}),e.jsxs("div",{className:"flex items-center gap-2 pt-2 border-t",children:[e.jsxs(C,{variant:"outline",size:"sm",className:"flex-1",onClick:()=>T(A),children:[e.jsx(On,{className:"h-4 w-4 mr-1"}),"编辑"]}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>$(A,"up"),disabled:A.priority===1,children:e.jsx(Dr,{className:"h-4 w-4"})}),e.jsx(C,{variant:"outline",size:"sm",onClick:()=>$(A,"down"),children:e.jsx($a,{className:"h-4 w-4"})}),e.jsx(C,{variant:"destructive",size:"sm",onClick:()=>M(A.id),children:e.jsx(ls,{className:"h-4 w-4"})})]})]})},A.id))})]}),e.jsx(Ks,{open:N,onOpenChange:v,children:e.jsxs(Ps,{className:"max-w-lg",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"添加镜像源"}),e.jsx(ot,{children:"添加新的 Git 镜像源配置"})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"add-id",children:"镜像源 ID *"}),e.jsx(ie,{id:"add-id",placeholder:"例如: my-mirror",value:y.id,onChange:A=>R({...y,id:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"add-name",children:"名称 *"}),e.jsx(ie,{id:"add-name",placeholder:"例如: 我的镜像源",value:y.name,onChange:A=>R({...y,name:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"add-raw",children:"Raw 文件前缀 *"}),e.jsx(ie,{id:"add-raw",placeholder:"https://example.com/raw",value:y.raw_prefix,onChange:A=>R({...y,raw_prefix:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"add-clone",children:"克隆前缀 *"}),e.jsx(ie,{id:"add-clone",placeholder:"https://example.com/clone",value:y.clone_prefix,onChange:A=>R({...y,clone_prefix:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"add-priority",children:"优先级"}),e.jsx(ie,{id:"add-priority",type:"number",min:"1",value:y.priority,onChange:A=>R({...y,priority:parseInt(A.target.value)||1})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"数字越小优先级越高"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"add-enabled",checked:y.enabled,onCheckedChange:A=>R({...y,enabled:A})}),e.jsx(E,{htmlFor:"add-enabled",children:"启用此镜像源"})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>v(!1),children:"取消"}),e.jsx(C,{onClick:k,children:"添加"})]})]})}),e.jsx(Ks,{open:b,onOpenChange:w,children:e.jsxs(Ps,{className:"max-w-lg",children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"编辑镜像源"}),e.jsx(ot,{children:"修改镜像源配置"})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"镜像源 ID"}),e.jsx(ie,{value:y.id,disabled:!0})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit-name",children:"名称 *"}),e.jsx(ie,{id:"edit-name",value:y.name,onChange:A=>R({...y,name:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit-raw",children:"Raw 文件前缀 *"}),e.jsx(ie,{id:"edit-raw",value:y.raw_prefix,onChange:A=>R({...y,raw_prefix:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit-clone",children:"克隆前缀 *"}),e.jsx(ie,{id:"edit-clone",value:y.clone_prefix,onChange:A=>R({...y,clone_prefix:A.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{htmlFor:"edit-priority",children:"优先级"}),e.jsx(ie,{id:"edit-priority",type:"number",min:"1",value:y.priority,onChange:A=>R({...y,priority:parseInt(A.target.value)||1})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"数字越小优先级越高"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ge,{id:"edit-enabled",checked:y.enabled,onCheckedChange:A=>R({...y,enabled:A})}),e.jsx(E,{htmlFor:"edit-enabled",children:"启用此镜像源"})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>w(!1),children:"取消"}),e.jsx(C,{onClick:I,children:"保存"})]})]})})]})})}function fk({pluginId:l,compact:n=!1}){const[i,c]=m.useState(null),[u,x]=m.useState(!0),[h,f]=m.useState(0),[p,g]=m.useState(""),[N,v]=m.useState(!1),{toast:b}=Ws(),w=async()=>{x(!0);const k=await wv(l);k&&c(k),x(!1)};m.useEffect(()=>{w()},[l]);const y=async()=>{const k=await tk(l);k.success?(b({title:"已点赞",description:"感谢你的支持!"}),w()):b({title:"点赞失败",description:k.error||"未知错误",variant:"destructive"})},R=async()=>{const k=await ak(l);k.success?(b({title:"已反馈",description:"感谢你的反馈!"}),w()):b({title:"操作失败",description:k.error||"未知错误",variant:"destructive"})},D=async()=>{if(h===0){b({title:"请选择评分",description:"至少选择 1 颗星",variant:"destructive"});return}const k=await lk(l,h,p||void 0);k.success?(b({title:"评分成功",description:"感谢你的评价!"}),v(!1),f(0),g(""),w()):b({title:"评分失败",description:k.error||"未知错误",variant:"destructive"})};return u?e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(Xt,{className:"h-4 w-4"}),e.jsx("span",{children:"-"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(an,{className:"h-4 w-4"}),e.jsx("span",{children:"-"})]})]}):i?n?e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",title:`下载量: ${i.downloads.toLocaleString()}`,children:[e.jsx(Xt,{className:"h-4 w-4"}),e.jsx("span",{children:i.downloads.toLocaleString()})]}),e.jsxs("div",{className:"flex items-center gap-1",title:`评分: ${i.rating.toFixed(1)} (${i.rating_count} 条评价)`,children:[e.jsx(an,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),e.jsx("span",{children:i.rating.toFixed(1)})]}),e.jsxs("div",{className:"flex items-center gap-1",title:`点赞数: ${i.likes}`,children:[e.jsx(dm,{className:"h-4 w-4"}),e.jsx("span",{children:i.likes})]})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(Xt,{className:"h-5 w-5 text-muted-foreground mb-1"}),e.jsx("span",{className:"text-2xl font-bold",children:i.downloads.toLocaleString()}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"下载量"})]}),e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(an,{className:"h-5 w-5 text-yellow-400 mb-1 fill-yellow-400"}),e.jsx("span",{className:"text-2xl font-bold",children:i.rating.toFixed(1)}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[i.rating_count," 条评价"]})]}),e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(dm,{className:"h-5 w-5 text-green-500 mb-1"}),e.jsx("span",{className:"text-2xl font-bold",children:i.likes}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"点赞"})]}),e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(Kp,{className:"h-5 w-5 text-red-500 mb-1"}),e.jsx("span",{className:"text-2xl font-bold",children:i.dislikes}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"点踩"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:y,children:[e.jsx(dm,{className:"h-4 w-4 mr-1"}),"点赞"]}),e.jsxs(C,{variant:"outline",size:"sm",onClick:R,children:[e.jsx(Kp,{className:"h-4 w-4 mr-1"}),"点踩"]}),e.jsxs(Ks,{open:N,onOpenChange:v,children:[e.jsx(Ho,{asChild:!0,children:e.jsxs(C,{variant:"default",size:"sm",children:[e.jsx(an,{className:"h-4 w-4 mr-1"}),"评分"]})}),e.jsxs(Ps,{children:[e.jsxs(Hs,{children:[e.jsx(Gs,{children:"为插件评分"}),e.jsx(ot,{children:"分享你的使用体验,帮助其他用户"})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx("div",{className:"flex gap-2",children:[1,2,3,4,5].map(k=>e.jsx("button",{onClick:()=>f(k),className:"focus:outline-none",children:e.jsx(an,{className:`h-8 w-8 transition-colors ${k<=h?"fill-yellow-400 text-yellow-400":"text-muted-foreground hover:text-yellow-300"}`})},k))}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[h===0&&"点击星星进行评分",h===1&&"很差",h===2&&"一般",h===3&&"还行",h===4&&"不错",h===5&&"非常好"]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-2 block",children:"评论(可选)"}),e.jsx(et,{value:p,onChange:k=>g(k.target.value),placeholder:"分享你的使用体验...",rows:4,maxLength:500}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1 text-right",children:[p.length," / 500"]})]})]}),e.jsxs(xt,{children:[e.jsx(C,{variant:"outline",onClick:()=>v(!1),children:"取消"}),e.jsx(C,{onClick:D,disabled:h===0,children:"提交评分"})]})]})]})]}),i.recent_ratings&&i.recent_ratings.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("h4",{className:"text-sm font-semibold",children:"最近评价"}),e.jsx("div",{className:"space-y-3",children:i.recent_ratings.map((k,I)=>e.jsxs("div",{className:"p-3 rounded-lg border bg-muted/50",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("div",{className:"flex gap-1",children:[1,2,3,4,5].map(M=>e.jsx(an,{className:`h-3 w-3 ${M<=k.rating?"fill-yellow-400 text-yellow-400":"text-muted-foreground"}`},M))}),e.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(k.created_at).toLocaleDateString()})]}),k.comment&&e.jsx("p",{className:"text-sm text-muted-foreground",children:k.comment})]},I))})]})]}):null}const pk={"Group Management":"群组管理","Entertainment & Interaction":"娱乐互动","Utility Tools":"实用工具","Content Generation":"内容生成",Multimedia:"多媒体","External Integration":"外部集成","Data Analysis & Insights":"数据分析与洞察",Other:"其他"};function gk(){const l=aa(),n=t0({strict:!1}),{toast:i}=Ws(),[c,u]=m.useState(null),[x,h]=m.useState(""),[f,p]=m.useState(!0),[g,N]=m.useState(!0),[v,b]=m.useState(null),[w,y]=m.useState(null),[R,D]=m.useState(null),[k,I]=m.useState(!1),[M,S]=m.useState(),[T,$]=m.useState(!1);m.useEffect(()=>{(async()=>{if(!n.pluginId){b("缺少插件 ID"),p(!1);return}try{p(!0),b(null);const fe=await we("/api/webui/plugins/fetch-raw",{method:"POST",body:JSON.stringify({owner:"Mai-with-u",repo:"plugin-repo",branch:"main",file_path:"plugin_details.json"})});if(!fe.ok)throw new Error("获取插件列表失败");const ge=await fe.json();if(!ge.success||!ge.data)throw new Error(ge.error||"获取插件列表失败");const V=JSON.parse(ge.data).find(je=>je.id===n.pluginId);if(!V)throw new Error("未找到该插件");const U={id:V.id,manifest:V.manifest,downloads:0,rating:0,review_count:0,installed:!1,published_at:new Date().toISOString(),updated_at:new Date().toISOString()};u(U);const[L,P,_e]=await Promise.all([gv(),jv(),Sl()]);y(L),D(P),I(nn(n.pluginId,_e)),S(rn(n.pluginId,_e))}catch(fe){b(fe instanceof Error?fe.message:"加载失败")}finally{p(!1)}})()},[n.pluginId]),m.useEffect(()=>{(async()=>{if(!c?.manifest?.repository_url){N(!1);return}try{N(!0);const fe=c.manifest.repository_url.match(/github\.com\/([^/]+)\/([^/\s]+)/);if(!fe){h("无法解析仓库地址");return}const[,ge,z]=fe,V=z.replace(/\.git$/,""),U=await we("/api/webui/plugins/fetch-raw",{method:"POST",body:JSON.stringify({owner:ge,repo:V,branch:"main",file_path:"README.md"})});if(!U.ok)throw new Error("获取 README 失败");const L=await U.json();L.success&&L.data?h(L.data):h("该插件暂无 README 文档")}catch(fe){console.error("加载 README 失败:",fe),h("加载 README 失败")}finally{N(!1)}})()},[c]);const A=()=>!c||!k||!M?!1:M!==c.manifest.version,Q=()=>!c||!R?!0:vv(c.manifest.host_application.min_version,c.manifest.host_application.max_version,R),G=async()=>{if(!(!c||!w?.installed))try{$(!0),await Nv(c.id,c.manifest.repository_url||"","main"),_v(c.id).catch(fe=>{console.warn("Failed to record download:",fe)}),i({title:"安装成功",description:`${c.manifest.name} 已成功安装`});const le=await Sl();I(nn(c.id,le)),S(rn(c.id,le))}catch(le){i({title:"安装失败",description:le instanceof Error?le.message:"未知错误",variant:"destructive"})}finally{$(!1)}},de=async()=>{if(c)try{$(!0),await bv(c.id),i({title:"卸载成功",description:`${c.manifest.name} 已成功卸载`});const le=await Sl();I(nn(c.id,le)),S(rn(c.id,le))}catch(le){i({title:"卸载失败",description:le instanceof Error?le.message:"未知错误",variant:"destructive"})}finally{$(!1)}},oe=async()=>{if(!(!c||!w?.installed))try{$(!0);const le=await yv(c.id,c.manifest.repository_url||"","main");i({title:"更新成功",description:`${c.manifest.name} 已从 ${le.old_version} 更新到 ${le.new_version}`});const fe=await Sl();I(nn(c.id,fe)),S(rn(c.id,fe))}catch(le){i({title:"更新失败",description:le instanceof Error?le.message:"未知错误",variant:"destructive"})}finally{$(!1)}};if(f)return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(C,{variant:"ghost",size:"icon",onClick:()=>l({to:"/plugins"}),children:e.jsx(Va,{className:"h-5 w-5"})}),e.jsx("div",{children:e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件详情"})})]}),e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx(zs,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-3 text-muted-foreground",children:"加载插件信息中..."})]})]});if(v||!c)return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(C,{variant:"ghost",size:"icon",onClick:()=>l({to:"/plugins"}),children:e.jsx(Va,{className:"h-5 w-5"})}),e.jsx("div",{children:e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件详情"})})]}),e.jsx(De,{className:"p-6",children:e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[e.jsx(Ct,{className:"h-12 w-12 text-destructive mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"加载失败"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:v}),e.jsx(C,{onClick:()=>l({to:"/plugins"}),children:"返回插件列表"})]})})]});const ve=Q();return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(C,{variant:"ghost",size:"icon",onClick:()=>l({to:"/plugins"}),className:"shrink-0",children:e.jsx(Va,{className:"h-5 w-5"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件详情"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:c.manifest.name})]})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:k?e.jsxs(e.Fragment,{children:[A()?e.jsx(C,{disabled:!w?.installed||T,onClick:oe,title:w?.installed?void 0:"Git 未安装",children:T?e.jsxs(e.Fragment,{children:[e.jsx(zs,{className:"h-4 w-4 mr-2 animate-spin"}),"更新中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(kt,{className:"h-4 w-4 mr-2"}),"更新"]})}):null,e.jsx(C,{variant:"destructive",disabled:!w?.installed||T,onClick:de,title:w?.installed?void 0:"Git 未安装",children:T?e.jsxs(e.Fragment,{children:[e.jsx(zs,{className:"h-4 w-4 mr-2 animate-spin"}),"卸载中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(ls,{className:"h-4 w-4 mr-2"}),"卸载"]})})]}):e.jsx(C,{disabled:!w?.installed||!ve||T,onClick:G,title:w?.installed?ve?void 0:`不兼容当前版本 (需要 ${c.manifest.host_application.min_version}${c.manifest.host_application.max_version?` - ${c.manifest.host_application.max_version}`:"+"},当前 ${R?.version})`:"Git 未安装",children:T?e.jsxs(e.Fragment,{children:[e.jsx(zs,{className:"h-4 w-4 mr-2 animate-spin"}),"安装中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Xt,{className:"h-4 w-4 mr-2"}),"安装"]})})})]}),e.jsx(es,{className:"h-[calc(100vh-200px)] sm:h-[calc(100vh-220px)]",children:e.jsxs("div",{className:"space-y-6 pr-4",children:[e.jsx(De,{children:e.jsx(Xe,{children:e.jsx("div",{className:"flex items-start justify-between gap-4",children:e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsx(We,{className:"text-2xl",children:c.manifest.name}),e.jsxs(Ae,{variant:"secondary",className:"text-sm",children:["v",c.manifest.version]}),k&&e.jsxs(Ae,{variant:"default",className:"text-sm",children:[e.jsx(ea,{className:"h-3 w-3 mr-1"}),"已安装 ",M&&`(v${M})`]}),A()&&e.jsxs(Ae,{variant:"outline",className:"text-sm border-orange-500 text-orange-500",children:[e.jsx(kt,{className:"h-3 w-3 mr-1"}),"可更新"]}),!ve&&e.jsxs(Ae,{variant:"destructive",className:"text-sm",children:[e.jsx(Ct,{className:"h-3 w-3 mr-1"}),"不兼容"]})]}),e.jsx(Is,{className:"text-base",children:c.manifest.description})]})})})}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"lg:col-span-1 space-y-6",children:[e.jsxs(De,{children:[e.jsx(Xe,{children:e.jsx(We,{className:"text-lg",children:"统计信息"})}),e.jsx(Qe,{children:e.jsx(fk,{pluginId:c.id})})]}),e.jsxs(De,{children:[e.jsx(Xe,{children:e.jsx(We,{className:"text-lg",children:"基本信息"})}),e.jsx(Qe,{className:"space-y-4",children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Dn,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"作者:"}),e.jsx("span",{className:"font-medium",children:c.manifest.author?.name||"Unknown"}),c.manifest.author?.url&&e.jsx("a",{href:c.manifest.author.url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:e.jsx(bo,{className:"h-3 w-3"})})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Wt,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"版本:"}),e.jsxs("span",{className:"font-medium",children:["v",c.manifest.version]})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(mj,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"许可证:"}),e.jsx("span",{className:"font-medium",children:c.manifest.license})]}),c.manifest.homepage_url&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Co,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"主页:"}),e.jsxs("a",{href:c.manifest.homepage_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline flex items-center gap-1",children:["访问",e.jsx(bo,{className:"h-3 w-3"})]})]}),c.manifest.repository_url&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Kw,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"仓库:"}),e.jsxs("a",{href:c.manifest.repository_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline flex items-center gap-1",children:["GitHub",e.jsx(bo,{className:"h-3 w-3"})]})]}),e.jsxs("div",{className:"pt-2 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm mb-2",children:[e.jsx(qt,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"支持版本:"})]}),e.jsxs("div",{className:"text-sm pl-6 font-medium",children:[c.manifest.host_application.min_version,c.manifest.host_application.max_version?` - ${c.manifest.host_application.max_version}`:" - 最新版本"]})]})]})})]}),(c.manifest.categories||c.manifest.keywords)&&e.jsxs(De,{children:[e.jsx(Xe,{children:e.jsx(We,{className:"text-lg",children:"分类与标签"})}),e.jsxs(Qe,{className:"space-y-4",children:[c.manifest.categories&&c.manifest.categories.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"分类"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:c.manifest.categories.map(le=>e.jsx(Ae,{variant:"secondary",children:pk[le]||le},le))})]}),c.manifest.keywords&&c.manifest.keywords.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"标签"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:c.manifest.keywords.map(le=>e.jsxs(Ae,{variant:"outline",className:"text-xs",children:[e.jsx($o,{className:"h-3 w-3 mr-1"}),le]},le))})]})]})]})]}),e.jsxs(De,{className:"lg:col-span-2",children:[e.jsx(Xe,{children:e.jsx(We,{className:"text-lg",children:"插件说明"})}),e.jsx(Qe,{children:e.jsx(es,{className:"h-[600px] pr-4",children:g?e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx(zs,{className:"h-6 w-6 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-3 text-sm text-muted-foreground",children:"加载说明文档中..."})]}):x?e.jsx(Im,{content:x}):e.jsx("div",{className:"text-center text-muted-foreground py-12",children:"暂无说明文档"})})})]})]})]})})]})}const Ui=m.forwardRef(({className:l,...n},i)=>e.jsx($g,{ref:i,className:B("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",l),...n}));Ui.displayName=$g.displayName;const jk=m.forwardRef(({className:l,...n},i)=>e.jsx(Ig,{ref:i,className:B("aspect-square h-full w-full",l),...n}));jk.displayName=Ig.displayName;const Bi=m.forwardRef(({className:l,...n},i)=>e.jsx(Pg,{ref:i,className:B("flex h-full w-full items-center justify-center rounded-full bg-muted",l),...n}));Bi.displayName=Pg.displayName;function vk(){return"webui_"+Math.random().toString(36).substr(2,9)+"_"+Date.now().toString(36)}function Nk(){const l="maibot_webui_user_id";let n=localStorage.getItem(l);return n||(n=vk(),localStorage.setItem(l,n)),n}function bk(){return localStorage.getItem("maibot_webui_user_name")||"WebUI用户"}function yk(l){localStorage.setItem("maibot_webui_user_name",l)}const Sv="maibot_webui_virtual_tabs";function wk(){try{const l=localStorage.getItem(Sv);if(l)return JSON.parse(l)}catch(l){console.error("[Chat] 加载虚拟标签页失败:",l)}return[]}function Ng(l){try{localStorage.setItem(Sv,JSON.stringify(l))}catch(n){console.error("[Chat] 保存虚拟标签页失败:",n)}}function _k({segment:l}){switch(l.type){case"text":return e.jsx("span",{className:"whitespace-pre-wrap",children:String(l.data)});case"image":case"emoji":return e.jsx("img",{src:String(l.data),alt:l.type==="emoji"?"表情包":"图片",className:B("rounded-lg max-w-full",l.type==="emoji"?"max-h-32":"max-h-64"),loading:"lazy",onError:n=>{const i=n.target;i.style.display="none",i.parentElement?.insertAdjacentHTML("beforeend",`[${l.type==="emoji"?"表情包":"图片"}加载失败]`)}});case"voice":return e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("audio",{controls:!0,src:String(l.data),className:"max-w-[200px] h-8",children:"您的浏览器不支持音频播放"})});case"video":return e.jsx("video",{controls:!0,src:String(l.data),className:"rounded-lg max-w-full max-h-64",children:"您的浏览器不支持视频播放"});case"face":return e.jsxs("span",{className:"text-muted-foreground",children:["[表情:",String(l.data),"]"]});case"music":return e.jsx("span",{className:"text-muted-foreground",children:"[音乐分享]"});case"file":return e.jsxs("span",{className:"text-muted-foreground",children:["[文件: ",String(l.data),"]"]});case"reply":return e.jsx("span",{className:"text-muted-foreground text-xs",children:"[回复消息]"});case"forward":return e.jsx("span",{className:"text-muted-foreground",children:"[转发消息]"});case"unknown":default:return e.jsxs("span",{className:"text-muted-foreground",children:["[",l.original_type||"未知消息","]"]})}}function Sk({message:l,isBot:n}){return l.message_type==="rich"&&l.segments&&l.segments.length>0?e.jsx("div",{className:"flex flex-col gap-2",children:l.segments.map((i,c)=>e.jsx(_k,{segment:i},c))}):e.jsx("span",{className:"whitespace-pre-wrap",children:l.content})}function kk(){const l={id:"webui-default",type:"webui",label:"WebUI",messages:[],isConnected:!1,isTyping:!1,sessionInfo:{}},n=()=>{const qe=wk().map(Ie=>{const Ve=Ie.virtualConfig;return!Ve.groupId&&Ve.platform&&Ve.userId&&(Ve.groupId=`webui_virtual_group_${Ve.platform}_${Ve.userId}`),{id:Ie.id,type:"virtual",label:Ie.label,virtualConfig:Ve,messages:[],isConnected:!1,isTyping:!1,sessionInfo:{}}});return[l,...qe]},[i,c]=m.useState(n),[u,x]=m.useState("webui-default"),h=i.find(F=>F.id===u)||i[0],[f,p]=m.useState(""),[g,N]=m.useState(!1),[v,b]=m.useState(!0),[w,y]=m.useState(bk()),[R,D]=m.useState(!1),[k,I]=m.useState(""),[M,S]=m.useState(!1),[T,$]=m.useState([]),[A,Q]=m.useState([]),[G,de]=m.useState(!1),[oe,ve]=m.useState(!1),[le,fe]=m.useState(""),[ge,z]=m.useState({platform:"",personId:"",userId:"",userName:"",groupName:"",groupId:""}),V=m.useRef(Nk()),U=m.useRef(new Map),L=m.useRef(null),P=m.useRef(new Map),_e=m.useRef(0),je=m.useRef(new Map),{toast:Se}=Ws(),Y=F=>(_e.current+=1,`${F}-${Date.now()}-${_e.current}-${Math.random().toString(36).substr(2,9)}`),be=m.useCallback((F,qe)=>{c(Ie=>Ie.map(Ve=>Ve.id===F?{...Ve,...qe}:Ve))},[]),Z=m.useCallback((F,qe)=>{c(Ie=>Ie.map(Ve=>Ve.id===F?{...Ve,messages:[...Ve.messages,qe]}:Ve))},[]),xe=m.useCallback(()=>{L.current?.scrollIntoView({behavior:"smooth"})},[]);m.useEffect(()=>{xe()},[h?.messages,xe]);const Me=m.useCallback(async()=>{de(!0);try{const F=await we("/api/chat/platforms");if(console.log("[Chat] 平台列表响应:",F.status,F.headers.get("content-type")),F.ok){const qe=F.headers.get("content-type");if(qe&&qe.includes("application/json")){const Ie=await F.json();console.log("[Chat] 平台列表数据:",Ie),$(Ie.platforms||[])}else{const Ie=await F.text();console.error("[Chat] 获取平台列表失败: 非 JSON 响应:",Ie.substring(0,200)),Se({title:"连接失败",description:"无法连接到后端服务,请确保 MaiBot 已启动",variant:"destructive"})}}else console.error("[Chat] 获取平台列表失败: HTTP",F.status),Se({title:"获取平台失败",description:`服务器返回错误: ${F.status}`,variant:"destructive"})}catch(F){console.error("[Chat] 获取平台列表失败:",F),Se({title:"网络错误",description:"无法连接到后端服务",variant:"destructive"})}finally{de(!1)}},[Se]),J=m.useCallback(async(F,qe)=>{ve(!0);try{const Ie=new URLSearchParams;F&&Ie.append("platform",F),qe&&Ie.append("search",qe),Ie.append("limit","50");const Ve=await we(`/api/chat/persons?${Ie.toString()}`);if(Ve.ok){const Cs=Ve.headers.get("content-type");if(Cs&&Cs.includes("application/json")){const ns=await Ve.json();Q(ns.persons||[])}else console.error("[Chat] 获取用户列表失败: 后端返回非 JSON 响应")}}catch(Ie){console.error("[Chat] 获取用户列表失败:",Ie)}finally{ve(!1)}},[]);m.useEffect(()=>{ge.platform&&J(ge.platform,le)},[ge.platform,le,J]);const ce=m.useCallback(async(F,qe)=>{b(!0);try{const Ie=new URLSearchParams;Ie.append("user_id",V.current),Ie.append("limit","50"),qe&&Ie.append("group_id",qe);const Ve=`/api/chat/history?${Ie.toString()}`;console.log("[Chat] 正在加载历史消息:",Ve);const Cs=await we(Ve);if(Cs.ok){const ns=await Cs.text();try{const Rs=JSON.parse(ns);if(Rs.messages&&Rs.messages.length>0){const Ee=Rs.messages.map(ts=>({id:ts.id,type:ts.type,content:ts.content,timestamp:ts.timestamp,sender:{name:ts.sender_name||(ts.is_bot?"麦麦":"WebUI用户"),user_id:ts.user_id,is_bot:ts.is_bot}}));be(F,{messages:Ee});const gs=je.current.get(F)||new Set;Ee.forEach(ts=>{if(ts.type==="bot"){const Ze=`bot-${ts.content}-${Math.floor(ts.timestamp*1e3)}`;gs.add(Ze)}}),je.current.set(F,gs)}}catch(Rs){console.error("[Chat] JSON 解析失败:",Rs)}}}catch(Ie){console.error("[Chat] 加载历史消息失败:",Ie)}finally{b(!1)}},[be]),Fe=m.useCallback(async(F,qe,Ie)=>{const Ve=U.current.get(F);if(Ve?.readyState===WebSocket.OPEN||Ve?.readyState===WebSocket.CONNECTING){console.log(`[Tab ${F}] WebSocket 已存在,跳过连接`);return}N(!0);let Cs=null;try{const gs=await we("/api/webui/ws-token");if(gs.ok){const ts=await gs.json();if(ts.success&&ts.token)Cs=ts.token;else{console.warn(`[Tab ${F}] 获取 WebSocket token 失败: ${ts.message||"未登录"}`),N(!1);return}}}catch(gs){console.error(`[Tab ${F}] 获取 WebSocket token 失败:`,gs),N(!1);return}if(!Cs){N(!1);return}const ns=window.location.protocol==="https:"?"wss:":"ws:",Rs=new URLSearchParams;Rs.append("token",Cs),qe==="virtual"&&Ie?(Rs.append("user_id",Ie.userId),Rs.append("user_name",Ie.userName),Rs.append("platform",Ie.platform),Rs.append("person_id",Ie.personId),Rs.append("group_name",Ie.groupName||"WebUI虚拟群聊"),Ie.groupId&&Rs.append("group_id",Ie.groupId)):(Rs.append("user_id",V.current),Rs.append("user_name",w));const Ee=`${ns}//${window.location.host}/api/chat/ws?${Rs.toString()}`;console.log(`[Tab ${F}] 正在连接 WebSocket:`,Ee);try{const gs=new WebSocket(Ee);U.current.set(F,gs),gs.onopen=()=>{be(F,{isConnected:!0}),N(!1),console.log(`[Tab ${F}] WebSocket 已连接`)},gs.onmessage=ts=>{try{const Ze=JSON.parse(ts.data);switch(Ze.type){case"session_info":be(F,{sessionInfo:{session_id:Ze.session_id,user_id:Ze.user_id,user_name:Ze.user_name,bot_name:Ze.bot_name}});break;case"system":Z(F,{id:Y("sys"),type:"system",content:Ze.content||"",timestamp:Ze.timestamp||Date.now()/1e3});break;case"user_message":{const js=Ze.sender?.user_id,dt=qe==="virtual"&&Ie?Ie.userId:V.current;console.log(`[Tab ${F}] 收到 user_message, sender: ${js}, current: ${dt}`);const Ot=js?js.replace(/^webui_user_/,""):"",ut=dt?dt.replace(/^webui_user_/,""):"";if(Ot&&ut&&Ot===ut){console.log(`[Tab ${F}] 跳过自己的消息(user_id 匹配)`);break}const _s=je.current.get(F)||new Set,Tt=`user-${Ze.content}-${Math.floor((Ze.timestamp||0)*1e3)}`;if(_s.has(Tt)){console.log(`[Tab ${F}] 跳过自己的消息(内容去重)`);break}if(_s.add(Tt),je.current.set(F,_s),_s.size>100){const Bt=_s.values().next().value;Bt&&_s.delete(Bt)}Z(F,{id:Ze.message_id||Y("user"),type:"user",content:Ze.content||"",timestamp:Ze.timestamp||Date.now()/1e3,sender:Ze.sender});break}case"bot_message":{be(F,{isTyping:!1});const js=je.current.get(F)||new Set,dt=`bot-${Ze.content}-${Math.floor((Ze.timestamp||0)*1e3)}`;if(js.has(dt))break;if(js.add(dt),je.current.set(F,js),js.size>100){const Ot=js.values().next().value;Ot&&js.delete(Ot)}c(Ot=>Ot.map(ut=>{if(ut.id!==F)return ut;const _s=ut.messages.filter(Bt=>Bt.type!=="thinking"),Tt={id:Y("bot"),type:"bot",content:Ze.content||"",message_type:Ze.message_type==="rich"?"rich":"text",segments:Ze.segments,timestamp:Ze.timestamp||Date.now()/1e3,sender:Ze.sender};return{...ut,messages:[..._s,Tt]}}));break}case"typing":be(F,{isTyping:Ze.is_typing||!1});break;case"error":c(js=>js.map(dt=>{if(dt.id!==F)return dt;const Ot=dt.messages.filter(ut=>ut.type!=="thinking");return{...dt,messages:[...Ot,{id:Y("error"),type:"error",content:Ze.content||"发生错误",timestamp:Ze.timestamp||Date.now()/1e3}]}})),Se({title:"错误",description:Ze.content,variant:"destructive"});break;case"pong":break;case"history":{const js=Ze.messages||[];if(js.length>0){const dt=je.current.get(F)||new Set,Ot=js.map(ut=>{const _s=ut.is_bot||!1,Tt=ut.id||Y(_s?"bot":"user"),Bt=`${_s?"bot":"user"}-${ut.content}-${Math.floor(ut.timestamp*1e3)}`;return dt.add(Bt),{id:Tt,type:_s?"bot":"user",content:ut.content,timestamp:ut.timestamp,sender:{name:ut.sender_name||(_s?"麦麦":"用户"),user_id:ut.sender_id,is_bot:_s}}});je.current.set(F,dt),be(F,{messages:Ot}),console.log(`[Tab ${F}] 已加载 ${Ot.length} 条历史消息`)}break}default:console.log("未知消息类型:",Ze.type)}}catch(Ze){console.error("解析消息失败:",Ze)}},gs.onclose=()=>{be(F,{isConnected:!1}),N(!1),U.current.delete(F),console.log(`[Tab ${F}] WebSocket 已断开`);const ts=P.current.get(F);ts&&clearTimeout(ts);const Ze=window.setTimeout(()=>{if(!q.current){const js=i.find(dt=>dt.id===F);js&&Fe(F,js.type,js.virtualConfig)}},5e3);P.current.set(F,Ze)},gs.onerror=ts=>{console.error(`[Tab ${F}] WebSocket 错误:`,ts),N(!1)}}catch(gs){console.error(`[Tab ${F}] 创建 WebSocket 失败:`,gs),N(!1)}},[w,be,Z,Se,i]),q=m.useRef(!1);m.useEffect(()=>{q.current=!1;const F=U.current,qe=P.current,Ie=je.current;ce("webui-default");const Ve=setTimeout(()=>{q.current||(Fe("webui-default","webui"),i.forEach(ns=>{ns.type==="virtual"&&ns.virtualConfig&&(Ie.set(ns.id,new Set),setTimeout(()=>{q.current||Fe(ns.id,"virtual",ns.virtualConfig)},200))}))},100),Cs=setInterval(()=>{F.forEach(ns=>{ns.readyState===WebSocket.OPEN&&ns.send(JSON.stringify({type:"ping"}))})},3e4);return()=>{q.current=!0,clearTimeout(Ve),clearInterval(Cs),qe.forEach(ns=>{clearTimeout(ns)}),qe.clear(),F.forEach(ns=>{ns.close()}),F.clear()}},[]);const ee=m.useCallback(()=>{const F=U.current.get(u);if(!f.trim()||!F||F.readyState!==WebSocket.OPEN)return;const qe=h?.type==="virtual"&&h.virtualConfig?.userName||w,Ie=f.trim(),Ve=Date.now()/1e3;F.send(JSON.stringify({type:"message",content:Ie,user_name:qe}));const Cs=je.current.get(u)||new Set,ns=`user-${Ie}-${Math.floor(Ve*1e3)}`;if(Cs.add(ns),je.current.set(u,Cs),Cs.size>100){const gs=Cs.values().next().value;gs&&Cs.delete(gs)}const Rs={id:Y("user"),type:"user",content:Ie,timestamp:Ve,sender:{name:qe,is_bot:!1}};Z(u,Rs);const Ee={id:Y("thinking"),type:"thinking",content:"",timestamp:Ve+.001,sender:{name:h?.sessionInfo.bot_name||"麦麦",is_bot:!0}};Z(u,Ee),p("")},[f,w,u,h,Z]),ke=F=>{F.key==="Enter"&&!F.shiftKey&&(F.preventDefault(),ee())},Te=()=>{I(w),D(!0)},Oe=()=>{const F=k.trim()||"WebUI用户";y(F),yk(F),D(!1);const qe=U.current.get(u);qe?.readyState===WebSocket.OPEN&&qe.send(JSON.stringify({type:"update_nickname",user_name:F}))},me=()=>{I(""),D(!1)},ze=F=>new Date(F*1e3).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"}),rs=()=>{const F=U.current.get(u);F&&(F.close(),U.current.delete(u)),Fe(u,h?.type||"webui",h?.virtualConfig)},Kt=()=>{z({platform:"",personId:"",userId:"",userName:"",groupName:"",groupId:""}),fe(""),Me(),S(!0)},Qt=()=>{if(!ge.platform||!ge.personId){Se({title:"配置不完整",description:"请选择平台和用户",variant:"destructive"});return}const F=`webui_virtual_group_${ge.platform}_${ge.userId}`,qe=`virtual-${ge.platform}-${ge.userId}-${Date.now()}`,Ie=ge.userName||ge.userId,Ve={id:qe,type:"virtual",label:Ie,virtualConfig:{...ge,groupId:F},messages:[],isConnected:!1,isTyping:!1,sessionInfo:{}};c(Cs=>{const ns=[...Cs,Ve],Rs=ns.filter(Ee=>Ee.type==="virtual"&&Ee.virtualConfig).map(Ee=>({id:Ee.id,label:Ee.label,virtualConfig:Ee.virtualConfig,createdAt:Date.now()}));return Ng(Rs),ns}),x(qe),S(!1),je.current.set(qe,new Set),setTimeout(()=>{Fe(qe,"virtual",ge)},100),Se({title:"虚拟身份标签页",description:`已创建 ${Ie} 的对话`})},ka=(F,qe)=>{if(qe?.stopPropagation(),F==="webui-default")return;const Ie=U.current.get(F);Ie&&(Ie.close(),U.current.delete(F));const Ve=P.current.get(F);Ve&&(clearTimeout(Ve),P.current.delete(F)),je.current.delete(F),c(Cs=>{const ns=Cs.filter(Ee=>Ee.id!==F),Rs=ns.filter(Ee=>Ee.type==="virtual"&&Ee.virtualConfig).map(Ee=>({id:Ee.id,label:Ee.label,virtualConfig:Ee.virtualConfig,createdAt:Date.now()}));return Ng(Rs),ns}),u===F&&x("webui-default")},yt=F=>{x(F)},st=F=>{z(qe=>({...qe,personId:F.person_id,userId:F.user_id,userName:F.nickname||F.person_name}))};return e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsx(Ks,{open:M,onOpenChange:S,children:e.jsxs(Ps,{className:"sm:max-w-[500px] max-h-[85vh] overflow-hidden flex flex-col",children:[e.jsxs(Hs,{children:[e.jsxs(Gs,{className:"flex items-center gap-2",children:[e.jsx(um,{className:"h-5 w-5"}),"新建虚拟身份对话"]}),e.jsx(ot,{children:"选择一个麦麦已认识的用户,以该用户的身份与麦麦对话。麦麦将使用她对该用户的记忆和认知来回应。"})]}),e.jsxs("div",{className:"space-y-4 flex-1 overflow-hidden flex flex-col",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(E,{className:"flex items-center gap-2",children:[e.jsx(Co,{className:"h-4 w-4"}),"选择平台"]}),e.jsxs(Be,{value:ge.platform,onValueChange:F=>{z(qe=>({...qe,platform:F,personId:"",userId:"",userName:""})),Q([])},children:[e.jsx(Le,{disabled:G,children:e.jsx($e,{placeholder:G?"加载中...":"选择平台"})}),e.jsx(Ue,{children:T.map(F=>e.jsxs(ae,{value:F.platform,children:[F.platform," (",F.count," 人)"]},F.platform))})]})]}),ge.platform&&e.jsxs("div",{className:"space-y-2 flex-1 overflow-hidden flex flex-col",children:[e.jsxs(E,{className:"flex items-center gap-2",children:[e.jsx(Tm,{className:"h-4 w-4"}),"选择用户"]}),e.jsxs("div",{className:"relative",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索用户名...",value:le,onChange:F=>fe(F.target.value),className:"pl-9"})]}),e.jsx(es,{className:"h-[250px] border rounded-md",children:e.jsx("div",{className:"p-2",children:oe?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(zs,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):A.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-muted-foreground",children:[e.jsx(Tm,{className:"h-8 w-8 mb-2 opacity-50"}),e.jsx("p",{className:"text-sm",children:"没有找到用户"})]}):e.jsx("div",{className:"space-y-1",children:A.map(F=>e.jsxs("button",{onClick:()=>st(F),className:B("w-full flex items-center gap-3 p-2 rounded-md text-left transition-colors",ge.personId===F.person_id?"bg-primary text-primary-foreground":"hover:bg-muted"),children:[e.jsx(Ui,{className:"h-8 w-8 shrink-0",children:e.jsx(Bi,{className:B("text-xs",ge.personId===F.person_id?"bg-primary-foreground/20":"bg-muted"),children:(F.nickname||F.person_name||"?").charAt(0)})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-medium truncate",children:F.nickname||F.person_name}),e.jsxs("div",{className:B("text-xs truncate",ge.personId===F.person_id?"text-primary-foreground/70":"text-muted-foreground"),children:["ID: ",F.user_id,F.is_known&&" · 已认识"]})]})]},F.person_id))})})})]}),ge.personId&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(E,{children:"虚拟群名(可选)"}),e.jsx(ie,{placeholder:"WebUI虚拟群聊",value:ge.groupName,onChange:F=>z(qe=>({...qe,groupName:F.target.value}))}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"麦麦会认为这是一个名为此名称的群聊"})]})]}),e.jsxs(xt,{className:"gap-2 sm:gap-0",children:[e.jsx(C,{variant:"outline",onClick:()=>S(!1),children:"取消"}),e.jsx(C,{onClick:Qt,disabled:!ge.platform||!ge.personId,children:"创建对话"})]})]})}),e.jsx("div",{className:"shrink-0 border-b bg-muted/30",children:e.jsx("div",{className:"max-w-4xl mx-auto px-2 sm:px-4",children:e.jsxs("div",{className:"flex items-center gap-1 overflow-x-auto py-1.5 scrollbar-thin",children:[i.map(F=>e.jsxs("div",{className:B("flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm whitespace-nowrap transition-colors cursor-pointer","hover:bg-muted",u===F.id?"bg-background shadow-sm border":"text-muted-foreground"),onClick:()=>yt(F.id),children:[F.type==="webui"?e.jsx(on,{className:"h-3.5 w-3.5"}):e.jsx(um,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"max-w-[100px] truncate",children:F.label}),e.jsx("span",{className:B("w-1.5 h-1.5 rounded-full",F.isConnected?"bg-green-500":"bg-muted-foreground/50")}),F.id!=="webui-default"&&e.jsx("span",{onClick:qe=>ka(F.id,qe),className:"ml-0.5 p-0.5 rounded hover:bg-muted-foreground/20 cursor-pointer",role:"button",tabIndex:0,onKeyDown:qe=>{(qe.key==="Enter"||qe.key===" ")&&(qe.preventDefault(),ka(F.id,qe))},children:e.jsx(_a,{className:"h-3 w-3"})})]},F.id)),e.jsx("button",{onClick:Kt,className:"flex items-center gap-1 px-2 py-1.5 rounded-md text-sm text-muted-foreground hover:bg-muted hover:text-foreground transition-colors",title:"新建虚拟身份对话",children:e.jsx(it,{className:"h-3.5 w-3.5"})})]})})}),e.jsx("div",{className:"shrink-0 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60",children:e.jsxs("div",{className:"p-3 sm:p-4 max-w-4xl mx-auto",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 min-w-0",children:[e.jsx(Ui,{className:"h-8 w-8 sm:h-10 sm:w-10 shrink-0",children:e.jsx(Bi,{className:"bg-primary/10 text-primary",children:e.jsx(Ri,{className:"h-4 w-4 sm:h-5 sm:w-5"})})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-base sm:text-lg font-semibold truncate",children:h?.sessionInfo.bot_name||"麦麦"}),e.jsx("div",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:h?.isConnected?e.jsxs(e.Fragment,{children:[e.jsx(Qw,{className:"h-3 w-3 text-green-500"}),e.jsx("span",{className:"text-green-600 dark:text-green-400",children:"已连接"})]}):g?e.jsxs(e.Fragment,{children:[e.jsx(zs,{className:"h-3 w-3 animate-spin"}),e.jsx("span",{children:"连接中..."})]}):e.jsxs(e.Fragment,{children:[e.jsx(Yw,{className:"h-3 w-3 text-red-500"}),e.jsx("span",{className:"text-red-600 dark:text-red-400",children:"未连接"})]})})]})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[v&&e.jsx(zs,{className:"h-4 w-4 animate-spin text-muted-foreground"}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:rs,disabled:g,title:"重新连接",children:e.jsx(kt,{className:B("h-4 w-4",g&&"animate-spin")})})]})]}),e.jsx("div",{className:"hidden sm:flex items-center gap-2 mt-2 text-sm text-muted-foreground",children:h?.type==="virtual"&&h.virtualConfig?e.jsxs(e.Fragment,{children:[e.jsx(um,{className:"h-3 w-3 text-primary"}),e.jsx("span",{children:"虚拟身份:"}),e.jsx("span",{className:"font-medium text-primary",children:h.virtualConfig.userName}),e.jsxs("span",{className:"text-xs",children:["(",h.virtualConfig.platform,")"]}),h.virtualConfig.groupName&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"mx-1",children:"·"}),e.jsxs("span",{className:"text-xs",children:["群:",h.virtualConfig.groupName]})]})]}):e.jsxs(e.Fragment,{children:[e.jsx(Dn,{className:"h-3 w-3"}),e.jsx("span",{children:"当前身份:"}),R?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{value:k,onChange:F=>I(F.target.value),onKeyDown:F=>{F.key==="Enter"&&Oe(),F.key==="Escape"&&me()},className:"h-7 w-32",placeholder:"输入昵称",autoFocus:!0}),e.jsx(C,{size:"sm",variant:"ghost",className:"h-7 px-2",onClick:Oe,children:"保存"}),e.jsx(C,{size:"sm",variant:"ghost",className:"h-7 px-2",onClick:me,children:"取消"})]}):e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"font-medium text-foreground",children:w}),e.jsx(C,{size:"sm",variant:"ghost",className:"h-6 w-6 p-0",onClick:Te,title:"修改昵称",children:e.jsx(Jw,{className:"h-3 w-3"})})]})]})})]})}),e.jsx("div",{className:"flex-1 overflow-hidden",children:e.jsx(es,{className:"h-full",children:e.jsxs("div",{className:"p-3 sm:p-4 max-w-4xl mx-auto space-y-3 sm:space-y-4",children:[h?.messages.length===0&&!v&&e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-muted-foreground",children:[e.jsx(Ri,{className:"h-12 w-12 mb-4 opacity-50"}),e.jsxs("p",{className:"text-sm",children:["开始与 ",h?.sessionInfo.bot_name||"麦麦"," 对话吧!"]})]}),h?.messages.map(F=>e.jsxs("div",{className:B("flex gap-2 sm:gap-3",F.type==="user"&&"flex-row-reverse",F.type==="system"&&"justify-center",F.type==="error"&&"justify-center"),children:[F.type==="system"&&e.jsx("div",{className:"text-xs text-muted-foreground bg-muted/50 px-3 py-1 rounded-full max-w-[90%]",children:F.content}),F.type==="error"&&e.jsx("div",{className:"text-xs text-red-600 dark:text-red-400 bg-red-100 dark:bg-red-900/30 px-3 py-1 rounded-full max-w-[90%]",children:F.content}),F.type==="thinking"&&e.jsxs(e.Fragment,{children:[e.jsx(Ui,{className:"h-7 w-7 sm:h-8 sm:w-8 shrink-0",children:e.jsx(Bi,{className:"bg-primary/10 text-primary",children:e.jsx(Ri,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4"})})}),e.jsxs("div",{className:"flex flex-col gap-1 max-w-[75%] sm:max-w-[70%]",children:[e.jsx("div",{className:"flex items-center gap-2 text-[10px] sm:text-xs text-muted-foreground",children:e.jsx("span",{className:"hidden sm:inline",children:F.sender?.name||h?.sessionInfo.bot_name})}),e.jsx("div",{className:"bg-muted rounded-2xl rounded-tl-sm px-4 py-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex gap-1",children:[e.jsx("span",{className:"w-2 h-2 bg-primary/60 rounded-full animate-bounce",style:{animationDelay:"0ms"}}),e.jsx("span",{className:"w-2 h-2 bg-primary/60 rounded-full animate-bounce",style:{animationDelay:"150ms"}}),e.jsx("span",{className:"w-2 h-2 bg-primary/60 rounded-full animate-bounce",style:{animationDelay:"300ms"}})]}),e.jsx("span",{className:"text-xs text-muted-foreground ml-1",children:"思考中..."})]})})]})]}),(F.type==="user"||F.type==="bot")&&e.jsxs(e.Fragment,{children:[e.jsx(Ui,{className:"h-7 w-7 sm:h-8 sm:w-8 shrink-0",children:e.jsx(Bi,{className:B("text-xs",F.type==="bot"?"bg-primary/10 text-primary":"bg-secondary text-secondary-foreground"),children:F.type==="bot"?e.jsx(Ri,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4"}):e.jsx(Dn,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4"})})}),e.jsxs("div",{className:B("flex flex-col gap-1 max-w-[75%] sm:max-w-[70%]",F.type==="user"&&"items-end"),children:[e.jsxs("div",{className:"flex items-center gap-2 text-[10px] sm:text-xs text-muted-foreground",children:[e.jsx("span",{className:"hidden sm:inline",children:F.sender?.name||(F.type==="bot"?h?.sessionInfo.bot_name:w)}),e.jsx("span",{children:ze(F.timestamp)})]}),e.jsx("div",{className:B("rounded-2xl px-3 py-2 text-sm break-words",F.type==="bot"?"bg-muted rounded-tl-sm":"bg-primary text-primary-foreground rounded-tr-sm"),children:e.jsx(Sk,{message:F,isBot:F.type==="bot"})})]})]})]},F.id)),e.jsx("div",{ref:L})]})})}),e.jsx("div",{className:"shrink-0 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60",children:e.jsx("div",{className:"p-3 sm:p-4 max-w-4xl mx-auto",children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ie,{value:f,onChange:F=>p(F.target.value),onKeyDown:ke,placeholder:h?.isConnected?"输入消息...":"等待连接...",disabled:!h?.isConnected,className:"flex-1 h-10 sm:h-10"}),e.jsx(C,{onClick:ee,disabled:!h?.isConnected||!f.trim(),size:"icon",className:"h-10 w-10 shrink-0",children:e.jsx(Xw,{className:"h-4 w-4"})})]})})})]})}var Ym="Radio",[Ck,kv]=Lo(Ym),[Tk,Ek]=Ck(Ym),Cv=m.forwardRef((l,n)=>{const{__scopeRadio:i,name:c,checked:u=!1,required:x,disabled:h,value:f="on",onCheck:p,form:g,...N}=l,[v,b]=m.useState(null),w=Uo(n,D=>b(D)),y=m.useRef(!1),R=v?g||!!v.closest("form"):!0;return e.jsxs(Tk,{scope:i,checked:u,disabled:h,children:[e.jsx($n.button,{type:"button",role:"radio","aria-checked":u,"data-state":Av(u),"data-disabled":h?"":void 0,disabled:h,value:f,...N,ref:w,onClick:cn(l.onClick,D=>{u||p?.(),R&&(y.current=D.isPropagationStopped(),y.current||D.stopPropagation())})}),R&&e.jsx(Mv,{control:v,bubbles:!y.current,name:c,value:f,checked:u,required:x,disabled:h,form:g,style:{transform:"translateX(-100%)"}})]})});Cv.displayName=Ym;var Tv="RadioIndicator",Ev=m.forwardRef((l,n)=>{const{__scopeRadio:i,forceMount:c,...u}=l,x=Ek(Tv,i);return e.jsx(gw,{present:c||x.checked,children:e.jsx($n.span,{"data-state":Av(x.checked),"data-disabled":x.disabled?"":void 0,...u,ref:n})})});Ev.displayName=Tv;var Mk="RadioBubbleInput",Mv=m.forwardRef(({__scopeRadio:l,control:n,checked:i,bubbles:c=!0,...u},x)=>{const h=m.useRef(null),f=Uo(h,x),p=jw(i),g=vw(n);return m.useEffect(()=>{const N=h.current;if(!N)return;const v=window.HTMLInputElement.prototype,w=Object.getOwnPropertyDescriptor(v,"checked").set;if(p!==i&&w){const y=new Event("click",{bubbles:c});w.call(N,i),N.dispatchEvent(y)}},[p,i,c]),e.jsx($n.input,{type:"radio","aria-hidden":!0,defaultChecked:i,...u,tabIndex:-1,ref:f,style:{...u.style,...g,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});Mv.displayName=Mk;function Av(l){return l?"checked":"unchecked"}var Ak=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],Qo="RadioGroup",[zk]=Lo(Qo,[Hg,kv]),zv=Hg(),Dv=kv(),[Dk,Ok]=zk(Qo),Ov=m.forwardRef((l,n)=>{const{__scopeRadioGroup:i,name:c,defaultValue:u,value:x,required:h=!1,disabled:f=!1,orientation:p,dir:g,loop:N=!0,onValueChange:v,...b}=l,w=zv(i),y=lj(g),[R,D]=Ro({prop:x,defaultProp:u??null,onChange:v,caller:Qo});return e.jsx(Dk,{scope:i,name:c,required:h,disabled:f,value:R,onValueChange:D,children:e.jsx(A0,{asChild:!0,...w,orientation:p,dir:y,loop:N,children:e.jsx($n.div,{role:"radiogroup","aria-required":h,"aria-orientation":p,"data-disabled":f?"":void 0,dir:y,...b,ref:n})})})});Ov.displayName=Qo;var Rv="RadioGroupItem",Lv=m.forwardRef((l,n)=>{const{__scopeRadioGroup:i,disabled:c,...u}=l,x=Ok(Rv,i),h=x.disabled||c,f=zv(i),p=Dv(i),g=m.useRef(null),N=Uo(n,g),v=x.value===u.value,b=m.useRef(!1);return m.useEffect(()=>{const w=R=>{Ak.includes(R.key)&&(b.current=!0)},y=()=>b.current=!1;return document.addEventListener("keydown",w),document.addEventListener("keyup",y),()=>{document.removeEventListener("keydown",w),document.removeEventListener("keyup",y)}},[]),e.jsx(z0,{asChild:!0,...f,focusable:!h,active:v,children:e.jsx(Cv,{disabled:h,required:x.required,checked:v,...p,...u,name:x.name,ref:N,onCheck:()=>x.onValueChange(u.value),onKeyDown:cn(w=>{w.key==="Enter"&&w.preventDefault()}),onFocus:cn(u.onFocus,()=>{b.current&&g.current?.click()})})})});Lv.displayName=Rv;var Rk="RadioGroupIndicator",Uv=m.forwardRef((l,n)=>{const{__scopeRadioGroup:i,...c}=l,u=Dv(i);return e.jsx(Ev,{...u,...c,ref:n})});Uv.displayName=Rk;var Bv=Ov,$v=Lv,Lk=Uv;const Jm=m.forwardRef(({className:l,...n},i)=>e.jsx(Bv,{className:B("grid gap-2",l),...n,ref:i}));Jm.displayName=Bv.displayName;const Do=m.forwardRef(({className:l,...n},i)=>e.jsx($v,{ref:i,className:B("aspect-square h-4 w-4 rounded-full border border-primary text-primary shadow focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",l),...n,children:e.jsx(Lk,{className:"flex items-center justify-center",children:e.jsx(Sj,{className:"h-2.5 w-2.5 fill-current text-current"})})}));Do.displayName=$v.displayName;function Uk({question:l,value:n,onChange:i,error:c,disabled:u=!1}){const[x,h]=m.useState(null),f=u||l.readOnly,p=()=>{switch(l.type){case"single":return e.jsx(Jm,{value:n||"",onValueChange:i,disabled:f,className:"space-y-2",children:l.options?.map(g=>e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Do,{value:g.value,id:`${l.id}-${g.id}`}),e.jsx(E,{htmlFor:`${l.id}-${g.id}`,className:"cursor-pointer font-normal",children:g.label})]},g.id))});case"multiple":{const g=n||[];return e.jsxs("div",{className:"space-y-2",children:[l.options?.map(N=>e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:`${l.id}-${N.id}`,checked:g.includes(N.value),disabled:f||l.maxSelections!==void 0&&g.length>=l.maxSelections&&!g.includes(N.value),onCheckedChange:v=>{i(v?[...g,N.value]:g.filter(b=>b!==N.value))}}),e.jsx(E,{htmlFor:`${l.id}-${N.id}`,className:"cursor-pointer font-normal",children:N.label})]},N.id)),l.maxSelections&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["最多选择 ",l.maxSelections," 项"]})]})}case"text":return e.jsx(ie,{value:n||"",onChange:g=>i(g.target.value),placeholder:l.placeholder||"请输入...",disabled:f,readOnly:l.readOnly,maxLength:l.maxLength,className:B(l.readOnly&&"bg-muted cursor-not-allowed")});case"textarea":return e.jsxs("div",{className:"space-y-1",children:[e.jsx(et,{value:n||"",onChange:g=>i(g.target.value),placeholder:l.placeholder||"请输入...",disabled:f,readOnly:l.readOnly,maxLength:l.maxLength,rows:4,className:B(l.readOnly&&"bg-muted cursor-not-allowed")}),l.maxLength&&e.jsxs("p",{className:"text-xs text-muted-foreground text-right",children:[(n||"").length," / ",l.maxLength]})]});case"rating":{const g=n||0,N=x!==null?x:g;return e.jsxs("div",{className:"flex items-center gap-1",children:[[1,2,3,4,5].map(v=>e.jsx("button",{type:"button",disabled:f,className:B("p-1 transition-colors focus:outline-none focus:ring-2 focus:ring-ring rounded",f&&"cursor-not-allowed opacity-50"),onMouseEnter:()=>!f&&h(v),onMouseLeave:()=>h(null),onClick:()=>!f&&i(v),children:e.jsx(an,{className:B("h-6 w-6 transition-colors",v<=N?"fill-yellow-400 text-yellow-400":"text-muted-foreground")})},v)),g>0&&e.jsxs("span",{className:"ml-2 text-sm text-muted-foreground",children:[g," / 5"]})]})}case"scale":{const g=l.min??1,N=l.max??10,v=l.step??1,b=n??g;return e.jsxs("div",{className:"space-y-4",children:[e.jsx(wa,{value:[b],onValueChange:([w])=>i(w),min:g,max:N,step:v,disabled:f}),e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:l.minLabel||g}),e.jsx("span",{className:"font-medium text-foreground",children:b}),e.jsx("span",{children:l.maxLabel||N})]})]})}case"dropdown":return e.jsxs(Be,{value:n||"",onValueChange:i,disabled:f,children:[e.jsx(Le,{children:e.jsx($e,{placeholder:l.placeholder||"请选择..."})}),e.jsx(Ue,{children:l.options?.map(g=>e.jsx(ae,{value:g.value,children:g.label},g.id))})]});default:return e.jsx("div",{className:"text-muted-foreground",children:"不支持的问题类型"})}};return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs(E,{className:"text-base font-medium",children:[l.title,l.required&&e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),l.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:l.description})]}),p(),c&&e.jsx("p",{className:"text-sm text-destructive",children:c})]})}const Iv="https://maibot-plugin-stats.maibot-webui.workers.dev";function Pv(){const l="maibot_user_id";let n=localStorage.getItem(l);if(!n){const i=Math.random().toString(36).substring(2,10),c=Date.now().toString(36),u=Math.random().toString(36).substring(2,10);n=`fp_${i}_${c}_${u}`,localStorage.setItem(l,n)}return n}async function Bk(l,n,i,c){try{const u=c?.userId||Pv(),x={surveyId:l,surveyVersion:n,userId:u,answers:i,submittedAt:new Date().toISOString(),allowMultiple:c?.allowMultiple,metadata:{userAgent:navigator.userAgent,language:navigator.language}},h=await fetch(`${Iv}/survey/submit`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(x)}),f=await h.json();return h.status===429?{success:!1,error:"提交过于频繁,请稍后再试"}:h.status===409?{success:!1,error:f.error||"你已经提交过这份问卷了"}:h.ok?{success:!0,submissionId:f.submissionId,message:f.message}:{success:!1,error:f.error||"提交失败"}}catch(u){return console.error("Error submitting survey:",u),{success:!1,error:"网络错误"}}}async function $k(l,n){try{const i=n||Pv(),c=new URLSearchParams({user_id:i,survey_id:l}),u=await fetch(`${Iv}/survey/check?${c}`);return u.ok?{success:!0,hasSubmitted:(await u.json()).hasSubmitted}:{success:!1,error:(await u.json()).error||"检查失败"}}catch(i){return console.error("Error checking submission:",i),{success:!1,error:"网络错误"}}}function Hv({config:l,initialAnswers:n,onSubmitSuccess:i,onSubmitError:c,showProgress:u=!0,paginateQuestions:x=!1,className:h}){const f=m.useCallback(()=>!n||n.length===0?{}:n.reduce((U,L)=>(U[L.questionId]=L.value,U),{}),[n]),[p,g]=m.useState(()=>f()),[N,v]=m.useState({}),[b,w]=m.useState(0),[y,R]=m.useState(!1),[D,k]=m.useState(!1),[I,M]=m.useState(null),[S,T]=m.useState(null),[$,A]=m.useState(!1),[Q,G]=m.useState(!0);m.useEffect(()=>{n&&n.length>0&&g(U=>({...U,...f()}))},[n,f]),m.useEffect(()=>{(async()=>{if(!l.settings?.allowMultiple){const L=await $k(l.id);L.success&&L.hasSubmitted&&A(!0)}G(!1)})()},[l.id,l.settings?.allowMultiple]);const de=m.useCallback(()=>{const U=new Date;return!(l.settings?.startTime&&new Date(l.settings.startTime)>U||l.settings?.endTime&&new Date(l.settings.endTime){const L=p[U.id];return L==null?!1:Array.isArray(L)?L.length>0:typeof L=="string"?L.trim()!=="":!0}).length,ve=oe/l.questions.length*100,le=m.useCallback((U,L)=>{g(P=>({...P,[U]:L})),v(P=>{const _e={...P};return delete _e[U],_e})},[]),fe=m.useCallback(()=>{const U={};for(const L of l.questions){if(L.required){const P=p[L.id];if(P==null){U[L.id]="此题为必填项";continue}if(Array.isArray(P)&&P.length===0){U[L.id]="请至少选择一项";continue}if(typeof P=="string"&&P.trim()===""){U[L.id]="此题为必填项";continue}}L.minLength&&typeof p[L.id]=="string"&&p[L.id].length{if(!fe()){if(x){const U=l.questions.findIndex(L=>N[L.id]);U>=0&&w(U)}return}R(!0),M(null);try{const U=l.questions.filter(P=>p[P.id]!==void 0).map(P=>({questionId:P.id,value:p[P.id]})),L=await Bk(l.id,l.version,U,{allowMultiple:l.settings?.allowMultiple});if(L.success&&L.submissionId)k(!0),T(L.submissionId),i?.(L.submissionId);else{const P=L.error||"提交失败";M(P),c?.(P)}}catch(U){const L=U instanceof Error?U.message:"提交失败";M(L),c?.(L)}finally{R(!1)}},[fe,x,l,p,N,i,c]),z=m.useCallback(U=>{U>=0&&Ue.jsxs("div",{className:B("p-4 rounded-lg border bg-card",N[U.id]?"border-destructive bg-destructive/5":"border-border"),children:[x&&e.jsxs("div",{className:"text-xs text-muted-foreground mb-2",children:["问题 ",b+1," / ",l.questions.length]}),!x&&e.jsxs("div",{className:"text-xs text-muted-foreground mb-2",children:[L+1,"."]}),e.jsx(Uk,{question:U,value:p[U.id],onChange:P=>le(U.id,P),error:N[U.id],disabled:y})]},U.id)),I&&e.jsxs(nt,{variant:"destructive",children:[e.jsx(Ct,{className:"h-4 w-4"}),e.jsx(rt,{children:I})]}),e.jsx("div",{className:"flex justify-between items-center py-4",children:x?e.jsxs(e.Fragment,{children:[e.jsxs(C,{variant:"outline",onClick:()=>z(b-1),disabled:b===0||y,children:[e.jsx(ll,{className:"h-4 w-4 mr-1"}),"上一题"]}),b===l.questions.length-1?e.jsxs(C,{onClick:ge,disabled:y,children:[y&&e.jsx(zs,{className:"h-4 w-4 mr-2 animate-spin"}),"提交问卷"]}):e.jsxs(C,{onClick:()=>z(b+1),disabled:y,children:["下一题",e.jsx(Sa,{className:"h-4 w-4 ml-1"})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:Object.keys(N).length>0&&e.jsxs("span",{className:"text-destructive",children:["还有 ",Object.keys(N).length," 个必填项未完成"]})}),e.jsxs(C,{onClick:ge,disabled:y,size:"lg",children:[y&&e.jsx(zs,{className:"h-4 w-4 mr-2 animate-spin"}),"提交问卷"]})]})})]})})]})}const Ik={id:"webui-feedback-v1",version:"1.0.0",title:"麦麦 WebUI 使用反馈问卷",description:"感谢您使用麦麦 WebUI!您的反馈将帮助我们不断改进产品体验。",questions:[{id:"webui_version",type:"text",title:"你正在使用的 WebUI 版本",description:"此项由系统自动填写",required:!0,readOnly:!0,placeholder:"自动检测中..."},{id:"ui_design_satisfaction",type:"single",title:"你觉得当前的 WebUI 界面设计如何?",required:!0,options:[{id:"very_satisfied",label:"非常满意",value:"very_satisfied"},{id:"satisfied",label:"满意",value:"satisfied"},{id:"neutral",label:"一般",value:"neutral"},{id:"dissatisfied",label:"不满意",value:"dissatisfied"},{id:"very_dissatisfied",label:"非常不满意",value:"very_dissatisfied"}]},{id:"problems_encountered",type:"multiple",title:"你在使用 WebUI 时遇到过哪些问题?",description:"可多选",required:!0,options:[{id:"lag",label:"界面卡顿",value:"lag"},{id:"incomplete",label:"功能不完整",value:"incomplete"},{id:"complex",label:"操作复杂",value:"complex"},{id:"bugs",label:"存在 Bug",value:"bugs"},{id:"none",label:"没有遇到问题",value:"none"},{id:"other",label:"其他",value:"other"}]},{id:"problems_other",type:"text",title:'如选择"其他",请说明遇到的问题',required:!1,placeholder:"请描述你遇到的其他问题...",maxLength:500},{id:"useful_features",type:"textarea",title:"你觉得哪些功能是最有用的?",required:!0,placeholder:"请分享你认为最有价值的功能...",maxLength:1e3},{id:"feature_requests",type:"textarea",title:"你希望在未来的版本中增加哪些功能?",required:!0,placeholder:"请告诉我们你期望的新功能...",maxLength:1e3},{id:"overall_satisfaction",type:"single",title:"你对麦麦 WebUI 的整体满意度如何?",required:!0,options:[{id:"very_satisfied",label:"非常满意",value:"very_satisfied"},{id:"satisfied",label:"满意",value:"satisfied"},{id:"neutral",label:"一般",value:"neutral"},{id:"dissatisfied",label:"不满意",value:"dissatisfied"},{id:"very_dissatisfied",label:"非常不满意",value:"very_dissatisfied"}]},{id:"would_recommend",type:"single",title:"你愿意推荐麦麦 WebUI 给其他人使用吗?",required:!0,options:[{id:"yes",label:"是",value:"yes"},{id:"no",label:"否",value:"no"}]},{id:"other_suggestions",type:"textarea",title:"其他建议或意见",description:"此项为选填",required:!1,placeholder:"如果你有任何其他想法或建议,请在此分享...",maxLength:2e3}],settings:{allowMultiple:!1,thankYouMessage:"感谢你的反馈!你的意见对我们非常重要,我们会认真考虑每一条建议。"}},Pk={id:"maibot-feedback-v1",version:"1.0.0",title:"麦麦使用体验反馈问卷",description:"感谢您使用麦麦!您的反馈将帮助我们打造更好的 AI 伙伴。",questions:[{id:"maibot_version",type:"text",title:"你正在使用的麦麦版本",description:"此项由系统自动填写",required:!0,readOnly:!0,placeholder:"自动检测中..."},{id:"improvement_areas",type:"textarea",title:"你认为麦麦还有哪些部分可以改进?",required:!0,placeholder:"请分享你认为可以改进的方面...",maxLength:1e3},{id:"problems_encountered",type:"multiple",title:"你在使用麦麦时遇到过哪些问题?",description:"可多选",required:!0,options:[{id:"incomplete",label:"功能不完整",value:"incomplete"},{id:"slow_response",label:"响应速度慢",value:"slow_response"},{id:"complex",label:"操作复杂",value:"complex"},{id:"unstable",label:"运行不稳定",value:"unstable"},{id:"config_difficult",label:"配置困难",value:"config_difficult"},{id:"none",label:"没有遇到问题",value:"none"},{id:"other",label:"其他",value:"other"}]},{id:"problems_other",type:"text",title:'如选择"其他",请说明遇到的问题',required:!1,placeholder:"请描述你遇到的其他问题...",maxLength:500},{id:"helpful_features",type:"textarea",title:"你觉得麦麦的哪些功能对你最有帮助?",required:!0,placeholder:"请分享对你最有帮助的功能...",maxLength:1e3},{id:"feature_requests",type:"textarea",title:"你希望在未来的版本中增加哪些功能?",required:!0,placeholder:"请告诉我们你期望的新功能...",maxLength:1e3},{id:"overall_satisfaction",type:"single",title:"你对麦麦的整体满意度如何?",required:!0,options:[{id:"very_satisfied",label:"非常满意",value:"very_satisfied"},{id:"satisfied",label:"满意",value:"satisfied"},{id:"neutral",label:"一般",value:"neutral"},{id:"dissatisfied",label:"不满意",value:"dissatisfied"},{id:"very_dissatisfied",label:"非常不满意",value:"very_dissatisfied"}]},{id:"would_recommend",type:"single",title:"你愿意推荐麦麦给其他人使用吗?",required:!0,options:[{id:"yes",label:"是",value:"yes"},{id:"no",label:"否",value:"no"}]},{id:"other_suggestions",type:"textarea",title:"其他建议或意见",description:"此项为选填",required:!1,placeholder:"如果你有任何其他想法或建议,请在此分享...",maxLength:2e3}],settings:{allowMultiple:!1,thankYouMessage:"感谢你的反馈!你的意见对麦麦的成长非常重要,我们会认真考虑每一条建议。"}};function Hk(){const[l,n]=m.useState(!0),i=m.useMemo(()=>JSON.parse(JSON.stringify(Ik)),[]);m.useEffect(()=>{n(!1)},[]);const c=m.useMemo(()=>[{questionId:"webui_version",value:`v${Po}`}],[]),u=m.useCallback(h=>{console.log("WebUI Survey submitted:",h)},[]),x=m.useCallback(h=>{console.error("WebUI Survey submission error:",h)},[]);return l?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(zs,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):i?e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsxs("div",{className:"mb-4 sm:mb-6 shrink-0",children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(kj,{className:"h-8 w-8",strokeWidth:2}),"WebUI 使用反馈问卷"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"感谢您的反馈,帮助我们持续改进产品体验"})]}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(Hv,{config:i,initialAnswers:c,showProgress:!0,paginateQuestions:!1,onSubmitSuccess:u,onSubmitError:x})})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center min-h-[400px] gap-4",children:[e.jsxs(nt,{variant:"destructive",className:"max-w-md",children:[e.jsx(Ct,{className:"h-4 w-4"}),e.jsx(rt,{children:"无法加载问卷配置"})]}),e.jsx(C,{variant:"outline",onClick:()=>window.location.reload(),children:"重试"})]})}function Gk(){const[l,n]=m.useState(null),[i,c]=m.useState(!0),[u,x]=m.useState("未知版本");m.useEffect(()=>{(async()=>{try{const v=await P1();x(v.version||"未知版本")}catch(v){console.error("Failed to get MaiBot version:",v),x("获取失败")}const N=JSON.parse(JSON.stringify(Pk));n(N),c(!1)})()},[]);const h=m.useMemo(()=>[{questionId:"maibot_version",value:u}],[u]),f=m.useCallback(g=>{console.log("MaiBot Survey submitted:",g)},[]),p=m.useCallback(g=>{console.error("MaiBot Survey submission error:",g)},[]);return i?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(zs,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):l?e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsxs("div",{className:"mb-4 sm:mb-6 shrink-0",children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(kj,{className:"h-8 w-8",strokeWidth:2}),"麦麦使用体验反馈问卷"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"感谢您的反馈,帮助我们打造更好的 AI 伙伴"})]}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(Hv,{config:l,initialAnswers:h,showProgress:!0,paginateQuestions:!1,onSubmitSuccess:f,onSubmitError:p})})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center min-h-[400px] gap-4",children:[e.jsxs(nt,{variant:"destructive",className:"max-w-md",children:[e.jsx(Ct,{className:"h-4 w-4"}),e.jsx(rt,{children:"无法加载问卷配置"})]}),e.jsx(C,{variant:"outline",onClick:()=>window.location.reload(),children:"重试"})]})}var Yo="DropdownMenu",[Fk]=Lo(Yo,[Gg]),la=Gg(),[qk,Gv]=Fk(Yo),Fv=l=>{const{__scopeDropdownMenu:n,children:i,dir:c,open:u,defaultOpen:x,onOpenChange:h,modal:f=!0}=l,p=la(n),g=m.useRef(null),[N,v]=Ro({prop:u,defaultProp:x??!1,onChange:h,caller:Yo});return e.jsx(qk,{scope:n,triggerId:Cm(),triggerRef:g,contentId:Cm(),open:N,onOpenChange:v,onOpenToggle:m.useCallback(()=>v(b=>!b),[v]),modal:f,children:e.jsx(G0,{...p,open:N,onOpenChange:v,dir:c,modal:f,children:i})})};Fv.displayName=Yo;var qv="DropdownMenuTrigger",Vv=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,disabled:c=!1,...u}=l,x=Gv(qv,i),h=la(i);return e.jsx(F0,{asChild:!0,...h,children:e.jsx($n.button,{type:"button",id:x.triggerId,"aria-haspopup":"menu","aria-expanded":x.open,"aria-controls":x.open?x.contentId:void 0,"data-state":x.open?"open":"closed","data-disabled":c?"":void 0,disabled:c,...u,ref:Nw(n,x.triggerRef),onPointerDown:cn(l.onPointerDown,f=>{!c&&f.button===0&&f.ctrlKey===!1&&(x.onOpenToggle(),x.open||f.preventDefault())}),onKeyDown:cn(l.onKeyDown,f=>{c||(["Enter"," "].includes(f.key)&&x.onOpenToggle(),f.key==="ArrowDown"&&x.onOpenChange(!0),["Enter"," ","ArrowDown"].includes(f.key)&&f.preventDefault())})})})});Vv.displayName=qv;var Vk="DropdownMenuPortal",Kv=l=>{const{__scopeDropdownMenu:n,...i}=l,c=la(n);return e.jsx(R0,{...c,...i})};Kv.displayName=Vk;var Qv="DropdownMenuContent",Yv=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=Gv(Qv,i),x=la(i),h=m.useRef(!1);return e.jsx(L0,{id:u.contentId,"aria-labelledby":u.triggerId,...x,...c,ref:n,onCloseAutoFocus:cn(l.onCloseAutoFocus,f=>{h.current||u.triggerRef.current?.focus(),h.current=!1,f.preventDefault()}),onInteractOutside:cn(l.onInteractOutside,f=>{const p=f.detail.originalEvent,g=p.button===0&&p.ctrlKey===!0,N=p.button===2||g;(!u.modal||N)&&(h.current=!0)}),style:{...l.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});Yv.displayName=Qv;var Kk="DropdownMenuGroup",Qk=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(q0,{...u,...c,ref:n})});Qk.displayName=Kk;var Yk="DropdownMenuLabel",Jv=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(P0,{...u,...c,ref:n})});Jv.displayName=Yk;var Jk="DropdownMenuItem",Xv=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(U0,{...u,...c,ref:n})});Xv.displayName=Jk;var Xk="DropdownMenuCheckboxItem",Zv=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(B0,{...u,...c,ref:n})});Zv.displayName=Xk;var Zk="DropdownMenuRadioGroup",Wk=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(V0,{...u,...c,ref:n})});Wk.displayName=Zk;var eC="DropdownMenuRadioItem",Wv=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(I0,{...u,...c,ref:n})});Wv.displayName=eC;var sC="DropdownMenuItemIndicator",eN=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx($0,{...u,...c,ref:n})});eN.displayName=sC;var tC="DropdownMenuSeparator",sN=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(H0,{...u,...c,ref:n})});sN.displayName=tC;var aC="DropdownMenuArrow",lC=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(K0,{...u,...c,ref:n})});lC.displayName=aC;var nC="DropdownMenuSubTrigger",tN=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(D0,{...u,...c,ref:n})});tN.displayName=nC;var rC="DropdownMenuSubContent",aN=m.forwardRef((l,n)=>{const{__scopeDropdownMenu:i,...c}=l,u=la(i);return e.jsx(O0,{...u,...c,ref:n,style:{...l.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});aN.displayName=rC;var iC=Fv,cC=Vv,oC=Kv,lN=Yv,nN=Jv,rN=Xv,iN=Zv,cN=Wv,oN=eN,dN=sN,uN=tN,mN=aN;const dC=iC,uC=cC,mC=m.forwardRef(({className:l,inset:n,children:i,...c},u)=>e.jsxs(uN,{ref:u,className:B("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",n&&"pl-8",l),...c,children:[i,e.jsx(Sa,{className:"ml-auto h-4 w-4"})]}));mC.displayName=uN.displayName;const xC=m.forwardRef(({className:l,...n},i)=>e.jsx(mN,{ref:i,className:B("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",l),...n}));xC.displayName=mN.displayName;const xN=m.forwardRef(({className:l,sideOffset:n=4,...i},c)=>e.jsx(oC,{children:e.jsx(lN,{ref:c,sideOffset:n,className:B("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",l),...i})}));xN.displayName=lN.displayName;const hN=m.forwardRef(({className:l,inset:n,...i},c)=>e.jsx(rN,{ref:c,className:B("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",n&&"pl-8",l),...i}));hN.displayName=rN.displayName;const hC=m.forwardRef(({className:l,children:n,checked:i,...c},u)=>e.jsxs(iN,{ref:u,className:B("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",l),checked:i,...c,children:[e.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(oN,{children:e.jsx(St,{className:"h-4 w-4"})})}),n]}));hC.displayName=iN.displayName;const fC=m.forwardRef(({className:l,children:n,...i},c)=>e.jsxs(cN,{ref:c,className:B("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",l),...i,children:[e.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(oN,{children:e.jsx(Sj,{className:"h-2 w-2 fill-current"})})}),n]}));fC.displayName=cN.displayName;const pC=m.forwardRef(({className:l,inset:n,...i},c)=>e.jsx(nN,{ref:c,className:B("px-2 py-1.5 text-sm font-semibold",n&&"pl-8",l),...i}));pC.displayName=nN.displayName;const gC=m.forwardRef(({className:l,...n},i)=>e.jsx(dN,{ref:i,className:B("-mx-1 my-1 h-px bg-muted",l),...n}));gC.displayName=dN.displayName;const fN=({className:l,...n})=>e.jsx("nav",{role:"navigation","aria-label":"pagination",className:B("mx-auto flex w-full justify-center",l),...n});fN.displayName="Pagination";const pN=m.forwardRef(({className:l,...n},i)=>e.jsx("ul",{ref:i,className:B("flex flex-row items-center gap-1",l),...n}));pN.displayName="PaginationContent";const So=m.forwardRef(({className:l,...n},i)=>e.jsx("li",{ref:i,className:B("",l),...n}));So.displayName="PaginationItem";const Jo=({className:l,isActive:n,size:i="icon",...c})=>e.jsx("a",{"aria-current":n?"page":void 0,className:B(Rr({variant:n?"outline":"ghost",size:i}),l),...c});Jo.displayName="PaginationLink";const gN=({className:l,...n})=>e.jsxs(Jo,{"aria-label":"Go to previous page",size:"default",className:B("gap-1 pl-2.5",l),...n,children:[e.jsx(ll,{className:"h-4 w-4"}),e.jsx("span",{children:"上一页"})]});gN.displayName="PaginationPrevious";const jN=({className:l,...n})=>e.jsxs(Jo,{"aria-label":"Go to next page",size:"default",className:B("gap-1 pr-2.5",l),...n,children:[e.jsx("span",{children:"下一页"}),e.jsx(Sa,{className:"h-4 w-4"})]});jN.displayName="PaginationNext";const km=[{value:"created_at",label:"最新发布",icon:kl},{value:"downloads",label:"下载最多",icon:Xt},{value:"likes",label:"最受欢迎",icon:To}];function jC(){const l=aa(),[n,i]=m.useState([]),[c,u]=m.useState(!0),[x,h]=m.useState(""),[f,p]=m.useState("downloads"),[g,N]=m.useState(1),[v,b]=m.useState(1),[w,y]=m.useState(0),[R,D]=m.useState(new Set),[k,I]=m.useState(new Set),M=ov(),S=m.useCallback(async()=>{u(!0);try{const G=await L_({status:"approved",page:g,page_size:12,search:x||void 0,sort_by:f,sort_order:"desc"});i(G.packs),b(G.total_pages),y(G.total);const de=new Set;for(const oe of G.packs)await cv(oe.id,M)&&de.add(oe.id);D(de)}catch(G){console.error("加载 Pack 列表失败:",G),Gt({title:"加载 Pack 列表失败",variant:"destructive"})}finally{u(!1)}},[g,x,f,M]);m.useEffect(()=>{S()},[S]);const T=G=>{G.preventDefault(),N(1),S()},$=async G=>{if(!k.has(G)){I(de=>new Set(de).add(G));try{const de=await iv(G,M);D(oe=>{const ve=new Set(oe);return de.liked?ve.add(G):ve.delete(G),ve}),i(oe=>oe.map(ve=>ve.id===G?{...ve,likes:de.likes}:ve))}catch(de){console.error("点赞失败:",de),Gt({title:"点赞失败",variant:"destructive"})}finally{I(de=>{const oe=new Set(de);return oe.delete(G),oe})}}},A=G=>{l({to:"/config/pack-market/$packId",params:{packId:G}})},Q=km.find(G=>G.value===f)||km[0];return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsx("div",{className:"mb-4 sm:mb-6",children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(Wt,{className:"h-8 w-8",strokeWidth:2}),"配置模板市场"]}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm sm:text-base",children:"浏览和应用社区分享的模型配置模板,快速配置你的 MaiBot"})]}),e.jsxs(C,{variant:"outline",onClick:S,disabled:c,className:"gap-2",children:[e.jsx(kt,{className:`h-4 w-4 ${c?"animate-spin":""}`}),"刷新"]})]})}),e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex gap-4 flex-wrap",children:[e.jsx("form",{onSubmit:T,className:"flex-1 min-w-[200px] max-w-md",children:e.jsxs("div",{className:"relative",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(ie,{placeholder:"搜索模板名称、描述...",value:x,onChange:G=>h(G.target.value),className:"pl-10"})]})}),e.jsxs(dC,{children:[e.jsx(uC,{asChild:!0,children:e.jsxs(C,{variant:"outline",className:"min-w-[140px] gap-2",children:[e.jsx(Zw,{className:"w-4 h-4"}),Q.label,e.jsx($a,{className:"w-4 h-4 ml-auto"})]})}),e.jsx(xN,{align:"end",children:km.map(G=>e.jsxs(hN,{onClick:()=>{p(G.value),N(1)},children:[e.jsx(G.icon,{className:"w-4 h-4 mr-2"}),G.label]},G.value))})]})]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["共找到 ",e.jsx("span",{className:"font-medium text-foreground",children:w})," 个模板"]}),c?e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:Array.from({length:6}).map((G,de)=>e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(Js,{className:"h-6 w-3/4"}),e.jsx(Js,{className:"h-4 w-full mt-2"})]}),e.jsx(Qe,{children:e.jsx(Js,{className:"h-20 w-full"})}),e.jsx(Io,{children:e.jsx(Js,{className:"h-9 w-full"})})]},de))}):n.length===0?e.jsx(De,{className:"py-12",children:e.jsxs(Qe,{className:"text-center text-muted-foreground",children:[e.jsx(Wt,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{className:"text-lg font-medium",children:"暂无模板"}),e.jsx("p",{className:"mt-1",children:"还没有人分享配置模板,快来分享第一个吧!"})]})}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:n.map(G=>e.jsx(vC,{pack:G,liked:R.has(G.id),liking:k.has(G.id),onLike:()=>$(G.id),onView:()=>A(G.id)},G.id))}),v>1&&e.jsx(fN,{children:e.jsxs(pN,{children:[e.jsx(So,{children:e.jsx(gN,{onClick:()=>N(G=>Math.max(1,G-1)),className:g===1?"pointer-events-none opacity-50":"cursor-pointer"})}),Array.from({length:v},(G,de)=>de+1).filter(G=>G===1||G===v||Math.abs(G-g)<=1).map((G,de,oe)=>{const ve=de>0&&G-oe[de-1]>1;return e.jsxs(So,{children:[ve&&e.jsx("span",{className:"px-2",children:"..."}),e.jsx(Jo,{onClick:()=>N(G),isActive:G===g,className:"cursor-pointer",children:G})]},G)}),e.jsx(So,{children:e.jsx(jN,{onClick:()=>N(G=>Math.min(v,G+1)),className:g===v?"pointer-events-none opacity-50":"cursor-pointer"})})]})})]})})]})}function vC({pack:l,liked:n,liking:i,onLike:c,onView:u}){const x=h=>new Date(h).toLocaleDateString("zh-CN",{year:"numeric",month:"short",day:"numeric"});return e.jsxs(De,{className:"flex flex-col hover:shadow-md transition-shadow",children:[e.jsxs(Xe,{className:"pb-3",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(We,{className:"text-lg line-clamp-1",children:l.name}),e.jsxs(Ae,{variant:"secondary",className:"text-xs",children:["v",l.version]})]}),e.jsx(Is,{className:"line-clamp-2 min-h-[40px]",children:l.description})]}),e.jsxs(Qe,{className:"flex-1 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Dn,{className:"w-3.5 h-3.5"}),l.author]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(kl,{className:"w-3.5 h-3.5"}),x(l.created_at)]})]}),e.jsxs("div",{className:"flex gap-4 text-sm",children:[e.jsxs("span",{className:"flex items-center gap-1 text-muted-foreground",title:"提供商数量",children:[e.jsx(Tl,{className:"w-3.5 h-3.5"}),l.provider_count]}),e.jsxs("span",{className:"flex items-center gap-1 text-muted-foreground",title:"模型数量",children:[e.jsx(Rn,{className:"w-3.5 h-3.5"}),l.model_count]}),e.jsxs("span",{className:"flex items-center gap-1 text-muted-foreground",title:"任务配置数",children:[e.jsx(Ln,{className:"w-3.5 h-3.5"}),l.task_count]})]}),l.tags&&l.tags.length>0&&e.jsxs("div",{className:"flex flex-wrap gap-1",children:[l.tags.slice(0,3).map(h=>e.jsxs(Ae,{variant:"outline",className:"text-xs",children:[e.jsx($o,{className:"w-2.5 h-2.5 mr-1"}),h]},h)),l.tags.length>3&&e.jsxs(Ae,{variant:"outline",className:"text-xs",children:["+",l.tags.length-3]})]})]}),e.jsx(Io,{className:"pt-3 border-t",children:e.jsxs("div",{className:"flex items-center justify-between w-full",children:[e.jsxs("div",{className:"flex items-center gap-3 text-sm text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Xt,{className:"w-4 h-4"}),l.downloads]}),e.jsxs("button",{onClick:h=>{h.stopPropagation(),c()},disabled:i,className:`flex items-center gap-1 transition-colors ${n?"text-red-500":"hover:text-red-500"} ${i?"opacity-50":""}`,children:[e.jsx(To,{className:`w-4 h-4 ${n?"fill-current":""}`}),l.likes]})]}),e.jsx(C,{size:"sm",onClick:u,children:"查看详情"})]})})]})}var Qa="Accordion",NC=["Home","End","ArrowDown","ArrowUp","ArrowLeft","ArrowRight"],[Xm,bC,yC]=bw(Qa),[Xo]=Lo(Qa,[yC,Fg]),Zm=Fg(),vN=Es.forwardRef((l,n)=>{const{type:i,...c}=l,u=c,x=c;return e.jsx(Xm.Provider,{scope:l.__scopeAccordion,children:i==="multiple"?e.jsx(kC,{...x,ref:n}):e.jsx(SC,{...u,ref:n})})});vN.displayName=Qa;var[NN,wC]=Xo(Qa),[bN,_C]=Xo(Qa,{collapsible:!1}),SC=Es.forwardRef((l,n)=>{const{value:i,defaultValue:c,onValueChange:u=()=>{},collapsible:x=!1,...h}=l,[f,p]=Ro({prop:i,defaultProp:c??"",onChange:u,caller:Qa});return e.jsx(NN,{scope:l.__scopeAccordion,value:Es.useMemo(()=>f?[f]:[],[f]),onItemOpen:p,onItemClose:Es.useCallback(()=>x&&p(""),[x,p]),children:e.jsx(bN,{scope:l.__scopeAccordion,collapsible:x,children:e.jsx(yN,{...h,ref:n})})})}),kC=Es.forwardRef((l,n)=>{const{value:i,defaultValue:c,onValueChange:u=()=>{},...x}=l,[h,f]=Ro({prop:i,defaultProp:c??[],onChange:u,caller:Qa}),p=Es.useCallback(N=>f((v=[])=>[...v,N]),[f]),g=Es.useCallback(N=>f((v=[])=>v.filter(b=>b!==N)),[f]);return e.jsx(NN,{scope:l.__scopeAccordion,value:h,onItemOpen:p,onItemClose:g,children:e.jsx(bN,{scope:l.__scopeAccordion,collapsible:!0,children:e.jsx(yN,{...x,ref:n})})})}),[CC,Zo]=Xo(Qa),yN=Es.forwardRef((l,n)=>{const{__scopeAccordion:i,disabled:c,dir:u,orientation:x="vertical",...h}=l,f=Es.useRef(null),p=Uo(f,n),g=bC(i),v=lj(u)==="ltr",b=cn(l.onKeyDown,w=>{if(!NC.includes(w.key))return;const y=w.target,R=g().filter(Q=>!Q.ref.current?.disabled),D=R.findIndex(Q=>Q.ref.current===y),k=R.length;if(D===-1)return;w.preventDefault();let I=D;const M=0,S=k-1,T=()=>{I=D+1,I>S&&(I=M)},$=()=>{I=D-1,I{const{__scopeAccordion:i,value:c,...u}=l,x=Zo(Oo,i),h=wC(Oo,i),f=Zm(i),p=Cm(),g=c&&h.value.includes(c)||!1,N=x.disabled||l.disabled;return e.jsx(TC,{scope:i,open:g,disabled:N,triggerId:p,children:e.jsx(Bg,{"data-orientation":x.orientation,"data-state":EN(g),...f,...u,ref:n,disabled:N,open:g,onOpenChange:v=>{v?h.onItemOpen(c):h.onItemClose(c)}})})});wN.displayName=Oo;var _N="AccordionHeader",SN=Es.forwardRef((l,n)=>{const{__scopeAccordion:i,...c}=l,u=Zo(Qa,i),x=Wm(_N,i);return e.jsx($n.h3,{"data-orientation":u.orientation,"data-state":EN(x.open),"data-disabled":x.disabled?"":void 0,...c,ref:n})});SN.displayName=_N;var Dm="AccordionTrigger",kN=Es.forwardRef((l,n)=>{const{__scopeAccordion:i,...c}=l,u=Zo(Qa,i),x=Wm(Dm,i),h=_C(Dm,i),f=Zm(i);return e.jsx(Xm.ItemSlot,{scope:i,children:e.jsx(Q0,{"aria-disabled":x.open&&!h.collapsible||void 0,"data-orientation":u.orientation,id:x.triggerId,...f,...c,ref:n})})});kN.displayName=Dm;var CN="AccordionContent",TN=Es.forwardRef((l,n)=>{const{__scopeAccordion:i,...c}=l,u=Zo(Qa,i),x=Wm(CN,i),h=Zm(i);return e.jsx(Y0,{role:"region","aria-labelledby":x.triggerId,"data-orientation":u.orientation,...h,...c,ref:n,style:{"--radix-accordion-content-height":"var(--radix-collapsible-content-height)","--radix-accordion-content-width":"var(--radix-collapsible-content-width)",...l.style}})});TN.displayName=CN;function EN(l){return l?"open":"closed"}var EC=vN,MC=wN,AC=SN,MN=kN,AN=TN;const zC=EC,zN=m.forwardRef(({className:l,...n},i)=>e.jsx(MC,{ref:i,className:B("border-b",l),...n}));zN.displayName="AccordionItem";const DN=m.forwardRef(({className:l,children:n,...i},c)=>e.jsx(AC,{className:"flex",children:e.jsxs(MN,{ref:c,className:B("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",l),...i,children:[n,e.jsx($a,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})]})}));DN.displayName=MN.displayName;const ON=m.forwardRef(({className:l,children:n,...i},c)=>e.jsx(AN,{ref:c,className:"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",...i,children:e.jsx("div",{className:B("pb-4 pt-0",l),children:n})}));ON.displayName=AN.displayName;const DC={utils:"通用工具",utils_small:"轻量工具",tool_use:"工具调用",replyer:"回复生成",planner:"规划推理",vlm:"视觉模型",voice:"语音处理",embedding:"向量嵌入",lpmm_entity_extract:"实体提取",lpmm_rdf_build:"RDF构建",lpmm_qa:"问答模型"};function OC(){const{packId:l}=$N.useParams(),n=aa(),[i,c]=m.useState(null),[u,x]=m.useState(!0),[h,f]=m.useState(!1),[p,g]=m.useState(!1),[N,v]=m.useState(!1),[b,w]=m.useState(1),[y,R]=m.useState(null),[D,k]=m.useState(!1),[I,M]=m.useState(!1),[S,T]=m.useState({apply_providers:!0,apply_models:!0,apply_task_config:!0,task_mode:"append",selected_providers:void 0,selected_models:void 0,selected_tasks:void 0}),[$,A]=m.useState({}),[Q,G]=m.useState({}),de=ov(),oe=m.useCallback(async()=>{if(l){x(!0);try{const z=await U_(l);c(z);const V=await cv(l,de);f(V)}catch(z){console.error("加载 Pack 失败:",z),Gt({title:"加载模板失败",variant:"destructive"})}finally{x(!1)}}},[l,de]);m.useEffect(()=>{oe()},[oe]);const ve=async()=>{if(!(!l||p)){g(!0);try{const z=await iv(l,de);f(z.liked),i&&c({...i,likes:z.likes})}catch(z){console.error("点赞失败:",z),Gt({title:"点赞失败",variant:"destructive"})}finally{g(!1)}}},le=async()=>{if(i){v(!0),w(1),k(!0);try{const z=await I_(i);R(z);const V={};for(const L of z.existing_providers)V[L.pack_provider.name]=L.local_providers[0].name;A(V);const U={};for(const L of z.new_providers)U[L.name]="";G(U)}catch(z){console.error("检测冲突失败:",z),Gt({title:"检测配置冲突失败",variant:"destructive"}),v(!1)}finally{k(!1)}}},fe=async()=>{if(i){if(S.apply_providers&&y){for(const z of y.new_providers)if(!Q[z.name]){Gt({title:`请填写提供商 "${z.name}" 的 API Key`,variant:"destructive"});return}}M(!0);try{await P_(i,S,$,Q),await $_(i.id,de),c({...i,downloads:i.downloads+1}),Gt({title:"配置模板应用成功!"}),v(!1)}catch(z){console.error("应用 Pack 失败:",z),Gt({title:z instanceof Error?z.message:"应用配置失败",variant:"destructive"})}finally{M(!1)}}},ge=z=>new Date(z).toLocaleDateString("zh-CN",{year:"numeric",month:"long",day:"numeric"});return u?e.jsx(LC,{}):i?e.jsx("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsxs(C,{variant:"ghost",size:"sm",onClick:()=>n({to:"/config/pack-market"}),className:"gap-2",children:[e.jsx(Va,{className:"w-4 h-4"}),"返回市场"]}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-6",children:[e.jsxs("div",{className:"flex-1 space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Wt,{className:"w-10 h-10 text-primary mt-1"}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[i.name,e.jsxs(Ae,{variant:"secondary",children:["v",i.version]})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:i.description})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-4 text-sm text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Dn,{className:"w-4 h-4"}),i.author]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(kl,{className:"w-4 h-4"}),ge(i.created_at)]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Xt,{className:"w-4 h-4"}),i.downloads," 次下载"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(To,{className:`w-4 h-4 ${h?"fill-red-500 text-red-500":""}`}),i.likes," 赞"]})]}),i.tags&&i.tags.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2",children:i.tags.map(z=>e.jsxs(Ae,{variant:"outline",children:[e.jsx($o,{className:"w-3 h-3 mr-1"}),z]},z))})]}),e.jsxs("div",{className:"flex flex-col gap-2 min-w-[160px]",children:[e.jsxs(C,{size:"lg",onClick:le,children:[e.jsx(Xt,{className:"w-4 h-4 mr-2"}),"应用模板"]}),e.jsxs(C,{variant:"outline",onClick:ve,disabled:p,className:h?"text-red-500 border-red-200":"",children:[e.jsx(To,{className:`w-4 h-4 mr-2 ${h?"fill-current":""}`}),h?"已点赞":"点赞"]})]})]}),e.jsx($r,{}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsx(De,{children:e.jsxs(Qe,{className:"flex items-center gap-3 py-4",children:[e.jsx(Tl,{className:"w-8 h-8 text-blue-500"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:i.providers.length}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"API 提供商"})]})]})}),e.jsx(De,{children:e.jsxs(Qe,{className:"flex items-center gap-3 py-4",children:[e.jsx(Rn,{className:"w-8 h-8 text-green-500"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:i.models.length}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"模型配置"})]})]})}),e.jsx(De,{children:e.jsxs(Qe,{className:"flex items-center gap-3 py-4",children:[e.jsx(Ln,{className:"w-8 h-8 text-purple-500"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:Object.keys(i.task_config).length}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"任务配置"})]})]})})]}),e.jsxs(ma,{defaultValue:"providers",className:"space-y-4",children:[e.jsxs(ta,{children:[e.jsxs(as,{value:"providers",children:[e.jsx(Tl,{className:"w-4 h-4 mr-2"}),"提供商 (",i.providers.length,")"]}),e.jsxs(as,{value:"models",children:[e.jsx(Rn,{className:"w-4 h-4 mr-2"}),"模型 (",i.models.length,")"]}),e.jsxs(as,{value:"tasks",children:[e.jsx(Ln,{className:"w-4 h-4 mr-2"}),"任务配置 (",Object.keys(i.task_config).length,")"]})]}),e.jsx(ys,{value:"providers",children:e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"API 提供商"}),e.jsx(Is,{children:"模板中包含的 API 提供商配置(不含 API Key)"})]}),e.jsx(Qe,{children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{children:"名称"}),e.jsx(Je,{children:"Base URL"}),e.jsx(Je,{children:"类型"})]})}),e.jsx(Al,{children:i.providers.map(z=>e.jsxs(ct,{children:[e.jsx(He,{className:"font-medium",children:z.name}),e.jsx(He,{className:"text-muted-foreground font-mono text-sm",children:z.base_url}),e.jsx(He,{children:e.jsx(Ae,{variant:"outline",children:z.client_type})})]},z.name))})]})})]})}),e.jsx(ys,{value:"models",children:e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"模型配置"}),e.jsx(Is,{children:"模板中包含的模型配置"})]}),e.jsx(Qe,{children:e.jsxs(El,{children:[e.jsx(Ml,{children:e.jsxs(ct,{children:[e.jsx(Je,{children:"模型名称"}),e.jsx(Je,{children:"标识符"}),e.jsx(Je,{children:"提供商"}),e.jsx(Je,{className:"text-right",children:"价格 (入/出)"})]})}),e.jsx(Al,{children:i.models.map(z=>e.jsxs(ct,{children:[e.jsx(He,{className:"font-medium",children:z.name}),e.jsx(He,{className:"text-muted-foreground font-mono text-sm",children:z.model_identifier}),e.jsx(He,{children:z.api_provider}),e.jsxs(He,{className:"text-right text-muted-foreground",children:["¥",z.price_in," / ¥",z.price_out]})]},z.name))})]})})]})}),e.jsx(ys,{value:"tasks",children:e.jsxs(De,{children:[e.jsxs(Xe,{children:[e.jsx(We,{children:"任务配置"}),e.jsx(Is,{children:"模板中各任务类型的模型分配"})]}),e.jsx(Qe,{children:e.jsx(zC,{type:"multiple",className:"w-full",children:Object.entries(i.task_config).map(([z,V])=>e.jsxs(zN,{value:z,children:[e.jsx(DN,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(In,{className:"w-4 h-4"}),DC[z]||z,e.jsxs(Ae,{variant:"secondary",className:"ml-2",children:[V.model_list.length," 个模型"]})]})}),e.jsx(ON,{children:e.jsxs("div",{className:"space-y-2 pl-6",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"分配的模型:"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:V.model_list.map(U=>e.jsx(Ae,{variant:"outline",children:U},U))}),V.temperature!==void 0&&e.jsxs("div",{className:"text-sm",children:["Temperature: ",e.jsx("span",{className:"font-mono",children:V.temperature})]}),V.max_tokens!==void 0&&e.jsxs("div",{className:"text-sm",children:["Max Tokens: ",e.jsx("span",{className:"font-mono",children:V.max_tokens})]})]})})]},z))})})]})})]}),e.jsx(RC,{open:N,onOpenChange:v,pack:i,step:b,setStep:w,conflicts:y,detectingConflicts:D,applying:I,options:S,setOptions:T,_providerMapping:$,_setProviderMapping:A,newProviderApiKeys:Q,setNewProviderApiKeys:G,onApply:fe})]})})}):e.jsxs("div",{className:"text-center py-12",children:[e.jsx(Wt,{className:"w-16 h-16 mx-auto mb-4 opacity-50"}),e.jsx("h2",{className:"text-xl font-semibold",children:"模板不存在"}),e.jsx("p",{className:"text-muted-foreground mt-2",children:"该配置模板可能已被删除或尚未通过审核"}),e.jsxs(C,{className:"mt-4",onClick:()=>n({to:"/config/pack-market"}),children:[e.jsx(Va,{className:"w-4 h-4 mr-2"}),"返回市场"]})]})}function RC({open:l,onOpenChange:n,pack:i,step:c,setStep:u,conflicts:x,detectingConflicts:h,applying:f,options:p,setOptions:g,_providerMapping:N,_setProviderMapping:v,newProviderApiKeys:b,setNewProviderApiKeys:w,onApply:y}){return e.jsx(Ks,{open:l,onOpenChange:n,children:e.jsxs(Ps,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(Hs,{children:[e.jsxs(Gs,{className:"flex items-center gap-2",children:[e.jsx(Wt,{className:"w-5 h-5"}),"应用配置模板"]}),e.jsxs(ot,{children:["步骤 ",c," / ",3,":",c===1&&"选择要应用的内容",c===2&&"配置提供商映射",c===3&&"确认并应用"]})]}),h?e.jsxs("div",{className:"py-8 text-center",children:[e.jsx(zs,{className:"w-8 h-8 mx-auto animate-spin text-primary"}),e.jsx("p",{className:"mt-4 text-muted-foreground",children:"正在检测配置冲突..."})]}):e.jsxs(e.Fragment,{children:[c===1&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"apply_providers",checked:p.apply_providers,onCheckedChange:D=>g({...p,apply_providers:D})}),e.jsxs(E,{htmlFor:"apply_providers",className:"flex items-center gap-2",children:[e.jsx(Tl,{className:"w-4 h-4"}),"应用提供商配置 (",i.providers.length," 个)"]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"apply_models",checked:p.apply_models,onCheckedChange:D=>g({...p,apply_models:D})}),e.jsxs(E,{htmlFor:"apply_models",className:"flex items-center gap-2",children:[e.jsx(Rn,{className:"w-4 h-4"}),"应用模型配置 (",i.models.length," 个)"]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Xs,{id:"apply_task_config",checked:p.apply_task_config,onCheckedChange:D=>g({...p,apply_task_config:D})}),e.jsxs(E,{htmlFor:"apply_task_config",className:"flex items-center gap-2",children:[e.jsx(Ln,{className:"w-4 h-4"}),"应用任务配置 (",Object.keys(i.task_config).length," 个)"]})]})]}),p.apply_task_config&&e.jsxs("div",{className:"pl-6 space-y-2 border-l-2 border-muted",children:[e.jsx(E,{className:"text-sm font-medium",children:"任务配置应用模式"}),e.jsxs(Jm,{value:p.task_mode,onValueChange:D=>g({...p,task_mode:D}),children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Do,{value:"append",id:"mode_append"}),e.jsx(E,{htmlFor:"mode_append",className:"font-normal",children:"追加模式 - 将模板中的模型添加到现有配置"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Do,{value:"replace",id:"mode_replace"}),e.jsx(E,{htmlFor:"mode_replace",className:"font-normal",children:"替换模式 - 用模板配置完全替换现有配置"})]})]})]})]}),c===2&&x&&e.jsxs("div",{className:"space-y-4",children:[p.apply_providers&&x.existing_providers.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsx(An,{children:"发现已有的提供商"}),e.jsx(rt,{children:"以下提供商的 URL 与您本地配置中的提供商匹配,将自动使用本地提供商:"})]}),e.jsx("div",{className:"space-y-2",children:x.existing_providers.map(({pack_provider:D,local_providers:k})=>e.jsxs("div",{className:"flex items-center gap-2 p-3 bg-muted rounded-lg",children:[e.jsx(St,{className:"w-4 h-4 text-green-500 flex-shrink-0"}),e.jsx("span",{className:"font-medium flex-shrink-0",children:D.name}),e.jsx(Sa,{className:"w-4 h-4 text-muted-foreground flex-shrink-0"}),k.length===1?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-muted-foreground",children:k[0].name}),e.jsx(Ae,{variant:"outline",className:"ml-auto",children:"URL 匹配"})]}):e.jsxs(e.Fragment,{children:[e.jsxs(Be,{value:N[D.name]||k[0].name,onValueChange:I=>v({...N,[D.name]:I}),children:[e.jsx(Le,{className:"w-[200px]",children:e.jsx($e,{})}),e.jsx(Ue,{children:k.map(I=>e.jsx(ae,{value:I.name,children:I.name},I.name))})]}),e.jsxs(Ae,{variant:"outline",className:"ml-auto",children:[k.length," 个匹配"]})]})]},D.name))})]}),p.apply_providers&&x.new_providers.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs(nt,{variant:"destructive",children:[e.jsx(Ft,{className:"h-4 w-4"}),e.jsx(An,{children:"需要配置 API Key"}),e.jsx(rt,{children:"以下提供商在您的本地配置中不存在,需要填写 API Key:"})]}),e.jsx("div",{className:"space-y-4",children:x.new_providers.map(D=>e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Om,{className:"w-4 h-4 text-amber-500"}),e.jsx("span",{className:"font-medium",children:D.name}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["(",D.base_url,")"]})]}),e.jsx(ie,{type:"password",placeholder:`输入 ${D.name} 的 API Key`,value:b[D.name]||"",onChange:k=>w({...b,[D.name]:k.target.value})})]},D.name))})]}),(!p.apply_providers||x.existing_providers.length===0&&x.new_providers.length===0)&&e.jsxs(nt,{children:[e.jsx(St,{className:"h-4 w-4"}),e.jsx(An,{children:"无需配置"}),e.jsx(rt,{children:"模板中没有提供商配置,或您选择不应用提供商。"})]})]}),c===3&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs(nt,{children:[e.jsx(qt,{className:"h-4 w-4"}),e.jsx(An,{children:"确认应用"}),e.jsx(rt,{children:"请确认以下将要应用的内容:"})]}),e.jsxs("div",{className:"space-y-2",children:[p.apply_providers&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(St,{className:"w-4 h-4 text-green-500"}),e.jsx(Tl,{className:"w-4 h-4"}),e.jsxs("span",{children:["应用 ",i.providers.length," 个提供商配置"]})]}),p.apply_models&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(St,{className:"w-4 h-4 text-green-500"}),e.jsx(Rn,{className:"w-4 h-4"}),e.jsxs("span",{children:["应用 ",i.models.length," 个模型配置"]})]}),p.apply_task_config&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(St,{className:"w-4 h-4 text-green-500"}),e.jsx(Ln,{className:"w-4 h-4"}),e.jsxs("span",{children:[p.task_mode==="append"?"追加":"替换"," ",Object.keys(i.task_config).length," 个任务配置"]})]})]}),x&&x.new_providers.length>0&&e.jsxs(nt,{variant:"destructive",children:[e.jsx(Ft,{className:"h-4 w-4"}),e.jsxs(rt,{children:["将添加 ",x.new_providers.length," 个新提供商,请确保已填写正确的 API Key。"]})]})]})]}),e.jsxs(xt,{className:"flex justify-between",children:[e.jsx("div",{children:c>1&&!h&&e.jsx(C,{variant:"outline",onClick:()=>u(c-1),disabled:f,children:"上一步"})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(C,{variant:"outline",onClick:()=>n(!1),disabled:f,children:"取消"}),c<3?e.jsx(C,{onClick:()=>u(c+1),disabled:h,children:"下一步"}):e.jsxs(C,{onClick:y,disabled:f,children:[f&&e.jsx(zs,{className:"w-4 h-4 mr-2 animate-spin"}),"应用模板"]})]})]})]})})}function LC(){return e.jsx("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:e.jsx(es,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsx(Js,{className:"h-9 w-24"}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-6",children:[e.jsxs("div",{className:"flex-1 space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Js,{className:"w-10 h-10"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx(Js,{className:"h-8 w-2/3"}),e.jsx(Js,{className:"h-4 w-full"})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(Js,{className:"h-4 w-24"}),e.jsx(Js,{className:"h-4 w-32"}),e.jsx(Js,{className:"h-4 w-28"}),e.jsx(Js,{className:"h-4 w-20"})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(Js,{className:"h-6 w-20"}),e.jsx(Js,{className:"h-6 w-24"}),e.jsx(Js,{className:"h-6 w-16"})]})]}),e.jsxs("div",{className:"flex flex-col gap-2 min-w-[160px]",children:[e.jsx(Js,{className:"h-10 w-full"}),e.jsx(Js,{className:"h-10 w-full"})]})]}),e.jsx(Js,{className:"h-px w-full"}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsx(Js,{className:"h-24"}),e.jsx(Js,{className:"h-24"}),e.jsx(Js,{className:"h-24"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Js,{className:"h-10 w-32"}),e.jsx(Js,{className:"h-10 w-32"}),e.jsx(Js,{className:"h-10 w-32"})]}),e.jsx(Js,{className:"h-96 w-full"})]})]})})})}function UC(){const l=aa(),[n,i]=m.useState(!0);return m.useEffect(()=>{let c=!1;return(async()=>{try{const x=await Fi();!c&&!x&&l({to:"/auth"})}catch{c||l({to:"/auth"})}finally{c||i(!1)}})(),()=>{c=!0}},[l]),{checking:n}}async function BC(){return await Fi()}const $C=Lr("pointer-events-none inline-flex select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono font-medium opacity-100",{variants:{size:{sm:"h-5 text-[10px]",default:"h-6 text-xs",lg:"h-7 text-sm"}},defaultVariants:{size:"default"}}),RN=m.forwardRef(({className:l,size:n,abbrTitle:i,children:c,...u},x)=>e.jsx("kbd",{className:B($C({size:n,className:l})),ref:x,...u,children:i?e.jsx("abbr",{title:i,children:c}):c}));RN.displayName="Kbd";const IC=[{icon:Bo,title:"首页",description:"查看仪表板概览",path:"/",category:"概览"},{icon:qa,title:"麦麦主程序配置",description:"配置麦麦的核心设置",path:"/config/bot",category:"配置"},{icon:Tl,title:"麦麦模型提供商配置",description:"配置模型提供商",path:"/config/modelProvider",category:"配置"},{icon:Cj,title:"麦麦模型配置",description:"配置模型参数",path:"/config/model",category:"配置"},{icon:Rm,title:"表情包管理",description:"管理麦麦的表情包",path:"/resource/emoji",category:"资源"},{icon:on,title:"表达方式管理",description:"管理麦麦的表达方式",path:"/resource/expression",category:"资源"},{icon:Tj,title:"人物信息管理",description:"管理人物信息",path:"/resource/person",category:"资源"},{icon:Or,title:"黑话管理",description:"管理麦麦学习到的黑话和俚语",path:"/resource/jargon",category:"资源"},{icon:Ww,title:"统计信息",description:"查看使用统计",path:"/statistics",category:"监控"},{icon:Wt,title:"插件市场",description:"浏览和安装插件",path:"/plugins",category:"扩展"},{icon:Lm,title:"日志查看器",description:"查看系统日志",path:"/logs",category:"监控"},{icon:In,title:"系统设置",description:"配置系统参数",path:"/settings",category:"系统"}];function PC({open:l,onOpenChange:n}){const[i,c]=m.useState(""),[u,x]=m.useState(0),h=aa(),f=IC.filter(N=>N.title.toLowerCase().includes(i.toLowerCase())||N.description.toLowerCase().includes(i.toLowerCase())||N.category.toLowerCase().includes(i.toLowerCase())),p=m.useCallback(N=>{h({to:N}),n(!1),c(""),x(0)},[h,n]),g=m.useCallback(N=>{N.key==="ArrowDown"?(N.preventDefault(),x(v=>(v+1)%f.length)):N.key==="ArrowUp"?(N.preventDefault(),x(v=>(v-1+f.length)%f.length)):N.key==="Enter"&&f[u]&&(N.preventDefault(),p(f[u].path))},[f,u,p]);return e.jsx(Ks,{open:l,onOpenChange:n,children:e.jsxs(Ps,{className:"max-w-2xl p-0 gap-0",children:[e.jsxs(Hs,{className:"px-4 pt-4 pb-0",children:[e.jsx(Gs,{className:"sr-only",children:"搜索"}),e.jsxs("div",{className:"relative",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground"}),e.jsx(ie,{value:i,onChange:N=>{c(N.target.value),x(0)},onKeyDown:g,placeholder:"搜索页面...",className:"h-12 pl-11 text-base border-0 focus-visible:ring-0 shadow-none",autoFocus:!0})]})]}),e.jsx("div",{className:"border-t",children:e.jsx(es,{className:"h-[400px]",children:f.length>0?e.jsx("div",{className:"p-2",children:f.map((N,v)=>{const b=N.icon;return e.jsxs("button",{onClick:()=>p(N.path),onMouseEnter:()=>x(v),className:B("w-full flex items-center gap-3 px-3 py-2.5 rounded-md text-left transition-colors",v===u?"bg-accent text-accent-foreground":"hover:bg-accent/50"),children:[e.jsx(b,{className:"h-5 w-5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"font-medium text-sm",children:N.title}),e.jsx("div",{className:"text-xs text-muted-foreground truncate",children:N.description})]}),e.jsx("div",{className:"text-xs text-muted-foreground px-2 py-1 bg-muted rounded",children:N.category})]},N.path)})}):e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Vt,{className:"h-12 w-12 text-muted-foreground/50 mb-4"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:i?"未找到匹配的页面":"输入关键词开始搜索"})]})})}),e.jsx("div",{className:"border-t px-4 py-3 flex items-center justify-between text-xs text-muted-foreground",children:e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"↑"}),e.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"↓"}),"导航"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"Enter"}),"选择"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("kbd",{className:"px-1.5 py-0.5 bg-muted rounded border",children:"Esc"}),"关闭"]})]})})]})})}function HC(){const l=window.location.protocol==="http:",n=window.location.hostname.toLowerCase(),i=n==="localhost"||n==="127.0.0.1"||n==="::1",c=sessionStorage.getItem("http-warning-dismissed")==="true",[u,x]=m.useState(l&&!i&&!c),[h,f]=m.useState(!1),p=()=>{f(!0),x(!1),sessionStorage.setItem("http-warning-dismissed","true")};return!u||h?null:e.jsx("div",{className:"relative bg-amber-500/10 border-b border-amber-500/20 backdrop-blur-sm",children:e.jsx("div",{className:"container mx-auto px-4 py-3",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3 flex-1",children:[e.jsx(Ft,{className:"h-5 w-5 text-amber-600 dark:text-amber-500 flex-shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("p",{className:"text-sm font-medium text-amber-900 dark:text-amber-100",children:[e.jsx("span",{className:"font-semibold",children:"安全警告:"}),"您正在使用 ",e.jsx("strong",{children:"HTTP"})," 访问 MaiBot WebUI"]}),e.jsx("p",{className:"text-xs text-amber-800 dark:text-amber-200 mt-1",children:"如果这是公网服务器,您的数据(包括 Token、聊天记录等)可能在传输过程中被窃取。强烈建议使用 HTTPS 访问或仅在本地网络使用。"})]})]}),e.jsx(C,{variant:"ghost",size:"icon",onClick:p,className:"h-8 w-8 text-amber-700 hover:text-amber-900 dark:text-amber-400 dark:hover:text-amber-200 flex-shrink-0","aria-label":"关闭警告",children:e.jsx(_a,{className:"h-4 w-4"})})]})})})}function GC(){const[l,n]=m.useState(0),[i,c]=m.useState(!1),u=m.useRef(null);m.useEffect(()=>{const g=N=>{const v=N.target;if(v.scrollHeight>v.clientHeight+100){u.current=v;const b=v.scrollTop,w=v.scrollHeight-v.clientHeight,y=w>0?b/w*100:0;n(y),c(b>300)}};return window.addEventListener("scroll",g,{capture:!0,passive:!0}),()=>window.removeEventListener("scroll",g,{capture:!0})},[]);const x=()=>{u.current?.scrollTo({top:0,behavior:"smooth"})},h=18,f=2*Math.PI*h,p=f-l/100*f;return e.jsx("div",{className:B("fixed bottom-24 right-8 z-50 transition-all duration-500 ease-in-out transform",i?"translate-x-0 opacity-100":"translate-x-32 opacity-0 pointer-events-none"),children:e.jsxs(C,{variant:"outline",size:"icon",className:B("relative h-12 w-12 rounded-full shadow-xl","bg-background/80 backdrop-blur-md border-border/50","hover:bg-accent hover:scale-110 hover:shadow-2xl hover:border-primary/50","transition-all duration-300","group"),onClick:x,"aria-label":"回到顶部",children:[e.jsxs("svg",{className:"absolute inset-0 h-full w-full -rotate-90 transform p-1",viewBox:"0 0 44 44",children:[e.jsx("circle",{className:"text-muted-foreground/10",strokeWidth:"3",stroke:"currentColor",fill:"transparent",r:h,cx:"22",cy:"22"}),e.jsx("circle",{className:"text-primary transition-all duration-100 ease-out",strokeWidth:"3",strokeDasharray:f,strokeDashoffset:p,strokeLinecap:"round",stroke:"currentColor",fill:"transparent",r:h,cx:"22",cy:"22"})]}),e.jsx(e1,{className:"h-5 w-5 text-primary transition-transform duration-300 group-hover:-translate-y-1 group-hover:scale-110",strokeWidth:2.5}),e.jsx("div",{className:"absolute inset-0 rounded-full bg-primary/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300"})]})})}const FC=ww,qC=_w,VC=Sw,LN=m.forwardRef(({className:l,sideOffset:n=4,...i},c)=>e.jsx(yw,{children:e.jsx(nj,{ref:c,sideOffset:n,className:B("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]",l),...i})}));LN.displayName=nj.displayName;function KC({children:l}){const{checking:n}=UC(),[i,c]=m.useState(!0),[u,x]=m.useState(!1),[h,f]=m.useState(!1),{theme:p,setTheme:g}=Bm(),N=a0();if(m.useEffect(()=>{const R=D=>{(D.metaKey||D.ctrlKey)&&D.key==="k"&&(D.preventDefault(),f(!0))};return window.addEventListener("keydown",R),()=>window.removeEventListener("keydown",R)},[]),n)return e.jsx("div",{className:"flex h-screen items-center justify-center bg-background",children:e.jsx("div",{className:"text-muted-foreground",children:"正在验证登录状态..."})});const v=[{title:"概览",items:[{icon:Bo,label:"首页",path:"/"}]},{title:"麦麦配置编辑",items:[{icon:qa,label:"麦麦主程序配置",path:"/config/bot"},{icon:Tl,label:"AI模型厂商配置",path:"/config/modelProvider",tourId:"sidebar-model-provider"},{icon:Cj,label:"模型管理与分配",path:"/config/model",tourId:"sidebar-model-management"},{icon:Qp,label:"麦麦适配器配置",path:"/config/adapter"}]},{title:"麦麦资源管理",items:[{icon:Rm,label:"表情包管理",path:"/resource/emoji"},{icon:on,label:"表达方式管理",path:"/resource/expression"},{icon:Or,label:"黑话管理",path:"/resource/jargon"},{icon:Tj,label:"人物信息管理",path:"/resource/person"},{icon:yj,label:"知识库图谱可视化",path:"/resource/knowledge-graph"},{icon:zr,label:"麦麦知识库管理",path:"/resource/knowledge-base"}]},{title:"扩展与监控",items:[{icon:Wt,label:"插件市场",path:"/plugins"},{icon:_j,label:"配置模板市场",path:"/config/pack-market"},{icon:Qp,label:"插件配置",path:"/plugin-config"},{icon:Lm,label:"日志查看器",path:"/logs"},{icon:on,label:"本地聊天室",path:"/chat"}]},{title:"系统",items:[{icon:In,label:"系统设置",path:"/settings"}]}],w=p==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":p,y=async()=>{await R1()};return e.jsx(FC,{delayDuration:300,children:e.jsxs("div",{className:"flex h-screen overflow-hidden",children:[e.jsxs("aside",{className:B("fixed inset-y-0 left-0 z-50 flex flex-col border-r bg-card transition-all duration-300 lg:relative lg:z-0","w-64 lg:w-auto",i?"lg:w-64":"lg:w-16",u?"translate-x-0":"-translate-x-full lg:translate-x-0"),children:[e.jsx("div",{className:"flex h-16 items-center border-b px-4",children:e.jsxs("div",{className:B("relative flex items-center justify-center flex-1 transition-all overflow-hidden","lg:flex-1",!i&&"lg:flex-none lg:w-8"),children:[e.jsxs("div",{className:B("flex items-baseline gap-2",!i&&"lg:hidden"),children:[e.jsx("span",{className:"font-bold text-xl text-primary-gradient whitespace-nowrap",children:"MaiBot WebUI"}),e.jsx("span",{className:"text-xs text-primary/60 whitespace-nowrap",children:n2()})]}),!i&&e.jsx("span",{className:"hidden lg:block font-bold text-primary-gradient text-2xl",children:"M"})]})}),e.jsx(es,{className:B("flex-1 overflow-x-hidden",!i&&"lg:w-16"),children:e.jsx("nav",{className:B("p-4",!i&&"lg:p-2 lg:w-16"),children:e.jsx("ul",{className:B("space-y-6",!i&&"lg:space-y-3 lg:w-full"),children:v.map((R,D)=>e.jsxs("li",{children:[e.jsx("div",{className:B("px-3 h-[1.25rem]","mb-2",!i&&"lg:mb-1 lg:invisible"),children:e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground/60 whitespace-nowrap",children:R.title})}),!i&&D>0&&e.jsx("div",{className:"hidden lg:block mb-2 border-t border-border"}),e.jsx("ul",{className:"space-y-1",children:R.items.map(k=>{const I=N({to:k.path}),M=k.icon,S=e.jsxs(e.Fragment,{children:[I&&e.jsx("div",{className:"absolute left-0 top-1/2 h-8 w-1 -translate-y-1/2 rounded-r-full bg-primary transition-opacity duration-300"}),e.jsxs("div",{className:B("flex items-center transition-all duration-300",i?"gap-3":"gap-3 lg:gap-0"),children:[e.jsx(M,{className:B("h-5 w-5 flex-shrink-0",I&&"text-primary"),strokeWidth:2,fill:"none"}),e.jsx("span",{className:B("text-sm font-medium whitespace-nowrap transition-all duration-300",I&&"font-semibold",i?"opacity-100 max-w-[200px]":"opacity-100 max-w-[200px] lg:opacity-0 lg:max-w-0 lg:overflow-hidden"),children:k.label})]})]});return e.jsx("li",{className:"relative",children:e.jsxs(qC,{children:[e.jsx(VC,{asChild:!0,children:e.jsx(Cr,{to:k.path,"data-tour":k.tourId,className:B("relative flex items-center rounded-lg py-2 transition-all duration-300","hover:bg-accent hover:text-accent-foreground",I?"bg-accent text-foreground":"text-muted-foreground hover:text-foreground",i?"px-3":"px-3 lg:px-0 lg:justify-center lg:w-12 lg:mx-auto"),onClick:()=>x(!1),children:S})}),!i&&e.jsx(LN,{side:"right",className:"hidden lg:block",children:e.jsx("p",{children:k.label})})]})},k.path)})})]},R.title))})})})]}),u&&e.jsx("div",{className:"fixed inset-0 z-40 bg-black/50 lg:hidden",onClick:()=>x(!1)}),e.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[e.jsx(HC,{}),e.jsxs("header",{className:"flex h-16 items-center justify-between border-b bg-card/80 backdrop-blur-md px-4 sticky top-0 z-10",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("button",{onClick:()=>x(!u),className:"rounded-lg p-2 hover:bg-accent lg:hidden",children:e.jsx(s1,{className:"h-5 w-5"})}),e.jsx("button",{onClick:()=>c(!i),className:"hidden rounded-lg p-2 hover:bg-accent lg:block",title:i?"收起侧边栏":"展开侧边栏",children:e.jsx(ll,{className:B("h-5 w-5 transition-transform",!i&&"rotate-180")})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>f(!0),className:"relative hidden md:flex items-center w-64 h-9 pl-9 pr-16 bg-background/50 border rounded-md hover:bg-accent/50 transition-colors text-left",children:[e.jsx(Vt,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"搜索..."}),e.jsxs(RN,{size:"sm",className:"absolute right-2 top-1/2 -translate-y-1/2",children:[e.jsx("span",{className:"text-xs",children:"⌘"}),"K"]})]}),e.jsx(PC,{open:h,onOpenChange:f}),e.jsxs(C,{variant:"ghost",size:"sm",onClick:()=>window.open("https://docs.mai-mai.org","_blank"),className:"gap-2",title:"查看麦麦文档",children:[e.jsx(t1,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"麦麦文档"})]}),e.jsx("button",{onClick:R=>{J1(w==="dark"?"light":"dark",g,R)},className:"rounded-lg p-2 hover:bg-accent",title:w==="dark"?"切换到浅色模式":"切换到深色模式",children:w==="dark"?e.jsx(hj,{className:"h-5 w-5"}):e.jsx(fj,{className:"h-5 w-5"})}),e.jsx("div",{className:"h-6 w-px bg-border"}),e.jsxs(C,{variant:"ghost",size:"sm",onClick:y,className:"gap-2",title:"登出系统",children:[e.jsx(a1,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"登出"})]})]})]}),e.jsx("main",{className:"flex-1 overflow-hidden bg-background",children:l}),e.jsx(GC,{})]})]})})}function QC(l){const n=l.split(` +`).slice(1),i=[];for(const c of n){const u=c.trim();if(!u.startsWith("at "))continue;const x=u.match(/at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/);x?i.push({functionName:x[1]||"",fileName:x[2],lineNumber:x[3],columnNumber:x[4],raw:u}):i.push({functionName:"",fileName:"",lineNumber:"",columnNumber:"",raw:u})}return i}function YC({error:l,errorInfo:n}){const[i,c]=m.useState(!0),[u,x]=m.useState(!1),[h,f]=m.useState(!1),p=l.stack?QC(l.stack):[],g=async()=>{const N=` +Error: ${l.name} +Message: ${l.message} + +Stack Trace: +${l.stack||"No stack trace available"} + +Component Stack: +${n?.componentStack||"No component stack available"} + +URL: ${window.location.href} +User Agent: ${navigator.userAgent} +Time: ${new Date().toISOString()} + `.trim();try{await navigator.clipboard.writeText(N),f(!0),setTimeout(()=>f(!1),2e3)}catch(v){console.error("Failed to copy:",v)}};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs(nt,{variant:"destructive",className:"border-red-500/50 bg-red-500/10",children:[e.jsx(Ft,{className:"h-4 w-4"}),e.jsxs(rt,{className:"font-mono text-sm",children:[e.jsxs("span",{className:"font-semibold",children:[l.name,":"]})," ",l.message]})]}),p.length>0&&e.jsxs(Ki,{open:i,onOpenChange:c,children:[e.jsx(Qi,{asChild:!0,children:e.jsxs(C,{variant:"ghost",className:"w-full justify-between p-3 h-auto",children:[e.jsxs("span",{className:"font-semibold text-sm flex items-center gap-2",children:[e.jsx(l1,{className:"h-4 w-4"}),"Stack Trace (",p.length," frames)"]}),i?e.jsx(Dr,{className:"h-4 w-4"}):e.jsx($a,{className:"h-4 w-4"})]})}),e.jsx(Yi,{children:e.jsx(es,{className:"h-[280px] rounded-md border bg-muted/30",children:e.jsx("div",{className:"p-3 space-y-1",children:p.map((N,v)=>e.jsx("div",{className:"font-mono text-xs p-2 rounded hover:bg-muted/50 transition-colors",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsxs("span",{className:"text-muted-foreground w-6 text-right flex-shrink-0",children:[v+1,"."]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{className:"text-primary font-medium",children:N.functionName}),N.fileName&&e.jsxs("div",{className:"text-muted-foreground mt-0.5 break-all",children:[N.fileName,N.lineNumber&&e.jsxs("span",{className:"text-yellow-600 dark:text-yellow-400",children:[":",N.lineNumber,":",N.columnNumber]})]})]})]})},v))})})})]}),n?.componentStack&&e.jsxs(Ki,{open:u,onOpenChange:x,children:[e.jsx(Qi,{asChild:!0,children:e.jsxs(C,{variant:"ghost",className:"w-full justify-between p-3 h-auto",children:[e.jsxs("span",{className:"font-semibold text-sm flex items-center gap-2",children:[e.jsx(Ft,{className:"h-4 w-4"}),"Component Stack"]}),u?e.jsx(Dr,{className:"h-4 w-4"}):e.jsx($a,{className:"h-4 w-4"})]})}),e.jsx(Yi,{children:e.jsx(es,{className:"h-[200px] rounded-md border bg-muted/30",children:e.jsx("pre",{className:"p-3 font-mono text-xs whitespace-pre-wrap text-muted-foreground",children:n.componentStack})})})]}),e.jsx(C,{variant:"outline",size:"sm",onClick:g,className:"w-full",children:h?e.jsxs(e.Fragment,{children:[e.jsx(St,{className:"mr-2 h-4 w-4 text-green-500"}),"已复制到剪贴板"]}):e.jsxs(e.Fragment,{children:[e.jsx(ko,{className:"mr-2 h-4 w-4"}),"复制错误信息"]})})]})}function UN({error:l,errorInfo:n}){const i=()=>{window.location.href="/"},c=()=>{window.location.reload()};return e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-background p-4",children:e.jsxs(De,{className:"w-full max-w-2xl shadow-lg",children:[e.jsxs(Xe,{className:"text-center pb-2",children:[e.jsx("div",{className:"mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100 dark:bg-red-900/30 mb-4",children:e.jsx(Ft,{className:"h-8 w-8 text-red-600 dark:text-red-400"})}),e.jsx(We,{className:"text-2xl font-bold",children:"页面出现了问题"}),e.jsx(Is,{className:"text-base mt-2",children:"应用程序遇到了意外错误。您可以尝试刷新页面或返回首页。"})]}),e.jsxs(Qe,{className:"space-y-4",children:[e.jsx(YC,{error:l,errorInfo:n}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 pt-2",children:[e.jsxs(C,{onClick:c,className:"flex-1",children:[e.jsx(kt,{className:"mr-2 h-4 w-4"}),"刷新页面"]}),e.jsxs(C,{onClick:i,variant:"outline",className:"flex-1",children:[e.jsx(Bo,{className:"mr-2 h-4 w-4"}),"返回首页"]})]}),e.jsx("p",{className:"text-xs text-center text-muted-foreground pt-2",children:"如果问题持续存在,请将错误信息复制并反馈给开发者"})]})]})})}class JC extends m.Component{constructor(n){super(n),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n}}componentDidCatch(n,i){console.error("ErrorBoundary caught an error:",n,i),this.setState({errorInfo:i})}handleReset=()=>{this.setState({hasError:!1,error:null,errorInfo:null})};render(){return this.state.hasError&&this.state.error?this.props.fallback?this.props.fallback:e.jsx(UN,{error:this.state.error,errorInfo:this.state.errorInfo}):this.props.children}}function BN({error:l}){return e.jsx(UN,{error:l,errorInfo:null})}const ec=l0({component:()=>e.jsxs(e.Fragment,{children:[e.jsx(bg,{}),!1]}),beforeLoad:()=>{if(window.location.pathname==="/"&&!BC())throw r0({to:"/auth"})}}),XC=Zs({getParentRoute:()=>ec,path:"/auth",component:y2}),ZC=Zs({getParentRoute:()=>ec,path:"/setup",component:B2}),ht=Zs({getParentRoute:()=>ec,id:"protected",component:()=>e.jsx(KC,{children:e.jsx(bg,{})}),errorComponent:({error:l})=>e.jsx(BN,{error:l})}),WC=Zs({getParentRoute:()=>ht,path:"/",component:V1}),e3=Zs({getParentRoute:()=>ht,path:"/config/bot",component:j_}),s3=Zs({getParentRoute:()=>ht,path:"/config/modelProvider",component:M_}),t3=Zs({getParentRoute:()=>ht,path:"/config/model",component:tS}),a3=Zs({getParentRoute:()=>ht,path:"/config/adapter",component:_S}),l3=Zs({getParentRoute:()=>ht,path:"/resource/emoji",component:KS}),n3=Zs({getParentRoute:()=>ht,path:"/resource/expression",component:n4}),r3=Zs({getParentRoute:()=>ht,path:"/resource/person",component:E4}),i3=Zs({getParentRoute:()=>ht,path:"/resource/jargon",component:v4}),c3=Zs({getParentRoute:()=>ht,path:"/resource/knowledge-graph",component:B4}),o3=Zs({getParentRoute:()=>ht,path:"/resource/knowledge-base",component:$4}),d3=Zs({getParentRoute:()=>ht,path:"/logs",component:P4}),u3=Zs({getParentRoute:()=>ht,path:"/chat",component:kk}),m3=Zs({getParentRoute:()=>ht,path:"/plugins",component:ik}),x3=Zs({getParentRoute:()=>ht,path:"/plugin-detail",component:gk}),h3=Zs({getParentRoute:()=>ht,path:"/model-presets",component:ok}),f3=Zs({getParentRoute:()=>ht,path:"/plugin-config",component:mk}),p3=Zs({getParentRoute:()=>ht,path:"/plugin-mirrors",component:hk}),g3=Zs({getParentRoute:()=>ht,path:"/settings",component:f2}),j3=Zs({getParentRoute:()=>ht,path:"/config/pack-market",component:jC}),$N=Zs({getParentRoute:()=>ht,path:"/config/pack-market/$packId",component:OC}),v3=Zs({getParentRoute:()=>ht,path:"/survey/webui-feedback",component:Hk}),N3=Zs({getParentRoute:()=>ht,path:"/survey/maibot-feedback",component:Gk}),b3=Zs({getParentRoute:()=>ec,path:"*",component:Xj}),y3=ec.addChildren([XC,ZC,ht.addChildren([WC,e3,s3,t3,a3,l3,n3,i3,r3,c3,o3,m3,x3,h3,f3,p3,d3,u3,g3,j3,$N,v3,N3]),b3]),w3=n0({routeTree:y3,defaultNotFoundComponent:Xj,defaultErrorComponent:({error:l})=>e.jsx(BN,{error:l})});function _3({children:l,defaultTheme:n="system",storageKey:i="ui-theme",...c}){const[u,x]=m.useState(()=>localStorage.getItem(i)||n);m.useEffect(()=>{const f=window.document.documentElement;if(f.classList.remove("light","dark"),u==="system"){const p=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";f.classList.add(p);return}f.classList.add(u)},[u]),m.useEffect(()=>{const f=localStorage.getItem("accent-color");if(f){const p=document.documentElement,N={blue:{hsl:"221.2 83.2% 53.3%",darkHsl:"217.2 91.2% 59.8%",gradient:null},purple:{hsl:"271 91% 65%",darkHsl:"270 95% 75%",gradient:null},green:{hsl:"142 71% 45%",darkHsl:"142 76% 36%",gradient:null},orange:{hsl:"25 95% 53%",darkHsl:"20 90% 48%",gradient:null},pink:{hsl:"330 81% 60%",darkHsl:"330 85% 70%",gradient:null},red:{hsl:"0 84% 60%",darkHsl:"0 90% 70%",gradient:null},"gradient-sunset":{hsl:"15 95% 60%",darkHsl:"15 95% 65%",gradient:"linear-gradient(135deg, hsl(25 95% 53%) 0%, hsl(330 81% 60%) 100%)"},"gradient-ocean":{hsl:"200 90% 55%",darkHsl:"200 90% 60%",gradient:"linear-gradient(135deg, hsl(221.2 83.2% 53.3%) 0%, hsl(189 94% 43%) 100%)"},"gradient-forest":{hsl:"150 70% 45%",darkHsl:"150 75% 40%",gradient:"linear-gradient(135deg, hsl(142 71% 45%) 0%, hsl(158 64% 52%) 100%)"},"gradient-aurora":{hsl:"310 85% 65%",darkHsl:"310 90% 70%",gradient:"linear-gradient(135deg, hsl(271 91% 65%) 0%, hsl(330 81% 60%) 100%)"},"gradient-fire":{hsl:"15 95% 55%",darkHsl:"15 95% 60%",gradient:"linear-gradient(135deg, hsl(0 84% 60%) 0%, hsl(25 95% 53%) 100%)"},"gradient-twilight":{hsl:"250 90% 60%",darkHsl:"250 95% 65%",gradient:"linear-gradient(135deg, hsl(239 84% 67%) 0%, hsl(271 91% 65%) 100%)"}}[f];N&&(p.style.setProperty("--primary",N.hsl),N.gradient?(p.style.setProperty("--primary-gradient",N.gradient),p.classList.add("has-gradient")):(p.style.removeProperty("--primary-gradient"),p.classList.remove("has-gradient")))}},[]);const h={theme:u,setTheme:f=>{localStorage.setItem(i,f),x(f)}};return e.jsx(qj.Provider,{...c,value:h,children:l})}function S3({children:l,defaultEnabled:n=!0,defaultWavesEnabled:i=!0,storageKey:c="enable-animations",wavesStorageKey:u="enable-waves-background"}){const[x,h]=m.useState(()=>{const N=localStorage.getItem(c);return N!==null?N==="true":n}),[f,p]=m.useState(()=>{const N=localStorage.getItem(u);return N!==null?N==="true":i});m.useEffect(()=>{const N=document.documentElement;x?N.classList.remove("no-animations"):N.classList.add("no-animations"),localStorage.setItem(c,String(x))},[x,c]),m.useEffect(()=>{localStorage.setItem(u,String(f))},[f,u]);const g={enableAnimations:x,setEnableAnimations:h,enableWavesBackground:f,setEnableWavesBackground:p};return e.jsx(Vj.Provider,{value:g,children:l})}const k3=kw,IN=m.forwardRef(({className:l,...n},i)=>e.jsx(rj,{ref:i,className:B("fixed bottom-0 right-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:max-w-[420px] gap-2",l),...n}));IN.displayName=rj.displayName;const C3=Lr("group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-slide-in-from-right data-[state=open]:animate-fade-in data-[state=closed]:animate-slide-out-to-right data-[state=closed]:animate-fade-out data-[swipe=end]:animate-slide-out-to-right",{variants:{variant:{default:"border bg-primary/5 text-foreground backdrop-blur-sm",destructive:"destructive group border-destructive bg-destructive/10 text-destructive-foreground backdrop-blur-sm"}},defaultVariants:{variant:"default"}}),PN=m.forwardRef(({className:l,variant:n,...i},c)=>e.jsx(ij,{ref:c,className:B(C3({variant:n}),l),...i}));PN.displayName=ij.displayName;const T3=m.forwardRef(({className:l,...n},i)=>e.jsx(cj,{ref:i,className:B("inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",l),...n}));T3.displayName=cj.displayName;const HN=m.forwardRef(({className:l,...n},i)=>e.jsx(oj,{ref:i,className:B("absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",l),"toast-close":"",...n,children:e.jsx(_a,{className:"h-4 w-4"})}));HN.displayName=oj.displayName;const GN=m.forwardRef(({className:l,...n},i)=>e.jsx(dj,{ref:i,className:B("text-sm font-semibold [&+div]:text-xs",l),...n}));GN.displayName=dj.displayName;const FN=m.forwardRef(({className:l,...n},i)=>e.jsx(uj,{ref:i,className:B("text-sm opacity-90",l),...n}));FN.displayName=uj.displayName;function E3(){const{toasts:l}=Ws();return e.jsxs(k3,{children:[l.map(function({id:n,title:i,description:c,action:u,...x}){return e.jsxs(PN,{...x,children:[e.jsxs("div",{className:"grid gap-1",children:[i&&e.jsx(GN,{children:i}),c&&e.jsx(FN,{children:c})]}),u,e.jsx(HN,{})]},n)}),e.jsx(IN,{})]})}O1.createRoot(document.getElementById("root")).render(e.jsx(m.StrictMode,{children:e.jsx(JC,{children:e.jsx(_3,{defaultTheme:"system",children:e.jsx(S3,{children:e.jsxs(__,{children:[e.jsx(i0,{router:w3}),e.jsx(C_,{}),e.jsx(E3,{})]})})})})})); diff --git a/webui/dist/assets/markdown-CKA5gBQ9.js b/webui/dist/assets/markdown-CKA5gBQ9.js new file mode 100644 index 00000000..1d7c44dc --- /dev/null +++ b/webui/dist/assets/markdown-CKA5gBQ9.js @@ -0,0 +1,295 @@ +import{j as gn}from"./router-9vIXuQkh.js";import{g as Oa}from"./react-vendor-BmxF9s7Q.js";function ni(e){const t=[],r=String(e||"");let n=r.indexOf(","),i=0,a=!1;for(;!a;){n===-1&&(n=r.length,a=!0);const l=r.slice(i,n).trim();(l||!a)&&t.push(l),i=n+1,n=r.indexOf(",",i)}return t}function Js(e,t){const r={};return(e[e.length-1]===""?[...e,""]:e).join((r.padRight?" ":"")+","+(r.padLeft===!1?"":" ")).trim()}const eo=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,to=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,ro={};function ii(e,t){return(ro.jsx?to:eo).test(e)}const no=/[ \t\n\f\r]/g;function io(e){return typeof e=="object"?e.type==="text"?ai(e.value):!1:ai(e)}function ai(e){return e.replace(no,"")===""}class Sr{constructor(t,r,n){this.normal=r,this.property=t,n&&(this.space=n)}}Sr.prototype.normal={};Sr.prototype.property={};Sr.prototype.space=void 0;function qa(e,t){const r={},n={};for(const i of e)Object.assign(r,i.property),Object.assign(n,i.normal);return new Sr(r,n,t)}function yr(e){return e.toLowerCase()}class He{constructor(t,r){this.attribute=r,this.property=t}}He.prototype.attribute="";He.prototype.booleanish=!1;He.prototype.boolean=!1;He.prototype.commaOrSpaceSeparated=!1;He.prototype.commaSeparated=!1;He.prototype.defined=!1;He.prototype.mustUseProperty=!1;He.prototype.number=!1;He.prototype.overloadedBoolean=!1;He.prototype.property="";He.prototype.spaceSeparated=!1;He.prototype.space=void 0;let ao=0;const te=qt(),Ae=qt(),Kn=qt(),R=qt(),pe=qt(),Kt=qt(),Ue=qt();function qt(){return 2**++ao}const Zn=Object.freeze(Object.defineProperty({__proto__:null,boolean:te,booleanish:Ae,commaOrSpaceSeparated:Ue,commaSeparated:Kt,number:R,overloadedBoolean:Kn,spaceSeparated:pe},Symbol.toStringTag,{value:"Module"})),vn=Object.keys(Zn);class v0 extends He{constructor(t,r,n,i){let a=-1;if(super(t,r),li(this,"space",i),typeof n=="number")for(;++a4&&r.slice(0,4)==="data"&&co.test(t)){if(t.charAt(4)==="-"){const a=t.slice(5).replace(si,mo);n="data"+a.charAt(0).toUpperCase()+a.slice(1)}else{const a=t.slice(4);if(!si.test(a)){let l=a.replace(uo,ho);l.charAt(0)!=="-"&&(l="-"+l),t="data"+l}}i=v0}return new i(n,t)}function ho(e){return"-"+e.toLowerCase()}function mo(e){return e.charAt(1).toUpperCase()}const Wa=qa([Ha,lo,$a,Ua,_a],"html"),tn=qa([Ha,so,$a,Ua,_a],"svg");function oi(e){const t=String(e||"").trim();return t?t.split(/[ \t\n\r\f]+/g):[]}function fo(e){return e.join(" ").trim()}var Gt={},yn,ui;function po(){if(ui)return yn;ui=1;var e=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,t=/\n/g,r=/^\s*/,n=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,i=/^:\s*/,a=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,l=/^[;\s]*/,s=/^\s+|\s+$/g,o=` +`,u="/",h="*",m="",d="comment",p="declaration";function y(M,S){if(typeof M!="string")throw new TypeError("First argument must be a string");if(!M)return[];S=S||{};var z=1,I=1;function V(Y){var q=Y.match(t);q&&(z+=q.length);var ae=Y.lastIndexOf(o);I=~ae?Y.length-ae:I+Y.length}function O(){var Y={line:z,column:I};return function(q){return q.position=new E(Y),U(),q}}function E(Y){this.start=Y,this.end={line:z,column:I},this.source=S.source}E.prototype.content=M;function G(Y){var q=new Error(S.source+":"+z+":"+I+": "+Y);if(q.reason=Y,q.filename=S.source,q.line=z,q.column=I,q.source=M,!S.silent)throw q}function K(Y){var q=Y.exec(M);if(q){var ae=q[0];return V(ae),M=M.slice(ae.length),q}}function U(){K(r)}function D(Y){var q;for(Y=Y||[];q=$();)q!==!1&&Y.push(q);return Y}function $(){var Y=O();if(!(u!=M.charAt(0)||h!=M.charAt(1))){for(var q=2;m!=M.charAt(q)&&(h!=M.charAt(q)||u!=M.charAt(q+1));)++q;if(q+=2,m===M.charAt(q-1))return G("End of comment missing");var ae=M.slice(2,q-2);return I+=2,V(ae),M=M.slice(q),I+=2,Y({type:d,comment:ae})}}function j(){var Y=O(),q=K(n);if(q){if($(),!K(i))return G("property missing ':'");var ae=K(a),fe=Y({type:p,property:w(q[0].replace(e,m)),value:ae?w(ae[0].replace(e,m)):m});return K(l),fe}}function ie(){var Y=[];D(Y);for(var q;q=j();)q!==!1&&(Y.push(q),D(Y));return Y}return U(),ie()}function w(M){return M?M.replace(s,m):m}return yn=y,yn}var ci;function go(){if(ci)return Gt;ci=1;var e=Gt&&Gt.__importDefault||function(n){return n&&n.__esModule?n:{default:n}};Object.defineProperty(Gt,"__esModule",{value:!0}),Gt.default=r;const t=e(po());function r(n,i){let a=null;if(!n||typeof n!="string")return a;const l=(0,t.default)(n),s=typeof i=="function";return l.forEach(o=>{if(o.type!=="declaration")return;const{property:u,value:h}=o;s?i(u,h,o):h&&(a=a||{},a[u]=h)}),a}return Gt}var ur={},hi;function vo(){if(hi)return ur;hi=1,Object.defineProperty(ur,"__esModule",{value:!0}),ur.camelCase=void 0;var e=/^--[a-zA-Z0-9_-]+$/,t=/-([a-z])/g,r=/^[^-]+$/,n=/^-(webkit|moz|ms|o|khtml)-/,i=/^-(ms)-/,a=function(u){return!u||r.test(u)||e.test(u)},l=function(u,h){return h.toUpperCase()},s=function(u,h){return"".concat(h,"-")},o=function(u,h){return h===void 0&&(h={}),a(u)?u:(u=u.toLowerCase(),h.reactCompat?u=u.replace(i,s):u=u.replace(n,s),u.replace(t,l))};return ur.camelCase=o,ur}var cr,mi;function yo(){if(mi)return cr;mi=1;var e=cr&&cr.__importDefault||function(i){return i&&i.__esModule?i:{default:i}},t=e(go()),r=vo();function n(i,a){var l={};return!i||typeof i!="string"||(0,t.default)(i,function(s,o){s&&o&&(l[(0,r.camelCase)(s,a)]=o)}),l}return n.default=n,cr=n,cr}var bo=yo();const xo=Oa(bo),Ya=Xa("end"),y0=Xa("start");function Xa(e){return t;function t(r){const n=r&&r.position&&r.position[e]||{};if(typeof n.line=="number"&&n.line>0&&typeof n.column=="number"&&n.column>0)return{line:n.line,column:n.column,offset:typeof n.offset=="number"&&n.offset>-1?n.offset:void 0}}}function wo(e){const t=y0(e),r=Ya(e);if(t&&r)return{start:t,end:r}}function pr(e){return!e||typeof e!="object"?"":"position"in e||"type"in e?fi(e.position):"start"in e||"end"in e?fi(e):"line"in e||"column"in e?Qn(e):""}function Qn(e){return pi(e&&e.line)+":"+pi(e&&e.column)}function fi(e){return Qn(e&&e.start)+"-"+Qn(e&&e.end)}function pi(e){return e&&typeof e=="number"?e:1}class Ee extends Error{constructor(t,r,n){super(),typeof r=="string"&&(n=r,r=void 0);let i="",a={},l=!1;if(r&&("line"in r&&"column"in r?a={place:r}:"start"in r&&"end"in r?a={place:r}:"type"in r?a={ancestors:[r],place:r.position}:a={...r}),typeof t=="string"?i=t:!a.cause&&t&&(l=!0,i=t.message,a.cause=t),!a.ruleId&&!a.source&&typeof n=="string"){const o=n.indexOf(":");o===-1?a.ruleId=n:(a.source=n.slice(0,o),a.ruleId=n.slice(o+1))}if(!a.place&&a.ancestors&&a.ancestors){const o=a.ancestors[a.ancestors.length-1];o&&(a.place=o.position)}const s=a.place&&"start"in a.place?a.place.start:a.place;this.ancestors=a.ancestors||void 0,this.cause=a.cause||void 0,this.column=s?s.column:void 0,this.fatal=void 0,this.file="",this.message=i,this.line=s?s.line:void 0,this.name=pr(a.place)||"1:1",this.place=a.place||void 0,this.reason=this.message,this.ruleId=a.ruleId||void 0,this.source=a.source||void 0,this.stack=l&&a.cause&&typeof a.cause.stack=="string"?a.cause.stack:"",this.actual=void 0,this.expected=void 0,this.note=void 0,this.url=void 0}}Ee.prototype.file="";Ee.prototype.name="";Ee.prototype.reason="";Ee.prototype.message="";Ee.prototype.stack="";Ee.prototype.column=void 0;Ee.prototype.line=void 0;Ee.prototype.ancestors=void 0;Ee.prototype.cause=void 0;Ee.prototype.fatal=void 0;Ee.prototype.place=void 0;Ee.prototype.ruleId=void 0;Ee.prototype.source=void 0;const b0={}.hasOwnProperty,ko=new Map,So=/[A-Z]/g,Ao=new Set(["table","tbody","thead","tfoot","tr"]),To=new Set(["td","th"]),Ka="https://github.com/syntax-tree/hast-util-to-jsx-runtime";function zo(e,t){if(!t||t.Fragment===void 0)throw new TypeError("Expected `Fragment` in options");const r=t.filePath||void 0;let n;if(t.development){if(typeof t.jsxDEV!="function")throw new TypeError("Expected `jsxDEV` in options when `development: true`");n=Fo(r,t.jsxDEV)}else{if(typeof t.jsx!="function")throw new TypeError("Expected `jsx` in production options");if(typeof t.jsxs!="function")throw new TypeError("Expected `jsxs` in production options");n=No(r,t.jsx,t.jsxs)}const i={Fragment:t.Fragment,ancestors:[],components:t.components||{},create:n,elementAttributeNameCase:t.elementAttributeNameCase||"react",evaluater:t.createEvaluater?t.createEvaluater():void 0,filePath:r,ignoreInvalidStyle:t.ignoreInvalidStyle||!1,passKeys:t.passKeys!==!1,passNode:t.passNode||!1,schema:t.space==="svg"?tn:Wa,stylePropertyNameCase:t.stylePropertyNameCase||"dom",tableCellAlignToStyle:t.tableCellAlignToStyle!==!1},a=Za(i,e,void 0);return a&&typeof a!="string"?a:i.create(e,i.Fragment,{children:a||void 0},void 0)}function Za(e,t,r){if(t.type==="element")return Mo(e,t,r);if(t.type==="mdxFlowExpression"||t.type==="mdxTextExpression")return Co(e,t);if(t.type==="mdxJsxFlowElement"||t.type==="mdxJsxTextElement")return Do(e,t,r);if(t.type==="mdxjsEsm")return Eo(e,t);if(t.type==="root")return Io(e,t,r);if(t.type==="text")return Bo(e,t)}function Mo(e,t,r){const n=e.schema;let i=n;t.tagName.toLowerCase()==="svg"&&n.space==="html"&&(i=tn,e.schema=i),e.ancestors.push(t);const a=Ja(e,t.tagName,!1),l=Lo(e,t);let s=w0(e,t);return Ao.has(t.tagName)&&(s=s.filter(function(o){return typeof o=="string"?!io(o):!0})),Qa(e,l,a,t),x0(l,s),e.ancestors.pop(),e.schema=n,e.create(t,a,l,r)}function Co(e,t){if(t.data&&t.data.estree&&e.evaluater){const n=t.data.estree.body[0];return n.type,e.evaluater.evaluateExpression(n.expression)}br(e,t.position)}function Eo(e,t){if(t.data&&t.data.estree&&e.evaluater)return e.evaluater.evaluateProgram(t.data.estree);br(e,t.position)}function Do(e,t,r){const n=e.schema;let i=n;t.name==="svg"&&n.space==="html"&&(i=tn,e.schema=i),e.ancestors.push(t);const a=t.name===null?e.Fragment:Ja(e,t.name,!0),l=Ro(e,t),s=w0(e,t);return Qa(e,l,a,t),x0(l,s),e.ancestors.pop(),e.schema=n,e.create(t,a,l,r)}function Io(e,t,r){const n={};return x0(n,w0(e,t)),e.create(t,e.Fragment,n,r)}function Bo(e,t){return t.value}function Qa(e,t,r,n){typeof r!="string"&&r!==e.Fragment&&e.passNode&&(t.node=n)}function x0(e,t){if(t.length>0){const r=t.length>1?t:t[0];r&&(e.children=r)}}function No(e,t,r){return n;function n(i,a,l,s){const u=Array.isArray(l.children)?r:t;return s?u(a,l,s):u(a,l)}}function Fo(e,t){return r;function r(n,i,a,l){const s=Array.isArray(a.children),o=y0(n);return t(i,a,l,s,{columnNumber:o?o.column-1:void 0,fileName:e,lineNumber:o?o.line:void 0},void 0)}}function Lo(e,t){const r={};let n,i;for(i in t.properties)if(i!=="children"&&b0.call(t.properties,i)){const a=Po(e,i,t.properties[i]);if(a){const[l,s]=a;e.tableCellAlignToStyle&&l==="align"&&typeof s=="string"&&To.has(t.tagName)?n=s:r[l]=s}}if(n){const a=r.style||(r.style={});a[e.stylePropertyNameCase==="css"?"text-align":"textAlign"]=n}return r}function Ro(e,t){const r={};for(const n of t.attributes)if(n.type==="mdxJsxExpressionAttribute")if(n.data&&n.data.estree&&e.evaluater){const a=n.data.estree.body[0];a.type;const l=a.expression;l.type;const s=l.properties[0];s.type,Object.assign(r,e.evaluater.evaluateExpression(s.argument))}else br(e,t.position);else{const i=n.name;let a;if(n.value&&typeof n.value=="object")if(n.value.data&&n.value.data.estree&&e.evaluater){const s=n.value.data.estree.body[0];s.type,a=e.evaluater.evaluateExpression(s.expression)}else br(e,t.position);else a=n.value===null?!0:n.value;r[i]=a}return r}function w0(e,t){const r=[];let n=-1;const i=e.passKeys?new Map:ko;for(;++ni?0:i+t:t=t>i?i:t,r=r>0?r:0,n.length<1e4)l=Array.from(n),l.unshift(t,r),e.splice(...l);else for(r&&e.splice(t,r);a0?(Ge(e,e.length,0,t),e):t}const vi={}.hasOwnProperty;function tl(e){const t={};let r=-1;for(;++r13&&r<32||r>126&&r<160||r>55295&&r<57344||r>64975&&r<65008||(r&65535)===65535||(r&65535)===65534||r>1114111?"�":String.fromCodePoint(r)}function it(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const Ne=It(/[A-Za-z]/),Ce=It(/[\dA-Za-z]/),Go=It(/[#-'*+\--9=?A-Z^-~]/);function Gr(e){return e!==null&&(e<32||e===127)}const Jn=It(/\d/),Wo=It(/[\dA-Fa-f]/),Yo=It(/[!-/:-@[-`{-~]/);function X(e){return e!==null&&e<-2}function he(e){return e!==null&&(e<0||e===32)}function le(e){return e===-2||e===-1||e===32}const rn=It(new RegExp("\\p{P}|\\p{S}","u")),Ot=It(/\s/);function It(e){return t;function t(r){return r!==null&&r>-1&&e.test(String.fromCharCode(r))}}function tr(e){const t=[];let r=-1,n=0,i=0;for(;++r55295&&a<57344){const s=e.charCodeAt(r+1);a<56320&&s>56319&&s<57344?(l=String.fromCharCode(a,s),i=1):l="�"}else l=String.fromCharCode(a);l&&(t.push(e.slice(n,r),encodeURIComponent(l)),n=r+i+1,l=""),i&&(r+=i,i=0)}return t.join("")+e.slice(n)}function ne(e,t,r,n){const i=n?n-1:Number.POSITIVE_INFINITY;let a=0;return l;function l(o){return le(o)?(e.enter(r),s(o)):t(o)}function s(o){return le(o)&&a++l))return;const G=t.events.length;let K=G,U,D;for(;K--;)if(t.events[K][0]==="exit"&&t.events[K][1].type==="chunkFlow"){if(U){D=t.events[K][1].end;break}U=!0}for(S(n),E=G;EI;){const O=r[V];t.containerState=O[1],O[0].exit.call(t,e)}r.length=I}function z(){i.write([null]),a=void 0,i=void 0,t.containerState._closeFlow=void 0}}function Jo(e,t,r){return ne(e,e.attempt(this.parser.constructs.document,t,r),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function Qt(e){if(e===null||he(e)||Ot(e))return 1;if(rn(e))return 2}function nn(e,t,r){const n=[];let i=-1;for(;++i1&&e[r][1].end.offset-e[r][1].start.offset>1?2:1;const m={...e[n][1].end},d={...e[r][1].start};bi(m,-o),bi(d,o),l={type:o>1?"strongSequence":"emphasisSequence",start:m,end:{...e[n][1].end}},s={type:o>1?"strongSequence":"emphasisSequence",start:{...e[r][1].start},end:d},a={type:o>1?"strongText":"emphasisText",start:{...e[n][1].end},end:{...e[r][1].start}},i={type:o>1?"strong":"emphasis",start:{...l.start},end:{...s.end}},e[n][1].end={...l.start},e[r][1].start={...s.end},u=[],e[n][1].end.offset-e[n][1].start.offset&&(u=Ke(u,[["enter",e[n][1],t],["exit",e[n][1],t]])),u=Ke(u,[["enter",i,t],["enter",l,t],["exit",l,t],["enter",a,t]]),u=Ke(u,nn(t.parser.constructs.insideSpan.null,e.slice(n+1,r),t)),u=Ke(u,[["exit",a,t],["enter",s,t],["exit",s,t],["exit",i,t]]),e[r][1].end.offset-e[r][1].start.offset?(h=2,u=Ke(u,[["enter",e[r][1],t],["exit",e[r][1],t]])):h=0,Ge(e,n-1,r-n+3,u),r=n+u.length-h-2;break}}for(r=-1;++r0&&le(E)?ne(e,z,"linePrefix",a+1)(E):z(E)}function z(E){return E===null||X(E)?e.check(xi,w,V)(E):(e.enter("codeFlowValue"),I(E))}function I(E){return E===null||X(E)?(e.exit("codeFlowValue"),z(E)):(e.consume(E),I)}function V(E){return e.exit("codeFenced"),t(E)}function O(E,G,K){let U=0;return D;function D(q){return E.enter("lineEnding"),E.consume(q),E.exit("lineEnding"),$}function $(q){return E.enter("codeFencedFence"),le(q)?ne(E,j,"linePrefix",n.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(q):j(q)}function j(q){return q===s?(E.enter("codeFencedFenceSequence"),ie(q)):K(q)}function ie(q){return q===s?(U++,E.consume(q),ie):U>=l?(E.exit("codeFencedFenceSequence"),le(q)?ne(E,Y,"whitespace")(q):Y(q)):K(q)}function Y(q){return q===null||X(q)?(E.exit("codeFencedFence"),G(q)):K(q)}}}function hu(e,t,r){const n=this;return i;function i(l){return l===null?r(l):(e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),a)}function a(l){return n.parser.lazy[n.now().line]?r(l):t(l)}}const xn={name:"codeIndented",tokenize:fu},mu={partial:!0,tokenize:pu};function fu(e,t,r){const n=this;return i;function i(u){return e.enter("codeIndented"),ne(e,a,"linePrefix",5)(u)}function a(u){const h=n.events[n.events.length-1];return h&&h[1].type==="linePrefix"&&h[2].sliceSerialize(h[1],!0).length>=4?l(u):r(u)}function l(u){return u===null?o(u):X(u)?e.attempt(mu,l,o)(u):(e.enter("codeFlowValue"),s(u))}function s(u){return u===null||X(u)?(e.exit("codeFlowValue"),l(u)):(e.consume(u),s)}function o(u){return e.exit("codeIndented"),t(u)}}function pu(e,t,r){const n=this;return i;function i(l){return n.parser.lazy[n.now().line]?r(l):X(l)?(e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),i):ne(e,a,"linePrefix",5)(l)}function a(l){const s=n.events[n.events.length-1];return s&&s[1].type==="linePrefix"&&s[2].sliceSerialize(s[1],!0).length>=4?t(l):X(l)?i(l):r(l)}}const du={name:"codeText",previous:vu,resolve:gu,tokenize:yu};function gu(e){let t=e.length-4,r=3,n,i;if((e[r][1].type==="lineEnding"||e[r][1].type==="space")&&(e[t][1].type==="lineEnding"||e[t][1].type==="space")){for(n=r;++n=this.left.length+this.right.length)throw new RangeError("Cannot access index `"+t+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return tthis.left.length?this.right.slice(this.right.length-n+this.left.length,this.right.length-t+this.left.length).reverse():this.left.slice(t).concat(this.right.slice(this.right.length-n+this.left.length).reverse())}splice(t,r,n){const i=r||0;this.setCursor(Math.trunc(t));const a=this.right.splice(this.right.length-i,Number.POSITIVE_INFINITY);return n&&hr(this.left,n),a.reverse()}pop(){return this.setCursor(Number.POSITIVE_INFINITY),this.left.pop()}push(t){this.setCursor(Number.POSITIVE_INFINITY),this.left.push(t)}pushMany(t){this.setCursor(Number.POSITIVE_INFINITY),hr(this.left,t)}unshift(t){this.setCursor(0),this.right.push(t)}unshiftMany(t){this.setCursor(0),hr(this.right,t.reverse())}setCursor(t){if(!(t===this.left.length||t>this.left.length&&this.right.length===0||t<0&&this.left.length===0))if(t=4?t(l):e.interrupt(n.parser.constructs.flow,r,t)(l)}}function sl(e,t,r,n,i,a,l,s,o){const u=o||Number.POSITIVE_INFINITY;let h=0;return m;function m(S){return S===60?(e.enter(n),e.enter(i),e.enter(a),e.consume(S),e.exit(a),d):S===null||S===32||S===41||Gr(S)?r(S):(e.enter(n),e.enter(l),e.enter(s),e.enter("chunkString",{contentType:"string"}),w(S))}function d(S){return S===62?(e.enter(a),e.consume(S),e.exit(a),e.exit(i),e.exit(n),t):(e.enter(s),e.enter("chunkString",{contentType:"string"}),p(S))}function p(S){return S===62?(e.exit("chunkString"),e.exit(s),d(S)):S===null||S===60||X(S)?r(S):(e.consume(S),S===92?y:p)}function y(S){return S===60||S===62||S===92?(e.consume(S),p):p(S)}function w(S){return!h&&(S===null||S===41||he(S))?(e.exit("chunkString"),e.exit(s),e.exit(l),e.exit(n),t(S)):h999||p===null||p===91||p===93&&!o||p===94&&!s&&"_hiddenFootnoteSupport"in l.parser.constructs?r(p):p===93?(e.exit(a),e.enter(i),e.consume(p),e.exit(i),e.exit(n),t):X(p)?(e.enter("lineEnding"),e.consume(p),e.exit("lineEnding"),h):(e.enter("chunkString",{contentType:"string"}),m(p))}function m(p){return p===null||p===91||p===93||X(p)||s++>999?(e.exit("chunkString"),h(p)):(e.consume(p),o||(o=!le(p)),p===92?d:m)}function d(p){return p===91||p===92||p===93?(e.consume(p),s++,m):m(p)}}function ul(e,t,r,n,i,a){let l;return s;function s(d){return d===34||d===39||d===40?(e.enter(n),e.enter(i),e.consume(d),e.exit(i),l=d===40?41:d,o):r(d)}function o(d){return d===l?(e.enter(i),e.consume(d),e.exit(i),e.exit(n),t):(e.enter(a),u(d))}function u(d){return d===l?(e.exit(a),o(l)):d===null?r(d):X(d)?(e.enter("lineEnding"),e.consume(d),e.exit("lineEnding"),ne(e,u,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),h(d))}function h(d){return d===l||d===null||X(d)?(e.exit("chunkString"),u(d)):(e.consume(d),d===92?m:h)}function m(d){return d===l||d===92?(e.consume(d),h):h(d)}}function dr(e,t){let r;return n;function n(i){return X(i)?(e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),r=!0,n):le(i)?ne(e,n,r?"linePrefix":"lineSuffix")(i):t(i)}}const zu={name:"definition",tokenize:Cu},Mu={partial:!0,tokenize:Eu};function Cu(e,t,r){const n=this;let i;return a;function a(p){return e.enter("definition"),l(p)}function l(p){return ol.call(n,e,s,r,"definitionLabel","definitionLabelMarker","definitionLabelString")(p)}function s(p){return i=it(n.sliceSerialize(n.events[n.events.length-1][1]).slice(1,-1)),p===58?(e.enter("definitionMarker"),e.consume(p),e.exit("definitionMarker"),o):r(p)}function o(p){return he(p)?dr(e,u)(p):u(p)}function u(p){return sl(e,h,r,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(p)}function h(p){return e.attempt(Mu,m,m)(p)}function m(p){return le(p)?ne(e,d,"whitespace")(p):d(p)}function d(p){return p===null||X(p)?(e.exit("definition"),n.parser.defined.push(i),t(p)):r(p)}}function Eu(e,t,r){return n;function n(s){return he(s)?dr(e,i)(s):r(s)}function i(s){return ul(e,a,r,"definitionTitle","definitionTitleMarker","definitionTitleString")(s)}function a(s){return le(s)?ne(e,l,"whitespace")(s):l(s)}function l(s){return s===null||X(s)?t(s):r(s)}}const Du={name:"hardBreakEscape",tokenize:Iu};function Iu(e,t,r){return n;function n(a){return e.enter("hardBreakEscape"),e.consume(a),i}function i(a){return X(a)?(e.exit("hardBreakEscape"),t(a)):r(a)}}const Bu={name:"headingAtx",resolve:Nu,tokenize:Fu};function Nu(e,t){let r=e.length-2,n=3,i,a;return e[n][1].type==="whitespace"&&(n+=2),r-2>n&&e[r][1].type==="whitespace"&&(r-=2),e[r][1].type==="atxHeadingSequence"&&(n===r-1||r-4>n&&e[r-2][1].type==="whitespace")&&(r-=n+1===r?2:4),r>n&&(i={type:"atxHeadingText",start:e[n][1].start,end:e[r][1].end},a={type:"chunkText",start:e[n][1].start,end:e[r][1].end,contentType:"text"},Ge(e,n,r-n+1,[["enter",i,t],["enter",a,t],["exit",a,t],["exit",i,t]])),e}function Fu(e,t,r){let n=0;return i;function i(h){return e.enter("atxHeading"),a(h)}function a(h){return e.enter("atxHeadingSequence"),l(h)}function l(h){return h===35&&n++<6?(e.consume(h),l):h===null||he(h)?(e.exit("atxHeadingSequence"),s(h)):r(h)}function s(h){return h===35?(e.enter("atxHeadingSequence"),o(h)):h===null||X(h)?(e.exit("atxHeading"),t(h)):le(h)?ne(e,s,"whitespace")(h):(e.enter("atxHeadingText"),u(h))}function o(h){return h===35?(e.consume(h),o):(e.exit("atxHeadingSequence"),s(h))}function u(h){return h===null||h===35||he(h)?(e.exit("atxHeadingText"),s(h)):(e.consume(h),u)}}const Lu=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],ki=["pre","script","style","textarea"],Ru={concrete:!0,name:"htmlFlow",resolveTo:qu,tokenize:Hu},Pu={partial:!0,tokenize:ju},Ou={partial:!0,tokenize:Vu};function qu(e){let t=e.length;for(;t--&&!(e[t][0]==="enter"&&e[t][1].type==="htmlFlow"););return t>1&&e[t-2][1].type==="linePrefix"&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function Hu(e,t,r){const n=this;let i,a,l,s,o;return u;function u(A){return h(A)}function h(A){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(A),m}function m(A){return A===33?(e.consume(A),d):A===47?(e.consume(A),a=!0,w):A===63?(e.consume(A),i=3,n.interrupt?t:k):Ne(A)?(e.consume(A),l=String.fromCharCode(A),M):r(A)}function d(A){return A===45?(e.consume(A),i=2,p):A===91?(e.consume(A),i=5,s=0,y):Ne(A)?(e.consume(A),i=4,n.interrupt?t:k):r(A)}function p(A){return A===45?(e.consume(A),n.interrupt?t:k):r(A)}function y(A){const De="CDATA[";return A===De.charCodeAt(s++)?(e.consume(A),s===De.length?n.interrupt?t:j:y):r(A)}function w(A){return Ne(A)?(e.consume(A),l=String.fromCharCode(A),M):r(A)}function M(A){if(A===null||A===47||A===62||he(A)){const De=A===47,Re=l.toLowerCase();return!De&&!a&&ki.includes(Re)?(i=1,n.interrupt?t(A):j(A)):Lu.includes(l.toLowerCase())?(i=6,De?(e.consume(A),S):n.interrupt?t(A):j(A)):(i=7,n.interrupt&&!n.parser.lazy[n.now().line]?r(A):a?z(A):I(A))}return A===45||Ce(A)?(e.consume(A),l+=String.fromCharCode(A),M):r(A)}function S(A){return A===62?(e.consume(A),n.interrupt?t:j):r(A)}function z(A){return le(A)?(e.consume(A),z):D(A)}function I(A){return A===47?(e.consume(A),D):A===58||A===95||Ne(A)?(e.consume(A),V):le(A)?(e.consume(A),I):D(A)}function V(A){return A===45||A===46||A===58||A===95||Ce(A)?(e.consume(A),V):O(A)}function O(A){return A===61?(e.consume(A),E):le(A)?(e.consume(A),O):I(A)}function E(A){return A===null||A===60||A===61||A===62||A===96?r(A):A===34||A===39?(e.consume(A),o=A,G):le(A)?(e.consume(A),E):K(A)}function G(A){return A===o?(e.consume(A),o=null,U):A===null||X(A)?r(A):(e.consume(A),G)}function K(A){return A===null||A===34||A===39||A===47||A===60||A===61||A===62||A===96||he(A)?O(A):(e.consume(A),K)}function U(A){return A===47||A===62||le(A)?I(A):r(A)}function D(A){return A===62?(e.consume(A),$):r(A)}function $(A){return A===null||X(A)?j(A):le(A)?(e.consume(A),$):r(A)}function j(A){return A===45&&i===2?(e.consume(A),ae):A===60&&i===1?(e.consume(A),fe):A===62&&i===4?(e.consume(A),ke):A===63&&i===3?(e.consume(A),k):A===93&&i===5?(e.consume(A),je):X(A)&&(i===6||i===7)?(e.exit("htmlFlowData"),e.check(Pu,be,ie)(A)):A===null||X(A)?(e.exit("htmlFlowData"),ie(A)):(e.consume(A),j)}function ie(A){return e.check(Ou,Y,be)(A)}function Y(A){return e.enter("lineEnding"),e.consume(A),e.exit("lineEnding"),q}function q(A){return A===null||X(A)?ie(A):(e.enter("htmlFlowData"),j(A))}function ae(A){return A===45?(e.consume(A),k):j(A)}function fe(A){return A===47?(e.consume(A),l="",Me):j(A)}function Me(A){if(A===62){const De=l.toLowerCase();return ki.includes(De)?(e.consume(A),ke):j(A)}return Ne(A)&&l.length<8?(e.consume(A),l+=String.fromCharCode(A),Me):j(A)}function je(A){return A===93?(e.consume(A),k):j(A)}function k(A){return A===62?(e.consume(A),ke):A===45&&i===2?(e.consume(A),k):j(A)}function ke(A){return A===null||X(A)?(e.exit("htmlFlowData"),be(A)):(e.consume(A),ke)}function be(A){return e.exit("htmlFlow"),t(A)}}function Vu(e,t,r){const n=this;return i;function i(l){return X(l)?(e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),a):r(l)}function a(l){return n.parser.lazy[n.now().line]?r(l):t(l)}}function ju(e,t,r){return n;function n(i){return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),e.attempt(Ar,t,r)}}const $u={name:"htmlText",tokenize:Uu};function Uu(e,t,r){const n=this;let i,a,l;return s;function s(k){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(k),o}function o(k){return k===33?(e.consume(k),u):k===47?(e.consume(k),O):k===63?(e.consume(k),I):Ne(k)?(e.consume(k),K):r(k)}function u(k){return k===45?(e.consume(k),h):k===91?(e.consume(k),a=0,y):Ne(k)?(e.consume(k),z):r(k)}function h(k){return k===45?(e.consume(k),p):r(k)}function m(k){return k===null?r(k):k===45?(e.consume(k),d):X(k)?(l=m,fe(k)):(e.consume(k),m)}function d(k){return k===45?(e.consume(k),p):m(k)}function p(k){return k===62?ae(k):k===45?d(k):m(k)}function y(k){const ke="CDATA[";return k===ke.charCodeAt(a++)?(e.consume(k),a===ke.length?w:y):r(k)}function w(k){return k===null?r(k):k===93?(e.consume(k),M):X(k)?(l=w,fe(k)):(e.consume(k),w)}function M(k){return k===93?(e.consume(k),S):w(k)}function S(k){return k===62?ae(k):k===93?(e.consume(k),S):w(k)}function z(k){return k===null||k===62?ae(k):X(k)?(l=z,fe(k)):(e.consume(k),z)}function I(k){return k===null?r(k):k===63?(e.consume(k),V):X(k)?(l=I,fe(k)):(e.consume(k),I)}function V(k){return k===62?ae(k):I(k)}function O(k){return Ne(k)?(e.consume(k),E):r(k)}function E(k){return k===45||Ce(k)?(e.consume(k),E):G(k)}function G(k){return X(k)?(l=G,fe(k)):le(k)?(e.consume(k),G):ae(k)}function K(k){return k===45||Ce(k)?(e.consume(k),K):k===47||k===62||he(k)?U(k):r(k)}function U(k){return k===47?(e.consume(k),ae):k===58||k===95||Ne(k)?(e.consume(k),D):X(k)?(l=U,fe(k)):le(k)?(e.consume(k),U):ae(k)}function D(k){return k===45||k===46||k===58||k===95||Ce(k)?(e.consume(k),D):$(k)}function $(k){return k===61?(e.consume(k),j):X(k)?(l=$,fe(k)):le(k)?(e.consume(k),$):U(k)}function j(k){return k===null||k===60||k===61||k===62||k===96?r(k):k===34||k===39?(e.consume(k),i=k,ie):X(k)?(l=j,fe(k)):le(k)?(e.consume(k),j):(e.consume(k),Y)}function ie(k){return k===i?(e.consume(k),i=void 0,q):k===null?r(k):X(k)?(l=ie,fe(k)):(e.consume(k),ie)}function Y(k){return k===null||k===34||k===39||k===60||k===61||k===96?r(k):k===47||k===62||he(k)?U(k):(e.consume(k),Y)}function q(k){return k===47||k===62||he(k)?U(k):r(k)}function ae(k){return k===62?(e.consume(k),e.exit("htmlTextData"),e.exit("htmlText"),t):r(k)}function fe(k){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(k),e.exit("lineEnding"),Me}function Me(k){return le(k)?ne(e,je,"linePrefix",n.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(k):je(k)}function je(k){return e.enter("htmlTextData"),l(k)}}const A0={name:"labelEnd",resolveAll:Yu,resolveTo:Xu,tokenize:Ku},_u={tokenize:Zu},Gu={tokenize:Qu},Wu={tokenize:Ju};function Yu(e){let t=-1;const r=[];for(;++t=3&&(u===null||X(u))?(e.exit("thematicBreak"),t(u)):r(u)}function o(u){return u===i?(e.consume(u),n++,o):(e.exit("thematicBreakSequence"),le(u)?ne(e,s,"whitespace")(u):s(u))}}const Pe={continuation:{tokenize:u1},exit:h1,name:"list",tokenize:o1},l1={partial:!0,tokenize:m1},s1={partial:!0,tokenize:c1};function o1(e,t,r){const n=this,i=n.events[n.events.length-1];let a=i&&i[1].type==="linePrefix"?i[2].sliceSerialize(i[1],!0).length:0,l=0;return s;function s(p){const y=n.containerState.type||(p===42||p===43||p===45?"listUnordered":"listOrdered");if(y==="listUnordered"?!n.containerState.marker||p===n.containerState.marker:Jn(p)){if(n.containerState.type||(n.containerState.type=y,e.enter(y,{_container:!0})),y==="listUnordered")return e.enter("listItemPrefix"),p===42||p===45?e.check($r,r,u)(p):u(p);if(!n.interrupt||p===49)return e.enter("listItemPrefix"),e.enter("listItemValue"),o(p)}return r(p)}function o(p){return Jn(p)&&++l<10?(e.consume(p),o):(!n.interrupt||l<2)&&(n.containerState.marker?p===n.containerState.marker:p===41||p===46)?(e.exit("listItemValue"),u(p)):r(p)}function u(p){return e.enter("listItemMarker"),e.consume(p),e.exit("listItemMarker"),n.containerState.marker=n.containerState.marker||p,e.check(Ar,n.interrupt?r:h,e.attempt(l1,d,m))}function h(p){return n.containerState.initialBlankLine=!0,a++,d(p)}function m(p){return le(p)?(e.enter("listItemPrefixWhitespace"),e.consume(p),e.exit("listItemPrefixWhitespace"),d):r(p)}function d(p){return n.containerState.size=a+n.sliceSerialize(e.exit("listItemPrefix"),!0).length,t(p)}}function u1(e,t,r){const n=this;return n.containerState._closeFlow=void 0,e.check(Ar,i,a);function i(s){return n.containerState.furtherBlankLines=n.containerState.furtherBlankLines||n.containerState.initialBlankLine,ne(e,t,"listItemIndent",n.containerState.size+1)(s)}function a(s){return n.containerState.furtherBlankLines||!le(s)?(n.containerState.furtherBlankLines=void 0,n.containerState.initialBlankLine=void 0,l(s)):(n.containerState.furtherBlankLines=void 0,n.containerState.initialBlankLine=void 0,e.attempt(s1,t,l)(s))}function l(s){return n.containerState._closeFlow=!0,n.interrupt=void 0,ne(e,e.attempt(Pe,t,r),"linePrefix",n.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(s)}}function c1(e,t,r){const n=this;return ne(e,i,"listItemIndent",n.containerState.size+1);function i(a){const l=n.events[n.events.length-1];return l&&l[1].type==="listItemIndent"&&l[2].sliceSerialize(l[1],!0).length===n.containerState.size?t(a):r(a)}}function h1(e){e.exit(this.containerState.type)}function m1(e,t,r){const n=this;return ne(e,i,"listItemPrefixWhitespace",n.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function i(a){const l=n.events[n.events.length-1];return!le(a)&&l&&l[1].type==="listItemPrefixWhitespace"?t(a):r(a)}}const Si={name:"setextUnderline",resolveTo:f1,tokenize:p1};function f1(e,t){let r=e.length,n,i,a;for(;r--;)if(e[r][0]==="enter"){if(e[r][1].type==="content"){n=r;break}e[r][1].type==="paragraph"&&(i=r)}else e[r][1].type==="content"&&e.splice(r,1),!a&&e[r][1].type==="definition"&&(a=r);const l={type:"setextHeading",start:{...e[n][1].start},end:{...e[e.length-1][1].end}};return e[i][1].type="setextHeadingText",a?(e.splice(i,0,["enter",l,t]),e.splice(a+1,0,["exit",e[n][1],t]),e[n][1].end={...e[a][1].end}):e[n][1]=l,e.push(["exit",l,t]),e}function p1(e,t,r){const n=this;let i;return a;function a(u){let h=n.events.length,m;for(;h--;)if(n.events[h][1].type!=="lineEnding"&&n.events[h][1].type!=="linePrefix"&&n.events[h][1].type!=="content"){m=n.events[h][1].type==="paragraph";break}return!n.parser.lazy[n.now().line]&&(n.interrupt||m)?(e.enter("setextHeadingLine"),i=u,l(u)):r(u)}function l(u){return e.enter("setextHeadingLineSequence"),s(u)}function s(u){return u===i?(e.consume(u),s):(e.exit("setextHeadingLineSequence"),le(u)?ne(e,o,"lineSuffix")(u):o(u))}function o(u){return u===null||X(u)?(e.exit("setextHeadingLine"),t(u)):r(u)}}const d1={tokenize:g1};function g1(e){const t=this,r=e.attempt(Ar,n,e.attempt(this.parser.constructs.flowInitial,i,ne(e,e.attempt(this.parser.constructs.flow,i,e.attempt(wu,i)),"linePrefix")));return r;function n(a){if(a===null){e.consume(a);return}return e.enter("lineEndingBlank"),e.consume(a),e.exit("lineEndingBlank"),t.currentConstruct=void 0,r}function i(a){if(a===null){e.consume(a);return}return e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),t.currentConstruct=void 0,r}}const v1={resolveAll:hl()},y1=cl("string"),b1=cl("text");function cl(e){return{resolveAll:hl(e==="text"?x1:void 0),tokenize:t};function t(r){const n=this,i=this.parser.constructs[e],a=r.attempt(i,l,s);return l;function l(h){return u(h)?a(h):s(h)}function s(h){if(h===null){r.consume(h);return}return r.enter("data"),r.consume(h),o}function o(h){return u(h)?(r.exit("data"),a(h)):(r.consume(h),o)}function u(h){if(h===null)return!0;const m=i[h];let d=-1;if(m)for(;++d-1){const s=l[0];typeof s=="string"?l[0]=s.slice(n):l.shift()}a>0&&l.push(e[i].slice(0,a))}return l}function N1(e,t){let r=-1;const n=[];let i;for(;++r0){const rt=ee.tokenStack[ee.tokenStack.length-1];(rt[1]||Ti).call(ee,void 0,rt[0])}for(H.position={start:At(B.length>0?B[0][1].start:{line:1,column:1,offset:0}),end:At(B.length>0?B[B.length-2][1].end:{line:1,column:1,offset:0})},ce=-1;++ce1?"-"+s:""),dataFootnoteRef:!0,ariaDescribedBy:["footnote-label"]},children:[{type:"text",value:String(l)}]};e.patch(t,o);const u={type:"element",tagName:"sup",properties:{},children:[o]};return e.patch(t,u),e.applyData(t,u)}function K1(e,t){const r={type:"element",tagName:"h"+t.depth,properties:{},children:e.all(t)};return e.patch(t,r),e.applyData(t,r)}function Z1(e,t){if(e.options.allowDangerousHtml){const r={type:"raw",value:t.value};return e.patch(t,r),e.applyData(t,r)}}function pl(e,t){const r=t.referenceType;let n="]";if(r==="collapsed"?n+="[]":r==="full"&&(n+="["+(t.label||t.identifier)+"]"),t.type==="imageReference")return[{type:"text",value:"!["+t.alt+n}];const i=e.all(t),a=i[0];a&&a.type==="text"?a.value="["+a.value:i.unshift({type:"text",value:"["});const l=i[i.length-1];return l&&l.type==="text"?l.value+=n:i.push({type:"text",value:n}),i}function Q1(e,t){const r=String(t.identifier).toUpperCase(),n=e.definitionById.get(r);if(!n)return pl(e,t);const i={src:tr(n.url||""),alt:t.alt};n.title!==null&&n.title!==void 0&&(i.title=n.title);const a={type:"element",tagName:"img",properties:i,children:[]};return e.patch(t,a),e.applyData(t,a)}function J1(e,t){const r={src:tr(t.url)};t.alt!==null&&t.alt!==void 0&&(r.alt=t.alt),t.title!==null&&t.title!==void 0&&(r.title=t.title);const n={type:"element",tagName:"img",properties:r,children:[]};return e.patch(t,n),e.applyData(t,n)}function ec(e,t){const r={type:"text",value:t.value.replace(/\r?\n|\r/g," ")};e.patch(t,r);const n={type:"element",tagName:"code",properties:{},children:[r]};return e.patch(t,n),e.applyData(t,n)}function tc(e,t){const r=String(t.identifier).toUpperCase(),n=e.definitionById.get(r);if(!n)return pl(e,t);const i={href:tr(n.url||"")};n.title!==null&&n.title!==void 0&&(i.title=n.title);const a={type:"element",tagName:"a",properties:i,children:e.all(t)};return e.patch(t,a),e.applyData(t,a)}function rc(e,t){const r={href:tr(t.url)};t.title!==null&&t.title!==void 0&&(r.title=t.title);const n={type:"element",tagName:"a",properties:r,children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function nc(e,t,r){const n=e.all(t),i=r?ic(r):dl(t),a={},l=[];if(typeof t.checked=="boolean"){const h=n[0];let m;h&&h.type==="element"&&h.tagName==="p"?m=h:(m={type:"element",tagName:"p",properties:{},children:[]},n.unshift(m)),m.children.length>0&&m.children.unshift({type:"text",value:" "}),m.children.unshift({type:"element",tagName:"input",properties:{type:"checkbox",checked:t.checked,disabled:!0},children:[]}),a.className=["task-list-item"]}let s=-1;for(;++s1}function ac(e,t){const r={},n=e.all(t);let i=-1;for(typeof t.start=="number"&&t.start!==1&&(r.start=t.start);++i0){const l={type:"element",tagName:"tbody",properties:{},children:e.wrap(r,!0)},s=y0(t.children[1]),o=Ya(t.children[t.children.length-1]);s&&o&&(l.position={start:s,end:o}),i.push(l)}const a={type:"element",tagName:"table",properties:{},children:e.wrap(i,!0)};return e.patch(t,a),e.applyData(t,a)}function cc(e,t,r){const n=r?r.children:void 0,a=(n?n.indexOf(t):1)===0?"th":"td",l=r&&r.type==="table"?r.align:void 0,s=l?l.length:t.children.length;let o=-1;const u=[];for(;++o0,!0),n[0]),i=n.index+n[0].length,n=r.exec(t);return a.push(Ci(t.slice(i),i>0,!1)),a.join("")}function Ci(e,t,r){let n=0,i=e.length;if(t){let a=e.codePointAt(n);for(;a===zi||a===Mi;)n++,a=e.codePointAt(n)}if(r){let a=e.codePointAt(i-1);for(;a===zi||a===Mi;)i--,a=e.codePointAt(i-1)}return i>n?e.slice(n,i):""}function fc(e,t){const r={type:"text",value:mc(String(t.value))};return e.patch(t,r),e.applyData(t,r)}function pc(e,t){const r={type:"element",tagName:"hr",properties:{},children:[]};return e.patch(t,r),e.applyData(t,r)}const dc={blockquote:U1,break:_1,code:G1,delete:W1,emphasis:Y1,footnoteReference:X1,heading:K1,html:Z1,imageReference:Q1,image:J1,inlineCode:ec,linkReference:tc,link:rc,listItem:nc,list:ac,paragraph:lc,root:sc,strong:oc,table:uc,tableCell:hc,tableRow:cc,text:fc,thematicBreak:pc,toml:Dr,yaml:Dr,definition:Dr,footnoteDefinition:Dr};function Dr(){}const gl=-1,an=0,gr=1,Wr=2,T0=3,z0=4,M0=5,C0=6,vl=7,yl=8,Ei=typeof self=="object"?self:globalThis,gc=(e,t)=>{const r=(i,a)=>(e.set(a,i),i),n=i=>{if(e.has(i))return e.get(i);const[a,l]=t[i];switch(a){case an:case gl:return r(l,i);case gr:{const s=r([],i);for(const o of l)s.push(n(o));return s}case Wr:{const s=r({},i);for(const[o,u]of l)s[n(o)]=n(u);return s}case T0:return r(new Date(l),i);case z0:{const{source:s,flags:o}=l;return r(new RegExp(s,o),i)}case M0:{const s=r(new Map,i);for(const[o,u]of l)s.set(n(o),n(u));return s}case C0:{const s=r(new Set,i);for(const o of l)s.add(n(o));return s}case vl:{const{name:s,message:o}=l;return r(new Ei[s](o),i)}case yl:return r(BigInt(l),i);case"BigInt":return r(Object(BigInt(l)),i);case"ArrayBuffer":return r(new Uint8Array(l).buffer,l);case"DataView":{const{buffer:s}=new Uint8Array(l);return r(new DataView(s),l)}}return r(new Ei[a](l),i)};return n},Di=e=>gc(new Map,e)(0),Wt="",{toString:vc}={},{keys:yc}=Object,mr=e=>{const t=typeof e;if(t!=="object"||!e)return[an,t];const r=vc.call(e).slice(8,-1);switch(r){case"Array":return[gr,Wt];case"Object":return[Wr,Wt];case"Date":return[T0,Wt];case"RegExp":return[z0,Wt];case"Map":return[M0,Wt];case"Set":return[C0,Wt];case"DataView":return[gr,r]}return r.includes("Array")?[gr,r]:r.includes("Error")?[vl,r]:[Wr,r]},Ir=([e,t])=>e===an&&(t==="function"||t==="symbol"),bc=(e,t,r,n)=>{const i=(l,s)=>{const o=n.push(l)-1;return r.set(s,o),o},a=l=>{if(r.has(l))return r.get(l);let[s,o]=mr(l);switch(s){case an:{let h=l;switch(o){case"bigint":s=yl,h=l.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+o);h=null;break;case"undefined":return i([gl],l)}return i([s,h],l)}case gr:{if(o){let d=l;return o==="DataView"?d=new Uint8Array(l.buffer):o==="ArrayBuffer"&&(d=new Uint8Array(l)),i([o,[...d]],l)}const h=[],m=i([s,h],l);for(const d of l)h.push(a(d));return m}case Wr:{if(o)switch(o){case"BigInt":return i([o,l.toString()],l);case"Boolean":case"Number":case"String":return i([o,l.valueOf()],l)}if(t&&"toJSON"in l)return a(l.toJSON());const h=[],m=i([s,h],l);for(const d of yc(l))(e||!Ir(mr(l[d])))&&h.push([a(d),a(l[d])]);return m}case T0:return i([s,l.toISOString()],l);case z0:{const{source:h,flags:m}=l;return i([s,{source:h,flags:m}],l)}case M0:{const h=[],m=i([s,h],l);for(const[d,p]of l)(e||!(Ir(mr(d))||Ir(mr(p))))&&h.push([a(d),a(p)]);return m}case C0:{const h=[],m=i([s,h],l);for(const d of l)(e||!Ir(mr(d)))&&h.push(a(d));return m}}const{message:u}=l;return i([s,{name:o,message:u}],l)};return a},Ii=(e,{json:t,lossy:r}={})=>{const n=[];return bc(!(t||r),!!t,new Map,n)(e),n},Yr=typeof structuredClone=="function"?(e,t)=>t&&("json"in t||"lossy"in t)?Di(Ii(e,t)):structuredClone(e):(e,t)=>Di(Ii(e,t));function xc(e,t){const r=[{type:"text",value:"↩"}];return t>1&&r.push({type:"element",tagName:"sup",properties:{},children:[{type:"text",value:String(t)}]}),r}function wc(e,t){return"Back to reference "+(e+1)+(t>1?"-"+t:"")}function kc(e){const t=typeof e.options.clobberPrefix=="string"?e.options.clobberPrefix:"user-content-",r=e.options.footnoteBackContent||xc,n=e.options.footnoteBackLabel||wc,i=e.options.footnoteLabel||"Footnotes",a=e.options.footnoteLabelTagName||"h2",l=e.options.footnoteLabelProperties||{className:["sr-only"]},s=[];let o=-1;for(;++o0&&y.push({type:"text",value:" "});let z=typeof r=="string"?r:r(o,p);typeof z=="string"&&(z={type:"text",value:z}),y.push({type:"element",tagName:"a",properties:{href:"#"+t+"fnref-"+d+(p>1?"-"+p:""),dataFootnoteBackref:"",ariaLabel:typeof n=="string"?n:n(o,p),className:["data-footnote-backref"]},children:Array.isArray(z)?z:[z]})}const M=h[h.length-1];if(M&&M.type==="element"&&M.tagName==="p"){const z=M.children[M.children.length-1];z&&z.type==="text"?z.value+=" ":M.children.push({type:"text",value:" "}),M.children.push(...y)}else h.push(...y);const S={type:"element",tagName:"li",properties:{id:t+"fn-"+d},children:e.wrap(h,!0)};e.patch(u,S),s.push(S)}if(s.length!==0)return{type:"element",tagName:"section",properties:{dataFootnotes:!0,className:["footnotes"]},children:[{type:"element",tagName:a,properties:{...Yr(l),id:"footnote-label"},children:[{type:"text",value:i}]},{type:"text",value:` +`},{type:"element",tagName:"ol",properties:{},children:e.wrap(s,!0)},{type:"text",value:` +`}]}}const Tr=(function(e){if(e==null)return zc;if(typeof e=="function")return ln(e);if(typeof e=="object")return Array.isArray(e)?Sc(e):Ac(e);if(typeof e=="string")return Tc(e);throw new Error("Expected function, string, or object as test")});function Sc(e){const t=[];let r=-1;for(;++r":""))+")"})}return d;function d(){let p=bl,y,w,M;if((!t||a(o,u,h[h.length-1]||void 0))&&(p=Ec(r(o,h)),p[0]===t0))return p;if("children"in o&&o.children){const S=o;if(S.children&&p[0]!==xl)for(w=(n?S.children.length:-1)+l,M=h.concat(S);w>-1&&w0&&r.push({type:"text",value:` +`}),r}function Bi(e){let t=0,r=e.charCodeAt(t);for(;r===9||r===32;)t++,r=e.charCodeAt(t);return e.slice(t)}function Ni(e,t){const r=Ic(e,t),n=r.one(e,void 0),i=kc(r),a=Array.isArray(n)?{type:"root",children:n}:n||{type:"root",children:[]};return i&&a.children.push({type:"text",value:` +`},i),a}function Rc(e,t){return e&&"run"in e?async function(r,n){const i=Ni(r,{file:n,...t});await e.run(i,n)}:function(r,n){return Ni(r,{file:n,...e||t})}}function Fi(e){if(e)throw e}var kn,Li;function Pc(){if(Li)return kn;Li=1;var e=Object.prototype.hasOwnProperty,t=Object.prototype.toString,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=function(u){return typeof Array.isArray=="function"?Array.isArray(u):t.call(u)==="[object Array]"},a=function(u){if(!u||t.call(u)!=="[object Object]")return!1;var h=e.call(u,"constructor"),m=u.constructor&&u.constructor.prototype&&e.call(u.constructor.prototype,"isPrototypeOf");if(u.constructor&&!h&&!m)return!1;var d;for(d in u);return typeof d>"u"||e.call(u,d)},l=function(u,h){r&&h.name==="__proto__"?r(u,h.name,{enumerable:!0,configurable:!0,value:h.newValue,writable:!0}):u[h.name]=h.newValue},s=function(u,h){if(h==="__proto__")if(e.call(u,h)){if(n)return n(u,h).value}else return;return u[h]};return kn=function o(){var u,h,m,d,p,y,w=arguments[0],M=1,S=arguments.length,z=!1;for(typeof w=="boolean"&&(z=w,w=arguments[1]||{},M=2),(w==null||typeof w!="object"&&typeof w!="function")&&(w={});Ml.length;let o;s&&l.push(i);try{o=e.apply(this,l)}catch(u){const h=u;if(s&&r)throw h;return i(h)}s||(o&&o.then&&typeof o.then=="function"?o.then(a,i):o instanceof Error?i(o):a(o))}function i(l,...s){r||(r=!0,t(l,...s))}function a(l){i(null,l)}}const at={basename:Vc,dirname:jc,extname:$c,join:Uc,sep:"/"};function Vc(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');zr(e);let r=0,n=-1,i=e.length,a;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(a){r=i+1;break}}else n<0&&(a=!0,n=i+1);return n<0?"":e.slice(r,n)}if(t===e)return"";let l=-1,s=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(a){r=i+1;break}}else l<0&&(a=!0,l=i+1),s>-1&&(e.codePointAt(i)===t.codePointAt(s--)?s<0&&(n=i):(s=-1,n=l));return r===n?n=l:n<0&&(n=e.length),e.slice(r,n)}function jc(e){if(zr(e),e.length===0)return".";let t=-1,r=e.length,n;for(;--r;)if(e.codePointAt(r)===47){if(n){t=r;break}}else n||(n=!0);return t<0?e.codePointAt(0)===47?"/":".":t===1&&e.codePointAt(0)===47?"//":e.slice(0,t)}function $c(e){zr(e);let t=e.length,r=-1,n=0,i=-1,a=0,l;for(;t--;){const s=e.codePointAt(t);if(s===47){if(l){n=t+1;break}continue}r<0&&(l=!0,r=t+1),s===46?i<0?i=t:a!==1&&(a=1):i>-1&&(a=-1)}return i<0||r<0||a===0||a===1&&i===r-1&&i===n+1?"":e.slice(i,r)}function Uc(...e){let t=-1,r;for(;++t0&&e.codePointAt(e.length-1)===47&&(r+="/"),t?"/"+r:r}function Gc(e,t){let r="",n=0,i=-1,a=0,l=-1,s,o;for(;++l<=e.length;){if(l2){if(o=r.lastIndexOf("/"),o!==r.length-1){o<0?(r="",n=0):(r=r.slice(0,o),n=r.length-1-r.lastIndexOf("/")),i=l,a=0;continue}}else if(r.length>0){r="",n=0,i=l,a=0;continue}}t&&(r=r.length>0?r+"/..":"..",n=2)}else r.length>0?r+="/"+e.slice(i+1,l):r=e.slice(i+1,l),n=l-i-1;i=l,a=0}else s===46&&a>-1?a++:a=-1}return r}function zr(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}const Wc={cwd:Yc};function Yc(){return"/"}function i0(e){return!!(e!==null&&typeof e=="object"&&"href"in e&&e.href&&"protocol"in e&&e.protocol&&e.auth===void 0)}function Xc(e){if(typeof e=="string")e=new URL(e);else if(!i0(e)){const t=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code="ERR_INVALID_ARG_TYPE",t}if(e.protocol!=="file:"){const t=new TypeError("The URL must be of scheme file");throw t.code="ERR_INVALID_URL_SCHEME",t}return Kc(e)}function Kc(e){if(e.hostname!==""){const n=new TypeError('File URL host must be "localhost" or empty on darwin');throw n.code="ERR_INVALID_FILE_URL_HOST",n}const t=e.pathname;let r=-1;for(;++r0){let[p,...y]=h;const w=n[d][1];n0(w)&&n0(p)&&(p=Sn(!0,w,p)),n[d]=[u,p,...y]}}}}const eh=new I0().freeze();function Mn(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `parser`")}function Cn(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `compiler`")}function En(e,t){if(t)throw new Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function Pi(e){if(!n0(e)||typeof e.type!="string")throw new TypeError("Expected node, got `"+e+"`")}function Oi(e,t,r){if(!r)throw new Error("`"+e+"` finished async. Use `"+t+"` instead")}function Br(e){return th(e)?e:new wl(e)}function th(e){return!!(e&&typeof e=="object"&&"message"in e&&"messages"in e)}function rh(e){return typeof e=="string"||nh(e)}function nh(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const ih="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",qi=[],Hi={allowDangerousHtml:!0},ah=/^(https?|ircs?|mailto|xmpp)$/i,lh=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"className",id:"remove-classname"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function s5(e){const t=sh(e),r=oh(e);return uh(t.runSync(t.parse(r),r),e)}function sh(e){const t=e.rehypePlugins||qi,r=e.remarkPlugins||qi,n=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...Hi}:Hi;return eh().use($1).use(r).use(Rc,n).use(t)}function oh(e){const t=e.children||"",r=new wl;return typeof t=="string"&&(r.value=t),r}function uh(e,t){const r=t.allowedElements,n=t.allowElement,i=t.components,a=t.disallowedElements,l=t.skipHtml,s=t.unwrapDisallowed,o=t.urlTransform||ch;for(const h of lh)Object.hasOwn(t,h.from)&&(""+h.from+(h.to?"use `"+h.to+"` instead":"remove it")+ih+h.id,void 0);return D0(e,u),zo(e,{Fragment:gn.Fragment,components:i,ignoreInvalidStyle:!0,jsx:gn.jsx,jsxs:gn.jsxs,passKeys:!0,passNode:!0});function u(h,m,d){if(h.type==="raw"&&d&&typeof m=="number")return l?d.children.splice(m,1):d.children[m]={type:"text",value:h.value},m;if(h.type==="element"){let p;for(p in bn)if(Object.hasOwn(bn,p)&&Object.hasOwn(h.properties,p)){const y=h.properties[p],w=bn[p];(w===null||w.includes(h.tagName))&&(h.properties[p]=o(String(y||""),p,h))}}if(h.type==="element"){let p=r?!r.includes(h.tagName):a?a.includes(h.tagName):!1;if(!p&&n&&typeof m=="number"&&(p=!n(h,m,d)),p&&d&&typeof m=="number")return s&&h.children?d.children.splice(m,1,...h.children):d.children.splice(m,1),m}}}function ch(e){const t=e.indexOf(":"),r=e.indexOf("?"),n=e.indexOf("#"),i=e.indexOf("/");return t===-1||i!==-1&&t>i||r!==-1&&t>r||n!==-1&&t>n||ah.test(e.slice(0,t))?e:""}function Vi(e,t){const r=String(e);if(typeof t!="string")throw new TypeError("Expected character");let n=0,i=r.indexOf(t);for(;i!==-1;)n++,i=r.indexOf(t,i+t.length);return n}function hh(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}function mh(e,t,r){const i=Tr((r||{}).ignore||[]),a=fh(t);let l=-1;for(;++l0?{type:"text",value:E}:void 0),E===!1?d.lastIndex=V+1:(y!==V&&z.push({type:"text",value:u.value.slice(y,V)}),Array.isArray(E)?z.push(...E):E&&z.push(E),y=V+I[0].length,S=!0),!d.global)break;I=d.exec(u.value)}return S?(y?\]}]+$/.exec(e);if(!t)return[e,void 0];e=e.slice(0,t.index);let r=t[0],n=r.indexOf(")");const i=Vi(e,"(");let a=Vi(e,")");for(;n!==-1&&i>a;)e+=r.slice(0,n+1),r=r.slice(n+1),n=r.indexOf(")"),a++;return[e,r]}function kl(e,t){const r=e.input.charCodeAt(e.index-1);return(e.index===0||Ot(r)||rn(r))&&(!t||r!==47)}Sl.peek=Rh;function Ch(){this.buffer()}function Eh(e){this.enter({type:"footnoteReference",identifier:"",label:""},e)}function Dh(){this.buffer()}function Ih(e){this.enter({type:"footnoteDefinition",identifier:"",label:"",children:[]},e)}function Bh(e){const t=this.resume(),r=this.stack[this.stack.length-1];r.type,r.identifier=it(this.sliceSerialize(e)).toLowerCase(),r.label=t}function Nh(e){this.exit(e)}function Fh(e){const t=this.resume(),r=this.stack[this.stack.length-1];r.type,r.identifier=it(this.sliceSerialize(e)).toLowerCase(),r.label=t}function Lh(e){this.exit(e)}function Rh(){return"["}function Sl(e,t,r,n){const i=r.createTracker(n);let a=i.move("[^");const l=r.enter("footnoteReference"),s=r.enter("reference");return a+=i.move(r.safe(r.associationId(e),{after:"]",before:a})),s(),l(),a+=i.move("]"),a}function Ph(){return{enter:{gfmFootnoteCallString:Ch,gfmFootnoteCall:Eh,gfmFootnoteDefinitionLabelString:Dh,gfmFootnoteDefinition:Ih},exit:{gfmFootnoteCallString:Bh,gfmFootnoteCall:Nh,gfmFootnoteDefinitionLabelString:Fh,gfmFootnoteDefinition:Lh}}}function Oh(e){let t=!1;return e&&e.firstLineBlank&&(t=!0),{handlers:{footnoteDefinition:r,footnoteReference:Sl},unsafe:[{character:"[",inConstruct:["label","phrasing","reference"]}]};function r(n,i,a,l){const s=a.createTracker(l);let o=s.move("[^");const u=a.enter("footnoteDefinition"),h=a.enter("label");return o+=s.move(a.safe(a.associationId(n),{before:o,after:"]"})),h(),o+=s.move("]:"),n.children&&n.children.length>0&&(s.shift(4),o+=s.move((t?` +`:" ")+a.indentLines(a.containerFlow(n,s.current()),t?Al:qh))),u(),o}}function qh(e,t,r){return t===0?e:Al(e,t,r)}function Al(e,t,r){return(r?"":" ")+e}const Hh=["autolink","destinationLiteral","destinationRaw","reference","titleQuote","titleApostrophe"];Tl.peek=_h;function Vh(){return{canContainEols:["delete"],enter:{strikethrough:$h},exit:{strikethrough:Uh}}}function jh(){return{unsafe:[{character:"~",inConstruct:"phrasing",notInConstruct:Hh}],handlers:{delete:Tl}}}function $h(e){this.enter({type:"delete",children:[]},e)}function Uh(e){this.exit(e)}function Tl(e,t,r,n){const i=r.createTracker(n),a=r.enter("strikethrough");let l=i.move("~~");return l+=r.containerPhrasing(e,{...i.current(),before:l,after:"~"}),l+=i.move("~~"),a(),l}function _h(){return"~"}function Gh(e){return e.length}function Wh(e,t){const r=t||{},n=(r.align||[]).concat(),i=r.stringLength||Gh,a=[],l=[],s=[],o=[];let u=0,h=-1;for(;++hu&&(u=e[h].length);++So[S])&&(o[S]=I)}w.push(z)}l[h]=w,s[h]=M}let m=-1;if(typeof n=="object"&&"length"in n)for(;++mo[m]&&(o[m]=z),p[m]=z),d[m]=I}l.splice(1,0,d),s.splice(1,0,p),h=-1;const y=[];for(;++h "),a.shift(2);const l=r.indentLines(r.containerFlow(e,a.current()),Kh);return i(),l}function Kh(e,t,r){return">"+(r?"":" ")+e}function Zh(e,t){return $i(e,t.inConstruct,!0)&&!$i(e,t.notInConstruct,!1)}function $i(e,t,r){if(typeof t=="string"&&(t=[t]),!t||t.length===0)return r;let n=-1;for(;++nl&&(l=a):a=1,i=n+t.length,n=r.indexOf(t,i);return l}function Qh(e,t){return!!(t.options.fences===!1&&e.value&&!e.lang&&/[^ \r\n]/.test(e.value)&&!/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(e.value))}function Jh(e){const t=e.options.fence||"`";if(t!=="`"&&t!=="~")throw new Error("Cannot serialize code with `"+t+"` for `options.fence`, expected `` ` `` or `~`");return t}function e4(e,t,r,n){const i=Jh(r),a=e.value||"",l=i==="`"?"GraveAccent":"Tilde";if(Qh(e,r)){const m=r.enter("codeIndented"),d=r.indentLines(a,t4);return m(),d}const s=r.createTracker(n),o=i.repeat(Math.max(zl(a,i)+1,3)),u=r.enter("codeFenced");let h=s.move(o);if(e.lang){const m=r.enter(`codeFencedLang${l}`);h+=s.move(r.safe(e.lang,{before:h,after:" ",encode:["`"],...s.current()})),m()}if(e.lang&&e.meta){const m=r.enter(`codeFencedMeta${l}`);h+=s.move(" "),h+=s.move(r.safe(e.meta,{before:h,after:` +`,encode:["`"],...s.current()})),m()}return h+=s.move(` +`),a&&(h+=s.move(a+` +`)),h+=s.move(o),u(),h}function t4(e,t,r){return(r?"":" ")+e}function B0(e){const t=e.options.quote||'"';if(t!=='"'&&t!=="'")throw new Error("Cannot serialize title with `"+t+"` for `options.quote`, expected `\"`, or `'`");return t}function r4(e,t,r,n){const i=B0(r),a=i==='"'?"Quote":"Apostrophe",l=r.enter("definition");let s=r.enter("label");const o=r.createTracker(n);let u=o.move("[");return u+=o.move(r.safe(r.associationId(e),{before:u,after:"]",...o.current()})),u+=o.move("]: "),s(),!e.url||/[\0- \u007F]/.test(e.url)?(s=r.enter("destinationLiteral"),u+=o.move("<"),u+=o.move(r.safe(e.url,{before:u,after:">",...o.current()})),u+=o.move(">")):(s=r.enter("destinationRaw"),u+=o.move(r.safe(e.url,{before:u,after:e.title?" ":` +`,...o.current()}))),s(),e.title&&(s=r.enter(`title${a}`),u+=o.move(" "+i),u+=o.move(r.safe(e.title,{before:u,after:i,...o.current()})),u+=o.move(i),s()),l(),u}function n4(e){const t=e.options.emphasis||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize emphasis with `"+t+"` for `options.emphasis`, expected `*`, or `_`");return t}function xr(e){return"&#x"+e.toString(16).toUpperCase()+";"}function Xr(e,t,r){const n=Qt(e),i=Qt(t);return n===void 0?i===void 0?r==="_"?{inside:!0,outside:!0}:{inside:!1,outside:!1}:i===1?{inside:!0,outside:!0}:{inside:!1,outside:!0}:n===1?i===void 0?{inside:!1,outside:!1}:i===1?{inside:!0,outside:!0}:{inside:!1,outside:!1}:i===void 0?{inside:!1,outside:!1}:i===1?{inside:!0,outside:!1}:{inside:!1,outside:!1}}Ml.peek=i4;function Ml(e,t,r,n){const i=n4(r),a=r.enter("emphasis"),l=r.createTracker(n),s=l.move(i);let o=l.move(r.containerPhrasing(e,{after:i,before:s,...l.current()}));const u=o.charCodeAt(0),h=Xr(n.before.charCodeAt(n.before.length-1),u,i);h.inside&&(o=xr(u)+o.slice(1));const m=o.charCodeAt(o.length-1),d=Xr(n.after.charCodeAt(0),m,i);d.inside&&(o=o.slice(0,-1)+xr(m));const p=l.move(i);return a(),r.attentionEncodeSurroundingInfo={after:d.outside,before:h.outside},s+o+p}function i4(e,t,r){return r.options.emphasis||"*"}function a4(e,t){let r=!1;return D0(e,function(n){if("value"in n&&/\r?\n|\r/.test(n.value)||n.type==="break")return r=!0,t0}),!!((!e.depth||e.depth<3)&&k0(e)&&(t.options.setext||r))}function l4(e,t,r,n){const i=Math.max(Math.min(6,e.depth||1),1),a=r.createTracker(n);if(a4(e,r)){const h=r.enter("headingSetext"),m=r.enter("phrasing"),d=r.containerPhrasing(e,{...a.current(),before:` +`,after:` +`});return m(),h(),d+` +`+(i===1?"=":"-").repeat(d.length-(Math.max(d.lastIndexOf("\r"),d.lastIndexOf(` +`))+1))}const l="#".repeat(i),s=r.enter("headingAtx"),o=r.enter("phrasing");a.move(l+" ");let u=r.containerPhrasing(e,{before:"# ",after:` +`,...a.current()});return/^[\t ]/.test(u)&&(u=xr(u.charCodeAt(0))+u.slice(1)),u=u?l+" "+u:l,r.options.closeAtx&&(u+=" "+l),o(),s(),u}Cl.peek=s4;function Cl(e){return e.value||""}function s4(){return"<"}El.peek=o4;function El(e,t,r,n){const i=B0(r),a=i==='"'?"Quote":"Apostrophe",l=r.enter("image");let s=r.enter("label");const o=r.createTracker(n);let u=o.move("![");return u+=o.move(r.safe(e.alt,{before:u,after:"]",...o.current()})),u+=o.move("]("),s(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(s=r.enter("destinationLiteral"),u+=o.move("<"),u+=o.move(r.safe(e.url,{before:u,after:">",...o.current()})),u+=o.move(">")):(s=r.enter("destinationRaw"),u+=o.move(r.safe(e.url,{before:u,after:e.title?" ":")",...o.current()}))),s(),e.title&&(s=r.enter(`title${a}`),u+=o.move(" "+i),u+=o.move(r.safe(e.title,{before:u,after:i,...o.current()})),u+=o.move(i),s()),u+=o.move(")"),l(),u}function o4(){return"!"}Dl.peek=u4;function Dl(e,t,r,n){const i=e.referenceType,a=r.enter("imageReference");let l=r.enter("label");const s=r.createTracker(n);let o=s.move("![");const u=r.safe(e.alt,{before:o,after:"]",...s.current()});o+=s.move(u+"]["),l();const h=r.stack;r.stack=[],l=r.enter("reference");const m=r.safe(r.associationId(e),{before:o,after:"]",...s.current()});return l(),r.stack=h,a(),i==="full"||!u||u!==m?o+=s.move(m+"]"):i==="shortcut"?o=o.slice(0,-1):o+=s.move("]"),o}function u4(){return"!"}Il.peek=c4;function Il(e,t,r){let n=e.value||"",i="`",a=-1;for(;new RegExp("(^|[^`])"+i+"([^`]|$)").test(n);)i+="`";for(/[^ \r\n]/.test(n)&&(/^[ \r\n]/.test(n)&&/[ \r\n]$/.test(n)||/^`|`$/.test(n))&&(n=" "+n+" ");++a\u007F]/.test(e.url))}Nl.peek=h4;function Nl(e,t,r,n){const i=B0(r),a=i==='"'?"Quote":"Apostrophe",l=r.createTracker(n);let s,o;if(Bl(e,r)){const h=r.stack;r.stack=[],s=r.enter("autolink");let m=l.move("<");return m+=l.move(r.containerPhrasing(e,{before:m,after:">",...l.current()})),m+=l.move(">"),s(),r.stack=h,m}s=r.enter("link"),o=r.enter("label");let u=l.move("[");return u+=l.move(r.containerPhrasing(e,{before:u,after:"](",...l.current()})),u+=l.move("]("),o(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(o=r.enter("destinationLiteral"),u+=l.move("<"),u+=l.move(r.safe(e.url,{before:u,after:">",...l.current()})),u+=l.move(">")):(o=r.enter("destinationRaw"),u+=l.move(r.safe(e.url,{before:u,after:e.title?" ":")",...l.current()}))),o(),e.title&&(o=r.enter(`title${a}`),u+=l.move(" "+i),u+=l.move(r.safe(e.title,{before:u,after:i,...l.current()})),u+=l.move(i),o()),u+=l.move(")"),s(),u}function h4(e,t,r){return Bl(e,r)?"<":"["}Fl.peek=m4;function Fl(e,t,r,n){const i=e.referenceType,a=r.enter("linkReference");let l=r.enter("label");const s=r.createTracker(n);let o=s.move("[");const u=r.containerPhrasing(e,{before:o,after:"]",...s.current()});o+=s.move(u+"]["),l();const h=r.stack;r.stack=[],l=r.enter("reference");const m=r.safe(r.associationId(e),{before:o,after:"]",...s.current()});return l(),r.stack=h,a(),i==="full"||!u||u!==m?o+=s.move(m+"]"):i==="shortcut"?o=o.slice(0,-1):o+=s.move("]"),o}function m4(){return"["}function N0(e){const t=e.options.bullet||"*";if(t!=="*"&&t!=="+"&&t!=="-")throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}function f4(e){const t=N0(e),r=e.options.bulletOther;if(!r)return t==="*"?"-":"*";if(r!=="*"&&r!=="+"&&r!=="-")throw new Error("Cannot serialize items with `"+r+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(r===t)throw new Error("Expected `bullet` (`"+t+"`) and `bulletOther` (`"+r+"`) to be different");return r}function p4(e){const t=e.options.bulletOrdered||".";if(t!=="."&&t!==")")throw new Error("Cannot serialize items with `"+t+"` for `options.bulletOrdered`, expected `.` or `)`");return t}function Ll(e){const t=e.options.rule||"*";if(t!=="*"&&t!=="-"&&t!=="_")throw new Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}function d4(e,t,r,n){const i=r.enter("list"),a=r.bulletCurrent;let l=e.ordered?p4(r):N0(r);const s=e.ordered?l==="."?")":".":f4(r);let o=t&&r.bulletLastUsed?l===r.bulletLastUsed:!1;if(!e.ordered){const h=e.children?e.children[0]:void 0;if((l==="*"||l==="-")&&h&&(!h.children||!h.children[0])&&r.stack[r.stack.length-1]==="list"&&r.stack[r.stack.length-2]==="listItem"&&r.stack[r.stack.length-3]==="list"&&r.stack[r.stack.length-4]==="listItem"&&r.indexStack[r.indexStack.length-1]===0&&r.indexStack[r.indexStack.length-2]===0&&r.indexStack[r.indexStack.length-3]===0&&(o=!0),Ll(r)===l&&h){let m=-1;for(;++m-1?t.start:1)+(r.options.incrementListMarker===!1?0:t.children.indexOf(e))+a);let l=a.length+1;(i==="tab"||i==="mixed"&&(t&&t.type==="list"&&t.spread||e.spread))&&(l=Math.ceil(l/4)*4);const s=r.createTracker(n);s.move(a+" ".repeat(l-a.length)),s.shift(l);const o=r.enter("listItem"),u=r.indentLines(r.containerFlow(e,s.current()),h);return o(),u;function h(m,d,p){return d?(p?"":" ".repeat(l))+m:(p?a:a+" ".repeat(l-a.length))+m}}function y4(e,t,r,n){const i=r.enter("paragraph"),a=r.enter("phrasing"),l=r.containerPhrasing(e,n);return a(),i(),l}const b4=Tr(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function x4(e,t,r,n){return(e.children.some(function(l){return b4(l)})?r.containerPhrasing:r.containerFlow).call(r,e,n)}function w4(e){const t=e.options.strong||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}Rl.peek=k4;function Rl(e,t,r,n){const i=w4(r),a=r.enter("strong"),l=r.createTracker(n),s=l.move(i+i);let o=l.move(r.containerPhrasing(e,{after:i,before:s,...l.current()}));const u=o.charCodeAt(0),h=Xr(n.before.charCodeAt(n.before.length-1),u,i);h.inside&&(o=xr(u)+o.slice(1));const m=o.charCodeAt(o.length-1),d=Xr(n.after.charCodeAt(0),m,i);d.inside&&(o=o.slice(0,-1)+xr(m));const p=l.move(i+i);return a(),r.attentionEncodeSurroundingInfo={after:d.outside,before:h.outside},s+o+p}function k4(e,t,r){return r.options.strong||"*"}function S4(e,t,r,n){return r.safe(e.value,n)}function A4(e){const t=e.options.ruleRepetition||3;if(t<3)throw new Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}function T4(e,t,r){const n=(Ll(r)+(r.options.ruleSpaces?" ":"")).repeat(A4(r));return r.options.ruleSpaces?n.slice(0,-1):n}const Pl={blockquote:Xh,break:Ui,code:e4,definition:r4,emphasis:Ml,hardBreak:Ui,heading:l4,html:Cl,image:El,imageReference:Dl,inlineCode:Il,link:Nl,linkReference:Fl,list:d4,listItem:v4,paragraph:y4,root:x4,strong:Rl,text:S4,thematicBreak:T4};function z4(){return{enter:{table:M4,tableData:_i,tableHeader:_i,tableRow:E4},exit:{codeText:D4,table:C4,tableData:Nn,tableHeader:Nn,tableRow:Nn}}}function M4(e){const t=e._align;this.enter({type:"table",align:t.map(function(r){return r==="none"?null:r}),children:[]},e),this.data.inTable=!0}function C4(e){this.exit(e),this.data.inTable=void 0}function E4(e){this.enter({type:"tableRow",children:[]},e)}function Nn(e){this.exit(e)}function _i(e){this.enter({type:"tableCell",children:[]},e)}function D4(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,I4));const r=this.stack[this.stack.length-1];r.type,r.value=t,this.exit(e)}function I4(e,t){return t==="|"?t:e}function B4(e){const t=e||{},r=t.tableCellPadding,n=t.tablePipeAlign,i=t.stringLength,a=r?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:` +`,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:d,table:l,tableCell:o,tableRow:s}};function l(p,y,w,M){return u(h(p,w,M),p.align)}function s(p,y,w,M){const S=m(p,w,M),z=u([S]);return z.slice(0,z.indexOf(` +`))}function o(p,y,w,M){const S=w.enter("tableCell"),z=w.enter("phrasing"),I=w.containerPhrasing(p,{...M,before:a,after:a});return z(),S(),I}function u(p,y){return Wh(p,{align:y,alignDelimiters:n,padding:r,stringLength:i})}function h(p,y,w){const M=p.children;let S=-1;const z=[],I=y.enter("table");for(;++S0&&!r&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),r}const K4={tokenize:im,partial:!0};function Z4(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:tm,continuation:{tokenize:rm},exit:nm}},text:{91:{name:"gfmFootnoteCall",tokenize:em},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:Q4,resolveTo:J4}}}}function Q4(e,t,r){const n=this;let i=n.events.length;const a=n.parser.gfmFootnotes||(n.parser.gfmFootnotes=[]);let l;for(;i--;){const o=n.events[i][1];if(o.type==="labelImage"){l=o;break}if(o.type==="gfmFootnoteCall"||o.type==="labelLink"||o.type==="label"||o.type==="image"||o.type==="link")break}return s;function s(o){if(!l||!l._balanced)return r(o);const u=it(n.sliceSerialize({start:l.end,end:n.now()}));return u.codePointAt(0)!==94||!a.includes(u.slice(1))?r(o):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(o),e.exit("gfmFootnoteCallLabelMarker"),t(o))}}function J4(e,t){let r=e.length;for(;r--;)if(e[r][1].type==="labelImage"&&e[r][0]==="enter"){e[r][1];break}e[r+1][1].type="data",e[r+3][1].type="gfmFootnoteCallLabelMarker";const n={type:"gfmFootnoteCall",start:Object.assign({},e[r+3][1].start),end:Object.assign({},e[e.length-1][1].end)},i={type:"gfmFootnoteCallMarker",start:Object.assign({},e[r+3][1].end),end:Object.assign({},e[r+3][1].end)};i.end.column++,i.end.offset++,i.end._bufferIndex++;const a={type:"gfmFootnoteCallString",start:Object.assign({},i.end),end:Object.assign({},e[e.length-1][1].start)},l={type:"chunkString",contentType:"string",start:Object.assign({},a.start),end:Object.assign({},a.end)},s=[e[r+1],e[r+2],["enter",n,t],e[r+3],e[r+4],["enter",i,t],["exit",i,t],["enter",a,t],["enter",l,t],["exit",l,t],["exit",a,t],e[e.length-2],e[e.length-1],["exit",n,t]];return e.splice(r,e.length-r+1,...s),e}function em(e,t,r){const n=this,i=n.parser.gfmFootnotes||(n.parser.gfmFootnotes=[]);let a=0,l;return s;function s(m){return e.enter("gfmFootnoteCall"),e.enter("gfmFootnoteCallLabelMarker"),e.consume(m),e.exit("gfmFootnoteCallLabelMarker"),o}function o(m){return m!==94?r(m):(e.enter("gfmFootnoteCallMarker"),e.consume(m),e.exit("gfmFootnoteCallMarker"),e.enter("gfmFootnoteCallString"),e.enter("chunkString").contentType="string",u)}function u(m){if(a>999||m===93&&!l||m===null||m===91||he(m))return r(m);if(m===93){e.exit("chunkString");const d=e.exit("gfmFootnoteCallString");return i.includes(it(n.sliceSerialize(d)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(m),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):r(m)}return he(m)||(l=!0),a++,e.consume(m),m===92?h:u}function h(m){return m===91||m===92||m===93?(e.consume(m),a++,u):u(m)}}function tm(e,t,r){const n=this,i=n.parser.gfmFootnotes||(n.parser.gfmFootnotes=[]);let a,l=0,s;return o;function o(y){return e.enter("gfmFootnoteDefinition")._container=!0,e.enter("gfmFootnoteDefinitionLabel"),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(y),e.exit("gfmFootnoteDefinitionLabelMarker"),u}function u(y){return y===94?(e.enter("gfmFootnoteDefinitionMarker"),e.consume(y),e.exit("gfmFootnoteDefinitionMarker"),e.enter("gfmFootnoteDefinitionLabelString"),e.enter("chunkString").contentType="string",h):r(y)}function h(y){if(l>999||y===93&&!s||y===null||y===91||he(y))return r(y);if(y===93){e.exit("chunkString");const w=e.exit("gfmFootnoteDefinitionLabelString");return a=it(n.sliceSerialize(w)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(y),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),d}return he(y)||(s=!0),l++,e.consume(y),y===92?m:h}function m(y){return y===91||y===92||y===93?(e.consume(y),l++,h):h(y)}function d(y){return y===58?(e.enter("definitionMarker"),e.consume(y),e.exit("definitionMarker"),i.includes(a)||i.push(a),ne(e,p,"gfmFootnoteDefinitionWhitespace")):r(y)}function p(y){return t(y)}}function rm(e,t,r){return e.check(Ar,t,e.attempt(K4,t,r))}function nm(e){e.exit("gfmFootnoteDefinition")}function im(e,t,r){const n=this;return ne(e,i,"gfmFootnoteDefinitionIndent",5);function i(a){const l=n.events[n.events.length-1];return l&&l[1].type==="gfmFootnoteDefinitionIndent"&&l[2].sliceSerialize(l[1],!0).length===4?t(a):r(a)}}function am(e){let r=(e||{}).singleTilde;const n={name:"strikethrough",tokenize:a,resolveAll:i};return r==null&&(r=!0),{text:{126:n},insideSpan:{null:[n]},attentionMarkers:{null:[126]}};function i(l,s){let o=-1;for(;++o1?o(y):(l.consume(y),m++,p);if(m<2&&!r)return o(y);const M=l.exit("strikethroughSequenceTemporary"),S=Qt(y);return M._open=!S||S===2&&!!w,M._close=!w||w===2&&!!S,s(y)}}}class lm{constructor(){this.map=[]}add(t,r,n){sm(this,t,r,n)}consume(t){if(this.map.sort(function(a,l){return a[0]-l[0]}),this.map.length===0)return;let r=this.map.length;const n=[];for(;r>0;)r-=1,n.push(t.slice(this.map[r][0]+this.map[r][1]),this.map[r][2]),t.length=this.map[r][0];n.push(t.slice()),t.length=0;let i=n.pop();for(;i;){for(const a of i)t.push(a);i=n.pop()}this.map.length=0}}function sm(e,t,r,n){let i=0;if(!(r===0&&n.length===0)){for(;i-1;){const Y=n.events[$][1].type;if(Y==="lineEnding"||Y==="linePrefix")$--;else break}const j=$>-1?n.events[$][1].type:null,ie=j==="tableHead"||j==="tableRow"?E:o;return ie===E&&n.parser.lazy[n.now().line]?r(D):ie(D)}function o(D){return e.enter("tableHead"),e.enter("tableRow"),u(D)}function u(D){return D===124||(l=!0,a+=1),h(D)}function h(D){return D===null?r(D):X(D)?a>1?(a=0,n.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(D),e.exit("lineEnding"),p):r(D):le(D)?ne(e,h,"whitespace")(D):(a+=1,l&&(l=!1,i+=1),D===124?(e.enter("tableCellDivider"),e.consume(D),e.exit("tableCellDivider"),l=!0,h):(e.enter("data"),m(D)))}function m(D){return D===null||D===124||he(D)?(e.exit("data"),h(D)):(e.consume(D),D===92?d:m)}function d(D){return D===92||D===124?(e.consume(D),m):m(D)}function p(D){return n.interrupt=!1,n.parser.lazy[n.now().line]?r(D):(e.enter("tableDelimiterRow"),l=!1,le(D)?ne(e,y,"linePrefix",n.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(D):y(D))}function y(D){return D===45||D===58?M(D):D===124?(l=!0,e.enter("tableCellDivider"),e.consume(D),e.exit("tableCellDivider"),w):O(D)}function w(D){return le(D)?ne(e,M,"whitespace")(D):M(D)}function M(D){return D===58?(a+=1,l=!0,e.enter("tableDelimiterMarker"),e.consume(D),e.exit("tableDelimiterMarker"),S):D===45?(a+=1,S(D)):D===null||X(D)?V(D):O(D)}function S(D){return D===45?(e.enter("tableDelimiterFiller"),z(D)):O(D)}function z(D){return D===45?(e.consume(D),z):D===58?(l=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(D),e.exit("tableDelimiterMarker"),I):(e.exit("tableDelimiterFiller"),I(D))}function I(D){return le(D)?ne(e,V,"whitespace")(D):V(D)}function V(D){return D===124?y(D):D===null||X(D)?!l||i!==a?O(D):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(D)):O(D)}function O(D){return r(D)}function E(D){return e.enter("tableRow"),G(D)}function G(D){return D===124?(e.enter("tableCellDivider"),e.consume(D),e.exit("tableCellDivider"),G):D===null||X(D)?(e.exit("tableRow"),t(D)):le(D)?ne(e,G,"whitespace")(D):(e.enter("data"),K(D))}function K(D){return D===null||D===124||he(D)?(e.exit("data"),G(D)):(e.consume(D),D===92?U:K)}function U(D){return D===92||D===124?(e.consume(D),K):K(D)}}function hm(e,t){let r=-1,n=!0,i=0,a=[0,0,0,0],l=[0,0,0,0],s=!1,o=0,u,h,m;const d=new lm;for(;++rr[2]+1){const y=r[2]+1,w=r[3]-r[2]-1;e.add(y,w,[])}}e.add(r[3]+1,0,[["exit",m,t]])}return i!==void 0&&(a.end=Object.assign({},Xt(t.events,i)),e.add(i,0,[["exit",a,t]]),a=void 0),a}function Wi(e,t,r,n,i){const a=[],l=Xt(t.events,r);i&&(i.end=Object.assign({},l),a.push(["exit",i,t])),n.end=Object.assign({},l),a.push(["exit",n,t]),e.add(r+1,0,a)}function Xt(e,t){const r=e[t],n=r[0]==="enter"?"start":"end";return r[1][n]}const mm={name:"tasklistCheck",tokenize:pm};function fm(){return{text:{91:mm}}}function pm(e,t,r){const n=this;return i;function i(o){return n.previous!==null||!n._gfmTasklistFirstContentOfListItem?r(o):(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(o),e.exit("taskListCheckMarker"),a)}function a(o){return he(o)?(e.enter("taskListCheckValueUnchecked"),e.consume(o),e.exit("taskListCheckValueUnchecked"),l):o===88||o===120?(e.enter("taskListCheckValueChecked"),e.consume(o),e.exit("taskListCheckValueChecked"),l):r(o)}function l(o){return o===93?(e.enter("taskListCheckMarker"),e.consume(o),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),s):r(o)}function s(o){return X(o)?t(o):le(o)?e.check({tokenize:dm},t,r)(o):r(o)}}function dm(e,t,r){return ne(e,n,"whitespace");function n(i){return i===null?r(i):t(i)}}function gm(e){return tl([V4(),Z4(),am(e),um(),fm()])}const vm={};function o5(e){const t=this,r=e||vm,n=t.data(),i=n.micromarkExtensions||(n.micromarkExtensions=[]),a=n.fromMarkdownExtensions||(n.fromMarkdownExtensions=[]),l=n.toMarkdownExtensions||(n.toMarkdownExtensions=[]);i.push(gm(r)),a.push(P4()),l.push(O4(r))}function ym(){return{enter:{mathFlow:e,mathFlowFenceMeta:t,mathText:a},exit:{mathFlow:i,mathFlowFence:n,mathFlowFenceMeta:r,mathFlowValue:s,mathText:l,mathTextData:s}};function e(o){const u={type:"element",tagName:"code",properties:{className:["language-math","math-display"]},children:[]};this.enter({type:"math",meta:null,value:"",data:{hName:"pre",hChildren:[u]}},o)}function t(){this.buffer()}function r(){const o=this.resume(),u=this.stack[this.stack.length-1];u.type,u.meta=o}function n(){this.data.mathFlowInside||(this.buffer(),this.data.mathFlowInside=!0)}function i(o){const u=this.resume().replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),h=this.stack[this.stack.length-1];h.type,this.exit(o),h.value=u;const m=h.data.hChildren[0];m.type,m.tagName,m.children.push({type:"text",value:u}),this.data.mathFlowInside=void 0}function a(o){this.enter({type:"inlineMath",value:"",data:{hName:"code",hProperties:{className:["language-math","math-inline"]},hChildren:[]}},o),this.buffer()}function l(o){const u=this.resume(),h=this.stack[this.stack.length-1];h.type,this.exit(o),h.value=u,h.data.hChildren.push({type:"text",value:u})}function s(o){this.config.enter.data.call(this,o),this.config.exit.data.call(this,o)}}function bm(e){let t=(e||{}).singleDollarTextMath;return t==null&&(t=!0),n.peek=i,{unsafe:[{character:"\r",inConstruct:"mathFlowMeta"},{character:` +`,inConstruct:"mathFlowMeta"},{character:"$",after:t?void 0:"\\$",inConstruct:"phrasing"},{character:"$",inConstruct:"mathFlowMeta"},{atBreak:!0,character:"$",after:"\\$"}],handlers:{math:r,inlineMath:n}};function r(a,l,s,o){const u=a.value||"",h=s.createTracker(o),m="$".repeat(Math.max(zl(u,"$")+1,2)),d=s.enter("mathFlow");let p=h.move(m);if(a.meta){const y=s.enter("mathFlowMeta");p+=h.move(s.safe(a.meta,{after:` +`,before:p,encode:["$"],...h.current()})),y()}return p+=h.move(` +`),u&&(p+=h.move(u+` +`)),p+=h.move(m),d(),p}function n(a,l,s){let o=a.value||"",u=1;for(t||u++;new RegExp("(^|[^$])"+"\\$".repeat(u)+"([^$]|$)").test(o);)u++;const h="$".repeat(u);/[^ \r\n]/.test(o)&&(/^[ \r\n]/.test(o)&&/[ \r\n]$/.test(o)||/^\$|\$$/.test(o))&&(o=" "+o+" ");let m=-1;for(;++mu&&(u=h):h&&(u!==void 0&&u>-1&&o.push(` +`.repeat(u)||" "),u=-1,o.push(h))}return o.join("")}function Kl(e,t,r){return e.type==="element"?Zm(e,t,r):e.type==="text"?r.whitespace==="normal"?Zl(e,r):Qm(e):[]}function Zm(e,t,r){const n=Ql(e,r),i=e.children||[];let a=-1,l=[];if(Xm(e))return l;let s,o;for(s0(e)||ra(e)&&Qi(t,e,ra)?o=` +`:Ym(e)?(s=2,o=2):Xl(e)&&(s=1,o=1);++a15?u="…"+s.slice(i-15,i):u=s.slice(0,i);var h;a+15":">","<":"<",'"':""","'":"'"},of=/[&><"']/g;function uf(e){return String(e).replace(of,t=>sf[t])}var Jl=function e(t){return t.type==="ordgroup"||t.type==="color"?t.body.length===1?e(t.body[0]):t:t.type==="font"?e(t.body):t},cf=function(t){var r=Jl(t);return r.type==="mathord"||r.type==="textord"||r.type==="atom"},hf=function(t){if(!t)throw new Error("Expected non-null, but got "+String(t));return t},mf=function(t){var r=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(t);return r?r[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(r[1])?null:r[1].toLowerCase():"_relative"},ue={deflt:nf,escape:uf,hyphenate:lf,getBaseElem:Jl,isCharacterBox:cf,protocolFromUrl:mf},Ur={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand ",cliProcessor:e=>e==="Infinity"?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function ff(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if(typeof r!="string")return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class R0{constructor(t){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,t=t||{};for(var r in Ur)if(Ur.hasOwnProperty(r)){var n=Ur[r];this[r]=t[r]!==void 0?n.processor?n.processor(t[r]):t[r]:ff(n)}}reportNonstrict(t,r,n){var i=this.strict;if(typeof i=="function"&&(i=i(t,r,n)),!(!i||i==="ignore")){if(i===!0||i==="error")throw new L("LaTeX-incompatible input and strict mode is set to 'error': "+(r+" ["+t+"]"),n);i==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+t+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+t+"]"))}}useStrictBehavior(t,r,n){var i=this.strict;if(typeof i=="function")try{i=i(t,r,n)}catch{i="error"}return!i||i==="ignore"?!1:i===!0||i==="error"?!0:i==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+t+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+t+"]")),!1)}isTrusted(t){if(t.url&&!t.protocol){var r=ue.protocolFromUrl(t.url);if(r==null)return!1;t.protocol=r}var n=typeof this.trust=="function"?this.trust(t):this.trust;return!!n}}class Tt{constructor(t,r,n){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=t,this.size=r,this.cramped=n}sup(){return lt[pf[this.id]]}sub(){return lt[df[this.id]]}fracNum(){return lt[gf[this.id]]}fracDen(){return lt[vf[this.id]]}cramp(){return lt[yf[this.id]]}text(){return lt[bf[this.id]]}isTight(){return this.size>=2}}var P0=0,Kr=1,Zt=2,vt=3,wr=4,Ze=5,Jt=6,Fe=7,lt=[new Tt(P0,0,!1),new Tt(Kr,0,!0),new Tt(Zt,1,!1),new Tt(vt,1,!0),new Tt(wr,2,!1),new Tt(Ze,2,!0),new Tt(Jt,3,!1),new Tt(Fe,3,!0)],pf=[wr,Ze,wr,Ze,Jt,Fe,Jt,Fe],df=[Ze,Ze,Ze,Ze,Fe,Fe,Fe,Fe],gf=[Zt,vt,wr,Ze,Jt,Fe,Jt,Fe],vf=[vt,vt,Ze,Ze,Fe,Fe,Fe,Fe],yf=[Kr,Kr,vt,vt,Ze,Ze,Fe,Fe],bf=[P0,Kr,Zt,vt,Zt,vt,Zt,vt],Q={DISPLAY:lt[P0],TEXT:lt[Zt],SCRIPT:lt[wr],SCRIPTSCRIPT:lt[Jt]},o0=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];function xf(e){for(var t=0;t=i[0]&&e<=i[1])return r.name}return null}var _r=[];o0.forEach(e=>e.blocks.forEach(t=>_r.push(...t)));function es(e){for(var t=0;t<_r.length;t+=2)if(e>=_r[t]&&e<=_r[t+1])return!0;return!1}var Yt=80,wf=function(t,r){return"M95,"+(622+t+r)+` +c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14 +c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54 +c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10 +s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429 +c69,-144,104.5,-217.7,106.5,-221 +l`+t/2.075+" -"+t+` +c5.3,-9.3,12,-14,20,-14 +H400000v`+(40+t)+`H845.2724 +s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7 +c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z +M`+(834+t)+" "+r+"h400000v"+(40+t)+"h-400000z"},kf=function(t,r){return"M263,"+(601+t+r)+`c0.7,0,18,39.7,52,119 +c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120 +c340,-704.7,510.7,-1060.3,512,-1067 +l`+t/2.084+" -"+t+` +c4.7,-7.3,11,-11,19,-11 +H40000v`+(40+t)+`H1012.3 +s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232 +c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1 +s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26 +c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z +M`+(1001+t)+" "+r+"h400000v"+(40+t)+"h-400000z"},Sf=function(t,r){return"M983 "+(10+t+r)+` +l`+t/3.13+" -"+t+` +c4,-6.7,10,-10,18,-10 H400000v`+(40+t)+` +H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7 +s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744 +c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30 +c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722 +c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5 +c53.7,-170.3,84.5,-266.8,92.5,-289.5z +M`+(1001+t)+" "+r+"h400000v"+(40+t)+"h-400000z"},Af=function(t,r){return"M424,"+(2398+t+r)+` +c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514 +c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20 +s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121 +s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081 +l`+t/4.223+" -"+t+`c4,-6.7,10,-10,18,-10 H400000 +v`+(40+t)+`H1014.6 +s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185 +c-2,6,-10,9,-24,9 +c-8,0,-12,-0.7,-12,-2z M`+(1001+t)+" "+r+` +h400000v`+(40+t)+"h-400000z"},Tf=function(t,r){return"M473,"+(2713+t+r)+` +c339.3,-1799.3,509.3,-2700,510,-2702 l`+t/5.298+" -"+t+` +c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+t)+`H1017.7 +s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9 +c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200 +c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26 +s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104, +606zM`+(1001+t)+" "+r+"h400000v"+(40+t)+"H1017.7z"},zf=function(t){var r=t/2;return"M400000 "+t+" H0 L"+r+" 0 l65 45 L145 "+(t-80)+" H400000z"},Mf=function(t,r,n){var i=n-54-r-t;return"M702 "+(t+r)+"H400000"+(40+t)+` +H742v`+i+`l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1 +h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170 +c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667 +219 661 l218 661zM702 `+r+"H400000v"+(40+t)+"H742z"},Cf=function(t,r,n){r=1e3*r;var i="";switch(t){case"sqrtMain":i=wf(r,Yt);break;case"sqrtSize1":i=kf(r,Yt);break;case"sqrtSize2":i=Sf(r,Yt);break;case"sqrtSize3":i=Af(r,Yt);break;case"sqrtSize4":i=Tf(r,Yt);break;case"sqrtTall":i=Mf(r,Yt,n)}return i},Ef=function(t,r){switch(t){case"⎜":return"M291 0 H417 V"+r+" H291z M291 0 H417 V"+r+" H291z";case"∣":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z";case"∥":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z"+("M367 0 H410 V"+r+" H367z M367 0 H410 V"+r+" H367z");case"⎟":return"M457 0 H583 V"+r+" H457z M457 0 H583 V"+r+" H457z";case"⎢":return"M319 0 H403 V"+r+" H319z M319 0 H403 V"+r+" H319z";case"⎥":return"M263 0 H347 V"+r+" H263z M263 0 H347 V"+r+" H263z";case"⎪":return"M384 0 H504 V"+r+" H384z M384 0 H504 V"+r+" H384z";case"⏐":return"M312 0 H355 V"+r+" H312z M312 0 H355 V"+r+" H312z";case"‖":return"M257 0 H300 V"+r+" H257z M257 0 H300 V"+r+" H257z"+("M478 0 H521 V"+r+" H478z M478 0 H521 V"+r+" H478z");default:return""}},na={doubleleftarrow:`M262 157 +l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3 + 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28 + 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5 +c2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5 + 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87 +-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7 +-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z +m8 0v40h399730v-40zm0 194v40h399730v-40z`,doublerightarrow:`M399738 392l +-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5 + 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88 +-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68 +-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18 +-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782 +c-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3 +-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z`,leftarrow:`M400000 241H110l3-3c68.7-52.7 113.7-120 + 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8 +-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247 +c-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208 + 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3 + 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202 + l-3-3h399890zM100 241v40h399900v-40z`,leftbrace:`M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117 +-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7 + 5-6 9-10 13-.7 1-7.3 1-20 1H6z`,leftbraceunder:`M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13 + 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688 + 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7 +-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z`,leftgroup:`M400000 80 +H435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0 + 435 0h399565z`,leftgroupunder:`M400000 262 +H435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219 + 435 219h399565z`,leftharpoon:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3 +-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5 +-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7 +-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z`,leftharpoonplus:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5 + 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3 +-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7 +-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z +m0 0v40h400000v-40z`,leftharpoondown:`M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333 + 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5 + 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667 +-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z`,leftharpoondownplus:`M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12 + 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7 +-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0 +v40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,lefthook:`M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5 +-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3 +-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21 + 71.5 23h399859zM103 281v-40h399897v40z`,leftlinesegment:`M40 281 V428 H0 V94 H40 V241 H400000 v40z +M40 281 V428 H0 V94 H40 V241 H400000 v40z`,leftmapsto:`M40 281 V448H0V74H40V241H400000v40z +M40 281 V448H0V74H40V241H400000v40z`,leftToFrom:`M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23 +-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8 +c28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3 + 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,longequal:`M0 50 h400000 v40H0z m0 194h40000v40H0z +M0 50 h400000 v40H0z m0 194h40000v40H0z`,midbrace:`M200428 334 +c-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14 +-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7 + 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11 + 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z`,midbraceunder:`M199572 214 +c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14 + 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3 + 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0 +-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z`,oiintSize1:`M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6 +-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z +m368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8 +60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z`,oiintSize2:`M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8 +-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z +m502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2 +c0 110 84 276 504 276s502.4-166 502.4-276z`,oiiintSize1:`M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6 +-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z +m525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0 +85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z`,oiiintSize2:`M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8 +-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z +m770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1 +c0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z`,rightarrow:`M0 241v40h399891c-47.3 35.3-84 78-110 128 +-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 + 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 + 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85 +-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 +-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 + 151.7 139 205zm0 0v40h399900v-40z`,rightbrace:`M400000 542l +-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5 +s-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1 +c124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z`,rightbraceunder:`M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3 + 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237 +-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z`,rightgroup:`M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0 + 3-1 3-3v-38c-76-158-257-219-435-219H0z`,rightgroupunder:`M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18 + 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z`,rightharpoon:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3 +-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2 +-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 + 69.2 92 94.5zm0 0v40h399900v-40z`,rightharpoonplus:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11 +-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7 + 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z +m0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z`,rightharpoondown:`M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8 + 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5 +-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95 +-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z`,rightharpoondownplus:`M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8 + 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 + 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3 +-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z +m0-194v40h400000v-40zm0 0v40h400000v-40z`,righthook:`M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3 + 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0 +-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21 + 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,rightlinesegment:`M399960 241 V94 h40 V428 h-40 V281 H0 v-40z +M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,rightToFrom:`M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23 + 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32 +-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142 +-167z M100 147v40h399900v-40zM0 341v40h399900v-40z`,twoheadleftarrow:`M0 167c68 40 + 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69 +-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3 +-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19 +-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101 + 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z`,twoheadrightarrow:`M400000 167 +c-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3 + 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42 + 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333 +-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70 + 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z`,tilde1:`M200 55.538c-77 0-168 73.953-177 73.953-3 0-7 +-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0 + 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0 + 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128 +-68.267.847-113-73.952-191-73.952z`,tilde2:`M344 55.266c-142 0-300.638 81.316-311.5 86.418 +-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9 + 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114 +c1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751 + 181.476 676 181.476c-149 0-189-126.21-332-126.21z`,tilde3:`M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457 +-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0 + 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697 + 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696 + -338 0-409-156.573-744-156.573z`,tilde4:`M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345 +-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409 + 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9 + 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409 + -175.236-744-175.236z`,vec:`M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5 +3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11 +10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63 +-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1 +-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59 +H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359 +c-16-25.333-24-45-24-59z`,widehat1:`M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22 +c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,widehat2:`M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10 +-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat3:`M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10 +-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat4:`M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10 +-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widecheck1:`M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1, +-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`,widecheck2:`M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck3:`M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck4:`M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,baraboveleftarrow:`M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202 +c4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5 +c-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130 +s-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47 +121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6 +s2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11 +c0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z +M100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z`,rightarrowabovebar:`M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32 +-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0 +13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39 +-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5 +-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 +-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 +151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z`,baraboveshortleftharpoon:`M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 +c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17 +c2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21 +c-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40 +c-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z +M0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z`,rightharpoonaboveshortbar:`M0,241 l0,40c399126,0,399993,0,399993,0 +c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, +-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 +c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z +M0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z`,shortbaraboveleftharpoon:`M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 +c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9, +1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7, +-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z +M93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z`,shortrightharpoonabovebar:`M53,241l0,40c398570,0,399437,0,399437,0 +c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, +-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 +c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z +M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},Df=function(t,r){switch(t){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v1759 h347 v-84 +H403z M403 1759 V0 H319 V1759 v`+r+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v1759 H0 v84 H347z +M347 1759 V0 H263 V1759 v`+r+" v1759 h84z";case"vert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+" v585 h43z";case"doublevert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+` v585 h43z +M367 15 v585 v`+r+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M410 15 H367 v585 v`+r+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+r+` v1715 h263 v84 H319z +MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+r+` v1799 H0 v-84 H319z +MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v602 h84z +M403 1759 V0 H319 V1759 v`+r+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v602 h84z +M347 1759 V0 h-84 V1759 v`+r+" v602 h84z";case"lparen":return`M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1 +c-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349, +-36,557 l0,`+(r+84)+`c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210, +949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9 +c0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5, +-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189 +l0,-`+(r+92)+`c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3, +-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z`;case"rparen":return`M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3, +63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5 +c11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,`+(r+9)+` +c-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664 +c-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11 +c0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17 +c242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558 +l0,-`+(r+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7, +-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}};class Mr{constructor(t){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=t,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(t){return this.classes.includes(t)}toNode(){for(var t=document.createDocumentFragment(),r=0;rr.toText();return this.children.map(t).join("")}}var st={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},Fr={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},ia={Å:"A",Ð:"D",Þ:"o",å:"a",ð:"d",þ:"o",А:"A",Б:"B",В:"B",Г:"F",Д:"A",Е:"E",Ж:"K",З:"3",И:"N",Й:"N",К:"K",Л:"N",М:"M",Н:"H",О:"O",П:"N",Р:"P",С:"C",Т:"T",У:"y",Ф:"O",Х:"X",Ц:"U",Ч:"h",Ш:"W",Щ:"W",Ъ:"B",Ы:"X",Ь:"B",Э:"3",Ю:"X",Я:"R",а:"a",б:"b",в:"a",г:"r",д:"y",е:"e",ж:"m",з:"e",и:"n",й:"n",к:"n",л:"n",м:"m",н:"n",о:"o",п:"n",р:"p",с:"c",т:"o",у:"y",ф:"b",х:"x",ц:"n",ч:"n",ш:"w",щ:"w",ъ:"a",ы:"m",ь:"a",э:"e",ю:"m",я:"r"};function If(e,t){st[e]=t}function O0(e,t,r){if(!st[t])throw new Error("Font metrics not found for font: "+t+".");var n=e.charCodeAt(0),i=st[t][n];if(!i&&e[0]in ia&&(n=ia[e[0]].charCodeAt(0),i=st[t][n]),!i&&r==="text"&&es(n)&&(i=st[t][77]),i)return{depth:i[0],height:i[1],italic:i[2],skew:i[3],width:i[4]}}var Ln={};function Bf(e){var t;if(e>=5?t=0:e>=3?t=1:t=2,!Ln[t]){var r=Ln[t]={cssEmPerMu:Fr.quad[t]/18};for(var n in Fr)Fr.hasOwnProperty(n)&&(r[n]=Fr[n][t])}return Ln[t]}var Nf=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],aa=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],la=function(t,r){return r.size<2?t:Nf[t-1][r.size-1]};class gt{constructor(t){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=t.style,this.color=t.color,this.size=t.size||gt.BASESIZE,this.textSize=t.textSize||this.size,this.phantom=!!t.phantom,this.font=t.font||"",this.fontFamily=t.fontFamily||"",this.fontWeight=t.fontWeight||"",this.fontShape=t.fontShape||"",this.sizeMultiplier=aa[this.size-1],this.maxSize=t.maxSize,this.minRuleThickness=t.minRuleThickness,this._fontMetrics=void 0}extend(t){var r={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var n in t)t.hasOwnProperty(n)&&(r[n]=t[n]);return new gt(r)}havingStyle(t){return this.style===t?this:this.extend({style:t,size:la(this.textSize,t)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(t){return this.size===t&&this.textSize===t?this:this.extend({style:this.style.text(),size:t,textSize:t,sizeMultiplier:aa[t-1]})}havingBaseStyle(t){t=t||this.style.text();var r=la(gt.BASESIZE,t);return this.size===r&&this.textSize===gt.BASESIZE&&this.style===t?this:this.extend({style:t,size:r})}havingBaseSizing(){var t;switch(this.style.id){case 4:case 5:t=3;break;case 6:case 7:t=1;break;default:t=6}return this.extend({style:this.style.text(),size:t})}withColor(t){return this.extend({color:t})}withPhantom(){return this.extend({phantom:!0})}withFont(t){return this.extend({font:t})}withTextFontFamily(t){return this.extend({fontFamily:t,font:""})}withTextFontWeight(t){return this.extend({fontWeight:t,font:""})}withTextFontShape(t){return this.extend({fontShape:t,font:""})}sizingClasses(t){return t.size!==this.size?["sizing","reset-size"+t.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==gt.BASESIZE?["sizing","reset-size"+this.size,"size"+gt.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=Bf(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}gt.BASESIZE=6;var u0={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},Ff={ex:!0,em:!0,mu:!0},ts=function(t){return typeof t!="string"&&(t=t.unit),t in u0||t in Ff||t==="ex"},ye=function(t,r){var n;if(t.unit in u0)n=u0[t.unit]/r.fontMetrics().ptPerEm/r.sizeMultiplier;else if(t.unit==="mu")n=r.fontMetrics().cssEmPerMu;else{var i;if(r.style.isTight()?i=r.havingStyle(r.style.text()):i=r,t.unit==="ex")n=i.fontMetrics().xHeight;else if(t.unit==="em")n=i.fontMetrics().quad;else throw new L("Invalid unit: '"+t.unit+"'");i!==r&&(n*=i.sizeMultiplier/r.sizeMultiplier)}return Math.min(t.number*n,r.maxSize)},P=function(t){return+t.toFixed(4)+"em"},Ct=function(t){return t.filter(r=>r).join(" ")},rs=function(t,r,n){if(this.classes=t||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=n||{},r){r.style.isTight()&&this.classes.push("mtight");var i=r.getColor();i&&(this.style.color=i)}},ns=function(t){var r=document.createElement(t);r.className=Ct(this.classes);for(var n in this.style)this.style.hasOwnProperty(n)&&(r.style[n]=this.style[n]);for(var i in this.attributes)this.attributes.hasOwnProperty(i)&&r.setAttribute(i,this.attributes[i]);for(var a=0;a/=\x00-\x1f]/,is=function(t){var r="<"+t;this.classes.length&&(r+=' class="'+ue.escape(Ct(this.classes))+'"');var n="";for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=ue.hyphenate(i)+":"+this.style[i]+";");n&&(r+=' style="'+ue.escape(n)+'"');for(var a in this.attributes)if(this.attributes.hasOwnProperty(a)){if(Lf.test(a))throw new L("Invalid attribute name '"+a+"'");r+=" "+a+'="'+ue.escape(this.attributes[a])+'"'}r+=">";for(var l=0;l",r};class Cr{constructor(t,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,rs.call(this,t,n,i),this.children=r||[]}setAttribute(t,r){this.attributes[t]=r}hasClass(t){return this.classes.includes(t)}toNode(){return ns.call(this,"span")}toMarkup(){return is.call(this,"span")}}class q0{constructor(t,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,rs.call(this,r,i),this.children=n||[],this.setAttribute("href",t)}setAttribute(t,r){this.attributes[t]=r}hasClass(t){return this.classes.includes(t)}toNode(){return ns.call(this,"a")}toMarkup(){return is.call(this,"a")}}class Rf{constructor(t,r,n){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=r,this.src=t,this.classes=["mord"],this.style=n}hasClass(t){return this.classes.includes(t)}toNode(){var t=document.createElement("img");t.src=this.src,t.alt=this.alt,t.className="mord";for(var r in this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);return t}toMarkup(){var t=''+ue.escape(this.alt)+'0&&(r=document.createElement("span"),r.style.marginRight=P(this.italic)),this.classes.length>0&&(r=r||document.createElement("span"),r.className=Ct(this.classes));for(var n in this.style)this.style.hasOwnProperty(n)&&(r=r||document.createElement("span"),r.style[n]=this.style[n]);return r?(r.appendChild(t),r):t}toMarkup(){var t=!1,r="0&&(n+="margin-right:"+this.italic+"em;");for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=ue.hyphenate(i)+":"+this.style[i]+";");n&&(t=!0,r+=' style="'+ue.escape(n)+'"');var a=ue.escape(this.text);return t?(r+=">",r+=a,r+="",r):a}}class bt{constructor(t,r){this.children=void 0,this.attributes=void 0,this.children=t||[],this.attributes=r||{}}toNode(){var t="http://www.w3.org/2000/svg",r=document.createElementNS(t,"svg");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);for(var i=0;i':''}}class c0{constructor(t){this.attributes=void 0,this.attributes=t||{}}toNode(){var t="http://www.w3.org/2000/svg",r=document.createElementNS(t,"line");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);return r}toMarkup(){var t=" but got "+String(e)+".")}var qf={bin:1,close:1,inner:1,open:1,punct:1,rel:1},Hf={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},de={math:{},text:{}};function c(e,t,r,n,i,a){de[e][i]={font:t,group:r,replace:n},a&&n&&(de[e][n]=de[e][i])}var f="math",N="text",g="main",b="ams",ge="accent-token",W="bin",Le="close",rr="inner",Z="mathord",Te="op-token",Ye="open",sn="punct",x="rel",St="spacing",T="textord";c(f,g,x,"≡","\\equiv",!0);c(f,g,x,"≺","\\prec",!0);c(f,g,x,"≻","\\succ",!0);c(f,g,x,"∼","\\sim",!0);c(f,g,x,"⊥","\\perp");c(f,g,x,"⪯","\\preceq",!0);c(f,g,x,"⪰","\\succeq",!0);c(f,g,x,"≃","\\simeq",!0);c(f,g,x,"∣","\\mid",!0);c(f,g,x,"≪","\\ll",!0);c(f,g,x,"≫","\\gg",!0);c(f,g,x,"≍","\\asymp",!0);c(f,g,x,"∥","\\parallel");c(f,g,x,"⋈","\\bowtie",!0);c(f,g,x,"⌣","\\smile",!0);c(f,g,x,"⊑","\\sqsubseteq",!0);c(f,g,x,"⊒","\\sqsupseteq",!0);c(f,g,x,"≐","\\doteq",!0);c(f,g,x,"⌢","\\frown",!0);c(f,g,x,"∋","\\ni",!0);c(f,g,x,"∝","\\propto",!0);c(f,g,x,"⊢","\\vdash",!0);c(f,g,x,"⊣","\\dashv",!0);c(f,g,x,"∋","\\owns");c(f,g,sn,".","\\ldotp");c(f,g,sn,"⋅","\\cdotp");c(f,g,T,"#","\\#");c(N,g,T,"#","\\#");c(f,g,T,"&","\\&");c(N,g,T,"&","\\&");c(f,g,T,"ℵ","\\aleph",!0);c(f,g,T,"∀","\\forall",!0);c(f,g,T,"ℏ","\\hbar",!0);c(f,g,T,"∃","\\exists",!0);c(f,g,T,"∇","\\nabla",!0);c(f,g,T,"♭","\\flat",!0);c(f,g,T,"ℓ","\\ell",!0);c(f,g,T,"♮","\\natural",!0);c(f,g,T,"♣","\\clubsuit",!0);c(f,g,T,"℘","\\wp",!0);c(f,g,T,"♯","\\sharp",!0);c(f,g,T,"♢","\\diamondsuit",!0);c(f,g,T,"ℜ","\\Re",!0);c(f,g,T,"♡","\\heartsuit",!0);c(f,g,T,"ℑ","\\Im",!0);c(f,g,T,"♠","\\spadesuit",!0);c(f,g,T,"§","\\S",!0);c(N,g,T,"§","\\S");c(f,g,T,"¶","\\P",!0);c(N,g,T,"¶","\\P");c(f,g,T,"†","\\dag");c(N,g,T,"†","\\dag");c(N,g,T,"†","\\textdagger");c(f,g,T,"‡","\\ddag");c(N,g,T,"‡","\\ddag");c(N,g,T,"‡","\\textdaggerdbl");c(f,g,Le,"⎱","\\rmoustache",!0);c(f,g,Ye,"⎰","\\lmoustache",!0);c(f,g,Le,"⟯","\\rgroup",!0);c(f,g,Ye,"⟮","\\lgroup",!0);c(f,g,W,"∓","\\mp",!0);c(f,g,W,"⊖","\\ominus",!0);c(f,g,W,"⊎","\\uplus",!0);c(f,g,W,"⊓","\\sqcap",!0);c(f,g,W,"∗","\\ast");c(f,g,W,"⊔","\\sqcup",!0);c(f,g,W,"◯","\\bigcirc",!0);c(f,g,W,"∙","\\bullet",!0);c(f,g,W,"‡","\\ddagger");c(f,g,W,"≀","\\wr",!0);c(f,g,W,"⨿","\\amalg");c(f,g,W,"&","\\And");c(f,g,x,"⟵","\\longleftarrow",!0);c(f,g,x,"⇐","\\Leftarrow",!0);c(f,g,x,"⟸","\\Longleftarrow",!0);c(f,g,x,"⟶","\\longrightarrow",!0);c(f,g,x,"⇒","\\Rightarrow",!0);c(f,g,x,"⟹","\\Longrightarrow",!0);c(f,g,x,"↔","\\leftrightarrow",!0);c(f,g,x,"⟷","\\longleftrightarrow",!0);c(f,g,x,"⇔","\\Leftrightarrow",!0);c(f,g,x,"⟺","\\Longleftrightarrow",!0);c(f,g,x,"↦","\\mapsto",!0);c(f,g,x,"⟼","\\longmapsto",!0);c(f,g,x,"↗","\\nearrow",!0);c(f,g,x,"↩","\\hookleftarrow",!0);c(f,g,x,"↪","\\hookrightarrow",!0);c(f,g,x,"↘","\\searrow",!0);c(f,g,x,"↼","\\leftharpoonup",!0);c(f,g,x,"⇀","\\rightharpoonup",!0);c(f,g,x,"↙","\\swarrow",!0);c(f,g,x,"↽","\\leftharpoondown",!0);c(f,g,x,"⇁","\\rightharpoondown",!0);c(f,g,x,"↖","\\nwarrow",!0);c(f,g,x,"⇌","\\rightleftharpoons",!0);c(f,b,x,"≮","\\nless",!0);c(f,b,x,"","\\@nleqslant");c(f,b,x,"","\\@nleqq");c(f,b,x,"⪇","\\lneq",!0);c(f,b,x,"≨","\\lneqq",!0);c(f,b,x,"","\\@lvertneqq");c(f,b,x,"⋦","\\lnsim",!0);c(f,b,x,"⪉","\\lnapprox",!0);c(f,b,x,"⊀","\\nprec",!0);c(f,b,x,"⋠","\\npreceq",!0);c(f,b,x,"⋨","\\precnsim",!0);c(f,b,x,"⪹","\\precnapprox",!0);c(f,b,x,"≁","\\nsim",!0);c(f,b,x,"","\\@nshortmid");c(f,b,x,"∤","\\nmid",!0);c(f,b,x,"⊬","\\nvdash",!0);c(f,b,x,"⊭","\\nvDash",!0);c(f,b,x,"⋪","\\ntriangleleft");c(f,b,x,"⋬","\\ntrianglelefteq",!0);c(f,b,x,"⊊","\\subsetneq",!0);c(f,b,x,"","\\@varsubsetneq");c(f,b,x,"⫋","\\subsetneqq",!0);c(f,b,x,"","\\@varsubsetneqq");c(f,b,x,"≯","\\ngtr",!0);c(f,b,x,"","\\@ngeqslant");c(f,b,x,"","\\@ngeqq");c(f,b,x,"⪈","\\gneq",!0);c(f,b,x,"≩","\\gneqq",!0);c(f,b,x,"","\\@gvertneqq");c(f,b,x,"⋧","\\gnsim",!0);c(f,b,x,"⪊","\\gnapprox",!0);c(f,b,x,"⊁","\\nsucc",!0);c(f,b,x,"⋡","\\nsucceq",!0);c(f,b,x,"⋩","\\succnsim",!0);c(f,b,x,"⪺","\\succnapprox",!0);c(f,b,x,"≆","\\ncong",!0);c(f,b,x,"","\\@nshortparallel");c(f,b,x,"∦","\\nparallel",!0);c(f,b,x,"⊯","\\nVDash",!0);c(f,b,x,"⋫","\\ntriangleright");c(f,b,x,"⋭","\\ntrianglerighteq",!0);c(f,b,x,"","\\@nsupseteqq");c(f,b,x,"⊋","\\supsetneq",!0);c(f,b,x,"","\\@varsupsetneq");c(f,b,x,"⫌","\\supsetneqq",!0);c(f,b,x,"","\\@varsupsetneqq");c(f,b,x,"⊮","\\nVdash",!0);c(f,b,x,"⪵","\\precneqq",!0);c(f,b,x,"⪶","\\succneqq",!0);c(f,b,x,"","\\@nsubseteqq");c(f,b,W,"⊴","\\unlhd");c(f,b,W,"⊵","\\unrhd");c(f,b,x,"↚","\\nleftarrow",!0);c(f,b,x,"↛","\\nrightarrow",!0);c(f,b,x,"⇍","\\nLeftarrow",!0);c(f,b,x,"⇏","\\nRightarrow",!0);c(f,b,x,"↮","\\nleftrightarrow",!0);c(f,b,x,"⇎","\\nLeftrightarrow",!0);c(f,b,x,"△","\\vartriangle");c(f,b,T,"ℏ","\\hslash");c(f,b,T,"▽","\\triangledown");c(f,b,T,"◊","\\lozenge");c(f,b,T,"Ⓢ","\\circledS");c(f,b,T,"®","\\circledR");c(N,b,T,"®","\\circledR");c(f,b,T,"∡","\\measuredangle",!0);c(f,b,T,"∄","\\nexists");c(f,b,T,"℧","\\mho");c(f,b,T,"Ⅎ","\\Finv",!0);c(f,b,T,"⅁","\\Game",!0);c(f,b,T,"‵","\\backprime");c(f,b,T,"▲","\\blacktriangle");c(f,b,T,"▼","\\blacktriangledown");c(f,b,T,"■","\\blacksquare");c(f,b,T,"⧫","\\blacklozenge");c(f,b,T,"★","\\bigstar");c(f,b,T,"∢","\\sphericalangle",!0);c(f,b,T,"∁","\\complement",!0);c(f,b,T,"ð","\\eth",!0);c(N,g,T,"ð","ð");c(f,b,T,"╱","\\diagup");c(f,b,T,"╲","\\diagdown");c(f,b,T,"□","\\square");c(f,b,T,"□","\\Box");c(f,b,T,"◊","\\Diamond");c(f,b,T,"¥","\\yen",!0);c(N,b,T,"¥","\\yen",!0);c(f,b,T,"✓","\\checkmark",!0);c(N,b,T,"✓","\\checkmark");c(f,b,T,"ℶ","\\beth",!0);c(f,b,T,"ℸ","\\daleth",!0);c(f,b,T,"ℷ","\\gimel",!0);c(f,b,T,"ϝ","\\digamma",!0);c(f,b,T,"ϰ","\\varkappa");c(f,b,Ye,"┌","\\@ulcorner",!0);c(f,b,Le,"┐","\\@urcorner",!0);c(f,b,Ye,"└","\\@llcorner",!0);c(f,b,Le,"┘","\\@lrcorner",!0);c(f,b,x,"≦","\\leqq",!0);c(f,b,x,"⩽","\\leqslant",!0);c(f,b,x,"⪕","\\eqslantless",!0);c(f,b,x,"≲","\\lesssim",!0);c(f,b,x,"⪅","\\lessapprox",!0);c(f,b,x,"≊","\\approxeq",!0);c(f,b,W,"⋖","\\lessdot");c(f,b,x,"⋘","\\lll",!0);c(f,b,x,"≶","\\lessgtr",!0);c(f,b,x,"⋚","\\lesseqgtr",!0);c(f,b,x,"⪋","\\lesseqqgtr",!0);c(f,b,x,"≑","\\doteqdot");c(f,b,x,"≓","\\risingdotseq",!0);c(f,b,x,"≒","\\fallingdotseq",!0);c(f,b,x,"∽","\\backsim",!0);c(f,b,x,"⋍","\\backsimeq",!0);c(f,b,x,"⫅","\\subseteqq",!0);c(f,b,x,"⋐","\\Subset",!0);c(f,b,x,"⊏","\\sqsubset",!0);c(f,b,x,"≼","\\preccurlyeq",!0);c(f,b,x,"⋞","\\curlyeqprec",!0);c(f,b,x,"≾","\\precsim",!0);c(f,b,x,"⪷","\\precapprox",!0);c(f,b,x,"⊲","\\vartriangleleft");c(f,b,x,"⊴","\\trianglelefteq");c(f,b,x,"⊨","\\vDash",!0);c(f,b,x,"⊪","\\Vvdash",!0);c(f,b,x,"⌣","\\smallsmile");c(f,b,x,"⌢","\\smallfrown");c(f,b,x,"≏","\\bumpeq",!0);c(f,b,x,"≎","\\Bumpeq",!0);c(f,b,x,"≧","\\geqq",!0);c(f,b,x,"⩾","\\geqslant",!0);c(f,b,x,"⪖","\\eqslantgtr",!0);c(f,b,x,"≳","\\gtrsim",!0);c(f,b,x,"⪆","\\gtrapprox",!0);c(f,b,W,"⋗","\\gtrdot");c(f,b,x,"⋙","\\ggg",!0);c(f,b,x,"≷","\\gtrless",!0);c(f,b,x,"⋛","\\gtreqless",!0);c(f,b,x,"⪌","\\gtreqqless",!0);c(f,b,x,"≖","\\eqcirc",!0);c(f,b,x,"≗","\\circeq",!0);c(f,b,x,"≜","\\triangleq",!0);c(f,b,x,"∼","\\thicksim");c(f,b,x,"≈","\\thickapprox");c(f,b,x,"⫆","\\supseteqq",!0);c(f,b,x,"⋑","\\Supset",!0);c(f,b,x,"⊐","\\sqsupset",!0);c(f,b,x,"≽","\\succcurlyeq",!0);c(f,b,x,"⋟","\\curlyeqsucc",!0);c(f,b,x,"≿","\\succsim",!0);c(f,b,x,"⪸","\\succapprox",!0);c(f,b,x,"⊳","\\vartriangleright");c(f,b,x,"⊵","\\trianglerighteq");c(f,b,x,"⊩","\\Vdash",!0);c(f,b,x,"∣","\\shortmid");c(f,b,x,"∥","\\shortparallel");c(f,b,x,"≬","\\between",!0);c(f,b,x,"⋔","\\pitchfork",!0);c(f,b,x,"∝","\\varpropto");c(f,b,x,"◀","\\blacktriangleleft");c(f,b,x,"∴","\\therefore",!0);c(f,b,x,"∍","\\backepsilon");c(f,b,x,"▶","\\blacktriangleright");c(f,b,x,"∵","\\because",!0);c(f,b,x,"⋘","\\llless");c(f,b,x,"⋙","\\gggtr");c(f,b,W,"⊲","\\lhd");c(f,b,W,"⊳","\\rhd");c(f,b,x,"≂","\\eqsim",!0);c(f,g,x,"⋈","\\Join");c(f,b,x,"≑","\\Doteq",!0);c(f,b,W,"∔","\\dotplus",!0);c(f,b,W,"∖","\\smallsetminus");c(f,b,W,"⋒","\\Cap",!0);c(f,b,W,"⋓","\\Cup",!0);c(f,b,W,"⩞","\\doublebarwedge",!0);c(f,b,W,"⊟","\\boxminus",!0);c(f,b,W,"⊞","\\boxplus",!0);c(f,b,W,"⋇","\\divideontimes",!0);c(f,b,W,"⋉","\\ltimes",!0);c(f,b,W,"⋊","\\rtimes",!0);c(f,b,W,"⋋","\\leftthreetimes",!0);c(f,b,W,"⋌","\\rightthreetimes",!0);c(f,b,W,"⋏","\\curlywedge",!0);c(f,b,W,"⋎","\\curlyvee",!0);c(f,b,W,"⊝","\\circleddash",!0);c(f,b,W,"⊛","\\circledast",!0);c(f,b,W,"⋅","\\centerdot");c(f,b,W,"⊺","\\intercal",!0);c(f,b,W,"⋒","\\doublecap");c(f,b,W,"⋓","\\doublecup");c(f,b,W,"⊠","\\boxtimes",!0);c(f,b,x,"⇢","\\dashrightarrow",!0);c(f,b,x,"⇠","\\dashleftarrow",!0);c(f,b,x,"⇇","\\leftleftarrows",!0);c(f,b,x,"⇆","\\leftrightarrows",!0);c(f,b,x,"⇚","\\Lleftarrow",!0);c(f,b,x,"↞","\\twoheadleftarrow",!0);c(f,b,x,"↢","\\leftarrowtail",!0);c(f,b,x,"↫","\\looparrowleft",!0);c(f,b,x,"⇋","\\leftrightharpoons",!0);c(f,b,x,"↶","\\curvearrowleft",!0);c(f,b,x,"↺","\\circlearrowleft",!0);c(f,b,x,"↰","\\Lsh",!0);c(f,b,x,"⇈","\\upuparrows",!0);c(f,b,x,"↿","\\upharpoonleft",!0);c(f,b,x,"⇃","\\downharpoonleft",!0);c(f,g,x,"⊶","\\origof",!0);c(f,g,x,"⊷","\\imageof",!0);c(f,b,x,"⊸","\\multimap",!0);c(f,b,x,"↭","\\leftrightsquigarrow",!0);c(f,b,x,"⇉","\\rightrightarrows",!0);c(f,b,x,"⇄","\\rightleftarrows",!0);c(f,b,x,"↠","\\twoheadrightarrow",!0);c(f,b,x,"↣","\\rightarrowtail",!0);c(f,b,x,"↬","\\looparrowright",!0);c(f,b,x,"↷","\\curvearrowright",!0);c(f,b,x,"↻","\\circlearrowright",!0);c(f,b,x,"↱","\\Rsh",!0);c(f,b,x,"⇊","\\downdownarrows",!0);c(f,b,x,"↾","\\upharpoonright",!0);c(f,b,x,"⇂","\\downharpoonright",!0);c(f,b,x,"⇝","\\rightsquigarrow",!0);c(f,b,x,"⇝","\\leadsto");c(f,b,x,"⇛","\\Rrightarrow",!0);c(f,b,x,"↾","\\restriction");c(f,g,T,"‘","`");c(f,g,T,"$","\\$");c(N,g,T,"$","\\$");c(N,g,T,"$","\\textdollar");c(f,g,T,"%","\\%");c(N,g,T,"%","\\%");c(f,g,T,"_","\\_");c(N,g,T,"_","\\_");c(N,g,T,"_","\\textunderscore");c(f,g,T,"∠","\\angle",!0);c(f,g,T,"∞","\\infty",!0);c(f,g,T,"′","\\prime");c(f,g,T,"△","\\triangle");c(f,g,T,"Γ","\\Gamma",!0);c(f,g,T,"Δ","\\Delta",!0);c(f,g,T,"Θ","\\Theta",!0);c(f,g,T,"Λ","\\Lambda",!0);c(f,g,T,"Ξ","\\Xi",!0);c(f,g,T,"Π","\\Pi",!0);c(f,g,T,"Σ","\\Sigma",!0);c(f,g,T,"Υ","\\Upsilon",!0);c(f,g,T,"Φ","\\Phi",!0);c(f,g,T,"Ψ","\\Psi",!0);c(f,g,T,"Ω","\\Omega",!0);c(f,g,T,"A","Α");c(f,g,T,"B","Β");c(f,g,T,"E","Ε");c(f,g,T,"Z","Ζ");c(f,g,T,"H","Η");c(f,g,T,"I","Ι");c(f,g,T,"K","Κ");c(f,g,T,"M","Μ");c(f,g,T,"N","Ν");c(f,g,T,"O","Ο");c(f,g,T,"P","Ρ");c(f,g,T,"T","Τ");c(f,g,T,"X","Χ");c(f,g,T,"¬","\\neg",!0);c(f,g,T,"¬","\\lnot");c(f,g,T,"⊤","\\top");c(f,g,T,"⊥","\\bot");c(f,g,T,"∅","\\emptyset");c(f,b,T,"∅","\\varnothing");c(f,g,Z,"α","\\alpha",!0);c(f,g,Z,"β","\\beta",!0);c(f,g,Z,"γ","\\gamma",!0);c(f,g,Z,"δ","\\delta",!0);c(f,g,Z,"ϵ","\\epsilon",!0);c(f,g,Z,"ζ","\\zeta",!0);c(f,g,Z,"η","\\eta",!0);c(f,g,Z,"θ","\\theta",!0);c(f,g,Z,"ι","\\iota",!0);c(f,g,Z,"κ","\\kappa",!0);c(f,g,Z,"λ","\\lambda",!0);c(f,g,Z,"μ","\\mu",!0);c(f,g,Z,"ν","\\nu",!0);c(f,g,Z,"ξ","\\xi",!0);c(f,g,Z,"ο","\\omicron",!0);c(f,g,Z,"π","\\pi",!0);c(f,g,Z,"ρ","\\rho",!0);c(f,g,Z,"σ","\\sigma",!0);c(f,g,Z,"τ","\\tau",!0);c(f,g,Z,"υ","\\upsilon",!0);c(f,g,Z,"ϕ","\\phi",!0);c(f,g,Z,"χ","\\chi",!0);c(f,g,Z,"ψ","\\psi",!0);c(f,g,Z,"ω","\\omega",!0);c(f,g,Z,"ε","\\varepsilon",!0);c(f,g,Z,"ϑ","\\vartheta",!0);c(f,g,Z,"ϖ","\\varpi",!0);c(f,g,Z,"ϱ","\\varrho",!0);c(f,g,Z,"ς","\\varsigma",!0);c(f,g,Z,"φ","\\varphi",!0);c(f,g,W,"∗","*",!0);c(f,g,W,"+","+");c(f,g,W,"−","-",!0);c(f,g,W,"⋅","\\cdot",!0);c(f,g,W,"∘","\\circ",!0);c(f,g,W,"÷","\\div",!0);c(f,g,W,"±","\\pm",!0);c(f,g,W,"×","\\times",!0);c(f,g,W,"∩","\\cap",!0);c(f,g,W,"∪","\\cup",!0);c(f,g,W,"∖","\\setminus",!0);c(f,g,W,"∧","\\land");c(f,g,W,"∨","\\lor");c(f,g,W,"∧","\\wedge",!0);c(f,g,W,"∨","\\vee",!0);c(f,g,T,"√","\\surd");c(f,g,Ye,"⟨","\\langle",!0);c(f,g,Ye,"∣","\\lvert");c(f,g,Ye,"∥","\\lVert");c(f,g,Le,"?","?");c(f,g,Le,"!","!");c(f,g,Le,"⟩","\\rangle",!0);c(f,g,Le,"∣","\\rvert");c(f,g,Le,"∥","\\rVert");c(f,g,x,"=","=");c(f,g,x,":",":");c(f,g,x,"≈","\\approx",!0);c(f,g,x,"≅","\\cong",!0);c(f,g,x,"≥","\\ge");c(f,g,x,"≥","\\geq",!0);c(f,g,x,"←","\\gets");c(f,g,x,">","\\gt",!0);c(f,g,x,"∈","\\in",!0);c(f,g,x,"","\\@not");c(f,g,x,"⊂","\\subset",!0);c(f,g,x,"⊃","\\supset",!0);c(f,g,x,"⊆","\\subseteq",!0);c(f,g,x,"⊇","\\supseteq",!0);c(f,b,x,"⊈","\\nsubseteq",!0);c(f,b,x,"⊉","\\nsupseteq",!0);c(f,g,x,"⊨","\\models");c(f,g,x,"←","\\leftarrow",!0);c(f,g,x,"≤","\\le");c(f,g,x,"≤","\\leq",!0);c(f,g,x,"<","\\lt",!0);c(f,g,x,"→","\\rightarrow",!0);c(f,g,x,"→","\\to");c(f,b,x,"≱","\\ngeq",!0);c(f,b,x,"≰","\\nleq",!0);c(f,g,St," ","\\ ");c(f,g,St," ","\\space");c(f,g,St," ","\\nobreakspace");c(N,g,St," ","\\ ");c(N,g,St," "," ");c(N,g,St," ","\\space");c(N,g,St," ","\\nobreakspace");c(f,g,St,null,"\\nobreak");c(f,g,St,null,"\\allowbreak");c(f,g,sn,",",",");c(f,g,sn,";",";");c(f,b,W,"⊼","\\barwedge",!0);c(f,b,W,"⊻","\\veebar",!0);c(f,g,W,"⊙","\\odot",!0);c(f,g,W,"⊕","\\oplus",!0);c(f,g,W,"⊗","\\otimes",!0);c(f,g,T,"∂","\\partial",!0);c(f,g,W,"⊘","\\oslash",!0);c(f,b,W,"⊚","\\circledcirc",!0);c(f,b,W,"⊡","\\boxdot",!0);c(f,g,W,"△","\\bigtriangleup");c(f,g,W,"▽","\\bigtriangledown");c(f,g,W,"†","\\dagger");c(f,g,W,"⋄","\\diamond");c(f,g,W,"⋆","\\star");c(f,g,W,"◃","\\triangleleft");c(f,g,W,"▹","\\triangleright");c(f,g,Ye,"{","\\{");c(N,g,T,"{","\\{");c(N,g,T,"{","\\textbraceleft");c(f,g,Le,"}","\\}");c(N,g,T,"}","\\}");c(N,g,T,"}","\\textbraceright");c(f,g,Ye,"{","\\lbrace");c(f,g,Le,"}","\\rbrace");c(f,g,Ye,"[","\\lbrack",!0);c(N,g,T,"[","\\lbrack",!0);c(f,g,Le,"]","\\rbrack",!0);c(N,g,T,"]","\\rbrack",!0);c(f,g,Ye,"(","\\lparen",!0);c(f,g,Le,")","\\rparen",!0);c(N,g,T,"<","\\textless",!0);c(N,g,T,">","\\textgreater",!0);c(f,g,Ye,"⌊","\\lfloor",!0);c(f,g,Le,"⌋","\\rfloor",!0);c(f,g,Ye,"⌈","\\lceil",!0);c(f,g,Le,"⌉","\\rceil",!0);c(f,g,T,"\\","\\backslash");c(f,g,T,"∣","|");c(f,g,T,"∣","\\vert");c(N,g,T,"|","\\textbar",!0);c(f,g,T,"∥","\\|");c(f,g,T,"∥","\\Vert");c(N,g,T,"∥","\\textbardbl");c(N,g,T,"~","\\textasciitilde");c(N,g,T,"\\","\\textbackslash");c(N,g,T,"^","\\textasciicircum");c(f,g,x,"↑","\\uparrow",!0);c(f,g,x,"⇑","\\Uparrow",!0);c(f,g,x,"↓","\\downarrow",!0);c(f,g,x,"⇓","\\Downarrow",!0);c(f,g,x,"↕","\\updownarrow",!0);c(f,g,x,"⇕","\\Updownarrow",!0);c(f,g,Te,"∐","\\coprod");c(f,g,Te,"⋁","\\bigvee");c(f,g,Te,"⋀","\\bigwedge");c(f,g,Te,"⨄","\\biguplus");c(f,g,Te,"⋂","\\bigcap");c(f,g,Te,"⋃","\\bigcup");c(f,g,Te,"∫","\\int");c(f,g,Te,"∫","\\intop");c(f,g,Te,"∬","\\iint");c(f,g,Te,"∭","\\iiint");c(f,g,Te,"∏","\\prod");c(f,g,Te,"∑","\\sum");c(f,g,Te,"⨂","\\bigotimes");c(f,g,Te,"⨁","\\bigoplus");c(f,g,Te,"⨀","\\bigodot");c(f,g,Te,"∮","\\oint");c(f,g,Te,"∯","\\oiint");c(f,g,Te,"∰","\\oiiint");c(f,g,Te,"⨆","\\bigsqcup");c(f,g,Te,"∫","\\smallint");c(N,g,rr,"…","\\textellipsis");c(f,g,rr,"…","\\mathellipsis");c(N,g,rr,"…","\\ldots",!0);c(f,g,rr,"…","\\ldots",!0);c(f,g,rr,"⋯","\\@cdots",!0);c(f,g,rr,"⋱","\\ddots",!0);c(f,g,T,"⋮","\\varvdots");c(N,g,T,"⋮","\\varvdots");c(f,g,ge,"ˊ","\\acute");c(f,g,ge,"ˋ","\\grave");c(f,g,ge,"¨","\\ddot");c(f,g,ge,"~","\\tilde");c(f,g,ge,"ˉ","\\bar");c(f,g,ge,"˘","\\breve");c(f,g,ge,"ˇ","\\check");c(f,g,ge,"^","\\hat");c(f,g,ge,"⃗","\\vec");c(f,g,ge,"˙","\\dot");c(f,g,ge,"˚","\\mathring");c(f,g,Z,"","\\@imath");c(f,g,Z,"","\\@jmath");c(f,g,T,"ı","ı");c(f,g,T,"ȷ","ȷ");c(N,g,T,"ı","\\i",!0);c(N,g,T,"ȷ","\\j",!0);c(N,g,T,"ß","\\ss",!0);c(N,g,T,"æ","\\ae",!0);c(N,g,T,"œ","\\oe",!0);c(N,g,T,"ø","\\o",!0);c(N,g,T,"Æ","\\AE",!0);c(N,g,T,"Œ","\\OE",!0);c(N,g,T,"Ø","\\O",!0);c(N,g,ge,"ˊ","\\'");c(N,g,ge,"ˋ","\\`");c(N,g,ge,"ˆ","\\^");c(N,g,ge,"˜","\\~");c(N,g,ge,"ˉ","\\=");c(N,g,ge,"˘","\\u");c(N,g,ge,"˙","\\.");c(N,g,ge,"¸","\\c");c(N,g,ge,"˚","\\r");c(N,g,ge,"ˇ","\\v");c(N,g,ge,"¨",'\\"');c(N,g,ge,"˝","\\H");c(N,g,ge,"◯","\\textcircled");var as={"--":!0,"---":!0,"``":!0,"''":!0};c(N,g,T,"–","--",!0);c(N,g,T,"–","\\textendash");c(N,g,T,"—","---",!0);c(N,g,T,"—","\\textemdash");c(N,g,T,"‘","`",!0);c(N,g,T,"‘","\\textquoteleft");c(N,g,T,"’","'",!0);c(N,g,T,"’","\\textquoteright");c(N,g,T,"“","``",!0);c(N,g,T,"“","\\textquotedblleft");c(N,g,T,"”","''",!0);c(N,g,T,"”","\\textquotedblright");c(f,g,T,"°","\\degree",!0);c(N,g,T,"°","\\degree");c(N,g,T,"°","\\textdegree",!0);c(f,g,T,"£","\\pounds");c(f,g,T,"£","\\mathsterling",!0);c(N,g,T,"£","\\pounds");c(N,g,T,"£","\\textsterling",!0);c(f,b,T,"✠","\\maltese");c(N,b,T,"✠","\\maltese");var oa='0123456789/@."';for(var Rn=0;Rn0)return nt(a,u,i,r,l.concat(h));if(o){var m,d;if(o==="boldsymbol"){var p=$f(a,i,r,l,n);m=p.fontName,d=[p.fontClass]}else s?(m=os[o].fontName,d=[o]):(m=Or(o,r.fontWeight,r.fontShape),d=[o,r.fontWeight,r.fontShape]);if(on(a,m,i).metrics)return nt(a,m,i,r,l.concat(d));if(as.hasOwnProperty(a)&&m.slice(0,10)==="Typewriter"){for(var y=[],w=0;w{if(Ct(e.classes)!==Ct(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(e.classes.length===1){var r=e.classes[0];if(r==="mbin"||r==="mord")return!1}for(var n in e.style)if(e.style.hasOwnProperty(n)&&e.style[n]!==t.style[n])return!1;for(var i in t.style)if(t.style.hasOwnProperty(i)&&e.style[i]!==t.style[i])return!1;return!0},Gf=e=>{for(var t=0;tr&&(r=l.height),l.depth>n&&(n=l.depth),l.maxFontSize>i&&(i=l.maxFontSize)}t.height=r,t.depth=n,t.maxFontSize=i},Oe=function(t,r,n,i){var a=new Cr(t,r,n,i);return H0(a),a},ls=(e,t,r,n)=>new Cr(e,t,r,n),Wf=function(t,r,n){var i=Oe([t],[],r);return i.height=Math.max(n||r.fontMetrics().defaultRuleThickness,r.minRuleThickness),i.style.borderBottomWidth=P(i.height),i.maxFontSize=1,i},Yf=function(t,r,n,i){var a=new q0(t,r,n,i);return H0(a),a},ss=function(t){var r=new Mr(t);return H0(r),r},Xf=function(t,r){return t instanceof Mr?Oe([],[t],r):t},Kf=function(t){if(t.positionType==="individualShift"){for(var r=t.children,n=[r[0]],i=-r[0].shift-r[0].elem.depth,a=i,l=1;l{var r=Oe(["mspace"],[],t),n=ye(e,t);return r.style.marginRight=P(n),r},Or=function(t,r,n){var i="";switch(t){case"amsrm":i="AMS";break;case"textrm":i="Main";break;case"textsf":i="SansSerif";break;case"texttt":i="Typewriter";break;default:i=t}var a;return r==="textbf"&&n==="textit"?a="BoldItalic":r==="textbf"?a="Bold":r==="textit"?a="Italic":a="Regular",i+"-"+a},os={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},us={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Jf=function(t,r){var[n,i,a]=us[t],l=new Et(n),s=new bt([l],{width:P(i),height:P(a),style:"width:"+P(i),viewBox:"0 0 "+1e3*i+" "+1e3*a,preserveAspectRatio:"xMinYMin"}),o=ls(["overlay"],[s],r);return o.height=a,o.style.height=P(a),o.style.width=P(i),o},C={fontMap:os,makeSymbol:nt,mathsym:jf,makeSpan:Oe,makeSvgSpan:ls,makeLineSpan:Wf,makeAnchor:Yf,makeFragment:ss,wrapFragment:Xf,makeVList:Zf,makeOrd:Uf,makeGlue:Qf,staticSvg:Jf,svgData:us,tryCombineChars:Gf},ve={number:3,unit:"mu"},Pt={number:4,unit:"mu"},dt={number:5,unit:"mu"},e2={mord:{mop:ve,mbin:Pt,mrel:dt,minner:ve},mop:{mord:ve,mop:ve,mrel:dt,minner:ve},mbin:{mord:Pt,mop:Pt,mopen:Pt,minner:Pt},mrel:{mord:dt,mop:dt,mopen:dt,minner:dt},mopen:{},mclose:{mop:ve,mbin:Pt,mrel:dt,minner:ve},mpunct:{mord:ve,mop:ve,mrel:dt,mopen:ve,mclose:ve,mpunct:ve,minner:ve},minner:{mord:ve,mop:ve,mbin:Pt,mrel:dt,mopen:ve,mpunct:ve,minner:ve}},t2={mord:{mop:ve},mop:{mord:ve,mop:ve},mbin:{},mrel:{},mopen:{},mclose:{mop:ve},mpunct:{},minner:{mop:ve}},cs={},Qr={},Jr={};function _(e){for(var{type:t,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:l}=e,s={type:t,numArgs:n.numArgs,argTypes:n.argTypes,allowedInArgument:!!n.allowedInArgument,allowedInText:!!n.allowedInText,allowedInMath:n.allowedInMath===void 0?!0:n.allowedInMath,numOptionalArgs:n.numOptionalArgs||0,infix:!!n.infix,primitive:!!n.primitive,handler:i},o=0;o{var M=w.classes[0],S=y.classes[0];M==="mbin"&&n2.includes(S)?w.classes[0]="mord":S==="mbin"&&r2.includes(M)&&(y.classes[0]="mord")},{node:m},d,p),fa(a,(y,w)=>{var M=m0(w),S=m0(y),z=M&&S?y.hasClass("mtight")?t2[M][S]:e2[M][S]:null;if(z)return C.makeGlue(z,u)},{node:m},d,p),a},fa=function e(t,r,n,i,a){i&&t.push(i);for(var l=0;ld=>{t.splice(m+1,0,d),l++})(l)}i&&t.pop()},hs=function(t){return t instanceof Mr||t instanceof q0||t instanceof Cr&&t.hasClass("enclosing")?t:null},l2=function e(t,r){var n=hs(t);if(n){var i=n.children;if(i.length){if(r==="right")return e(i[i.length-1],"right");if(r==="left")return e(i[0],"left")}}return t},m0=function(t,r){return t?(r&&(t=l2(t,r)),a2[t.classes[0]]||null):null},kr=function(t,r){var n=["nulldelimiter"].concat(t.baseSizingClasses());return xt(r.concat(n))},oe=function(t,r,n){if(!t)return xt();if(Qr[t.type]){var i=Qr[t.type](t,r);if(n&&r.size!==n.size){i=xt(r.sizingClasses(n),[i],r);var a=r.sizeMultiplier/n.sizeMultiplier;i.height*=a,i.depth*=a}return i}else throw new L("Got group of unknown type: '"+t.type+"'")};function qr(e,t){var r=xt(["base"],e,t),n=xt(["strut"]);return n.style.height=P(r.height+r.depth),r.depth&&(n.style.verticalAlign=P(-r.depth)),r.children.unshift(n),r}function f0(e,t){var r=null;e.length===1&&e[0].type==="tag"&&(r=e[0].tag,e=e[0].body);var n=ze(e,t,"root"),i;n.length===2&&n[1].hasClass("tag")&&(i=n.pop());for(var a=[],l=[],s=0;s0&&(a.push(qr(l,t)),l=[]),a.push(n[s]));l.length>0&&a.push(qr(l,t));var u;r?(u=qr(ze(r,t,!0)),u.classes=["tag"],a.push(u)):i&&a.push(i);var h=xt(["katex-html"],a);if(h.setAttribute("aria-hidden","true"),u){var m=u.children[0];m.style.height=P(h.height+h.depth),h.depth&&(m.style.verticalAlign=P(-h.depth))}return h}function ms(e){return new Mr(e)}class _e{constructor(t,r,n){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=t,this.attributes={},this.children=r||[],this.classes=n||[]}setAttribute(t,r){this.attributes[t]=r}getAttribute(t){return this.attributes[t]}toNode(){var t=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&t.setAttribute(r,this.attributes[r]);this.classes.length>0&&(t.className=Ct(this.classes));for(var n=0;n0&&(t+=' class ="'+ue.escape(Ct(this.classes))+'"'),t+=">";for(var n=0;n",t}toText(){return this.children.map(t=>t.toText()).join("")}}class ot{constructor(t){this.text=void 0,this.text=t}toNode(){return document.createTextNode(this.text)}toMarkup(){return ue.escape(this.toText())}toText(){return this.text}}class s2{constructor(t){this.width=void 0,this.character=void 0,this.width=t,t>=.05555&&t<=.05556?this.character=" ":t>=.1666&&t<=.1667?this.character=" ":t>=.2222&&t<=.2223?this.character=" ":t>=.2777&&t<=.2778?this.character="  ":t>=-.05556&&t<=-.05555?this.character=" ⁣":t>=-.1667&&t<=-.1666?this.character=" ⁣":t>=-.2223&&t<=-.2222?this.character=" ⁣":t>=-.2778&&t<=-.2777?this.character=" ⁣":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var t=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return t.setAttribute("width",P(this.width)),t}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}}var F={MathNode:_e,TextNode:ot,SpaceNode:s2,newDocumentFragment:ms},Je=function(t,r,n){return de[r][t]&&de[r][t].replace&&t.charCodeAt(0)!==55349&&!(as.hasOwnProperty(t)&&n&&(n.fontFamily&&n.fontFamily.slice(4,6)==="tt"||n.font&&n.font.slice(4,6)==="tt"))&&(t=de[r][t].replace),new F.TextNode(t)},V0=function(t){return t.length===1?t[0]:new F.MathNode("mrow",t)},j0=function(t,r){if(r.fontFamily==="texttt")return"monospace";if(r.fontFamily==="textsf")return r.fontShape==="textit"&&r.fontWeight==="textbf"?"sans-serif-bold-italic":r.fontShape==="textit"?"sans-serif-italic":r.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(r.fontShape==="textit"&&r.fontWeight==="textbf")return"bold-italic";if(r.fontShape==="textit")return"italic";if(r.fontWeight==="textbf")return"bold";var n=r.font;if(!n||n==="mathnormal")return null;var i=t.mode;if(n==="mathit")return"italic";if(n==="boldsymbol")return t.type==="textord"?"bold":"bold-italic";if(n==="mathbf")return"bold";if(n==="mathbb")return"double-struck";if(n==="mathsfit")return"sans-serif-italic";if(n==="mathfrak")return"fraktur";if(n==="mathscr"||n==="mathcal")return"script";if(n==="mathsf")return"sans-serif";if(n==="mathtt")return"monospace";var a=t.text;if(["\\imath","\\jmath"].includes(a))return null;de[i][a]&&de[i][a].replace&&(a=de[i][a].replace);var l=C.fontMap[n].fontName;return O0(a,l,i)?C.fontMap[n].variant:null};function Hn(e){if(!e)return!1;if(e.type==="mi"&&e.children.length===1){var t=e.children[0];return t instanceof ot&&t.text==="."}else if(e.type==="mo"&&e.children.length===1&&e.getAttribute("separator")==="true"&&e.getAttribute("lspace")==="0em"&&e.getAttribute("rspace")==="0em"){var r=e.children[0];return r instanceof ot&&r.text===","}else return!1}var Ve=function(t,r,n){if(t.length===1){var i=me(t[0],r);return n&&i instanceof _e&&i.type==="mo"&&(i.setAttribute("lspace","0em"),i.setAttribute("rspace","0em")),[i]}for(var a=[],l,s=0;s=1&&(l.type==="mn"||Hn(l))){var u=o.children[0];u instanceof _e&&u.type==="mn"&&(u.children=[...l.children,...u.children],a.pop())}else if(l.type==="mi"&&l.children.length===1){var h=l.children[0];if(h instanceof ot&&h.text==="̸"&&(o.type==="mo"||o.type==="mi"||o.type==="mn")){var m=o.children[0];m instanceof ot&&m.text.length>0&&(m.text=m.text.slice(0,1)+"̸"+m.text.slice(1),a.pop())}}}a.push(o),l=o}return a},Dt=function(t,r,n){return V0(Ve(t,r,n))},me=function(t,r){if(!t)return new F.MathNode("mrow");if(Jr[t.type]){var n=Jr[t.type](t,r);return n}else throw new L("Got group of unknown type: '"+t.type+"'")};function pa(e,t,r,n,i){var a=Ve(e,r),l;a.length===1&&a[0]instanceof _e&&["mrow","mtable"].includes(a[0].type)?l=a[0]:l=new F.MathNode("mrow",a);var s=new F.MathNode("annotation",[new F.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var o=new F.MathNode("semantics",[l,s]),u=new F.MathNode("math",[o]);u.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&u.setAttribute("display","block");var h=i?"katex":"katex-mathml";return C.makeSpan([h],[u])}var fs=function(t){return new gt({style:t.displayMode?Q.DISPLAY:Q.TEXT,maxSize:t.maxSize,minRuleThickness:t.minRuleThickness})},ps=function(t,r){if(r.displayMode){var n=["katex-display"];r.leqno&&n.push("leqno"),r.fleqn&&n.push("fleqn"),t=C.makeSpan(n,[t])}return t},o2=function(t,r,n){var i=fs(n),a;if(n.output==="mathml")return pa(t,r,i,n.displayMode,!0);if(n.output==="html"){var l=f0(t,i);a=C.makeSpan(["katex"],[l])}else{var s=pa(t,r,i,n.displayMode,!1),o=f0(t,i);a=C.makeSpan(["katex"],[s,o])}return ps(a,n)},u2=function(t,r,n){var i=fs(n),a=f0(t,i),l=C.makeSpan(["katex"],[a]);return ps(l,n)},c2={widehat:"^",widecheck:"ˇ",widetilde:"~",utilde:"~",overleftarrow:"←",underleftarrow:"←",xleftarrow:"←",overrightarrow:"→",underrightarrow:"→",xrightarrow:"→",underbrace:"⏟",overbrace:"⏞",overgroup:"⏠",undergroup:"⏡",overleftrightarrow:"↔",underleftrightarrow:"↔",xleftrightarrow:"↔",Overrightarrow:"⇒",xRightarrow:"⇒",overleftharpoon:"↼",xleftharpoonup:"↼",overrightharpoon:"⇀",xrightharpoonup:"⇀",xLeftarrow:"⇐",xLeftrightarrow:"⇔",xhookleftarrow:"↩",xhookrightarrow:"↪",xmapsto:"↦",xrightharpoondown:"⇁",xleftharpoondown:"↽",xrightleftharpoons:"⇌",xleftrightharpoons:"⇋",xtwoheadleftarrow:"↞",xtwoheadrightarrow:"↠",xlongequal:"=",xtofrom:"⇄",xrightleftarrows:"⇄",xrightequilibrium:"⇌",xleftequilibrium:"⇋","\\cdrightarrow":"→","\\cdleftarrow":"←","\\cdlongequal":"="},h2=function(t){var r=new F.MathNode("mo",[new F.TextNode(c2[t.replace(/^\\/,"")])]);return r.setAttribute("stretchy","true"),r},m2={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},f2=function(t){return t.type==="ordgroup"?t.body.length:1},p2=function(t,r){function n(){var s=4e5,o=t.label.slice(1);if(["widehat","widecheck","widetilde","utilde"].includes(o)){var u=t,h=f2(u.base),m,d,p;if(h>5)o==="widehat"||o==="widecheck"?(m=420,s=2364,p=.42,d=o+"4"):(m=312,s=2340,p=.34,d="tilde4");else{var y=[1,1,2,2,3,3][h];o==="widehat"||o==="widecheck"?(s=[0,1062,2364,2364,2364][y],m=[0,239,300,360,420][y],p=[0,.24,.3,.3,.36,.42][y],d=o+y):(s=[0,600,1033,2339,2340][y],m=[0,260,286,306,312][y],p=[0,.26,.286,.3,.306,.34][y],d="tilde"+y)}var w=new Et(d),M=new bt([w],{width:"100%",height:P(p),viewBox:"0 0 "+s+" "+m,preserveAspectRatio:"none"});return{span:C.makeSvgSpan([],[M],r),minWidth:0,height:p}}else{var S=[],z=m2[o],[I,V,O]=z,E=O/1e3,G=I.length,K,U;if(G===1){var D=z[3];K=["hide-tail"],U=[D]}else if(G===2)K=["halfarrow-left","halfarrow-right"],U=["xMinYMin","xMaxYMin"];else if(G===3)K=["brace-left","brace-center","brace-right"],U=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support + `+G+" children.");for(var $=0;$0&&(i.style.minWidth=P(a)),i},d2=function(t,r,n,i,a){var l,s=t.height+t.depth+n+i;if(/fbox|color|angl/.test(r)){if(l=C.makeSpan(["stretchy",r],[],a),r==="fbox"){var o=a.color&&a.getColor();o&&(l.style.borderColor=o)}}else{var u=[];/^[bx]cancel$/.test(r)&&u.push(new c0({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(r)&&u.push(new c0({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new bt(u,{width:"100%",height:P(s)});l=C.makeSvgSpan([],[h],a)}return l.height=s,l.style.height=P(s),l},wt={encloseSpan:d2,mathMLnode:h2,svgSpan:p2};function re(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function $0(e){var t=un(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function un(e){return e&&(e.type==="atom"||Hf.hasOwnProperty(e.type))?e:null}var U0=(e,t)=>{var r,n,i;e&&e.type==="supsub"?(n=re(e.base,"accent"),r=n.base,e.base=r,i=Of(oe(e,t)),e.base=n):(n=re(e,"accent"),r=n.base);var a=oe(r,t.havingCrampedStyle()),l=n.isShifty&&ue.isCharacterBox(r),s=0;if(l){var o=ue.getBaseElem(r),u=oe(o,t.havingCrampedStyle());s=sa(u).skew}var h=n.label==="\\c",m=h?a.height+a.depth:Math.min(a.height,t.fontMetrics().xHeight),d;if(n.isStretchy)d=wt.svgSpan(n,t),d=C.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"elem",elem:d,wrapperClasses:["svg-align"],wrapperStyle:s>0?{width:"calc(100% - "+P(2*s)+")",marginLeft:P(2*s)}:void 0}]},t);else{var p,y;n.label==="\\vec"?(p=C.staticSvg("vec",t),y=C.svgData.vec[1]):(p=C.makeOrd({mode:n.mode,text:n.label},t,"textord"),p=sa(p),p.italic=0,y=p.width,h&&(m+=p.depth)),d=C.makeSpan(["accent-body"],[p]);var w=n.label==="\\textcircled";w&&(d.classes.push("accent-full"),m=a.height);var M=s;w||(M-=y/2),d.style.left=P(M),n.label==="\\textcircled"&&(d.style.top=".2em"),d=C.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:-m},{type:"elem",elem:d}]},t)}var S=C.makeSpan(["mord","accent"],[d],t);return i?(i.children[0]=S,i.height=Math.max(S.height,i.height),i.classes[0]="mord",i):S},ds=(e,t)=>{var r=e.isStretchy?wt.mathMLnode(e.label):new F.MathNode("mo",[Je(e.label,e.mode)]),n=new F.MathNode("mover",[me(e.base,t),r]);return n.setAttribute("accent","true"),n},g2=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(e=>"\\"+e).join("|"));_({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{var r=en(t[0]),n=!g2.test(e.funcName),i=!n||e.funcName==="\\widehat"||e.funcName==="\\widetilde"||e.funcName==="\\widecheck";return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:i,base:r}},htmlBuilder:U0,mathmlBuilder:ds});_({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{var r=t[0],n=e.parser.mode;return n==="math"&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:U0,mathmlBuilder:ds});_({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:i}},htmlBuilder:(e,t)=>{var r=oe(e.base,t),n=wt.svgSpan(e,t),i=e.label==="\\utilde"?.12:0,a=C.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:i},{type:"elem",elem:r}]},t);return C.makeSpan(["mord","accentunder"],[a],t)},mathmlBuilder:(e,t)=>{var r=wt.mathMLnode(e.label),n=new F.MathNode("munder",[me(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var Hr=e=>{var t=new F.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};_({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:n,funcName:i}=e;return{type:"xArrow",mode:n.mode,label:i,body:t[0],below:r[0]}},htmlBuilder(e,t){var r=t.style,n=t.havingStyle(r.sup()),i=C.wrapFragment(oe(e.body,n,t),t),a=e.label.slice(0,2)==="\\x"?"x":"cd";i.classes.push(a+"-arrow-pad");var l;e.below&&(n=t.havingStyle(r.sub()),l=C.wrapFragment(oe(e.below,n,t),t),l.classes.push(a+"-arrow-pad"));var s=wt.svgSpan(e,t),o=-t.fontMetrics().axisHeight+.5*s.height,u=-t.fontMetrics().axisHeight-.5*s.height-.111;(i.depth>.25||e.label==="\\xleftequilibrium")&&(u-=i.depth);var h;if(l){var m=-t.fontMetrics().axisHeight+l.height+.5*s.height+.111;h=C.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:u},{type:"elem",elem:s,shift:o},{type:"elem",elem:l,shift:m}]},t)}else h=C.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:u},{type:"elem",elem:s,shift:o}]},t);return h.children[0].children[0].children[1].classes.push("svg-align"),C.makeSpan(["mrel","x-arrow"],[h],t)},mathmlBuilder(e,t){var r=wt.mathMLnode(e.label);r.setAttribute("minsize",e.label.charAt(0)==="x"?"1.75em":"3.0em");var n;if(e.body){var i=Hr(me(e.body,t));if(e.below){var a=Hr(me(e.below,t));n=new F.MathNode("munderover",[r,a,i])}else n=new F.MathNode("mover",[r,i])}else if(e.below){var l=Hr(me(e.below,t));n=new F.MathNode("munder",[r,l])}else n=Hr(),n=new F.MathNode("mover",[r,n]);return n}});var v2=C.makeSpan;function gs(e,t){var r=ze(e.body,t,!0);return v2([e.mclass],r,t)}function vs(e,t){var r,n=Ve(e.body,t);return e.mclass==="minner"?r=new F.MathNode("mpadded",n):e.mclass==="mord"?e.isCharacterBox?(r=n[0],r.type="mi"):r=new F.MathNode("mi",n):(e.isCharacterBox?(r=n[0],r.type="mo"):r=new F.MathNode("mo",n),e.mclass==="mbin"?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):e.mclass==="mpunct"?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):e.mclass==="mopen"||e.mclass==="mclose"?(r.attributes.lspace="0em",r.attributes.rspace="0em"):e.mclass==="minner"&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}_({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){var{parser:r,funcName:n}=e,i=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:we(i),isCharacterBox:ue.isCharacterBox(i)}},htmlBuilder:gs,mathmlBuilder:vs});var cn=e=>{var t=e.type==="ordgroup"&&e.body.length?e.body[0]:e;return t.type==="atom"&&(t.family==="bin"||t.family==="rel")?"m"+t.family:"mord"};_({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){var{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:cn(t[0]),body:we(t[1]),isCharacterBox:ue.isCharacterBox(t[1])}}});_({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){var{parser:r,funcName:n}=e,i=t[1],a=t[0],l;n!=="\\stackrel"?l=cn(i):l="mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:n!=="\\stackrel",body:we(i)},o={type:"supsub",mode:a.mode,base:s,sup:n==="\\underset"?null:a,sub:n==="\\underset"?a:null};return{type:"mclass",mode:r.mode,mclass:l,body:[o],isCharacterBox:ue.isCharacterBox(o)}},htmlBuilder:gs,mathmlBuilder:vs});_({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:cn(t[0]),body:we(t[0])}},htmlBuilder(e,t){var r=ze(e.body,t,!0),n=C.makeSpan([e.mclass],r,t);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder(e,t){var r=Ve(e.body,t),n=new F.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});var y2={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},da=()=>({type:"styling",body:[],mode:"math",style:"display"}),ga=e=>e.type==="textord"&&e.text==="@",b2=(e,t)=>(e.type==="mathord"||e.type==="atom")&&e.text===t;function x2(e,t,r){var n=y2[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":{var i=r.callFunction("\\\\cdleft",[t[0]],[]),a={type:"atom",text:n,mode:"math",family:"rel"},l=r.callFunction("\\Big",[a],[]),s=r.callFunction("\\\\cdright",[t[1]],[]),o={type:"ordgroup",mode:"math",body:[i,l,s]};return r.callFunction("\\\\cdparent",[o],[])}case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var u={type:"textord",text:"\\Vert",mode:"math"};return r.callFunction("\\Big",[u],[])}default:return{type:"textord",text:" ",mode:"math"}}}function w2(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if(r==="&"||r==="\\\\")e.consume();else if(r==="\\end"){t[t.length-1].length===0&&t.pop();break}else throw new L("Expected \\\\ or \\cr or \\end",e.nextToken)}for(var n=[],i=[n],a=0;a-1))if("<>AV".indexOf(u)>-1)for(var m=0;m<2;m++){for(var d=!0,p=o+1;pAV=|." after @',l[o]);var y=x2(u,h,e),w={type:"styling",body:[y],mode:"math",style:"display"};n.push(w),s=da()}a%2===0?n.push(s):n.shift(),n=[],i.push(n)}e.gullet.endGroup(),e.gullet.endGroup();var M=new Array(i[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:i,arraystretch:1,addJot:!0,rowGaps:[null],cols:M,colSeparationType:"CD",hLinesBeforeRow:new Array(i.length+1).fill([])}}_({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:n}=e;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder(e,t){var r=t.havingStyle(t.style.sup()),n=C.wrapFragment(oe(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=P(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder(e,t){var r=new F.MathNode("mrow",[me(e.label,t)]);return r=new F.MathNode("mpadded",[r]),r.setAttribute("width","0"),e.side==="left"&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),r=new F.MathNode("mstyle",[r]),r.setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}});_({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){var{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){var r=C.wrapFragment(oe(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder(e,t){return new F.MathNode("mrow",[me(e.fragment,t)])}});_({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){for(var{parser:r}=e,n=re(t[0],"ordgroup"),i=n.body,a="",l=0;l=1114111)throw new L("\\@char with invalid code point "+a);return o<=65535?u=String.fromCharCode(o):(o-=65536,u=String.fromCharCode((o>>10)+55296,(o&1023)+56320)),{type:"textord",mode:r.mode,text:u}}});var ys=(e,t)=>{var r=ze(e.body,t.withColor(e.color),!1);return C.makeFragment(r)},bs=(e,t)=>{var r=Ve(e.body,t.withColor(e.color)),n=new F.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};_({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){var{parser:r}=e,n=re(t[0],"color-token").color,i=t[1];return{type:"color",mode:r.mode,color:n,body:we(i)}},htmlBuilder:ys,mathmlBuilder:bs});_({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){var{parser:r,breakOnTokenText:n}=e,i=re(t[0],"color-token").color;r.gullet.macros.set("\\current@color",i);var a=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:i,body:a}},htmlBuilder:ys,mathmlBuilder:bs});_({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){var{parser:n}=e,i=n.gullet.future().text==="["?n.parseSizeGroup(!0):null,a=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:a,size:i&&re(i,"size").value}},htmlBuilder(e,t){var r=C.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=P(ye(e.size,t)))),r},mathmlBuilder(e,t){var r=new F.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",P(ye(e.size,t)))),r}});var p0={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},xs=e=>{var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new L("Expected a control sequence",e);return t},k2=e=>{var t=e.gullet.popToken();return t.text==="="&&(t=e.gullet.popToken(),t.text===" "&&(t=e.gullet.popToken())),t},ws=(e,t,r,n)=>{var i=e.gullet.macros.get(r.text);i==null&&(r.noexpand=!0,i={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,i,n)};_({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t,funcName:r}=e;t.consumeSpaces();var n=t.fetch();if(p0[n.text])return(r==="\\global"||r==="\\\\globallong")&&(n.text=p0[n.text]),re(t.parseFunction(),"internal");throw new L("Invalid token after macro prefix",n)}});_({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,n=t.gullet.popToken(),i=n.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new L("Expected a control sequence",n);for(var a=0,l,s=[[]];t.gullet.future().text!=="{";)if(n=t.gullet.popToken(),n.text==="#"){if(t.gullet.future().text==="{"){l=t.gullet.future(),s[a].push("{");break}if(n=t.gullet.popToken(),!/^[1-9]$/.test(n.text))throw new L('Invalid argument number "'+n.text+'"');if(parseInt(n.text)!==a+1)throw new L('Argument number "'+n.text+'" out of order');a++,s.push([])}else{if(n.text==="EOF")throw new L("Expected a macro definition");s[a].push(n.text)}var{tokens:o}=t.gullet.consumeArg();return l&&o.unshift(l),(r==="\\edef"||r==="\\xdef")&&(o=t.gullet.expandTokens(o),o.reverse()),t.gullet.macros.set(i,{tokens:o,numArgs:a,delimiters:s},r===p0[r]),{type:"internal",mode:t.mode}}});_({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,n=xs(t.gullet.popToken());t.gullet.consumeSpaces();var i=k2(t);return ws(t,n,i,r==="\\\\globallet"),{type:"internal",mode:t.mode}}});_({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,n=xs(t.gullet.popToken()),i=t.gullet.popToken(),a=t.gullet.popToken();return ws(t,n,a,r==="\\\\globalfuture"),t.gullet.pushToken(a),t.gullet.pushToken(i),{type:"internal",mode:t.mode}}});var fr=function(t,r,n){var i=de.math[t]&&de.math[t].replace,a=O0(i||t,r,n);if(!a)throw new Error("Unsupported symbol "+t+" and font size "+r+".");return a},_0=function(t,r,n,i){var a=n.havingBaseStyle(r),l=C.makeSpan(i.concat(a.sizingClasses(n)),[t],n),s=a.sizeMultiplier/n.sizeMultiplier;return l.height*=s,l.depth*=s,l.maxFontSize=a.sizeMultiplier,l},ks=function(t,r,n){var i=r.havingBaseStyle(n),a=(1-r.sizeMultiplier/i.sizeMultiplier)*r.fontMetrics().axisHeight;t.classes.push("delimcenter"),t.style.top=P(a),t.height-=a,t.depth+=a},S2=function(t,r,n,i,a,l){var s=C.makeSymbol(t,"Main-Regular",a,i),o=_0(s,r,i,l);return n&&ks(o,i,r),o},A2=function(t,r,n,i){return C.makeSymbol(t,"Size"+r+"-Regular",n,i)},Ss=function(t,r,n,i,a,l){var s=A2(t,r,a,i),o=_0(C.makeSpan(["delimsizing","size"+r],[s],i),Q.TEXT,i,l);return n&&ks(o,i,Q.TEXT),o},Vn=function(t,r,n){var i;r==="Size1-Regular"?i="delim-size1":i="delim-size4";var a=C.makeSpan(["delimsizinginner",i],[C.makeSpan([],[C.makeSymbol(t,r,n)])]);return{type:"elem",elem:a}},jn=function(t,r,n){var i=st["Size4-Regular"][t.charCodeAt(0)]?st["Size4-Regular"][t.charCodeAt(0)][4]:st["Size1-Regular"][t.charCodeAt(0)][4],a=new Et("inner",Ef(t,Math.round(1e3*r))),l=new bt([a],{width:P(i),height:P(r),style:"width:"+P(i),viewBox:"0 0 "+1e3*i+" "+Math.round(1e3*r),preserveAspectRatio:"xMinYMin"}),s=C.makeSvgSpan([],[l],n);return s.height=r,s.style.height=P(r),s.style.width=P(i),{type:"elem",elem:s}},d0=.008,Vr={type:"kern",size:-1*d0},T2=["|","\\lvert","\\rvert","\\vert"],z2=["\\|","\\lVert","\\rVert","\\Vert"],As=function(t,r,n,i,a,l){var s,o,u,h,m="",d=0;s=u=h=t,o=null;var p="Size1-Regular";t==="\\uparrow"?u=h="⏐":t==="\\Uparrow"?u=h="‖":t==="\\downarrow"?s=u="⏐":t==="\\Downarrow"?s=u="‖":t==="\\updownarrow"?(s="\\uparrow",u="⏐",h="\\downarrow"):t==="\\Updownarrow"?(s="\\Uparrow",u="‖",h="\\Downarrow"):T2.includes(t)?(u="∣",m="vert",d=333):z2.includes(t)?(u="∥",m="doublevert",d=556):t==="["||t==="\\lbrack"?(s="⎡",u="⎢",h="⎣",p="Size4-Regular",m="lbrack",d=667):t==="]"||t==="\\rbrack"?(s="⎤",u="⎥",h="⎦",p="Size4-Regular",m="rbrack",d=667):t==="\\lfloor"||t==="⌊"?(u=s="⎢",h="⎣",p="Size4-Regular",m="lfloor",d=667):t==="\\lceil"||t==="⌈"?(s="⎡",u=h="⎢",p="Size4-Regular",m="lceil",d=667):t==="\\rfloor"||t==="⌋"?(u=s="⎥",h="⎦",p="Size4-Regular",m="rfloor",d=667):t==="\\rceil"||t==="⌉"?(s="⎤",u=h="⎥",p="Size4-Regular",m="rceil",d=667):t==="("||t==="\\lparen"?(s="⎛",u="⎜",h="⎝",p="Size4-Regular",m="lparen",d=875):t===")"||t==="\\rparen"?(s="⎞",u="⎟",h="⎠",p="Size4-Regular",m="rparen",d=875):t==="\\{"||t==="\\lbrace"?(s="⎧",o="⎨",h="⎩",u="⎪",p="Size4-Regular"):t==="\\}"||t==="\\rbrace"?(s="⎫",o="⎬",h="⎭",u="⎪",p="Size4-Regular"):t==="\\lgroup"||t==="⟮"?(s="⎧",h="⎩",u="⎪",p="Size4-Regular"):t==="\\rgroup"||t==="⟯"?(s="⎫",h="⎭",u="⎪",p="Size4-Regular"):t==="\\lmoustache"||t==="⎰"?(s="⎧",h="⎭",u="⎪",p="Size4-Regular"):(t==="\\rmoustache"||t==="⎱")&&(s="⎫",h="⎩",u="⎪",p="Size4-Regular");var y=fr(s,p,a),w=y.height+y.depth,M=fr(u,p,a),S=M.height+M.depth,z=fr(h,p,a),I=z.height+z.depth,V=0,O=1;if(o!==null){var E=fr(o,p,a);V=E.height+E.depth,O=2}var G=w+I+V,K=Math.max(0,Math.ceil((r-G)/(O*S))),U=G+K*O*S,D=i.fontMetrics().axisHeight;n&&(D*=i.sizeMultiplier);var $=U/2-D,j=[];if(m.length>0){var ie=U-w-I,Y=Math.round(U*1e3),q=Df(m,Math.round(ie*1e3)),ae=new Et(m,q),fe=(d/1e3).toFixed(3)+"em",Me=(Y/1e3).toFixed(3)+"em",je=new bt([ae],{width:fe,height:Me,viewBox:"0 0 "+d+" "+Y}),k=C.makeSvgSpan([],[je],i);k.height=Y/1e3,k.style.width=fe,k.style.height=Me,j.push({type:"elem",elem:k})}else{if(j.push(Vn(h,p,a)),j.push(Vr),o===null){var ke=U-w-I+2*d0;j.push(jn(u,ke,i))}else{var be=(U-w-I-V)/2+2*d0;j.push(jn(u,be,i)),j.push(Vr),j.push(Vn(o,p,a)),j.push(Vr),j.push(jn(u,be,i))}j.push(Vr),j.push(Vn(s,p,a))}var A=i.havingBaseStyle(Q.TEXT),De=C.makeVList({positionType:"bottom",positionData:$,children:j},A);return _0(C.makeSpan(["delimsizing","mult"],[De],A),Q.TEXT,i,l)},$n=80,Un=.08,_n=function(t,r,n,i,a){var l=Cf(t,i,n),s=new Et(t,l),o=new bt([s],{width:"400em",height:P(r),viewBox:"0 0 400000 "+n,preserveAspectRatio:"xMinYMin slice"});return C.makeSvgSpan(["hide-tail"],[o],a)},M2=function(t,r){var n=r.havingBaseSizing(),i=Cs("\\surd",t*n.sizeMultiplier,Ms,n),a=n.sizeMultiplier,l=Math.max(0,r.minRuleThickness-r.fontMetrics().sqrtRuleThickness),s,o=0,u=0,h=0,m;return i.type==="small"?(h=1e3+1e3*l+$n,t<1?a=1:t<1.4&&(a=.7),o=(1+l+Un)/a,u=(1+l)/a,s=_n("sqrtMain",o,h,l,r),s.style.minWidth="0.853em",m=.833/a):i.type==="large"?(h=(1e3+$n)*vr[i.size],u=(vr[i.size]+l)/a,o=(vr[i.size]+l+Un)/a,s=_n("sqrtSize"+i.size,o,h,l,r),s.style.minWidth="1.02em",m=1/a):(o=t+l+Un,u=t+l,h=Math.floor(1e3*t+l)+$n,s=_n("sqrtTall",o,h,l,r),s.style.minWidth="0.742em",m=1.056),s.height=u,s.style.height=P(o),{span:s,advanceWidth:m,ruleWidth:(r.fontMetrics().sqrtRuleThickness+l)*a}},Ts=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","\\surd"],C2=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱"],zs=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],vr=[0,1.2,1.8,2.4,3],E2=function(t,r,n,i,a){if(t==="<"||t==="\\lt"||t==="⟨"?t="\\langle":(t===">"||t==="\\gt"||t==="⟩")&&(t="\\rangle"),Ts.includes(t)||zs.includes(t))return Ss(t,r,!1,n,i,a);if(C2.includes(t))return As(t,vr[r],!1,n,i,a);throw new L("Illegal delimiter: '"+t+"'")},D2=[{type:"small",style:Q.SCRIPTSCRIPT},{type:"small",style:Q.SCRIPT},{type:"small",style:Q.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],I2=[{type:"small",style:Q.SCRIPTSCRIPT},{type:"small",style:Q.SCRIPT},{type:"small",style:Q.TEXT},{type:"stack"}],Ms=[{type:"small",style:Q.SCRIPTSCRIPT},{type:"small",style:Q.SCRIPT},{type:"small",style:Q.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],B2=function(t){if(t.type==="small")return"Main-Regular";if(t.type==="large")return"Size"+t.size+"-Regular";if(t.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+t.type+"' here.")},Cs=function(t,r,n,i){for(var a=Math.min(2,3-i.style.size),l=a;lr)return n[l]}return n[n.length-1]},Es=function(t,r,n,i,a,l){t==="<"||t==="\\lt"||t==="⟨"?t="\\langle":(t===">"||t==="\\gt"||t==="⟩")&&(t="\\rangle");var s;zs.includes(t)?s=D2:Ts.includes(t)?s=Ms:s=I2;var o=Cs(t,r,s,i);return o.type==="small"?S2(t,o.style,n,i,a,l):o.type==="large"?Ss(t,o.size,n,i,a,l):As(t,r,n,i,a,l)},N2=function(t,r,n,i,a,l){var s=i.fontMetrics().axisHeight*i.sizeMultiplier,o=901,u=5/i.fontMetrics().ptPerEm,h=Math.max(r-s,n+s),m=Math.max(h/500*o,2*h-u);return Es(t,m,!0,i,a,l)},yt={sqrtImage:M2,sizedDelim:E2,sizeToMaxHeight:vr,customSizedDelim:Es,leftRightDelim:N2},va={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},F2=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","<",">","\\langle","⟨","\\rangle","⟩","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function hn(e,t){var r=un(e);if(r&&F2.includes(r.text))return r;throw r?new L("Invalid delimiter '"+r.text+"' after '"+t.funcName+"'",e):new L("Invalid delimiter type '"+e.type+"'",e)}_({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{var r=hn(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:va[e.funcName].size,mclass:va[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>e.delim==="."?C.makeSpan([e.mclass]):yt.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{var t=[];e.delim!=="."&&t.push(Je(e.delim,e.mode));var r=new F.MathNode("mo",t);e.mclass==="mopen"||e.mclass==="mclose"?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=P(yt.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}});function ya(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}_({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=e.parser.gullet.macros.get("\\current@color");if(r&&typeof r!="string")throw new L("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:hn(t[0],e).text,color:r}}});_({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=hn(t[0],e),n=e.parser;++n.leftrightDepth;var i=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var a=re(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:i,left:r.text,right:a.delim,rightColor:a.color}},htmlBuilder:(e,t)=>{ya(e);for(var r=ze(e.body,t,!0,["mopen","mclose"]),n=0,i=0,a=!1,l=0;l{ya(e);var r=Ve(e.body,t);if(e.left!=="."){var n=new F.MathNode("mo",[Je(e.left,e.mode)]);n.setAttribute("fence","true"),r.unshift(n)}if(e.right!=="."){var i=new F.MathNode("mo",[Je(e.right,e.mode)]);i.setAttribute("fence","true"),e.rightColor&&i.setAttribute("mathcolor",e.rightColor),r.push(i)}return V0(r)}});_({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=hn(t[0],e);if(!e.parser.leftrightDepth)throw new L("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{var r;if(e.delim===".")r=kr(t,[]);else{r=yt.sizedDelim(e.delim,1,t,e.mode,[]);var n={delim:e.delim,options:t};r.isMiddle=n}return r},mathmlBuilder:(e,t)=>{var r=e.delim==="\\vert"||e.delim==="|"?Je("|","text"):Je(e.delim,e.mode),n=new F.MathNode("mo",[r]);return n.setAttribute("fence","true"),n.setAttribute("lspace","0.05em"),n.setAttribute("rspace","0.05em"),n}});var G0=(e,t)=>{var r=C.wrapFragment(oe(e.body,t),t),n=e.label.slice(1),i=t.sizeMultiplier,a,l=0,s=ue.isCharacterBox(e.body);if(n==="sout")a=C.makeSpan(["stretchy","sout"]),a.height=t.fontMetrics().defaultRuleThickness/i,l=-.5*t.fontMetrics().xHeight;else if(n==="phase"){var o=ye({number:.6,unit:"pt"},t),u=ye({number:.35,unit:"ex"},t),h=t.havingBaseSizing();i=i/h.sizeMultiplier;var m=r.height+r.depth+o+u;r.style.paddingLeft=P(m/2+o);var d=Math.floor(1e3*m*i),p=zf(d),y=new bt([new Et("phase",p)],{width:"400em",height:P(d/1e3),viewBox:"0 0 400000 "+d,preserveAspectRatio:"xMinYMin slice"});a=C.makeSvgSpan(["hide-tail"],[y],t),a.style.height=P(m),l=r.depth+o+u}else{/cancel/.test(n)?s||r.classes.push("cancel-pad"):n==="angl"?r.classes.push("anglpad"):r.classes.push("boxpad");var w=0,M=0,S=0;/box/.test(n)?(S=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),w=t.fontMetrics().fboxsep+(n==="colorbox"?0:S),M=w):n==="angl"?(S=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness),w=4*S,M=Math.max(0,.25-r.depth)):(w=s?.2:0,M=w),a=wt.encloseSpan(r,n,w,M,t),/fbox|boxed|fcolorbox/.test(n)?(a.style.borderStyle="solid",a.style.borderWidth=P(S)):n==="angl"&&S!==.049&&(a.style.borderTopWidth=P(S),a.style.borderRightWidth=P(S)),l=r.depth+M,e.backgroundColor&&(a.style.backgroundColor=e.backgroundColor,e.borderColor&&(a.style.borderColor=e.borderColor))}var z;if(e.backgroundColor)z=C.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:l},{type:"elem",elem:r,shift:0}]},t);else{var I=/cancel|phase/.test(n)?["svg-align"]:[];z=C.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:0},{type:"elem",elem:a,shift:l,wrapperClasses:I}]},t)}return/cancel/.test(n)&&(z.height=r.height,z.depth=r.depth),/cancel/.test(n)&&!s?C.makeSpan(["mord","cancel-lap"],[z],t):C.makeSpan(["mord"],[z],t)},W0=(e,t)=>{var r=0,n=new F.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[me(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),e.label==="\\fcolorbox"){var i=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+i+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};_({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){var{parser:n,funcName:i}=e,a=re(t[0],"color-token").color,l=t[1];return{type:"enclose",mode:n.mode,label:i,backgroundColor:a,body:l}},htmlBuilder:G0,mathmlBuilder:W0});_({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){var{parser:n,funcName:i}=e,a=re(t[0],"color-token").color,l=re(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:i,backgroundColor:l,borderColor:a,body:s}},htmlBuilder:G0,mathmlBuilder:W0});_({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}});_({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:n}=e,i=t[0];return{type:"enclose",mode:r.mode,label:n,body:i}},htmlBuilder:G0,mathmlBuilder:W0});_({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});var Ds={};function ct(e){for(var{type:t,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:l}=e,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:i},o=0;o{var t=e.parser.settings;if(!t.displayMode)throw new L("{"+e.envName+"} can be used only in display mode.")};function Y0(e){if(e.indexOf("ed")===-1)return e.indexOf("*")===-1}function Bt(e,t,r){var{hskipBeforeAndAfter:n,addJot:i,cols:a,arraystretch:l,colSeparationType:s,autoTag:o,singleRow:u,emptySingleRow:h,maxNumCols:m,leqno:d}=t;if(e.gullet.beginGroup(),u||e.gullet.macros.set("\\cr","\\\\\\relax"),!l){var p=e.gullet.expandMacroAsText("\\arraystretch");if(p==null)l=1;else if(l=parseFloat(p),!l||l<0)throw new L("Invalid \\arraystretch: "+p)}e.gullet.beginGroup();var y=[],w=[y],M=[],S=[],z=o!=null?[]:void 0;function I(){o&&e.gullet.macros.set("\\@eqnsw","1",!0)}function V(){z&&(e.gullet.macros.get("\\df@tag")?(z.push(e.subparse([new We("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):z.push(!!o&&e.gullet.macros.get("\\@eqnsw")==="1"))}for(I(),S.push(ba(e));;){var O=e.parseExpression(!1,u?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),O={type:"ordgroup",mode:e.mode,body:O},r&&(O={type:"styling",mode:e.mode,style:r,body:[O]}),y.push(O);var E=e.fetch().text;if(E==="&"){if(m&&y.length===m){if(u||s)throw new L("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else if(E==="\\end"){V(),y.length===1&&O.type==="styling"&&O.body[0].body.length===0&&(w.length>1||!h)&&w.pop(),S.length0&&(I+=.25),u.push({pos:I,isDashed:Ut[Nt]})}for(V(l[0]),n=0;n0&&($+=z,G<$&&(G=$),$=0)),t.addJot&&(G+=w),K.height=E,K.depth=G,I+=E,K.pos=I,I+=G+$,o[n]=K,V(l[n+1])}var j=I/2+r.fontMetrics().axisHeight,ie=t.cols||[],Y=[],q,ae,fe=[];if(t.tags&&t.tags.some(Ut=>Ut))for(n=0;n=s)){var Xe=void 0;(i>0||t.hskipBeforeAndAfter)&&(Xe=ue.deflt(be.pregap,d),Xe!==0&&(q=C.makeSpan(["arraycolsep"],[]),q.style.width=P(Xe),Y.push(q)));var Ie=[];for(n=0;n0){for(var pn=C.makeLineSpan("hline",r,h),dn=C.makeLineSpan("hdashline",r,h),ir=[{type:"elem",elem:o,shift:0}];u.length>0;){var ar=u.pop(),lr=ar.pos-j;ar.isDashed?ir.push({type:"elem",elem:dn,shift:lr}):ir.push({type:"elem",elem:pn,shift:lr})}o=C.makeVList({positionType:"individualShift",children:ir},r)}if(fe.length===0)return C.makeSpan(["mord"],[o],r);var $t=C.makeVList({positionType:"individualShift",children:fe},r);return $t=C.makeSpan(["tag"],[$t],r),C.makeFragment([o,$t])},L2={c:"center ",l:"left ",r:"right "},mt=function(t,r){for(var n=[],i=new F.MathNode("mtd",[],["mtr-glue"]),a=new F.MathNode("mtd",[],["mml-eqn-num"]),l=0;l0){var y=t.cols,w="",M=!1,S=0,z=y.length;y[0].type==="separator"&&(d+="top ",S=1),y[y.length-1].type==="separator"&&(d+="bottom ",z-=1);for(var I=S;I0?"left ":"",d+=K[K.length-1].length>0?"right ":"";for(var U=1;U-1?"alignat":"align",a=t.envName==="split",l=Bt(t.parser,{cols:n,addJot:!0,autoTag:a?void 0:Y0(t.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:a?2:void 0,leqno:t.parser.settings.leqno},"display"),s,o=0,u={type:"ordgroup",mode:t.mode,body:[]};if(r[0]&&r[0].type==="ordgroup"){for(var h="",m=0;m0&&p&&(M=1),n[y]={type:"align",align:w,pregap:M,postgap:0}}return l.colSeparationType=p?"align":"alignat",l};ct({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){var r=un(t[0]),n=r?[t[0]]:re(t[0],"ordgroup").body,i=n.map(function(l){var s=$0(l),o=s.text;if("lcr".indexOf(o)!==-1)return{type:"align",align:o};if(o==="|")return{type:"separator",separator:"|"};if(o===":")return{type:"separator",separator:":"};throw new L("Unknown column alignment: "+o,l)}),a={cols:i,hskipBeforeAndAfter:!0,maxNumCols:i.length};return Bt(e.parser,a,X0(e.envName))},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",n={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if(e.envName.charAt(e.envName.length-1)==="*"){var i=e.parser;if(i.consumeSpaces(),i.fetch().text==="["){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,"lcr".indexOf(r)===-1)throw new L("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),n.cols=[{type:"align",align:r}]}}var a=Bt(e.parser,n,X0(e.envName)),l=Math.max(0,...a.body.map(s=>s.length));return a.cols=new Array(l).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[a],left:t[0],right:t[1],rightColor:void 0}:a},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){var t={arraystretch:.5},r=Bt(e.parser,t,"script");return r.colSeparationType="small",r},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){var r=un(t[0]),n=r?[t[0]]:re(t[0],"ordgroup").body,i=n.map(function(l){var s=$0(l),o=s.text;if("lc".indexOf(o)!==-1)return{type:"align",align:o};throw new L("Unknown column alignment: "+o,l)});if(i.length>1)throw new L("{subarray} can contain only one column");var a={cols:i,hskipBeforeAndAfter:!1,arraystretch:.5};if(a=Bt(e.parser,a,"script"),a.body.length>0&&a.body[0].length>1)throw new L("{subarray} can contain only one column");return a},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){var t={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},r=Bt(e.parser,t,X0(e.envName));return{type:"leftright",mode:e.mode,body:[r],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Bs,htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){["gather","gather*"].includes(e.envName)&&mn(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Y0(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Bt(e.parser,t,"display")},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Bs,htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){mn(e);var t={autoTag:Y0(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Bt(e.parser,t,"display")},htmlBuilder:ht,mathmlBuilder:mt});ct({type:"array",names:["CD"],props:{numArgs:0},handler(e){return mn(e),w2(e.parser)},htmlBuilder:ht,mathmlBuilder:mt});v("\\nonumber","\\gdef\\@eqnsw{0}");v("\\notag","\\nonumber");_({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(e,t){throw new L(e.funcName+" valid only within array environment")}});var xa=Ds;_({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(e,t){var{parser:r,funcName:n}=e,i=t[0];if(i.type!=="ordgroup")throw new L("Invalid environment name",i);for(var a="",l=0;l{var r=e.font,n=t.withFont(r);return oe(e.body,n)},Fs=(e,t)=>{var r=e.font,n=t.withFont(r);return me(e.body,n)},wa={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};_({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=en(t[0]),a=n;return a in wa&&(a=wa[a]),{type:"font",mode:r.mode,font:a.slice(1),body:i}},htmlBuilder:Ns,mathmlBuilder:Fs});_({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{var{parser:r}=e,n=t[0],i=ue.isCharacterBox(n);return{type:"mclass",mode:r.mode,mclass:cn(n),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:n}],isCharacterBox:i}}});_({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:n,breakOnTokenText:i}=e,{mode:a}=r,l=r.parseExpression(!0,i),s="math"+n.slice(1);return{type:"font",mode:a,font:s,body:{type:"ordgroup",mode:r.mode,body:l}}},htmlBuilder:Ns,mathmlBuilder:Fs});var Ls=(e,t)=>{var r=t;return e==="display"?r=r.id>=Q.SCRIPT.id?r.text():Q.DISPLAY:e==="text"&&r.size===Q.DISPLAY.size?r=Q.TEXT:e==="script"?r=Q.SCRIPT:e==="scriptscript"&&(r=Q.SCRIPTSCRIPT),r},K0=(e,t)=>{var r=Ls(e.size,t.style),n=r.fracNum(),i=r.fracDen(),a;a=t.havingStyle(n);var l=oe(e.numer,a,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,o=3.5/t.fontMetrics().ptPerEm;l.height=l.height0?y=3*d:y=7*d,w=t.fontMetrics().denom1):(m>0?(p=t.fontMetrics().num2,y=d):(p=t.fontMetrics().num3,y=3*d),w=t.fontMetrics().denom2);var M;if(h){var z=t.fontMetrics().axisHeight;p-l.depth-(z+.5*m){var r=new F.MathNode("mfrac",[me(e.numer,t),me(e.denom,t)]);if(!e.hasBarLine)r.setAttribute("linethickness","0px");else if(e.barSize){var n=ye(e.barSize,t);r.setAttribute("linethickness",P(n))}var i=Ls(e.size,t.style);if(i.size!==t.style.size){r=new F.MathNode("mstyle",[r]);var a=i.size===Q.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",a),r.setAttribute("scriptlevel","0")}if(e.leftDelim!=null||e.rightDelim!=null){var l=[];if(e.leftDelim!=null){var s=new F.MathNode("mo",[new F.TextNode(e.leftDelim.replace("\\",""))]);s.setAttribute("fence","true"),l.push(s)}if(l.push(r),e.rightDelim!=null){var o=new F.MathNode("mo",[new F.TextNode(e.rightDelim.replace("\\",""))]);o.setAttribute("fence","true"),l.push(o)}return V0(l)}return r};_({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=t[0],a=t[1],l,s=null,o=null,u="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":l=!0;break;case"\\\\atopfrac":l=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":l=!1,s="(",o=")";break;case"\\\\bracefrac":l=!1,s="\\{",o="\\}";break;case"\\\\brackfrac":l=!1,s="[",o="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":u="display";break;case"\\tfrac":case"\\tbinom":u="text";break}return{type:"genfrac",mode:r.mode,continued:!1,numer:i,denom:a,hasBarLine:l,leftDelim:s,rightDelim:o,size:u,barSize:null}},htmlBuilder:K0,mathmlBuilder:Z0});_({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=t[0],a=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:i,denom:a,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}});_({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){var{parser:t,funcName:r,token:n}=e,i;switch(r){case"\\over":i="\\frac";break;case"\\choose":i="\\binom";break;case"\\atop":i="\\\\atopfrac";break;case"\\brace":i="\\\\bracefrac";break;case"\\brack":i="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:t.mode,replaceWith:i,token:n}}});var ka=["display","text","script","scriptscript"],Sa=function(t){var r=null;return t.length>0&&(r=t,r=r==="."?null:r),r};_({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){var{parser:r}=e,n=t[4],i=t[5],a=en(t[0]),l=a.type==="atom"&&a.family==="open"?Sa(a.text):null,s=en(t[1]),o=s.type==="atom"&&s.family==="close"?Sa(s.text):null,u=re(t[2],"size"),h,m=null;u.isBlank?h=!0:(m=u.value,h=m.number>0);var d="auto",p=t[3];if(p.type==="ordgroup"){if(p.body.length>0){var y=re(p.body[0],"textord");d=ka[Number(y.text)]}}else p=re(p,"textord"),d=ka[Number(p.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:h,barSize:m,leftDelim:l,rightDelim:o,size:d}},htmlBuilder:K0,mathmlBuilder:Z0});_({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){var{parser:r,funcName:n,token:i}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:re(t[0],"size").value,token:i}}});_({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=t[0],a=hf(re(t[1],"infix").size),l=t[2],s=a.number>0;return{type:"genfrac",mode:r.mode,numer:i,denom:l,continued:!1,hasBarLine:s,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:K0,mathmlBuilder:Z0});var Rs=(e,t)=>{var r=t.style,n,i;e.type==="supsub"?(n=e.sup?oe(e.sup,t.havingStyle(r.sup()),t):oe(e.sub,t.havingStyle(r.sub()),t),i=re(e.base,"horizBrace")):i=re(e,"horizBrace");var a=oe(i.base,t.havingBaseStyle(Q.DISPLAY)),l=wt.svgSpan(i,t),s;if(i.isOver?(s=C.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:.1},{type:"elem",elem:l}]},t),s.children[0].children[0].children[1].classes.push("svg-align")):(s=C.makeVList({positionType:"bottom",positionData:a.depth+.1+l.height,children:[{type:"elem",elem:l},{type:"kern",size:.1},{type:"elem",elem:a}]},t),s.children[0].children[0].children[0].classes.push("svg-align")),n){var o=C.makeSpan(["mord",i.isOver?"mover":"munder"],[s],t);i.isOver?s=C.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.2},{type:"elem",elem:n}]},t):s=C.makeVList({positionType:"bottom",positionData:o.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:o}]},t)}return C.makeSpan(["mord",i.isOver?"mover":"munder"],[s],t)},R2=(e,t)=>{var r=wt.mathMLnode(e.label);return new F.MathNode(e.isOver?"mover":"munder",[me(e.base,t),r])};_({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:n}=e;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:Rs,mathmlBuilder:R2});_({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,n=t[1],i=re(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:i})?{type:"href",mode:r.mode,href:i,body:we(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{var r=ze(e.body,t,!1);return C.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{var r=Dt(e.body,t);return r instanceof _e||(r=new _e("mrow",[r])),r.setAttribute("href",e.href),r}});_({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,n=re(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var i=[],a=0;a{var{parser:r,funcName:n,token:i}=e,a=re(t[0],"raw").string,l=t[1];r.settings.strict&&r.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var s,o={};switch(n){case"\\htmlClass":o.class=a,s={command:"\\htmlClass",class:a};break;case"\\htmlId":o.id=a,s={command:"\\htmlId",id:a};break;case"\\htmlStyle":o.style=a,s={command:"\\htmlStyle",style:a};break;case"\\htmlData":{for(var u=a.split(","),h=0;h{var r=ze(e.body,t,!1),n=["enclosing"];e.attributes.class&&n.push(...e.attributes.class.trim().split(/\s+/));var i=C.makeSpan(n,r,t);for(var a in e.attributes)a!=="class"&&e.attributes.hasOwnProperty(a)&&i.setAttribute(a,e.attributes[a]);return i},mathmlBuilder:(e,t)=>Dt(e.body,t)});_({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:we(t[0]),mathml:we(t[1])}},htmlBuilder:(e,t)=>{var r=ze(e.html,t,!1);return C.makeFragment(r)},mathmlBuilder:(e,t)=>Dt(e.mathml,t)});var Gn=function(t){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(t))return{number:+t,unit:"bp"};var r=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(t);if(!r)throw new L("Invalid size: '"+t+"' in \\includegraphics");var n={number:+(r[1]+r[2]),unit:r[3]};if(!ts(n))throw new L("Invalid unit: '"+n.unit+"' in \\includegraphics.");return n};_({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{var{parser:n}=e,i={number:0,unit:"em"},a={number:.9,unit:"em"},l={number:0,unit:"em"},s="";if(r[0])for(var o=re(r[0],"raw").string,u=o.split(","),h=0;h{var r=ye(e.height,t),n=0;e.totalheight.number>0&&(n=ye(e.totalheight,t)-r);var i=0;e.width.number>0&&(i=ye(e.width,t));var a={height:P(r+n)};i>0&&(a.width=P(i)),n>0&&(a.verticalAlign=P(-n));var l=new Rf(e.src,e.alt,a);return l.height=r,l.depth=n,l},mathmlBuilder:(e,t)=>{var r=new F.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=ye(e.height,t),i=0;if(e.totalheight.number>0&&(i=ye(e.totalheight,t)-n,r.setAttribute("valign",P(-i))),r.setAttribute("height",P(n+i)),e.width.number>0){var a=ye(e.width,t);r.setAttribute("width",P(a))}return r.setAttribute("src",e.src),r}});_({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:n}=e,i=re(t[0],"size");if(r.settings.strict){var a=n[1]==="m",l=i.value.unit==="mu";a?(l||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, "+("not "+i.value.unit+" units")),r.mode!=="math"&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):l&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:i.value}},htmlBuilder(e,t){return C.makeGlue(e.dimension,t)},mathmlBuilder(e,t){var r=ye(e.dimension,t);return new F.SpaceNode(r)}});_({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:i}},htmlBuilder:(e,t)=>{var r;e.alignment==="clap"?(r=C.makeSpan([],[oe(e.body,t)]),r=C.makeSpan(["inner"],[r],t)):r=C.makeSpan(["inner"],[oe(e.body,t)]);var n=C.makeSpan(["fix"],[]),i=C.makeSpan([e.alignment],[r,n],t),a=C.makeSpan(["strut"]);return a.style.height=P(i.height+i.depth),i.depth&&(a.style.verticalAlign=P(-i.depth)),i.children.unshift(a),i=C.makeSpan(["thinbox"],[i],t),C.makeSpan(["mord","vbox"],[i],t)},mathmlBuilder:(e,t)=>{var r=new F.MathNode("mpadded",[me(e.body,t)]);if(e.alignment!=="rlap"){var n=e.alignment==="llap"?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}});_({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){var{funcName:r,parser:n}=e,i=n.mode;n.switchMode("math");var a=r==="\\("?"\\)":"$",l=n.parseExpression(!1,a);return n.expect(a),n.switchMode(i),{type:"styling",mode:n.mode,style:"text",body:l}}});_({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new L("Mismatched "+e.funcName)}});var Aa=(e,t)=>{switch(t.style.size){case Q.DISPLAY.size:return e.display;case Q.TEXT.size:return e.text;case Q.SCRIPT.size:return e.script;case Q.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};_({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:we(t[0]),text:we(t[1]),script:we(t[2]),scriptscript:we(t[3])}},htmlBuilder:(e,t)=>{var r=Aa(e,t),n=ze(r,t,!1);return C.makeFragment(n)},mathmlBuilder:(e,t)=>{var r=Aa(e,t);return Dt(r,t)}});var Ps=(e,t,r,n,i,a,l)=>{e=C.makeSpan([],[e]);var s=r&&ue.isCharacterBox(r),o,u;if(t){var h=oe(t,n.havingStyle(i.sup()),n);u={elem:h,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-h.depth)}}if(r){var m=oe(r,n.havingStyle(i.sub()),n);o={elem:m,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-m.height)}}var d;if(u&&o){var p=n.fontMetrics().bigOpSpacing5+o.elem.height+o.elem.depth+o.kern+e.depth+l;d=C.makeVList({positionType:"bottom",positionData:p,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:o.elem,marginLeft:P(-a)},{type:"kern",size:o.kern},{type:"elem",elem:e},{type:"kern",size:u.kern},{type:"elem",elem:u.elem,marginLeft:P(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(o){var y=e.height-l;d=C.makeVList({positionType:"top",positionData:y,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:o.elem,marginLeft:P(-a)},{type:"kern",size:o.kern},{type:"elem",elem:e}]},n)}else if(u){var w=e.depth+l;d=C.makeVList({positionType:"bottom",positionData:w,children:[{type:"elem",elem:e},{type:"kern",size:u.kern},{type:"elem",elem:u.elem,marginLeft:P(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else return e;var M=[d];if(o&&a!==0&&!s){var S=C.makeSpan(["mspace"],[],n);S.style.marginRight=P(a),M.unshift(S)}return C.makeSpan(["mop","op-limits"],M,n)},Os=["\\smallint"],nr=(e,t)=>{var r,n,i=!1,a;e.type==="supsub"?(r=e.sup,n=e.sub,a=re(e.base,"op"),i=!0):a=re(e,"op");var l=t.style,s=!1;l.size===Q.DISPLAY.size&&a.symbol&&!Os.includes(a.name)&&(s=!0);var o;if(a.symbol){var u=s?"Size2-Regular":"Size1-Regular",h="";if((a.name==="\\oiint"||a.name==="\\oiiint")&&(h=a.name.slice(1),a.name=h==="oiint"?"\\iint":"\\iiint"),o=C.makeSymbol(a.name,u,"math",t,["mop","op-symbol",s?"large-op":"small-op"]),h.length>0){var m=o.italic,d=C.staticSvg(h+"Size"+(s?"2":"1"),t);o=C.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:d,shift:s?.08:0}]},t),a.name="\\"+h,o.classes.unshift("mop"),o.italic=m}}else if(a.body){var p=ze(a.body,t,!0);p.length===1&&p[0]instanceof Qe?(o=p[0],o.classes[0]="mop"):o=C.makeSpan(["mop"],p,t)}else{for(var y=[],w=1;w{var r;if(e.symbol)r=new _e("mo",[Je(e.name,e.mode)]),Os.includes(e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new _e("mo",Ve(e.body,t));else{r=new _e("mi",[new ot(e.name.slice(1))]);var n=new _e("mo",[Je("⁡","text")]);e.parentIsSupSub?r=new _e("mrow",[r,n]):r=ms([r,n])}return r},P2={"∏":"\\prod","∐":"\\coprod","∑":"\\sum","⋀":"\\bigwedge","⋁":"\\bigvee","⋂":"\\bigcap","⋃":"\\bigcup","⨀":"\\bigodot","⨁":"\\bigoplus","⨂":"\\bigotimes","⨄":"\\biguplus","⨆":"\\bigsqcup"};_({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","∏","∐","∑","⋀","⋁","⋂","⋃","⨀","⨁","⨂","⨄","⨆"],props:{numArgs:0},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=n;return i.length===1&&(i=P2[i]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:i}},htmlBuilder:nr,mathmlBuilder:Er});_({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var{parser:r}=e,n=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:we(n)}},htmlBuilder:nr,mathmlBuilder:Er});var O2={"∫":"\\int","∬":"\\iint","∭":"\\iiint","∮":"\\oint","∯":"\\oiint","∰":"\\oiiint"};_({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:nr,mathmlBuilder:Er});_({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:nr,mathmlBuilder:Er});_({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","∫","∬","∭","∮","∯","∰"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e,n=r;return n.length===1&&(n=O2[n]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:nr,mathmlBuilder:Er});var qs=(e,t)=>{var r,n,i=!1,a;e.type==="supsub"?(r=e.sup,n=e.sub,a=re(e.base,"operatorname"),i=!0):a=re(e,"operatorname");var l;if(a.body.length>0){for(var s=a.body.map(m=>{var d=m.text;return typeof d=="string"?{type:"textord",mode:m.mode,text:d}:m}),o=ze(s,t.withFont("mathrm"),!0),u=0;u{for(var r=Ve(e.body,t.withFont("mathrm")),n=!0,i=0;ih.toText()).join("");r=[new F.TextNode(s)]}var o=new F.MathNode("mi",r);o.setAttribute("mathvariant","normal");var u=new F.MathNode("mo",[Je("⁡","text")]);return e.parentIsSupSub?new F.MathNode("mrow",[o,u]):F.newDocumentFragment([o,u])};_({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:n}=e,i=t[0];return{type:"operatorname",mode:r.mode,body:we(i),alwaysHandleSupSub:n==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},htmlBuilder:qs,mathmlBuilder:q2});v("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");Vt({type:"ordgroup",htmlBuilder(e,t){return e.semisimple?C.makeFragment(ze(e.body,t,!1)):C.makeSpan(["mord"],ze(e.body,t,!0),t)},mathmlBuilder(e,t){return Dt(e.body,t,!0)}});_({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){var{parser:r}=e,n=t[0];return{type:"overline",mode:r.mode,body:n}},htmlBuilder(e,t){var r=oe(e.body,t.havingCrampedStyle()),n=C.makeLineSpan("overline-line",t),i=t.fontMetrics().defaultRuleThickness,a=C.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*i},{type:"elem",elem:n},{type:"kern",size:i}]},t);return C.makeSpan(["mord","overline"],[a],t)},mathmlBuilder(e,t){var r=new F.MathNode("mo",[new F.TextNode("‾")]);r.setAttribute("stretchy","true");var n=new F.MathNode("mover",[me(e.body,t),r]);return n.setAttribute("accent","true"),n}});_({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,n=t[0];return{type:"phantom",mode:r.mode,body:we(n)}},htmlBuilder:(e,t)=>{var r=ze(e.body,t.withPhantom(),!1);return C.makeFragment(r)},mathmlBuilder:(e,t)=>{var r=Ve(e.body,t);return new F.MathNode("mphantom",r)}});_({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,n=t[0];return{type:"hphantom",mode:r.mode,body:n}},htmlBuilder:(e,t)=>{var r=C.makeSpan([],[oe(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var n=0;n{var r=Ve(we(e.body),t),n=new F.MathNode("mphantom",r),i=new F.MathNode("mpadded",[n]);return i.setAttribute("height","0px"),i.setAttribute("depth","0px"),i}});_({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,n=t[0];return{type:"vphantom",mode:r.mode,body:n}},htmlBuilder:(e,t)=>{var r=C.makeSpan(["inner"],[oe(e.body,t.withPhantom())]),n=C.makeSpan(["fix"],[]);return C.makeSpan(["mord","rlap"],[r,n],t)},mathmlBuilder:(e,t)=>{var r=Ve(we(e.body),t),n=new F.MathNode("mphantom",r),i=new F.MathNode("mpadded",[n]);return i.setAttribute("width","0px"),i}});_({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e,n=re(t[0],"size").value,i=t[1];return{type:"raisebox",mode:r.mode,dy:n,body:i}},htmlBuilder(e,t){var r=oe(e.body,t),n=ye(e.dy,t);return C.makeVList({positionType:"shift",positionData:-n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){var r=new F.MathNode("mpadded",[me(e.body,t)]),n=e.dy.number+e.dy.unit;return r.setAttribute("voffset",n),r}});_({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(e){var{parser:t}=e;return{type:"internal",mode:t.mode}}});_({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(e,t,r){var{parser:n}=e,i=r[0],a=re(t[0],"size"),l=re(t[1],"size");return{type:"rule",mode:n.mode,shift:i&&re(i,"size").value,width:a.value,height:l.value}},htmlBuilder(e,t){var r=C.makeSpan(["mord","rule"],[],t),n=ye(e.width,t),i=ye(e.height,t),a=e.shift?ye(e.shift,t):0;return r.style.borderRightWidth=P(n),r.style.borderTopWidth=P(i),r.style.bottom=P(a),r.width=n,r.height=i+a,r.depth=-a,r.maxFontSize=i*1.125*t.sizeMultiplier,r},mathmlBuilder(e,t){var r=ye(e.width,t),n=ye(e.height,t),i=e.shift?ye(e.shift,t):0,a=t.color&&t.getColor()||"black",l=new F.MathNode("mspace");l.setAttribute("mathbackground",a),l.setAttribute("width",P(r)),l.setAttribute("height",P(n));var s=new F.MathNode("mpadded",[l]);return i>=0?s.setAttribute("height",P(i)):(s.setAttribute("height",P(i)),s.setAttribute("depth",P(-i))),s.setAttribute("voffset",P(i)),s}});function Hs(e,t,r){for(var n=ze(e,t,!1),i=t.sizeMultiplier/r.sizeMultiplier,a=0;a{var r=t.havingSize(e.size);return Hs(e.body,r,t)};_({type:"sizing",names:Ta,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{breakOnTokenText:r,funcName:n,parser:i}=e,a=i.parseExpression(!1,r);return{type:"sizing",mode:i.mode,size:Ta.indexOf(n)+1,body:a}},htmlBuilder:H2,mathmlBuilder:(e,t)=>{var r=t.havingSize(e.size),n=Ve(e.body,r),i=new F.MathNode("mstyle",n);return i.setAttribute("mathsize",P(r.sizeMultiplier)),i}});_({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{var{parser:n}=e,i=!1,a=!1,l=r[0]&&re(r[0],"ordgroup");if(l)for(var s="",o=0;o{var r=C.makeSpan([],[oe(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(var n=0;n{var r=new F.MathNode("mpadded",[me(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}});_({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:n}=e,i=r[0],a=t[0];return{type:"sqrt",mode:n.mode,body:a,index:i}},htmlBuilder(e,t){var r=oe(e.body,t.havingCrampedStyle());r.height===0&&(r.height=t.fontMetrics().xHeight),r=C.wrapFragment(r,t);var n=t.fontMetrics(),i=n.defaultRuleThickness,a=i;t.style.idr.height+r.depth+l&&(l=(l+m-r.height-r.depth)/2);var d=o.height-r.height-l-u;r.style.paddingLeft=P(h);var p=C.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+d)},{type:"elem",elem:o},{type:"kern",size:u}]},t);if(e.index){var y=t.havingStyle(Q.SCRIPTSCRIPT),w=oe(e.index,y,t),M=.6*(p.height-p.depth),S=C.makeVList({positionType:"shift",positionData:-M,children:[{type:"elem",elem:w}]},t),z=C.makeSpan(["root"],[S]);return C.makeSpan(["mord","sqrt"],[z,p],t)}else return C.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){var{body:r,index:n}=e;return n?new F.MathNode("mroot",[me(r,t),me(n,t)]):new F.MathNode("msqrt",[me(r,t)])}});var za={display:Q.DISPLAY,text:Q.TEXT,script:Q.SCRIPT,scriptscript:Q.SCRIPTSCRIPT};_({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){var{breakOnTokenText:r,funcName:n,parser:i}=e,a=i.parseExpression(!0,r),l=n.slice(1,n.length-5);return{type:"styling",mode:i.mode,style:l,body:a}},htmlBuilder(e,t){var r=za[e.style],n=t.havingStyle(r).withFont("");return Hs(e.body,n,t)},mathmlBuilder(e,t){var r=za[e.style],n=t.havingStyle(r),i=Ve(e.body,n),a=new F.MathNode("mstyle",i),l={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},s=l[e.style];return a.setAttribute("scriptlevel",s[0]),a.setAttribute("displaystyle",s[1]),a}});var V2=function(t,r){var n=t.base;if(n)if(n.type==="op"){var i=n.limits&&(r.style.size===Q.DISPLAY.size||n.alwaysHandleSupSub);return i?nr:null}else if(n.type==="operatorname"){var a=n.alwaysHandleSupSub&&(r.style.size===Q.DISPLAY.size||n.limits);return a?qs:null}else{if(n.type==="accent")return ue.isCharacterBox(n.base)?U0:null;if(n.type==="horizBrace"){var l=!t.sub;return l===n.isOver?Rs:null}else return null}else return null};Vt({type:"supsub",htmlBuilder(e,t){var r=V2(e,t);if(r)return r(e,t);var{base:n,sup:i,sub:a}=e,l=oe(n,t),s,o,u=t.fontMetrics(),h=0,m=0,d=n&&ue.isCharacterBox(n);if(i){var p=t.havingStyle(t.style.sup());s=oe(i,p,t),d||(h=l.height-p.fontMetrics().supDrop*p.sizeMultiplier/t.sizeMultiplier)}if(a){var y=t.havingStyle(t.style.sub());o=oe(a,y,t),d||(m=l.depth+y.fontMetrics().subDrop*y.sizeMultiplier/t.sizeMultiplier)}var w;t.style===Q.DISPLAY?w=u.sup1:t.style.cramped?w=u.sup3:w=u.sup2;var M=t.sizeMultiplier,S=P(.5/u.ptPerEm/M),z=null;if(o){var I=e.base&&e.base.type==="op"&&e.base.name&&(e.base.name==="\\oiint"||e.base.name==="\\oiiint");(l instanceof Qe||I)&&(z=P(-l.italic))}var V;if(s&&o){h=Math.max(h,w,s.depth+.25*u.xHeight),m=Math.max(m,u.sub2);var O=u.defaultRuleThickness,E=4*O;if(h-s.depth-(o.height-m)0&&(h+=G,m-=G)}var K=[{type:"elem",elem:o,shift:m,marginRight:S,marginLeft:z},{type:"elem",elem:s,shift:-h,marginRight:S}];V=C.makeVList({positionType:"individualShift",children:K},t)}else if(o){m=Math.max(m,u.sub1,o.height-.8*u.xHeight);var U=[{type:"elem",elem:o,marginLeft:z,marginRight:S}];V=C.makeVList({positionType:"shift",positionData:m,children:U},t)}else if(s)h=Math.max(h,w,s.depth+.25*u.xHeight),V=C.makeVList({positionType:"shift",positionData:-h,children:[{type:"elem",elem:s,marginRight:S}]},t);else throw new Error("supsub must have either sup or sub.");var D=m0(l,"right")||"mord";return C.makeSpan([D],[l,C.makeSpan(["msupsub"],[V])],t)},mathmlBuilder(e,t){var r=!1,n,i;e.base&&e.base.type==="horizBrace"&&(i=!!e.sup,i===e.base.isOver&&(r=!0,n=e.base.isOver)),e.base&&(e.base.type==="op"||e.base.type==="operatorname")&&(e.base.parentIsSupSub=!0);var a=[me(e.base,t)];e.sub&&a.push(me(e.sub,t)),e.sup&&a.push(me(e.sup,t));var l;if(r)l=n?"mover":"munder";else if(e.sub)if(e.sup){var u=e.base;u&&u.type==="op"&&u.limits&&t.style===Q.DISPLAY||u&&u.type==="operatorname"&&u.alwaysHandleSupSub&&(t.style===Q.DISPLAY||u.limits)?l="munderover":l="msubsup"}else{var o=e.base;o&&o.type==="op"&&o.limits&&(t.style===Q.DISPLAY||o.alwaysHandleSupSub)||o&&o.type==="operatorname"&&o.alwaysHandleSupSub&&(o.limits||t.style===Q.DISPLAY)?l="munder":l="msub"}else{var s=e.base;s&&s.type==="op"&&s.limits&&(t.style===Q.DISPLAY||s.alwaysHandleSupSub)||s&&s.type==="operatorname"&&s.alwaysHandleSupSub&&(s.limits||t.style===Q.DISPLAY)?l="mover":l="msup"}return new F.MathNode(l,a)}});Vt({type:"atom",htmlBuilder(e,t){return C.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder(e,t){var r=new F.MathNode("mo",[Je(e.text,e.mode)]);if(e.family==="bin"){var n=j0(e,t);n==="bold-italic"&&r.setAttribute("mathvariant",n)}else e.family==="punct"?r.setAttribute("separator","true"):(e.family==="open"||e.family==="close")&&r.setAttribute("stretchy","false");return r}});var Vs={mi:"italic",mn:"normal",mtext:"normal"};Vt({type:"mathord",htmlBuilder(e,t){return C.makeOrd(e,t,"mathord")},mathmlBuilder(e,t){var r=new F.MathNode("mi",[Je(e.text,e.mode,t)]),n=j0(e,t)||"italic";return n!==Vs[r.type]&&r.setAttribute("mathvariant",n),r}});Vt({type:"textord",htmlBuilder(e,t){return C.makeOrd(e,t,"textord")},mathmlBuilder(e,t){var r=Je(e.text,e.mode,t),n=j0(e,t)||"normal",i;return e.mode==="text"?i=new F.MathNode("mtext",[r]):/[0-9]/.test(e.text)?i=new F.MathNode("mn",[r]):e.text==="\\prime"?i=new F.MathNode("mo",[r]):i=new F.MathNode("mi",[r]),n!==Vs[i.type]&&i.setAttribute("mathvariant",n),i}});var Wn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Yn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};Vt({type:"spacing",htmlBuilder(e,t){if(Yn.hasOwnProperty(e.text)){var r=Yn[e.text].className||"";if(e.mode==="text"){var n=C.makeOrd(e,t,"textord");return n.classes.push(r),n}else return C.makeSpan(["mspace",r],[C.mathsym(e.text,e.mode,t)],t)}else{if(Wn.hasOwnProperty(e.text))return C.makeSpan(["mspace",Wn[e.text]],[],t);throw new L('Unknown type of space "'+e.text+'"')}},mathmlBuilder(e,t){var r;if(Yn.hasOwnProperty(e.text))r=new F.MathNode("mtext",[new F.TextNode(" ")]);else{if(Wn.hasOwnProperty(e.text))return new F.MathNode("mspace");throw new L('Unknown type of space "'+e.text+'"')}return r}});var Ma=()=>{var e=new F.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};Vt({type:"tag",mathmlBuilder(e,t){var r=new F.MathNode("mtable",[new F.MathNode("mtr",[Ma(),new F.MathNode("mtd",[Dt(e.body,t)]),Ma(),new F.MathNode("mtd",[Dt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var Ca={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},Ea={"\\textbf":"textbf","\\textmd":"textmd"},j2={"\\textit":"textit","\\textup":"textup"},Da=(e,t)=>{var r=e.font;if(r){if(Ca[r])return t.withTextFontFamily(Ca[r]);if(Ea[r])return t.withTextFontWeight(Ea[r]);if(r==="\\emph")return t.fontShape==="textit"?t.withTextFontShape("textup"):t.withTextFontShape("textit")}else return t;return t.withTextFontShape(j2[r])};_({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:n}=e,i=t[0];return{type:"text",mode:r.mode,body:we(i),font:n}},htmlBuilder(e,t){var r=Da(e,t),n=ze(e.body,r,!0);return C.makeSpan(["mord","text"],n,r)},mathmlBuilder(e,t){var r=Da(e,t);return Dt(e.body,r)}});_({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=oe(e.body,t),n=C.makeLineSpan("underline-line",t),i=t.fontMetrics().defaultRuleThickness,a=C.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:i},{type:"elem",elem:n},{type:"kern",size:3*i},{type:"elem",elem:r}]},t);return C.makeSpan(["mord","underline"],[a],t)},mathmlBuilder(e,t){var r=new F.MathNode("mo",[new F.TextNode("‾")]);r.setAttribute("stretchy","true");var n=new F.MathNode("munder",[me(e.body,t),r]);return n.setAttribute("accentunder","true"),n}});_({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=oe(e.body,t),n=t.fontMetrics().axisHeight,i=.5*(r.height-n-(r.depth+n));return C.makeVList({positionType:"shift",positionData:i,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){return new F.MathNode("mpadded",[me(e.body,t)],["vcenter"])}});_({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new L("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){for(var r=Ia(e),n=[],i=t.havingStyle(t.style.text()),a=0;ae.body.replace(/ /g,e.star?"␣":" "),Mt=cs,js=`[ \r + ]`,$2="\\\\[a-zA-Z@]+",U2="\\\\[^\uD800-\uDFFF]",_2="("+$2+")"+js+"*",G2=`\\\\( +|[ \r ]+ +?)[ \r ]*`,g0="[̀-ͯ]",W2=new RegExp(g0+"+$"),Y2="("+js+"+)|"+(G2+"|")+"([!-\\[\\]-‧‪-퟿豈-￿]"+(g0+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(g0+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+_2)+("|"+U2+")");class Ba{constructor(t,r){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=t,this.settings=r,this.tokenRegex=new RegExp(Y2,"g"),this.catcodes={"%":14,"~":13}}setCatcode(t,r){this.catcodes[t]=r}lex(){var t=this.input,r=this.tokenRegex.lastIndex;if(r===t.length)return new We("EOF",new qe(this,r,r));var n=this.tokenRegex.exec(t);if(n===null||n.index!==r)throw new L("Unexpected character: '"+t[r]+"'",new We(t[r],new qe(this,r,r+1)));var i=n[6]||n[3]||(n[2]?"\\ ":" ");if(this.catcodes[i]===14){var a=t.indexOf(` +`,this.tokenRegex.lastIndex);return a===-1?(this.tokenRegex.lastIndex=t.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=a+1,this.lex()}return new We(i,new qe(this,r,this.tokenRegex.lastIndex))}}class X2{constructor(t,r){t===void 0&&(t={}),r===void 0&&(r={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=r,this.builtins=t,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new L("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var t=this.undefStack.pop();for(var r in t)t.hasOwnProperty(r)&&(t[r]==null?delete this.current[r]:this.current[r]=t[r])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(t){return this.current.hasOwnProperty(t)||this.builtins.hasOwnProperty(t)}get(t){return this.current.hasOwnProperty(t)?this.current[t]:this.builtins[t]}set(t,r,n){if(n===void 0&&(n=!1),n){for(var i=0;i0&&(this.undefStack[this.undefStack.length-1][t]=r)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(t)&&(a[t]=this.current[t])}r==null?delete this.current[t]:this.current[t]=r}}var K2=Is;v("\\noexpand",function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}});v("\\expandafter",function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}});v("\\@firstoftwo",function(e){var t=e.consumeArgs(2);return{tokens:t[0],numArgs:0}});v("\\@secondoftwo",function(e){var t=e.consumeArgs(2);return{tokens:t[1],numArgs:0}});v("\\@ifnextchar",function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return t[0].length===1&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}});v("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");v("\\TextOrMath",function(e){var t=e.consumeArgs(2);return e.mode==="text"?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}});var Na={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};v("\\char",function(e){var t=e.popToken(),r,n="";if(t.text==="'")r=8,t=e.popToken();else if(t.text==='"')r=16,t=e.popToken();else if(t.text==="`")if(t=e.popToken(),t.text[0]==="\\")n=t.text.charCodeAt(1);else{if(t.text==="EOF")throw new L("\\char` missing argument");n=t.text.charCodeAt(0)}else r=10;if(r){if(n=Na[t.text],n==null||n>=r)throw new L("Invalid base-"+r+" digit "+t.text);for(var i;(i=Na[e.future().text])!=null&&i{var i=e.consumeArg().tokens;if(i.length!==1)throw new L("\\newcommand's first argument must be a macro name");var a=i[0].text,l=e.isDefined(a);if(l&&!t)throw new L("\\newcommand{"+a+"} attempting to redefine "+(a+"; use \\renewcommand"));if(!l&&!r)throw new L("\\renewcommand{"+a+"} when command "+a+" does not yet exist; use \\newcommand");var s=0;if(i=e.consumeArg().tokens,i.length===1&&i[0].text==="["){for(var o="",u=e.expandNextToken();u.text!=="]"&&u.text!=="EOF";)o+=u.text,u=e.expandNextToken();if(!o.match(/^\s*[0-9]+\s*$/))throw new L("Invalid number of arguments: "+o);s=parseInt(o),i=e.consumeArg().tokens}return l&&n||e.macros.set(a,{tokens:i,numArgs:s}),""};v("\\newcommand",e=>Q0(e,!1,!0,!1));v("\\renewcommand",e=>Q0(e,!0,!1,!1));v("\\providecommand",e=>Q0(e,!0,!0,!0));v("\\message",e=>{var t=e.consumeArgs(1)[0];return console.log(t.reverse().map(r=>r.text).join("")),""});v("\\errmessage",e=>{var t=e.consumeArgs(1)[0];return console.error(t.reverse().map(r=>r.text).join("")),""});v("\\show",e=>{var t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),Mt[r],de.math[r],de.text[r]),""});v("\\bgroup","{");v("\\egroup","}");v("~","\\nobreakspace");v("\\lq","`");v("\\rq","'");v("\\aa","\\r a");v("\\AA","\\r A");v("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`©}");v("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");v("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}");v("ℬ","\\mathscr{B}");v("ℰ","\\mathscr{E}");v("ℱ","\\mathscr{F}");v("ℋ","\\mathscr{H}");v("ℐ","\\mathscr{I}");v("ℒ","\\mathscr{L}");v("ℳ","\\mathscr{M}");v("ℛ","\\mathscr{R}");v("ℭ","\\mathfrak{C}");v("ℌ","\\mathfrak{H}");v("ℨ","\\mathfrak{Z}");v("\\Bbbk","\\Bbb{k}");v("·","\\cdotp");v("\\llap","\\mathllap{\\textrm{#1}}");v("\\rlap","\\mathrlap{\\textrm{#1}}");v("\\clap","\\mathclap{\\textrm{#1}}");v("\\mathstrut","\\vphantom{(}");v("\\underbar","\\underline{\\text{#1}}");v("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');v("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`≠}}");v("\\ne","\\neq");v("≠","\\neq");v("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`∉}}");v("∉","\\notin");v("≘","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`≘}}");v("≙","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`≘}}");v("≚","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`≚}}");v("≛","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`≛}}");v("≝","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`≝}}");v("≞","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`≞}}");v("≟","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`≟}}");v("⟂","\\perp");v("‼","\\mathclose{!\\mkern-0.8mu!}");v("∌","\\notni");v("⌜","\\ulcorner");v("⌝","\\urcorner");v("⌞","\\llcorner");v("⌟","\\lrcorner");v("©","\\copyright");v("®","\\textregistered");v("️","\\textregistered");v("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');v("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');v("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');v("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');v("\\vdots","{\\varvdots\\rule{0pt}{15pt}}");v("⋮","\\vdots");v("\\varGamma","\\mathit{\\Gamma}");v("\\varDelta","\\mathit{\\Delta}");v("\\varTheta","\\mathit{\\Theta}");v("\\varLambda","\\mathit{\\Lambda}");v("\\varXi","\\mathit{\\Xi}");v("\\varPi","\\mathit{\\Pi}");v("\\varSigma","\\mathit{\\Sigma}");v("\\varUpsilon","\\mathit{\\Upsilon}");v("\\varPhi","\\mathit{\\Phi}");v("\\varPsi","\\mathit{\\Psi}");v("\\varOmega","\\mathit{\\Omega}");v("\\substack","\\begin{subarray}{c}#1\\end{subarray}");v("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");v("\\boxed","\\fbox{$\\displaystyle{#1}$}");v("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");v("\\implies","\\DOTSB\\;\\Longrightarrow\\;");v("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");v("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");v("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");var Fa={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};v("\\dots",function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in Fa?t=Fa[r]:(r.slice(0,4)==="\\not"||r in de.math&&["bin","rel"].includes(de.math[r].group))&&(t="\\dotsb"),t});var J0={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};v("\\dotso",function(e){var t=e.future().text;return t in J0?"\\ldots\\,":"\\ldots"});v("\\dotsc",function(e){var t=e.future().text;return t in J0&&t!==","?"\\ldots\\,":"\\ldots"});v("\\cdots",function(e){var t=e.future().text;return t in J0?"\\@cdots\\,":"\\@cdots"});v("\\dotsb","\\cdots");v("\\dotsm","\\cdots");v("\\dotsi","\\!\\cdots");v("\\dotsx","\\ldots\\,");v("\\DOTSI","\\relax");v("\\DOTSB","\\relax");v("\\DOTSX","\\relax");v("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");v("\\,","\\tmspace+{3mu}{.1667em}");v("\\thinspace","\\,");v("\\>","\\mskip{4mu}");v("\\:","\\tmspace+{4mu}{.2222em}");v("\\medspace","\\:");v("\\;","\\tmspace+{5mu}{.2777em}");v("\\thickspace","\\;");v("\\!","\\tmspace-{3mu}{.1667em}");v("\\negthinspace","\\!");v("\\negmedspace","\\tmspace-{4mu}{.2222em}");v("\\negthickspace","\\tmspace-{5mu}{.277em}");v("\\enspace","\\kern.5em ");v("\\enskip","\\hskip.5em\\relax");v("\\quad","\\hskip1em\\relax");v("\\qquad","\\hskip2em\\relax");v("\\tag","\\@ifstar\\tag@literal\\tag@paren");v("\\tag@paren","\\tag@literal{({#1})}");v("\\tag@literal",e=>{if(e.macros.get("\\df@tag"))throw new L("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});v("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");v("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");v("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");v("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");v("\\newline","\\\\\\relax");v("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var $s=P(st["Main-Regular"][84][1]-.7*st["Main-Regular"][65][1]);v("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+$s+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");v("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+$s+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");v("\\hspace","\\@ifstar\\@hspacer\\@hspace");v("\\@hspace","\\hskip #1\\relax");v("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");v("\\ordinarycolon",":");v("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");v("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');v("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');v("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');v("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');v("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');v("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');v("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');v("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');v("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');v("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');v("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');v("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');v("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');v("∷","\\dblcolon");v("∹","\\eqcolon");v("≔","\\coloneqq");v("≕","\\eqqcolon");v("⩴","\\Coloneqq");v("\\ratio","\\vcentcolon");v("\\coloncolon","\\dblcolon");v("\\colonequals","\\coloneqq");v("\\coloncolonequals","\\Coloneqq");v("\\equalscolon","\\eqqcolon");v("\\equalscoloncolon","\\Eqqcolon");v("\\colonminus","\\coloneq");v("\\coloncolonminus","\\Coloneq");v("\\minuscolon","\\eqcolon");v("\\minuscoloncolon","\\Eqcolon");v("\\coloncolonapprox","\\Colonapprox");v("\\coloncolonsim","\\Colonsim");v("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");v("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");v("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");v("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");v("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`∌}}");v("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");v("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");v("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");v("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");v("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");v("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");v("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");v("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");v("\\gvertneqq","\\html@mathml{\\@gvertneqq}{≩}");v("\\lvertneqq","\\html@mathml{\\@lvertneqq}{≨}");v("\\ngeqq","\\html@mathml{\\@ngeqq}{≱}");v("\\ngeqslant","\\html@mathml{\\@ngeqslant}{≱}");v("\\nleqq","\\html@mathml{\\@nleqq}{≰}");v("\\nleqslant","\\html@mathml{\\@nleqslant}{≰}");v("\\nshortmid","\\html@mathml{\\@nshortmid}{∤}");v("\\nshortparallel","\\html@mathml{\\@nshortparallel}{∦}");v("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{⊈}");v("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{⊉}");v("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{⊊}");v("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{⫋}");v("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{⊋}");v("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{⫌}");v("\\imath","\\html@mathml{\\@imath}{ı}");v("\\jmath","\\html@mathml{\\@jmath}{ȷ}");v("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`⟦}}");v("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`⟧}}");v("⟦","\\llbracket");v("⟧","\\rrbracket");v("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`⦃}}");v("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`⦄}}");v("⦃","\\lBrace");v("⦄","\\rBrace");v("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`⦵}}");v("⦵","\\minuso");v("\\darr","\\downarrow");v("\\dArr","\\Downarrow");v("\\Darr","\\Downarrow");v("\\lang","\\langle");v("\\rang","\\rangle");v("\\uarr","\\uparrow");v("\\uArr","\\Uparrow");v("\\Uarr","\\Uparrow");v("\\N","\\mathbb{N}");v("\\R","\\mathbb{R}");v("\\Z","\\mathbb{Z}");v("\\alef","\\aleph");v("\\alefsym","\\aleph");v("\\Alpha","\\mathrm{A}");v("\\Beta","\\mathrm{B}");v("\\bull","\\bullet");v("\\Chi","\\mathrm{X}");v("\\clubs","\\clubsuit");v("\\cnums","\\mathbb{C}");v("\\Complex","\\mathbb{C}");v("\\Dagger","\\ddagger");v("\\diamonds","\\diamondsuit");v("\\empty","\\emptyset");v("\\Epsilon","\\mathrm{E}");v("\\Eta","\\mathrm{H}");v("\\exist","\\exists");v("\\harr","\\leftrightarrow");v("\\hArr","\\Leftrightarrow");v("\\Harr","\\Leftrightarrow");v("\\hearts","\\heartsuit");v("\\image","\\Im");v("\\infin","\\infty");v("\\Iota","\\mathrm{I}");v("\\isin","\\in");v("\\Kappa","\\mathrm{K}");v("\\larr","\\leftarrow");v("\\lArr","\\Leftarrow");v("\\Larr","\\Leftarrow");v("\\lrarr","\\leftrightarrow");v("\\lrArr","\\Leftrightarrow");v("\\Lrarr","\\Leftrightarrow");v("\\Mu","\\mathrm{M}");v("\\natnums","\\mathbb{N}");v("\\Nu","\\mathrm{N}");v("\\Omicron","\\mathrm{O}");v("\\plusmn","\\pm");v("\\rarr","\\rightarrow");v("\\rArr","\\Rightarrow");v("\\Rarr","\\Rightarrow");v("\\real","\\Re");v("\\reals","\\mathbb{R}");v("\\Reals","\\mathbb{R}");v("\\Rho","\\mathrm{P}");v("\\sdot","\\cdot");v("\\sect","\\S");v("\\spades","\\spadesuit");v("\\sub","\\subset");v("\\sube","\\subseteq");v("\\supe","\\supseteq");v("\\Tau","\\mathrm{T}");v("\\thetasym","\\vartheta");v("\\weierp","\\wp");v("\\Zeta","\\mathrm{Z}");v("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");v("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");v("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");v("\\bra","\\mathinner{\\langle{#1}|}");v("\\ket","\\mathinner{|{#1}\\rangle}");v("\\braket","\\mathinner{\\langle{#1}\\rangle}");v("\\Bra","\\left\\langle#1\\right|");v("\\Ket","\\left|#1\\right\\rangle");var Us=e=>t=>{var r=t.consumeArg().tokens,n=t.consumeArg().tokens,i=t.consumeArg().tokens,a=t.consumeArg().tokens,l=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var o=m=>d=>{e&&(d.macros.set("|",l),i.length&&d.macros.set("\\|",s));var p=m;if(!m&&i.length){var y=d.future();y.text==="|"&&(d.popToken(),p=!0)}return{tokens:p?i:n,numArgs:0}};t.macros.set("|",o(!1)),i.length&&t.macros.set("\\|",o(!0));var u=t.consumeArg().tokens,h=t.expandTokens([...a,...u,...r]);return t.macros.endGroup(),{tokens:h.reverse(),numArgs:0}};v("\\bra@ket",Us(!1));v("\\bra@set",Us(!0));v("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");v("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");v("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");v("\\angln","{\\angl n}");v("\\blue","\\textcolor{##6495ed}{#1}");v("\\orange","\\textcolor{##ffa500}{#1}");v("\\pink","\\textcolor{##ff00af}{#1}");v("\\red","\\textcolor{##df0030}{#1}");v("\\green","\\textcolor{##28ae7b}{#1}");v("\\gray","\\textcolor{gray}{#1}");v("\\purple","\\textcolor{##9d38bd}{#1}");v("\\blueA","\\textcolor{##ccfaff}{#1}");v("\\blueB","\\textcolor{##80f6ff}{#1}");v("\\blueC","\\textcolor{##63d9ea}{#1}");v("\\blueD","\\textcolor{##11accd}{#1}");v("\\blueE","\\textcolor{##0c7f99}{#1}");v("\\tealA","\\textcolor{##94fff5}{#1}");v("\\tealB","\\textcolor{##26edd5}{#1}");v("\\tealC","\\textcolor{##01d1c1}{#1}");v("\\tealD","\\textcolor{##01a995}{#1}");v("\\tealE","\\textcolor{##208170}{#1}");v("\\greenA","\\textcolor{##b6ffb0}{#1}");v("\\greenB","\\textcolor{##8af281}{#1}");v("\\greenC","\\textcolor{##74cf70}{#1}");v("\\greenD","\\textcolor{##1fab54}{#1}");v("\\greenE","\\textcolor{##0d923f}{#1}");v("\\goldA","\\textcolor{##ffd0a9}{#1}");v("\\goldB","\\textcolor{##ffbb71}{#1}");v("\\goldC","\\textcolor{##ff9c39}{#1}");v("\\goldD","\\textcolor{##e07d10}{#1}");v("\\goldE","\\textcolor{##a75a05}{#1}");v("\\redA","\\textcolor{##fca9a9}{#1}");v("\\redB","\\textcolor{##ff8482}{#1}");v("\\redC","\\textcolor{##f9685d}{#1}");v("\\redD","\\textcolor{##e84d39}{#1}");v("\\redE","\\textcolor{##bc2612}{#1}");v("\\maroonA","\\textcolor{##ffbde0}{#1}");v("\\maroonB","\\textcolor{##ff92c6}{#1}");v("\\maroonC","\\textcolor{##ed5fa6}{#1}");v("\\maroonD","\\textcolor{##ca337c}{#1}");v("\\maroonE","\\textcolor{##9e034e}{#1}");v("\\purpleA","\\textcolor{##ddd7ff}{#1}");v("\\purpleB","\\textcolor{##c6b9fc}{#1}");v("\\purpleC","\\textcolor{##aa87ff}{#1}");v("\\purpleD","\\textcolor{##7854ab}{#1}");v("\\purpleE","\\textcolor{##543b78}{#1}");v("\\mintA","\\textcolor{##f5f9e8}{#1}");v("\\mintB","\\textcolor{##edf2df}{#1}");v("\\mintC","\\textcolor{##e0e5cc}{#1}");v("\\grayA","\\textcolor{##f6f7f7}{#1}");v("\\grayB","\\textcolor{##f0f1f2}{#1}");v("\\grayC","\\textcolor{##e3e5e6}{#1}");v("\\grayD","\\textcolor{##d6d8da}{#1}");v("\\grayE","\\textcolor{##babec2}{#1}");v("\\grayF","\\textcolor{##888d93}{#1}");v("\\grayG","\\textcolor{##626569}{#1}");v("\\grayH","\\textcolor{##3b3e40}{#1}");v("\\grayI","\\textcolor{##21242c}{#1}");v("\\kaBlue","\\textcolor{##314453}{#1}");v("\\kaGreen","\\textcolor{##71B307}{#1}");var _s={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class Z2{constructor(t,r,n){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=r,this.expansionCount=0,this.feed(t),this.macros=new X2(K2,r.macros),this.mode=n,this.stack=[]}feed(t){this.lexer=new Ba(t,this.settings)}switchMode(t){this.mode=t}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(t){this.stack.push(t)}pushTokens(t){this.stack.push(...t)}scanArgument(t){var r,n,i;if(t){if(this.consumeSpaces(),this.future().text!=="[")return null;r=this.popToken(),{tokens:i,end:n}=this.consumeArg(["]"])}else({tokens:i,start:r,end:n}=this.consumeArg());return this.pushToken(new We("EOF",n.loc)),this.pushTokens(i),new We("",qe.range(r,n))}consumeSpaces(){for(;;){var t=this.future();if(t.text===" ")this.stack.pop();else break}}consumeArg(t){var r=[],n=t&&t.length>0;n||this.consumeSpaces();var i=this.future(),a,l=0,s=0;do{if(a=this.popToken(),r.push(a),a.text==="{")++l;else if(a.text==="}"){if(--l,l===-1)throw new L("Extra }",a)}else if(a.text==="EOF")throw new L("Unexpected end of input in a macro argument, expected '"+(t&&n?t[s]:"}")+"'",a);if(t&&n)if((l===0||l===1&&t[s]==="{")&&a.text===t[s]){if(++s,s===t.length){r.splice(-s,s);break}}else s=0}while(l!==0||n);return i.text==="{"&&r[r.length-1].text==="}"&&(r.pop(),r.shift()),r.reverse(),{tokens:r,start:i,end:a}}consumeArgs(t,r){if(r){if(r.length!==t+1)throw new L("The length of delimiters doesn't match the number of args!");for(var n=r[0],i=0;ithis.settings.maxExpand)throw new L("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(t){var r=this.popToken(),n=r.text,i=r.noexpand?null:this._getExpansion(n);if(i==null||t&&i.unexpandable){if(t&&i==null&&n[0]==="\\"&&!this.isDefined(n))throw new L("Undefined control sequence: "+n);return this.pushToken(r),!1}this.countExpansion(1);var a=i.tokens,l=this.consumeArgs(i.numArgs,i.delimiters);if(i.numArgs){a=a.slice();for(var s=a.length-1;s>=0;--s){var o=a[s];if(o.text==="#"){if(s===0)throw new L("Incomplete placeholder at end of macro body",o);if(o=a[--s],o.text==="#")a.splice(s+1,1);else if(/^[1-9]$/.test(o.text))a.splice(s,2,...l[+o.text-1]);else throw new L("Not a valid argument number",o)}}}return this.pushTokens(a),a.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var t=this.stack.pop();return t.treatAsRelax&&(t.text="\\relax"),t}throw new Error}expandMacro(t){return this.macros.has(t)?this.expandTokens([new We(t)]):void 0}expandTokens(t){var r=[],n=this.stack.length;for(this.pushTokens(t);this.stack.length>n;)if(this.expandOnce(!0)===!1){var i=this.stack.pop();i.treatAsRelax&&(i.noexpand=!1,i.treatAsRelax=!1),r.push(i)}return this.countExpansion(r.length),r}expandMacroAsText(t){var r=this.expandMacro(t);return r&&r.map(n=>n.text).join("")}_getExpansion(t){var r=this.macros.get(t);if(r==null)return r;if(t.length===1){var n=this.lexer.catcodes[t];if(n!=null&&n!==13)return}var i=typeof r=="function"?r(this):r;if(typeof i=="string"){var a=0;if(i.indexOf("#")!==-1)for(var l=i.replace(/##/g,"");l.indexOf("#"+(a+1))!==-1;)++a;for(var s=new Ba(i,this.settings),o=[],u=s.lex();u.text!=="EOF";)o.push(u),u=s.lex();o.reverse();var h={tokens:o,numArgs:a};return h}return i}isDefined(t){return this.macros.has(t)||Mt.hasOwnProperty(t)||de.math.hasOwnProperty(t)||de.text.hasOwnProperty(t)||_s.hasOwnProperty(t)}isExpandable(t){var r=this.macros.get(t);return r!=null?typeof r=="string"||typeof r=="function"||!r.unexpandable:Mt.hasOwnProperty(t)&&!Mt[t].primitive}}var La=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,jr=Object.freeze({"₊":"+","₋":"-","₌":"=","₍":"(","₎":")","₀":"0","₁":"1","₂":"2","₃":"3","₄":"4","₅":"5","₆":"6","₇":"7","₈":"8","₉":"9","ₐ":"a","ₑ":"e","ₕ":"h","ᵢ":"i","ⱼ":"j","ₖ":"k","ₗ":"l","ₘ":"m","ₙ":"n","ₒ":"o","ₚ":"p","ᵣ":"r","ₛ":"s","ₜ":"t","ᵤ":"u","ᵥ":"v","ₓ":"x","ᵦ":"β","ᵧ":"γ","ᵨ":"ρ","ᵩ":"ϕ","ᵪ":"χ","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")","⁰":"0","¹":"1","²":"2","³":"3","⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᴬ":"A","ᴮ":"B","ᴰ":"D","ᴱ":"E","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","ᴿ":"R","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g",ʰ:"h","ⁱ":"i",ʲ:"j","ᵏ":"k",ˡ:"l","ᵐ":"m",ⁿ:"n","ᵒ":"o","ᵖ":"p",ʳ:"r",ˢ:"s","ᵗ":"t","ᵘ":"u","ᵛ":"v",ʷ:"w",ˣ:"x",ʸ:"y","ᶻ":"z","ᵝ":"β","ᵞ":"γ","ᵟ":"δ","ᵠ":"ϕ","ᵡ":"χ","ᶿ":"θ"}),Xn={"́":{text:"\\'",math:"\\acute"},"̀":{text:"\\`",math:"\\grave"},"̈":{text:'\\"',math:"\\ddot"},"̃":{text:"\\~",math:"\\tilde"},"̄":{text:"\\=",math:"\\bar"},"̆":{text:"\\u",math:"\\breve"},"̌":{text:"\\v",math:"\\check"},"̂":{text:"\\^",math:"\\hat"},"̇":{text:"\\.",math:"\\dot"},"̊":{text:"\\r",math:"\\mathring"},"̋":{text:"\\H"},"̧":{text:"\\c"}},Ra={á:"á",à:"à",ä:"ä",ǟ:"ǟ",ã:"ã",ā:"ā",ă:"ă",ắ:"ắ",ằ:"ằ",ẵ:"ẵ",ǎ:"ǎ",â:"â",ấ:"ấ",ầ:"ầ",ẫ:"ẫ",ȧ:"ȧ",ǡ:"ǡ",å:"å",ǻ:"ǻ",ḃ:"ḃ",ć:"ć",ḉ:"ḉ",č:"č",ĉ:"ĉ",ċ:"ċ",ç:"ç",ď:"ď",ḋ:"ḋ",ḑ:"ḑ",é:"é",è:"è",ë:"ë",ẽ:"ẽ",ē:"ē",ḗ:"ḗ",ḕ:"ḕ",ĕ:"ĕ",ḝ:"ḝ",ě:"ě",ê:"ê",ế:"ế",ề:"ề",ễ:"ễ",ė:"ė",ȩ:"ȩ",ḟ:"ḟ",ǵ:"ǵ",ḡ:"ḡ",ğ:"ğ",ǧ:"ǧ",ĝ:"ĝ",ġ:"ġ",ģ:"ģ",ḧ:"ḧ",ȟ:"ȟ",ĥ:"ĥ",ḣ:"ḣ",ḩ:"ḩ",í:"í",ì:"ì",ï:"ï",ḯ:"ḯ",ĩ:"ĩ",ī:"ī",ĭ:"ĭ",ǐ:"ǐ",î:"î",ǰ:"ǰ",ĵ:"ĵ",ḱ:"ḱ",ǩ:"ǩ",ķ:"ķ",ĺ:"ĺ",ľ:"ľ",ļ:"ļ",ḿ:"ḿ",ṁ:"ṁ",ń:"ń",ǹ:"ǹ",ñ:"ñ",ň:"ň",ṅ:"ṅ",ņ:"ņ",ó:"ó",ò:"ò",ö:"ö",ȫ:"ȫ",õ:"õ",ṍ:"ṍ",ṏ:"ṏ",ȭ:"ȭ",ō:"ō",ṓ:"ṓ",ṑ:"ṑ",ŏ:"ŏ",ǒ:"ǒ",ô:"ô",ố:"ố",ồ:"ồ",ỗ:"ỗ",ȯ:"ȯ",ȱ:"ȱ",ő:"ő",ṕ:"ṕ",ṗ:"ṗ",ŕ:"ŕ",ř:"ř",ṙ:"ṙ",ŗ:"ŗ",ś:"ś",ṥ:"ṥ",š:"š",ṧ:"ṧ",ŝ:"ŝ",ṡ:"ṡ",ş:"ş",ẗ:"ẗ",ť:"ť",ṫ:"ṫ",ţ:"ţ",ú:"ú",ù:"ù",ü:"ü",ǘ:"ǘ",ǜ:"ǜ",ǖ:"ǖ",ǚ:"ǚ",ũ:"ũ",ṹ:"ṹ",ū:"ū",ṻ:"ṻ",ŭ:"ŭ",ǔ:"ǔ",û:"û",ů:"ů",ű:"ű",ṽ:"ṽ",ẃ:"ẃ",ẁ:"ẁ",ẅ:"ẅ",ŵ:"ŵ",ẇ:"ẇ",ẘ:"ẘ",ẍ:"ẍ",ẋ:"ẋ",ý:"ý",ỳ:"ỳ",ÿ:"ÿ",ỹ:"ỹ",ȳ:"ȳ",ŷ:"ŷ",ẏ:"ẏ",ẙ:"ẙ",ź:"ź",ž:"ž",ẑ:"ẑ",ż:"ż",Á:"Á",À:"À",Ä:"Ä",Ǟ:"Ǟ",Ã:"Ã",Ā:"Ā",Ă:"Ă",Ắ:"Ắ",Ằ:"Ằ",Ẵ:"Ẵ",Ǎ:"Ǎ",Â:"Â",Ấ:"Ấ",Ầ:"Ầ",Ẫ:"Ẫ",Ȧ:"Ȧ",Ǡ:"Ǡ",Å:"Å",Ǻ:"Ǻ",Ḃ:"Ḃ",Ć:"Ć",Ḉ:"Ḉ",Č:"Č",Ĉ:"Ĉ",Ċ:"Ċ",Ç:"Ç",Ď:"Ď",Ḋ:"Ḋ",Ḑ:"Ḑ",É:"É",È:"È",Ë:"Ë",Ẽ:"Ẽ",Ē:"Ē",Ḗ:"Ḗ",Ḕ:"Ḕ",Ĕ:"Ĕ",Ḝ:"Ḝ",Ě:"Ě",Ê:"Ê",Ế:"Ế",Ề:"Ề",Ễ:"Ễ",Ė:"Ė",Ȩ:"Ȩ",Ḟ:"Ḟ",Ǵ:"Ǵ",Ḡ:"Ḡ",Ğ:"Ğ",Ǧ:"Ǧ",Ĝ:"Ĝ",Ġ:"Ġ",Ģ:"Ģ",Ḧ:"Ḧ",Ȟ:"Ȟ",Ĥ:"Ĥ",Ḣ:"Ḣ",Ḩ:"Ḩ",Í:"Í",Ì:"Ì",Ï:"Ï",Ḯ:"Ḯ",Ĩ:"Ĩ",Ī:"Ī",Ĭ:"Ĭ",Ǐ:"Ǐ",Î:"Î",İ:"İ",Ĵ:"Ĵ",Ḱ:"Ḱ",Ǩ:"Ǩ",Ķ:"Ķ",Ĺ:"Ĺ",Ľ:"Ľ",Ļ:"Ļ",Ḿ:"Ḿ",Ṁ:"Ṁ",Ń:"Ń",Ǹ:"Ǹ",Ñ:"Ñ",Ň:"Ň",Ṅ:"Ṅ",Ņ:"Ņ",Ó:"Ó",Ò:"Ò",Ö:"Ö",Ȫ:"Ȫ",Õ:"Õ",Ṍ:"Ṍ",Ṏ:"Ṏ",Ȭ:"Ȭ",Ō:"Ō",Ṓ:"Ṓ",Ṑ:"Ṑ",Ŏ:"Ŏ",Ǒ:"Ǒ",Ô:"Ô",Ố:"Ố",Ồ:"Ồ",Ỗ:"Ỗ",Ȯ:"Ȯ",Ȱ:"Ȱ",Ő:"Ő",Ṕ:"Ṕ",Ṗ:"Ṗ",Ŕ:"Ŕ",Ř:"Ř",Ṙ:"Ṙ",Ŗ:"Ŗ",Ś:"Ś",Ṥ:"Ṥ",Š:"Š",Ṧ:"Ṧ",Ŝ:"Ŝ",Ṡ:"Ṡ",Ş:"Ş",Ť:"Ť",Ṫ:"Ṫ",Ţ:"Ţ",Ú:"Ú",Ù:"Ù",Ü:"Ü",Ǘ:"Ǘ",Ǜ:"Ǜ",Ǖ:"Ǖ",Ǚ:"Ǚ",Ũ:"Ũ",Ṹ:"Ṹ",Ū:"Ū",Ṻ:"Ṻ",Ŭ:"Ŭ",Ǔ:"Ǔ",Û:"Û",Ů:"Ů",Ű:"Ű",Ṽ:"Ṽ",Ẃ:"Ẃ",Ẁ:"Ẁ",Ẅ:"Ẅ",Ŵ:"Ŵ",Ẇ:"Ẇ",Ẍ:"Ẍ",Ẋ:"Ẋ",Ý:"Ý",Ỳ:"Ỳ",Ÿ:"Ÿ",Ỹ:"Ỹ",Ȳ:"Ȳ",Ŷ:"Ŷ",Ẏ:"Ẏ",Ź:"Ź",Ž:"Ž",Ẑ:"Ẑ",Ż:"Ż",ά:"ά",ὰ:"ὰ",ᾱ:"ᾱ",ᾰ:"ᾰ",έ:"έ",ὲ:"ὲ",ή:"ή",ὴ:"ὴ",ί:"ί",ὶ:"ὶ",ϊ:"ϊ",ΐ:"ΐ",ῒ:"ῒ",ῑ:"ῑ",ῐ:"ῐ",ό:"ό",ὸ:"ὸ",ύ:"ύ",ὺ:"ὺ",ϋ:"ϋ",ΰ:"ΰ",ῢ:"ῢ",ῡ:"ῡ",ῠ:"ῠ",ώ:"ώ",ὼ:"ὼ",Ύ:"Ύ",Ὺ:"Ὺ",Ϋ:"Ϋ",Ῡ:"Ῡ",Ῠ:"Ῠ",Ώ:"Ώ",Ὼ:"Ὼ"};class fn{constructor(t,r){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Z2(t,r,this.mode),this.settings=r,this.leftrightDepth=0}expect(t,r){if(r===void 0&&(r=!0),this.fetch().text!==t)throw new L("Expected '"+t+"', got '"+this.fetch().text+"'",this.fetch());r&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(t){this.mode=t,this.gullet.switchMode(t)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var t=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),t}finally{this.gullet.endGroups()}}subparse(t){var r=this.nextToken;this.consume(),this.gullet.pushToken(new We("}")),this.gullet.pushTokens(t);var n=this.parseExpression(!1);return this.expect("}"),this.nextToken=r,n}parseExpression(t,r){for(var n=[];;){this.mode==="math"&&this.consumeSpaces();var i=this.fetch();if(fn.endOfExpression.indexOf(i.text)!==-1||r&&i.text===r||t&&Mt[i.text]&&Mt[i.text].infix)break;var a=this.parseAtom(r);if(a){if(a.type==="internal")continue}else break;n.push(a)}return this.mode==="text"&&this.formLigatures(n),this.handleInfixNodes(n)}handleInfixNodes(t){for(var r=-1,n,i=0;i=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+r[0]+'" used in math mode',t);var s=de[this.mode][r].group,o=qe.range(t),u;if(qf.hasOwnProperty(s)){var h=s;u={type:"atom",mode:this.mode,family:h,loc:o,text:r}}else u={type:s,mode:this.mode,loc:o,text:r};l=u}else if(r.charCodeAt(0)>=128)this.settings.strict&&(es(r.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+r[0]+'" used in math mode',t):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+r[0]+'"'+(" ("+r.charCodeAt(0)+")"),t)),l={type:"textord",mode:"text",loc:qe.range(t),text:r};else return null;if(this.consume(),a)for(var m=0;m=0;)c=dn(e,t,n,r,u+1,i+1,s),c>f&&(u===o?c*=jn:ts.test(e.charAt(u-1))?(c*=Ji,p=e.slice(o,u-1).match(ns),p&&o>0&&(c*=Math.pow(Zt,p.length))):rs.test(e.charAt(u-1))?(c*=Zi,h=e.slice(o,u-1).match(Nr),h&&o>0&&(c*=Math.pow(Zt,h.length))):(c*=Xi,o>0&&(c*=Math.pow(Zt,u-o))),e.charAt(u)!==t.charAt(i)&&(c*=Qi)),(cc&&(c=d*Kt)),c>f&&(f=c),u=n.indexOf(l,u+1);return s[a]=f,f}function Bn(e){return e.toLowerCase().replace(Nr," ")}function os(e,t,n){return e=n&&n.length>0?`${e+" "+n.join(" ")}`:e,dn(e,t,Bn(e),Bn(t),0,0,{})}var is=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Be=is.reduce((e,t)=>{const n=fi(`Primitive.${t}`),r=b.forwardRef((o,i)=>{const{asChild:s,...a}=o,l=s?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),yi.jsx(l,{...a,ref:i})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{}),at='[cmdk-group=""]',Jt='[cmdk-group-items=""]',ss='[cmdk-group-heading=""]',Dr='[cmdk-item=""]',Ln=`${Dr}:not([aria-disabled="true"])`,pn="cmdk-item-select",Ve="data-value",as=(e,t,n)=>os(e,t,n),Ir=b.createContext(void 0),bt=()=>b.useContext(Ir),Wr=b.createContext(void 0),On=()=>b.useContext(Wr),Rr=b.createContext(void 0),Ar=b.forwardRef((e,t)=>{let n=Ke(()=>{var k,R;return{search:"",value:(R=(k=e.value)!=null?k:e.defaultValue)!=null?R:"",selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}}}),r=Ke(()=>new Set),o=Ke(()=>new Map),i=Ke(()=>new Map),s=Ke(()=>new Set),a=_r(e),{label:l,children:u,value:f,onValueChange:c,filter:d,shouldFilter:p,loop:h,disablePointerSelection:v=!1,vimBindings:S=!0,...y}=e,m=Ze(),E=Ze(),M=Ze(),C=b.useRef(null),O=gs();ze(()=>{if(f!==void 0){let k=f.trim();n.current.value=k,D.emit()}},[f]),ze(()=>{O(6,fe)},[]);let D=b.useMemo(()=>({subscribe:k=>(s.current.add(k),()=>s.current.delete(k)),snapshot:()=>n.current,setState:(k,R,B)=>{var W,U,V,ne;if(!Object.is(n.current[k],R)){if(n.current[k]=R,k==="search")ue(),$(),O(1,oe);else if(k==="value"){if(document.activeElement.hasAttribute("cmdk-input")||document.activeElement.hasAttribute("cmdk-root")){let Q=document.getElementById(M);Q?Q.focus():(W=document.getElementById(m))==null||W.focus()}if(O(7,()=>{var Q;n.current.selectedItemId=(Q=X())==null?void 0:Q.id,D.emit()}),B||O(5,fe),((U=a.current)==null?void 0:U.value)!==void 0){let Q=R??"";(ne=(V=a.current).onValueChange)==null||ne.call(V,Q);return}}D.emit()}},emit:()=>{s.current.forEach(k=>k())}}),[]),j=b.useMemo(()=>({value:(k,R,B)=>{var W;R!==((W=i.current.get(k))==null?void 0:W.value)&&(i.current.set(k,{value:R,keywords:B}),n.current.filtered.items.set(k,Z(R,B)),O(2,()=>{$(),D.emit()}))},item:(k,R)=>(r.current.add(k),R&&(o.current.has(R)?o.current.get(R).add(k):o.current.set(R,new Set([k]))),O(3,()=>{ue(),$(),n.current.value||oe(),D.emit()}),()=>{i.current.delete(k),r.current.delete(k),n.current.filtered.items.delete(k);let B=X();O(4,()=>{ue(),B?.getAttribute("id")===k&&oe(),D.emit()})}),group:k=>(o.current.has(k)||o.current.set(k,new Set),()=>{i.current.delete(k),o.current.delete(k)}),filter:()=>a.current.shouldFilter,label:l||e["aria-label"],getDisablePointerSelection:()=>a.current.disablePointerSelection,listId:m,inputId:M,labelId:E,listInnerRef:C}),[]);function Z(k,R){var B,W;let U=(W=(B=a.current)==null?void 0:B.filter)!=null?W:as;return k?U(k,n.current.search,R):0}function $(){if(!n.current.search||a.current.shouldFilter===!1)return;let k=n.current.filtered.items,R=[];n.current.filtered.groups.forEach(W=>{let U=o.current.get(W),V=0;U.forEach(ne=>{let Q=k.get(ne);V=Math.max(Q,V)}),R.push([W,V])});let B=C.current;de().sort((W,U)=>{var V,ne;let Q=W.getAttribute("id"),xe=U.getAttribute("id");return((V=k.get(xe))!=null?V:0)-((ne=k.get(Q))!=null?ne:0)}).forEach(W=>{let U=W.closest(Jt);U?U.appendChild(W.parentElement===U?W:W.closest(`${Jt} > *`)):B.appendChild(W.parentElement===B?W:W.closest(`${Jt} > *`))}),R.sort((W,U)=>U[1]-W[1]).forEach(W=>{var U;let V=(U=C.current)==null?void 0:U.querySelector(`${at}[${Ve}="${encodeURIComponent(W[0])}"]`);V?.parentElement.appendChild(V)})}function oe(){let k=de().find(B=>B.getAttribute("aria-disabled")!=="true"),R=k?.getAttribute(Ve);D.setState("value",R||void 0)}function ue(){var k,R,B,W;if(!n.current.search||a.current.shouldFilter===!1){n.current.filtered.count=r.current.size;return}n.current.filtered.groups=new Set;let U=0;for(let V of r.current){let ne=(R=(k=i.current.get(V))==null?void 0:k.value)!=null?R:"",Q=(W=(B=i.current.get(V))==null?void 0:B.keywords)!=null?W:[],xe=Z(ne,Q);n.current.filtered.items.set(V,xe),xe>0&&U++}for(let[V,ne]of o.current)for(let Q of ne)if(n.current.filtered.items.get(Q)>0){n.current.filtered.groups.add(V);break}n.current.filtered.count=U}function fe(){var k,R,B;let W=X();W&&(((k=W.parentElement)==null?void 0:k.firstChild)===W&&((B=(R=W.closest(at))==null?void 0:R.querySelector(ss))==null||B.scrollIntoView({block:"nearest"})),W.scrollIntoView({block:"nearest"}))}function X(){var k;return(k=C.current)==null?void 0:k.querySelector(`${Dr}[aria-selected="true"]`)}function de(){var k;return Array.from(((k=C.current)==null?void 0:k.querySelectorAll(Ln))||[])}function Ae(k){let R=de()[k];R&&D.setState("value",R.getAttribute(Ve))}function Le(k){var R;let B=X(),W=de(),U=W.findIndex(ne=>ne===B),V=W[U+k];(R=a.current)!=null&&R.loop&&(V=U+k<0?W[W.length-1]:U+k===W.length?W[0]:W[U+k]),V&&D.setState("value",V.getAttribute(Ve))}function qe(k){let R=X(),B=R?.closest(at),W;for(;B&&!W;)B=k>0?ys(B,at):vs(B,at),W=B?.querySelector(Ln);W?D.setState("value",W.getAttribute(Ve)):Le(k)}let ie=()=>Ae(de().length-1),se=k=>{k.preventDefault(),k.metaKey?ie():k.altKey?qe(1):Le(1)},pe=k=>{k.preventDefault(),k.metaKey?Ae(0):k.altKey?qe(-1):Le(-1)};return b.createElement(Be.div,{ref:t,tabIndex:-1,...y,"cmdk-root":"",onKeyDown:k=>{var R;(R=y.onKeyDown)==null||R.call(y,k);let B=k.nativeEvent.isComposing||k.keyCode===229;if(!(k.defaultPrevented||B))switch(k.key){case"n":case"j":{S&&k.ctrlKey&&se(k);break}case"ArrowDown":{se(k);break}case"p":case"k":{S&&k.ctrlKey&&pe(k);break}case"ArrowUp":{pe(k);break}case"Home":{k.preventDefault(),Ae(0);break}case"End":{k.preventDefault(),ie();break}case"Enter":{k.preventDefault();let W=X();if(W){let U=new Event(pn);W.dispatchEvent(U)}}}}},b.createElement("label",{"cmdk-label":"",htmlFor:j.inputId,id:j.labelId,style:ws},l),jt(e,k=>b.createElement(Wr.Provider,{value:D},b.createElement(Ir.Provider,{value:j},k))))}),ls=b.forwardRef((e,t)=>{var n,r;let o=Ze(),i=b.useRef(null),s=b.useContext(Rr),a=bt(),l=_r(e),u=(r=(n=l.current)==null?void 0:n.forceMount)!=null?r:s?.forceMount;ze(()=>{if(!u)return a.item(o,s?.id)},[u]);let f=Fr(o,i,[e.value,e.children,i],e.keywords),c=On(),d=Fe(O=>O.value&&O.value===f.current),p=Fe(O=>u||a.filter()===!1?!0:O.search?O.filtered.items.get(o)>0:!0);b.useEffect(()=>{let O=i.current;if(!(!O||e.disabled))return O.addEventListener(pn,h),()=>O.removeEventListener(pn,h)},[p,e.onSelect,e.disabled]);function h(){var O,D;v(),(D=(O=l.current).onSelect)==null||D.call(O,f.current)}function v(){c.setState("value",f.current,!0)}if(!p)return null;let{disabled:S,value:y,onSelect:m,forceMount:E,keywords:M,...C}=e;return b.createElement(Be.div,{ref:mt(i,t),...C,id:o,"cmdk-item":"",role:"option","aria-disabled":!!S,"aria-selected":!!d,"data-disabled":!!S,"data-selected":!!d,onPointerMove:S||a.getDisablePointerSelection()?void 0:v,onClick:S?void 0:h},e.children)}),cs=b.forwardRef((e,t)=>{let{heading:n,children:r,forceMount:o,...i}=e,s=Ze(),a=b.useRef(null),l=b.useRef(null),u=Ze(),f=bt(),c=Fe(p=>o||f.filter()===!1?!0:p.search?p.filtered.groups.has(s):!0);ze(()=>f.group(s),[]),Fr(s,a,[e.value,e.heading,l]);let d=b.useMemo(()=>({id:s,forceMount:o}),[o]);return b.createElement(Be.div,{ref:mt(a,t),...i,"cmdk-group":"",role:"presentation",hidden:c?void 0:!0},n&&b.createElement("div",{ref:l,"cmdk-group-heading":"","aria-hidden":!0,id:u},n),jt(e,p=>b.createElement("div",{"cmdk-group-items":"",role:"group","aria-labelledby":n?u:void 0},b.createElement(Rr.Provider,{value:d},p))))}),us=b.forwardRef((e,t)=>{let{alwaysRender:n,...r}=e,o=b.useRef(null),i=Fe(s=>!s.search);return!n&&!i?null:b.createElement(Be.div,{ref:mt(o,t),...r,"cmdk-separator":"",role:"separator"})}),fs=b.forwardRef((e,t)=>{let{onValueChange:n,...r}=e,o=e.value!=null,i=On(),s=Fe(u=>u.search),a=Fe(u=>u.selectedItemId),l=bt();return b.useEffect(()=>{e.value!=null&&i.setState("search",e.value)},[e.value]),b.createElement(Be.input,{ref:t,...r,"cmdk-input":"",autoComplete:"off",autoCorrect:"off",spellCheck:!1,"aria-autocomplete":"list",role:"combobox","aria-expanded":!0,"aria-controls":l.listId,"aria-labelledby":l.labelId,"aria-activedescendant":a,id:l.inputId,type:"text",value:o?e.value:s,onChange:u=>{o||i.setState("search",u.target.value),n?.(u.target.value)}})}),ds=b.forwardRef((e,t)=>{let{children:n,label:r="Suggestions",...o}=e,i=b.useRef(null),s=b.useRef(null),a=Fe(u=>u.selectedItemId),l=bt();return b.useEffect(()=>{if(s.current&&i.current){let u=s.current,f=i.current,c,d=new ResizeObserver(()=>{c=requestAnimationFrame(()=>{let p=u.offsetHeight;f.style.setProperty("--cmdk-list-height",p.toFixed(1)+"px")})});return d.observe(u),()=>{cancelAnimationFrame(c),d.unobserve(u)}}},[]),b.createElement(Be.div,{ref:mt(i,t),...o,"cmdk-list":"",role:"listbox",tabIndex:-1,"aria-activedescendant":a,"aria-label":r,id:l.listId},jt(e,u=>b.createElement("div",{ref:mt(s,l.listInnerRef),"cmdk-list-sizer":""},u)))}),ps=b.forwardRef((e,t)=>{let{open:n,onOpenChange:r,overlayClassName:o,contentClassName:i,container:s,...a}=e;return b.createElement(di,{open:n,onOpenChange:r},b.createElement(pi,{container:s},b.createElement(hi,{"cmdk-overlay":"",className:o}),b.createElement(mi,{"aria-label":e.label,"cmdk-dialog":"",className:i},b.createElement(Ar,{ref:t,...a}))))}),hs=b.forwardRef((e,t)=>Fe(n=>n.filtered.count===0)?b.createElement(Be.div,{ref:t,...e,"cmdk-empty":"",role:"presentation"}):null),ms=b.forwardRef((e,t)=>{let{progress:n,children:r,label:o="Loading...",...i}=e;return b.createElement(Be.div,{ref:t,...i,"cmdk-loading":"",role:"progressbar","aria-valuenow":n,"aria-valuemin":0,"aria-valuemax":100,"aria-label":o},jt(e,s=>b.createElement("div",{"aria-hidden":!0},s)))}),nf=Object.assign(Ar,{List:ds,Item:ls,Input:fs,Group:cs,Separator:us,Dialog:ps,Empty:hs,Loading:ms});function ys(e,t){let n=e.nextElementSibling;for(;n;){if(n.matches(t))return n;n=n.nextElementSibling}}function vs(e,t){let n=e.previousElementSibling;for(;n;){if(n.matches(t))return n;n=n.previousElementSibling}}function _r(e){let t=b.useRef(e);return ze(()=>{t.current=e}),t}var ze=typeof window>"u"?b.useEffect:b.useLayoutEffect;function Ke(e){let t=b.useRef();return t.current===void 0&&(t.current=e()),t}function Fe(e){let t=On(),n=()=>e(t.snapshot());return b.useSyncExternalStore(t.subscribe,n,n)}function Fr(e,t,n,r=[]){let o=b.useRef(),i=bt();return ze(()=>{var s;let a=(()=>{var u;for(let f of n){if(typeof f=="string")return f.trim();if(typeof f=="object"&&"current"in f)return f.current?(u=f.current.textContent)==null?void 0:u.trim():o.current}})(),l=r.map(u=>u.trim());i.value(e,a,l),(s=t.current)==null||s.setAttribute(Ve,a),o.current=a}),o}var gs=()=>{let[e,t]=b.useState(),n=Ke(()=>new Map);return ze(()=>{n.current.forEach(r=>r()),n.current=new Map},[e]),(r,o)=>{n.current.set(r,o),t({})}};function bs(e){let t=e.type;return typeof t=="function"?t(e.props):"render"in t?t.render(e.props):e}function jt({asChild:e,children:t},n){return e&&b.isValidElement(t)?b.cloneElement(bs(t),{ref:t.ref},n(t.props.children)):n(t)}var ws={position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"};function jr(e){return t=>typeof t===e}var Os=jr("function"),Ss=e=>e===null,$n=e=>Object.prototype.toString.call(e).slice(8,-1)==="RegExp",Hn=e=>!Es(e)&&!Ss(e)&&(Os(e)||typeof e=="object"),Es=jr("undefined");function ks(e,t){const{length:n}=e;if(n!==t.length)return!1;for(let r=n;r--!==0;)if(!re(e[r],t[r]))return!1;return!0}function Cs(e,t){if(e.byteLength!==t.byteLength)return!1;const n=new DataView(e.buffer),r=new DataView(t.buffer);let o=e.byteLength;for(;o--;)if(n.getUint8(o)!==r.getUint8(o))return!1;return!0}function Ts(e,t){if(e.size!==t.size)return!1;for(const n of e.entries())if(!t.has(n[0]))return!1;for(const n of e.entries())if(!re(n[1],t.get(n[0])))return!1;return!0}function Ms(e,t){if(e.size!==t.size)return!1;for(const n of e.entries())if(!t.has(n[0]))return!1;return!0}function re(e,t){if(e===t)return!0;if(e&&Hn(e)&&t&&Hn(t)){if(e.constructor!==t.constructor)return!1;if(Array.isArray(e)&&Array.isArray(t))return ks(e,t);if(e instanceof Map&&t instanceof Map)return Ts(e,t);if(e instanceof Set&&t instanceof Set)return Ms(e,t);if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t))return Cs(e,t);if($n(e)&&$n(t))return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===t.toString();const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let o=n.length;o--!==0;)if(!Object.prototype.hasOwnProperty.call(t,n[o]))return!1;for(let o=n.length;o--!==0;){const i=n[o];if(!(i==="_owner"&&e.$$typeof)&&!re(e[i],t[i]))return!1}return!0}return Number.isNaN(e)&&Number.isNaN(t)?!0:e===t}var Ps=["Array","ArrayBuffer","AsyncFunction","AsyncGenerator","AsyncGeneratorFunction","Date","Error","Function","Generator","GeneratorFunction","HTMLElement","Map","Object","Promise","RegExp","Set","WeakMap","WeakSet"],xs=["bigint","boolean","null","number","string","symbol","undefined"];function Bt(e){const t=Object.prototype.toString.call(e).slice(8,-1);if(/HTML\w+Element/.test(t))return"HTMLElement";if(Ns(t))return t}function be(e){return t=>Bt(t)===e}function Ns(e){return Ps.includes(e)}function tt(e){return t=>typeof t===e}function Ds(e){return xs.includes(e)}var Is=["innerHTML","ownerDocument","style","attributes","nodeValue"];function P(e){if(e===null)return"null";switch(typeof e){case"bigint":return"bigint";case"boolean":return"boolean";case"number":return"number";case"string":return"string";case"symbol":return"symbol";case"undefined":return"undefined"}if(P.array(e))return"Array";if(P.plainFunction(e))return"Function";const t=Bt(e);return t||"Object"}P.array=Array.isArray;P.arrayOf=(e,t)=>!P.array(e)&&!P.function(t)?!1:e.every(n=>t(n));P.asyncGeneratorFunction=e=>Bt(e)==="AsyncGeneratorFunction";P.asyncFunction=be("AsyncFunction");P.bigint=tt("bigint");P.boolean=e=>e===!0||e===!1;P.date=be("Date");P.defined=e=>!P.undefined(e);P.domElement=e=>P.object(e)&&!P.plainObject(e)&&e.nodeType===1&&P.string(e.nodeName)&&Is.every(t=>t in e);P.empty=e=>P.string(e)&&e.length===0||P.array(e)&&e.length===0||P.object(e)&&!P.map(e)&&!P.set(e)&&Object.keys(e).length===0||P.set(e)&&e.size===0||P.map(e)&&e.size===0;P.error=be("Error");P.function=tt("function");P.generator=e=>P.iterable(e)&&P.function(e.next)&&P.function(e.throw);P.generatorFunction=be("GeneratorFunction");P.instanceOf=(e,t)=>!e||!t?!1:Object.getPrototypeOf(e)===t.prototype;P.iterable=e=>!P.nullOrUndefined(e)&&P.function(e[Symbol.iterator]);P.map=be("Map");P.nan=e=>Number.isNaN(e);P.null=e=>e===null;P.nullOrUndefined=e=>P.null(e)||P.undefined(e);P.number=e=>tt("number")(e)&&!P.nan(e);P.numericString=e=>P.string(e)&&e.length>0&&!Number.isNaN(Number(e));P.object=e=>!P.nullOrUndefined(e)&&(P.function(e)||typeof e=="object");P.oneOf=(e,t)=>P.array(e)?e.indexOf(t)>-1:!1;P.plainFunction=be("Function");P.plainObject=e=>{if(Bt(e)!=="Object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.getPrototypeOf({})};P.primitive=e=>P.null(e)||Ds(typeof e);P.promise=be("Promise");P.propertyOf=(e,t,n)=>{if(!P.object(e)||!t)return!1;const r=e[t];return P.function(n)?n(r):P.defined(r)};P.regexp=be("RegExp");P.set=be("Set");P.string=tt("string");P.symbol=tt("symbol");P.undefined=tt("undefined");P.weakMap=be("WeakMap");P.weakSet=be("WeakSet");var x=P;function Ws(...e){return e.every(t=>x.string(t)||x.array(t)||x.plainObject(t))}function Rs(e,t,n){return Br(e,t)?[e,t].every(x.array)?!e.some(Gn(n))&&t.some(Gn(n)):[e,t].every(x.plainObject)?!Object.entries(e).some(qn(n))&&Object.entries(t).some(qn(n)):t===n:!1}function zn(e,t,n){const{actual:r,key:o,previous:i,type:s}=n,a=Ce(e,o),l=Ce(t,o);let u=[a,l].every(x.number)&&(s==="increased"?al);return x.undefined(r)||(u=u&&l===r),x.undefined(i)||(u=u&&a===i),u}function Un(e,t,n){const{key:r,type:o,value:i}=n,s=Ce(e,r),a=Ce(t,r),l=o==="added"?s:a,u=o==="added"?a:s;if(!x.nullOrUndefined(i)){if(x.defined(l)){if(x.array(l)||x.plainObject(l))return Rs(l,u,i)}else return re(u,i);return!1}return[s,a].every(x.array)?!u.every(Sn(l)):[s,a].every(x.plainObject)?As(Object.keys(l),Object.keys(u)):![s,a].every(f=>x.primitive(f)&&x.defined(f))&&(o==="added"?!x.defined(s)&&x.defined(a):x.defined(s)&&!x.defined(a))}function Yn(e,t,{key:n}={}){let r=Ce(e,n),o=Ce(t,n);if(!Br(r,o))throw new TypeError("Inputs have different types");if(!Ws(r,o))throw new TypeError("Inputs don't have length");return[r,o].every(x.plainObject)&&(r=Object.keys(r),o=Object.keys(o)),[r,o]}function qn(e){return([t,n])=>x.array(e)?re(e,n)||e.some(r=>re(r,n)||x.array(n)&&Sn(n)(r)):x.plainObject(e)&&e[t]?!!e[t]&&re(e[t],n):re(e,n)}function As(e,t){return t.some(n=>!e.includes(n))}function Gn(e){return t=>x.array(e)?e.some(n=>re(n,t)||x.array(t)&&Sn(t)(n)):re(e,t)}function lt(e,t){return x.array(e)?e.some(n=>re(n,t)):re(e,t)}function Sn(e){return t=>e.some(n=>re(n,t))}function Br(...e){return e.every(x.array)||e.every(x.number)||e.every(x.plainObject)||e.every(x.string)}function Ce(e,t){return x.plainObject(e)||x.array(e)?x.string(t)?t.split(".").reduce((r,o)=>r&&r[o],e):x.number(t)?e[t]:e:e}function Rt(e,t){if([e,t].some(x.nullOrUndefined))throw new Error("Missing required parameters");if(![e,t].every(f=>x.plainObject(f)||x.array(f)))throw new Error("Expected plain objects or array");return{added:(f,c)=>{try{return Un(e,t,{key:f,type:"added",value:c})}catch{return!1}},changed:(f,c,d)=>{try{const p=Ce(e,f),h=Ce(t,f),v=x.defined(c),S=x.defined(d);if(v||S){const y=S?lt(d,p):!lt(c,p),m=lt(c,h);return y&&m}return[p,h].every(x.array)||[p,h].every(x.plainObject)?!re(p,h):p!==h}catch{return!1}},changedFrom:(f,c,d)=>{if(!x.defined(f))return!1;try{const p=Ce(e,f),h=Ce(t,f),v=x.defined(d);return lt(c,p)&&(v?lt(d,h):!v)}catch{return!1}},decreased:(f,c,d)=>{if(!x.defined(f))return!1;try{return zn(e,t,{key:f,actual:c,previous:d,type:"decreased"})}catch{return!1}},emptied:f=>{try{const[c,d]=Yn(e,t,{key:f});return!!c.length&&!d.length}catch{return!1}},filled:f=>{try{const[c,d]=Yn(e,t,{key:f});return!c.length&&!!d.length}catch{return!1}},increased:(f,c,d)=>{if(!x.defined(f))return!1;try{return zn(e,t,{key:f,actual:c,previous:d,type:"increased"})}catch{return!1}},removed:(f,c)=>{try{return Un(e,t,{key:f,type:"removed",value:c})}catch{return!1}}}}var Xt,Vn;function _s(){if(Vn)return Xt;Vn=1;var e=new Error("Element already at target scroll position"),t=new Error("Scroll cancelled"),n=Math.min,r=Date.now;Xt={left:o("scrollLeft"),top:o("scrollTop")};function o(a){return function(u,f,c,d){c=c||{},typeof c=="function"&&(d=c,c={}),typeof d!="function"&&(d=s);var p=r(),h=u[a],v=c.ease||i,S=isNaN(c.duration)?350:+c.duration,y=!1;return h===f?d(e,u[a]):requestAnimationFrame(E),m;function m(){y=!0}function E(M){if(y)return d(t,u[a]);var C=r(),O=n(1,(C-p)/S),D=v(O);u[a]=D*(f-h)+h,O<1?requestAnimationFrame(E):requestAnimationFrame(function(){d(null,u[a])})}}}function i(a){return .5*(1-Math.cos(Math.PI*a))}function s(){}return Xt}var Fs=_s();const js=gt(Fs);var It={exports:{}},Bs=It.exports,Kn;function Ls(){return Kn||(Kn=1,(function(e){(function(t,n){e.exports?e.exports=n():t.Scrollparent=n()})(Bs,function(){function t(r){var o=getComputedStyle(r,null).getPropertyValue("overflow");return o.indexOf("scroll")>-1||o.indexOf("auto")>-1}function n(r){if(r instanceof HTMLElement||r instanceof SVGElement){for(var o=r.parentNode;o.parentNode;){if(t(o))return o;o=o.parentNode}return document.scrollingElement||document.documentElement}}return n})})(It)),It.exports}var $s=Ls();const Lr=gt($s);var Qt,Zn;function Hs(){if(Zn)return Qt;Zn=1;var e=function(r){return Object.prototype.hasOwnProperty.call(r,"props")},t=function(r,o){return r+n(o)},n=function(r){return r===null||typeof r=="boolean"||typeof r>"u"?"":typeof r=="number"?r.toString():typeof r=="string"?r:Array.isArray(r)?r.reduce(t,""):e(r)&&Object.prototype.hasOwnProperty.call(r.props,"children")?n(r.props.children):""};return n.default=n,Qt=n,Qt}var zs=Hs();const Jn=gt(zs);var en,Xn;function Us(){if(Xn)return en;Xn=1;var e=function(m){return t(m)&&!n(m)};function t(y){return!!y&&typeof y=="object"}function n(y){var m=Object.prototype.toString.call(y);return m==="[object RegExp]"||m==="[object Date]"||i(y)}var r=typeof Symbol=="function"&&Symbol.for,o=r?Symbol.for("react.element"):60103;function i(y){return y.$$typeof===o}function s(y){return Array.isArray(y)?[]:{}}function a(y,m){return m.clone!==!1&&m.isMergeableObject(y)?v(s(y),y,m):y}function l(y,m,E){return y.concat(m).map(function(M){return a(M,E)})}function u(y,m){if(!m.customMerge)return v;var E=m.customMerge(y);return typeof E=="function"?E:v}function f(y){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(y).filter(function(m){return Object.propertyIsEnumerable.call(y,m)}):[]}function c(y){return Object.keys(y).concat(f(y))}function d(y,m){try{return m in y}catch{return!1}}function p(y,m){return d(y,m)&&!(Object.hasOwnProperty.call(y,m)&&Object.propertyIsEnumerable.call(y,m))}function h(y,m,E){var M={};return E.isMergeableObject(y)&&c(y).forEach(function(C){M[C]=a(y[C],E)}),c(m).forEach(function(C){p(y,C)||(d(y,C)&&E.isMergeableObject(m[C])?M[C]=u(C,E)(y[C],m[C],E):M[C]=a(m[C],E))}),M}function v(y,m,E){E=E||{},E.arrayMerge=E.arrayMerge||l,E.isMergeableObject=E.isMergeableObject||e,E.cloneUnlessOtherwiseSpecified=a;var M=Array.isArray(m),C=Array.isArray(y),O=M===C;return O?M?E.arrayMerge(y,m,E):h(y,m,E):a(m,E)}v.all=function(m,E){if(!Array.isArray(m))throw new Error("first argument should be an array");return m.reduce(function(M,C){return v(M,C,E)},{})};var S=v;return en=S,en}var Ys=Us();const ve=gt(Ys);var tn={exports:{}},nn,Qn;function qs(){if(Qn)return nn;Qn=1;var e="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";return nn=e,nn}var rn,er;function Gs(){if(er)return rn;er=1;var e=qs();function t(){}function n(){}return n.resetWarningCache=t,rn=function(){function r(s,a,l,u,f,c){if(c!==e){var d=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 d.name="Invariant Violation",d}}r.isRequired=r;function o(){return r}var i={array:r,bigint:r,bool:r,func:r,number:r,object:r,string:r,symbol:r,any:r,arrayOf:o,element:r,elementType:r,instanceOf:o,node:r,objectOf:o,oneOf:o,oneOfType:o,shape:o,exact:o,checkPropTypes:n,resetWarningCache:t};return i.PropTypes=i,i},rn}var tr;function Vs(){return tr||(tr=1,tn.exports=Gs()()),tn.exports}var Ks=Vs();const T=gt(Ks);var wt=typeof window<"u"&&typeof document<"u"&&typeof navigator<"u",Zs=(function(){for(var e=["Edge","Trident","Firefox"],t=0;t=0)return 1;return 0})();function Js(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}function Xs(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},Zs))}}var Qs=wt&&window.Promise,ea=Qs?Js:Xs;function $r(e){var t={};return e&&t.toString.call(e)==="[object Function]"}function Ye(e,t){if(e.nodeType!==1)return[];var n=e.ownerDocument.defaultView,r=n.getComputedStyle(e,null);return t?r[t]:r}function En(e){return e.nodeName==="HTML"?e:e.parentNode||e.host}function Ot(e){if(!e)return document.body;switch(e.nodeName){case"HTML":case"BODY":return e.ownerDocument.body;case"#document":return e.body}var t=Ye(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/(auto|scroll|overlay)/.test(n+o+r)?e:Ot(En(e))}function Hr(e){return e&&e.referenceNode?e.referenceNode:e}var nr=wt&&!!(window.MSInputMethodContext&&document.documentMode),rr=wt&&/MSIE 10/.test(navigator.userAgent);function nt(e){return e===11?nr:e===10?rr:nr||rr}function Je(e){if(!e)return document.documentElement;for(var t=nt(10)?document.body:null,n=e.offsetParent||null;n===t&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var r=n&&n.nodeName;return!r||r==="BODY"||r==="HTML"?e?e.ownerDocument.documentElement:document.documentElement:["TH","TD","TABLE"].indexOf(n.nodeName)!==-1&&Ye(n,"position")==="static"?Je(n):n}function ta(e){var t=e.nodeName;return t==="BODY"?!1:t==="HTML"||Je(e.firstElementChild)===e}function hn(e){return e.parentNode!==null?hn(e.parentNode):e}function At(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var n=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,r=n?e:t,o=n?t:e,i=document.createRange();i.setStart(r,0),i.setEnd(o,0);var s=i.commonAncestorContainer;if(e!==s&&t!==s||r.contains(o))return ta(s)?s:Je(s);var a=hn(e);return a.host?At(a.host,t):At(e,hn(t).host)}function Xe(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"top",n=t==="top"?"scrollTop":"scrollLeft",r=e.nodeName;if(r==="BODY"||r==="HTML"){var o=e.ownerDocument.documentElement,i=e.ownerDocument.scrollingElement||o;return i[n]}return e[n]}function na(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1,r=Xe(t,"top"),o=Xe(t,"left"),i=n?-1:1;return e.top+=r*i,e.bottom+=r*i,e.left+=o*i,e.right+=o*i,e}function or(e,t){var n=t==="x"?"Left":"Top",r=n==="Left"?"Right":"Bottom";return parseFloat(e["border"+n+"Width"])+parseFloat(e["border"+r+"Width"])}function ir(e,t,n,r){return Math.max(t["offset"+e],t["scroll"+e],n["client"+e],n["offset"+e],n["scroll"+e],nt(10)?parseInt(n["offset"+e])+parseInt(r["margin"+(e==="Height"?"Top":"Left")])+parseInt(r["margin"+(e==="Height"?"Bottom":"Right")]):0)}function zr(e){var t=e.body,n=e.documentElement,r=nt(10)&&getComputedStyle(n);return{height:ir("Height",t,n,r),width:ir("Width",t,n,r)}}var ra=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},oa=(function(){function e(t,n){for(var r=0;r2&&arguments[2]!==void 0?arguments[2]:!1,r=nt(10),o=t.nodeName==="HTML",i=mn(e),s=mn(t),a=Ot(e),l=Ye(t),u=parseFloat(l.borderTopWidth),f=parseFloat(l.borderLeftWidth);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var c=je({top:i.top-s.top-u,left:i.left-s.left-f,width:i.width,height:i.height});if(c.marginTop=0,c.marginLeft=0,!r&&o){var d=parseFloat(l.marginTop),p=parseFloat(l.marginLeft);c.top-=u-d,c.bottom-=u-d,c.left-=f-p,c.right-=f-p,c.marginTop=d,c.marginLeft=p}return(r&&!n?t.contains(a):t===a&&a.nodeName!=="BODY")&&(c=na(c,t)),c}function ia(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=e.ownerDocument.documentElement,r=kn(e,n),o=Math.max(n.clientWidth,window.innerWidth||0),i=Math.max(n.clientHeight,window.innerHeight||0),s=t?0:Xe(n),a=t?0:Xe(n,"left"),l={top:s-r.top+r.marginTop,left:a-r.left+r.marginLeft,width:o,height:i};return je(l)}function Ur(e){var t=e.nodeName;if(t==="BODY"||t==="HTML")return!1;if(Ye(e,"position")==="fixed")return!0;var n=En(e);return n?Ur(n):!1}function Yr(e){if(!e||!e.parentElement||nt())return document.documentElement;for(var t=e.parentElement;t&&Ye(t,"transform")==="none";)t=t.parentElement;return t||document.documentElement}function Cn(e,t,n,r){var o=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1,i={top:0,left:0},s=o?Yr(e):At(e,Hr(t));if(r==="viewport")i=ia(s,o);else{var a=void 0;r==="scrollParent"?(a=Ot(En(t)),a.nodeName==="BODY"&&(a=e.ownerDocument.documentElement)):r==="window"?a=e.ownerDocument.documentElement:a=r;var l=kn(a,s,o);if(a.nodeName==="HTML"&&!Ur(s)){var u=zr(e.ownerDocument),f=u.height,c=u.width;i.top+=l.top-l.marginTop,i.bottom=f+l.top,i.left+=l.left-l.marginLeft,i.right=c+l.left}else i=l}n=n||0;var d=typeof n=="number";return i.left+=d?n:n.left||0,i.top+=d?n:n.top||0,i.right-=d?n:n.right||0,i.bottom-=d?n:n.bottom||0,i}function sa(e){var t=e.width,n=e.height;return t*n}function qr(e,t,n,r,o){var i=arguments.length>5&&arguments[5]!==void 0?arguments[5]:0;if(e.indexOf("auto")===-1)return e;var s=Cn(n,r,i,o),a={top:{width:s.width,height:t.top-s.top},right:{width:s.right-t.right,height:s.height},bottom:{width:s.width,height:s.bottom-t.bottom},left:{width:t.left-s.left,height:s.height}},l=Object.keys(a).map(function(d){return he({key:d},a[d],{area:sa(a[d])})}).sort(function(d,p){return p.area-d.area}),u=l.filter(function(d){var p=d.width,h=d.height;return p>=n.clientWidth&&h>=n.clientHeight}),f=u.length>0?u[0].key:l[0].key,c=e.split("-")[1];return f+(c?"-"+c:"")}function Gr(e,t,n){var r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:null,o=r?Yr(t):At(t,Hr(n));return kn(n,o,r)}function Vr(e){var t=e.ownerDocument.defaultView,n=t.getComputedStyle(e),r=parseFloat(n.marginTop||0)+parseFloat(n.marginBottom||0),o=parseFloat(n.marginLeft||0)+parseFloat(n.marginRight||0),i={width:e.offsetWidth+o,height:e.offsetHeight+r};return i}function _t(e){var t={left:"right",right:"left",bottom:"top",top:"bottom"};return e.replace(/left|right|bottom|top/g,function(n){return t[n]})}function Kr(e,t,n){n=n.split("-")[0];var r=Vr(e),o={width:r.width,height:r.height},i=["right","left"].indexOf(n)!==-1,s=i?"top":"left",a=i?"left":"top",l=i?"height":"width",u=i?"width":"height";return o[s]=t[s]+t[l]/2-r[l]/2,n===a?o[a]=t[a]-r[u]:o[a]=t[_t(a)],o}function St(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function aa(e,t,n){if(Array.prototype.findIndex)return e.findIndex(function(o){return o[t]===n});var r=St(e,function(o){return o[t]===n});return e.indexOf(r)}function Zr(e,t,n){var r=n===void 0?e:e.slice(0,aa(e,"name",n));return r.forEach(function(o){o.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var i=o.function||o.fn;o.enabled&&$r(i)&&(t.offsets.popper=je(t.offsets.popper),t.offsets.reference=je(t.offsets.reference),t=i(t,o))}),t}function la(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=Gr(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=qr(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=Kr(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",e=Zr(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function Jr(e,t){return e.some(function(n){var r=n.name,o=n.enabled;return o&&r===t})}function Tn(e){for(var t=[!1,"ms","Webkit","Moz","O"],n=e.charAt(0).toUpperCase()+e.slice(1),r=0;rs[p]&&(e.offsets.popper[c]+=a[c]+h-s[p]),e.offsets.popper=je(e.offsets.popper);var v=a[c]+a[u]/2-h/2,S=Ye(e.instance.popper),y=parseFloat(S["margin"+f]),m=parseFloat(S["border"+f+"Width"]),E=v-e.offsets.popper[c]-y-m;return E=Math.max(Math.min(s[u]-h,E),0),e.arrowElement=r,e.offsets.arrow=(n={},Qe(n,c,Math.round(E)),Qe(n,d,""),n),e}function Oa(e){return e==="end"?"start":e==="start"?"end":e}var to=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],on=to.slice(3);function sr(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=on.indexOf(e),r=on.slice(n+1).concat(on.slice(0,n));return t?r.reverse():r}var sn={FLIP:"flip",CLOCKWISE:"clockwise",COUNTERCLOCKWISE:"counterclockwise"};function Sa(e,t){if(Jr(e.instance.modifiers,"inner")||e.flipped&&e.placement===e.originalPlacement)return e;var n=Cn(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),r=e.placement.split("-")[0],o=_t(r),i=e.placement.split("-")[1]||"",s=[];switch(t.behavior){case sn.FLIP:s=[r,o];break;case sn.CLOCKWISE:s=sr(r);break;case sn.COUNTERCLOCKWISE:s=sr(r,!0);break;default:s=t.behavior}return s.forEach(function(a,l){if(r!==a||s.length===l+1)return e;r=e.placement.split("-")[0],o=_t(r);var u=e.offsets.popper,f=e.offsets.reference,c=Math.floor,d=r==="left"&&c(u.right)>c(f.left)||r==="right"&&c(u.left)c(f.top)||r==="bottom"&&c(u.top)c(n.right),v=c(u.top)c(n.bottom),y=r==="left"&&p||r==="right"&&h||r==="top"&&v||r==="bottom"&&S,m=["top","bottom"].indexOf(r)!==-1,E=!!t.flipVariations&&(m&&i==="start"&&p||m&&i==="end"&&h||!m&&i==="start"&&v||!m&&i==="end"&&S),M=!!t.flipVariationsByContent&&(m&&i==="start"&&h||m&&i==="end"&&p||!m&&i==="start"&&S||!m&&i==="end"&&v),C=E||M;(d||y||C)&&(e.flipped=!0,(d||y)&&(r=s[l+1]),C&&(i=Oa(i)),e.placement=r+(i?"-"+i:""),e.offsets.popper=he({},e.offsets.popper,Kr(e.instance.popper,e.offsets.reference,e.placement)),e=Zr(e.instance.modifiers,e,"flip"))}),e}function Ea(e){var t=e.offsets,n=t.popper,r=t.reference,o=e.placement.split("-")[0],i=Math.floor,s=["top","bottom"].indexOf(o)!==-1,a=s?"right":"bottom",l=s?"left":"top",u=s?"width":"height";return n[a]i(r[a])&&(e.offsets.popper[l]=i(r[a])),e}function ka(e,t,n,r){var o=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),i=+o[1],s=o[2];if(!i)return e;if(s.indexOf("%")===0){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=r}var l=je(a);return l[t]/100*i}else if(s==="vh"||s==="vw"){var u=void 0;return s==="vh"?u=Math.max(document.documentElement.clientHeight,window.innerHeight||0):u=Math.max(document.documentElement.clientWidth,window.innerWidth||0),u/100*i}else return i}function Ca(e,t,n,r){var o=[0,0],i=["right","left"].indexOf(r)!==-1,s=e.split(/(\+|\-)/).map(function(f){return f.trim()}),a=s.indexOf(St(s,function(f){return f.search(/,|\s/)!==-1}));s[a]&&s[a].indexOf(",")===-1&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,u=a!==-1?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return u=u.map(function(f,c){var d=(c===1?!i:i)?"height":"width",p=!1;return f.reduce(function(h,v){return h[h.length-1]===""&&["+","-"].indexOf(v)!==-1?(h[h.length-1]=v,p=!0,h):p?(h[h.length-1]+=v,p=!1,h):h.concat(v)},[]).map(function(h){return ka(h,d,t,n)})}),u.forEach(function(f,c){f.forEach(function(d,p){Mn(d)&&(o[c]+=d*(f[p-1]==="-"?-1:1))})}),o}function Ta(e,t){var n=t.offset,r=e.placement,o=e.offsets,i=o.popper,s=o.reference,a=r.split("-")[0],l=void 0;return Mn(+n)?l=[+n,0]:l=Ca(n,i,s,a),a==="left"?(i.top+=l[0],i.left-=l[1]):a==="right"?(i.top+=l[0],i.left+=l[1]):a==="top"?(i.left+=l[0],i.top-=l[1]):a==="bottom"&&(i.left+=l[0],i.top+=l[1]),e.popper=i,e}function Ma(e,t){var n=t.boundariesElement||Je(e.instance.popper);e.instance.reference===n&&(n=Je(n));var r=Tn("transform"),o=e.instance.popper.style,i=o.top,s=o.left,a=o[r];o.top="",o.left="",o[r]="";var l=Cn(e.instance.popper,e.instance.reference,t.padding,n,e.positionFixed);o.top=i,o.left=s,o[r]=a,t.boundaries=l;var u=t.priority,f=e.offsets.popper,c={primary:function(p){var h=f[p];return f[p]l[p]&&!t.escapeWithReference&&(v=Math.min(f[h],l[p]-(p==="right"?f.width:f.height))),Qe({},h,v)}};return u.forEach(function(d){var p=["left","top"].indexOf(d)!==-1?"primary":"secondary";f=he({},f,c[p](d))}),e.offsets.popper=f,e}function Pa(e){var t=e.placement,n=t.split("-")[0],r=t.split("-")[1];if(r){var o=e.offsets,i=o.reference,s=o.popper,a=["bottom","top"].indexOf(n)!==-1,l=a?"left":"top",u=a?"width":"height",f={start:Qe({},l,i[l]),end:Qe({},l,i[l]+i[u]-s[u])};e.offsets.popper=he({},s,f[r])}return e}function xa(e){if(!eo(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=St(e.instance.modifiers,function(r){return r.name==="preventOverflow"}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.right2&&arguments[2]!==void 0?arguments[2]:{};ra(this,e),this.scheduleUpdate=function(){return requestAnimationFrame(r.update)},this.update=ea(this.update.bind(this)),this.options=he({},e.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=t&&t.jquery?t[0]:t,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(he({},e.Defaults.modifiers,o.modifiers)).forEach(function(s){r.options.modifiers[s]=he({},e.Defaults.modifiers[s]||{},o.modifiers?o.modifiers[s]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(s){return he({name:s},r.options.modifiers[s])}).sort(function(s,a){return s.order-a.order}),this.modifiers.forEach(function(s){s.enabled&&$r(s.onLoad)&&s.onLoad(r.reference,r.popper,r.options,s,r.state)}),this.update();var i=this.options.eventsEnabled;i&&this.enableEventListeners(),this.state.eventsEnabled=i}return oa(e,[{key:"update",value:function(){return la.call(this)}},{key:"destroy",value:function(){return ca.call(this)}},{key:"enableEventListeners",value:function(){return fa.call(this)}},{key:"disableEventListeners",value:function(){return pa.call(this)}}]),e})();yt.Utils=(typeof window<"u"?window:global).PopperUtils;yt.placements=to;yt.Defaults=Ia;var Wa=["innerHTML","ownerDocument","style","attributes","nodeValue"],Ra=["Array","ArrayBuffer","AsyncFunction","AsyncGenerator","AsyncGeneratorFunction","Date","Error","Function","Generator","GeneratorFunction","HTMLElement","Map","Object","Promise","RegExp","Set","WeakMap","WeakSet"],Aa=["bigint","boolean","null","number","string","symbol","undefined"];function Lt(e){var t=Object.prototype.toString.call(e).slice(8,-1);if(/HTML\w+Element/.test(t))return"HTMLElement";if(_a(t))return t}function we(e){return function(t){return Lt(t)===e}}function _a(e){return Ra.includes(e)}function rt(e){return function(t){return typeof t===e}}function Fa(e){return Aa.includes(e)}function g(e){if(e===null)return"null";switch(typeof e){case"bigint":return"bigint";case"boolean":return"boolean";case"number":return"number";case"string":return"string";case"symbol":return"symbol";case"undefined":return"undefined"}if(g.array(e))return"Array";if(g.plainFunction(e))return"Function";var t=Lt(e);return t||"Object"}g.array=Array.isArray;g.arrayOf=function(e,t){return!g.array(e)&&!g.function(t)?!1:e.every(function(n){return t(n)})};g.asyncGeneratorFunction=function(e){return Lt(e)==="AsyncGeneratorFunction"};g.asyncFunction=we("AsyncFunction");g.bigint=rt("bigint");g.boolean=function(e){return e===!0||e===!1};g.date=we("Date");g.defined=function(e){return!g.undefined(e)};g.domElement=function(e){return g.object(e)&&!g.plainObject(e)&&e.nodeType===1&&g.string(e.nodeName)&&Wa.every(function(t){return t in e})};g.empty=function(e){return g.string(e)&&e.length===0||g.array(e)&&e.length===0||g.object(e)&&!g.map(e)&&!g.set(e)&&Object.keys(e).length===0||g.set(e)&&e.size===0||g.map(e)&&e.size===0};g.error=we("Error");g.function=rt("function");g.generator=function(e){return g.iterable(e)&&g.function(e.next)&&g.function(e.throw)};g.generatorFunction=we("GeneratorFunction");g.instanceOf=function(e,t){return!e||!t?!1:Object.getPrototypeOf(e)===t.prototype};g.iterable=function(e){return!g.nullOrUndefined(e)&&g.function(e[Symbol.iterator])};g.map=we("Map");g.nan=function(e){return Number.isNaN(e)};g.null=function(e){return e===null};g.nullOrUndefined=function(e){return g.null(e)||g.undefined(e)};g.number=function(e){return rt("number")(e)&&!g.nan(e)};g.numericString=function(e){return g.string(e)&&e.length>0&&!Number.isNaN(Number(e))};g.object=function(e){return!g.nullOrUndefined(e)&&(g.function(e)||typeof e=="object")};g.oneOf=function(e,t){return g.array(e)?e.indexOf(t)>-1:!1};g.plainFunction=we("Function");g.plainObject=function(e){if(Lt(e)!=="Object")return!1;var t=Object.getPrototypeOf(e);return t===null||t===Object.getPrototypeOf({})};g.primitive=function(e){return g.null(e)||Fa(typeof e)};g.promise=we("Promise");g.propertyOf=function(e,t,n){if(!g.object(e)||!t)return!1;var r=e[t];return g.function(n)?n(r):g.defined(r)};g.regexp=we("RegExp");g.set=we("Set");g.string=rt("string");g.symbol=rt("symbol");g.undefined=rt("undefined");g.weakMap=we("WeakMap");g.weakSet=we("WeakSet");function no(e){return function(t){return typeof t===e}}var ja=no("function"),Ba=function(e){return e===null},ar=function(e){return Object.prototype.toString.call(e).slice(8,-1)==="RegExp"},lr=function(e){return!La(e)&&!Ba(e)&&(ja(e)||typeof e=="object")},La=no("undefined"),vn=function(e){var t=typeof Symbol=="function"&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&typeof e.length=="number")return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};function $a(e,t){var n=e.length;if(n!==t.length)return!1;for(var r=n;r--!==0;)if(!ae(e[r],t[r]))return!1;return!0}function Ha(e,t){if(e.byteLength!==t.byteLength)return!1;for(var n=new DataView(e.buffer),r=new DataView(t.buffer),o=e.byteLength;o--;)if(n.getUint8(o)!==r.getUint8(o))return!1;return!0}function za(e,t){var n,r,o,i;if(e.size!==t.size)return!1;try{for(var s=vn(e.entries()),a=s.next();!a.done;a=s.next()){var l=a.value;if(!t.has(l[0]))return!1}}catch(c){n={error:c}}finally{try{a&&!a.done&&(r=s.return)&&r.call(s)}finally{if(n)throw n.error}}try{for(var u=vn(e.entries()),f=u.next();!f.done;f=u.next()){var l=f.value;if(!ae(l[1],t.get(l[0])))return!1}}catch(c){o={error:c}}finally{try{f&&!f.done&&(i=u.return)&&i.call(u)}finally{if(o)throw o.error}}return!0}function Ua(e,t){var n,r;if(e.size!==t.size)return!1;try{for(var o=vn(e.entries()),i=o.next();!i.done;i=o.next()){var s=i.value;if(!t.has(s[0]))return!1}}catch(a){n={error:a}}finally{try{i&&!i.done&&(r=o.return)&&r.call(o)}finally{if(n)throw n.error}}return!0}function ae(e,t){if(e===t)return!0;if(e&&lr(e)&&t&&lr(t)){if(e.constructor!==t.constructor)return!1;if(Array.isArray(e)&&Array.isArray(t))return $a(e,t);if(e instanceof Map&&t instanceof Map)return za(e,t);if(e instanceof Set&&t instanceof Set)return Ua(e,t);if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t))return Ha(e,t);if(ar(e)&&ar(t))return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===t.toString();var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(var o=n.length;o--!==0;)if(!Object.prototype.hasOwnProperty.call(t,n[o]))return!1;for(var o=n.length;o--!==0;){var i=n[o];if(!(i==="_owner"&&e.$$typeof)&&!ae(e[i],t[i]))return!1}return!0}return Number.isNaN(e)&&Number.isNaN(t)?!0:e===t}function Ya(){for(var e=[],t=0;tl);return g.undefined(r)||(u=u&&l===r),g.undefined(i)||(u=u&&a===i),u}function ur(e,t,n){var r=n.key,o=n.type,i=n.value,s=Te(e,r),a=Te(t,r),l=o==="added"?s:a,u=o==="added"?a:s;if(!g.nullOrUndefined(i)){if(g.defined(l)){if(g.array(l)||g.plainObject(l))return qa(l,u,i)}else return ae(u,i);return!1}return[s,a].every(g.array)?!u.every(Pn(l)):[s,a].every(g.plainObject)?Ga(Object.keys(l),Object.keys(u)):![s,a].every(function(f){return g.primitive(f)&&g.defined(f)})&&(o==="added"?!g.defined(s)&&g.defined(a):g.defined(s)&&!g.defined(a))}function fr(e,t,n){var r=n===void 0?{}:n,o=r.key,i=Te(e,o),s=Te(t,o);if(!ro(i,s))throw new TypeError("Inputs have different types");if(!Ya(i,s))throw new TypeError("Inputs don't have length");return[i,s].every(g.plainObject)&&(i=Object.keys(i),s=Object.keys(s)),[i,s]}function dr(e){return function(t){var n=t[0],r=t[1];return g.array(e)?ae(e,r)||e.some(function(o){return ae(o,r)||g.array(r)&&Pn(r)(o)}):g.plainObject(e)&&e[n]?!!e[n]&&ae(e[n],r):ae(e,r)}}function Ga(e,t){return t.some(function(n){return!e.includes(n)})}function pr(e){return function(t){return g.array(e)?e.some(function(n){return ae(n,t)||g.array(t)&&Pn(t)(n)}):ae(e,t)}}function ct(e,t){return g.array(e)?e.some(function(n){return ae(n,t)}):ae(e,t)}function Pn(e){return function(t){return e.some(function(n){return ae(n,t)})}}function ro(){for(var e=[],t=0;t"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function Ja(e,t){if(e==null)return{};var n={},r=Object.keys(e),o,i;for(i=0;i=0)&&(n[o]=e[o]);return n}function oo(e,t){if(e==null)return{};var n=Ja(e,t),r,o;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function Ne(e){if(e===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Xa(e,t){if(t&&(typeof t=="object"||typeof t=="function"))return t;if(t!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return Ne(e)}function Tt(e){var t=Za();return function(){var r=Ft(e),o;if(t){var i=Ft(this).constructor;o=Reflect.construct(r,arguments,i)}else o=r.apply(this,arguments);return Xa(this,o)}}function Qa(e,t){if(typeof e!="object"||e===null)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t);if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}function io(e){var t=Qa(e,"string");return typeof t=="symbol"?t:String(t)}var el={flip:{padding:20},preventOverflow:{padding:10}},tl="The typeValidator argument must be a function with the signature function(props, propName, componentName).",nl="The error message is optional, but must be a string if provided.";function rl(e,t,n,r){return typeof e=="boolean"?e:typeof e=="function"?e(t,n,r):e?!!e:!1}function ol(e,t){return Object.hasOwnProperty.call(e,t)}function il(e,t,n,r){return new Error("Required ".concat(e[t]," `").concat(t,"` was not specified in `").concat(n,"`."))}function sl(e,t){if(typeof e!="function")throw new TypeError(tl);if(t&&typeof t!="string")throw new TypeError(nl)}function mr(e,t,n){return sl(e,n),function(r,o,i){for(var s=arguments.length,a=new Array(s>3?s-3:0),l=3;l3&&arguments[3]!==void 0?arguments[3]:!1;e.addEventListener(t,n,r)}function ll(e,t,n){var r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;e.removeEventListener(t,n,r)}function cl(e,t,n){var r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,o;o=function(s){n(s),ll(e,t,o)},al(e,t,o,r)}function yr(){}var so=(function(e){Ct(n,e);var t=Tt(n);function n(){return Et(this,n),t.apply(this,arguments)}return kt(n,[{key:"componentDidMount",value:function(){Ee()&&(this.node||this.appendNode(),ut||this.renderPortal())}},{key:"componentDidUpdate",value:function(){Ee()&&(ut||this.renderPortal())}},{key:"componentWillUnmount",value:function(){!Ee()||!this.node||(ut||Nt.unmountComponentAtNode(this.node),this.node&&this.node.parentNode===document.body&&(document.body.removeChild(this.node),this.node=void 0))}},{key:"appendNode",value:function(){var o=this.props,i=o.id,s=o.zIndex;this.node||(this.node=document.createElement("div"),i&&(this.node.id=i),s&&(this.node.style.zIndex=s),document.body.appendChild(this.node))}},{key:"renderPortal",value:function(){if(!Ee())return null;var o=this.props,i=o.children,s=o.setRef;if(this.node||this.appendNode(),ut)return Nt.createPortal(i,this.node);var a=Nt.unstable_renderSubtreeIntoContainer(this,i.length>1?w.createElement("div",null,i):i[0],this.node);return s(a),null}},{key:"renderReact16",value:function(){var o=this.props,i=o.hasChildren,s=o.placement,a=o.target;return i?this.renderPortal():a||s==="center"?this.renderPortal():null}},{key:"render",value:function(){return ut?this.renderReact16():null}}]),n})(w.Component);te(so,"propTypes",{children:T.oneOfType([T.element,T.array]),hasChildren:T.bool,id:T.oneOfType([T.string,T.number]),placement:T.string,setRef:T.func.isRequired,target:T.oneOfType([T.object,T.string]),zIndex:T.number});var ao=(function(e){Ct(n,e);var t=Tt(n);function n(){return Et(this,n),t.apply(this,arguments)}return kt(n,[{key:"parentStyle",get:function(){var o=this.props,i=o.placement,s=o.styles,a=s.arrow.length,l={pointerEvents:"none",position:"absolute",width:"100%"};return i.startsWith("top")?(l.bottom=0,l.left=0,l.right=0,l.height=a):i.startsWith("bottom")?(l.left=0,l.right=0,l.top=0,l.height=a):i.startsWith("left")?(l.right=0,l.top=0,l.bottom=0):i.startsWith("right")&&(l.left=0,l.top=0),l}},{key:"render",value:function(){var o=this.props,i=o.placement,s=o.setArrowRef,a=o.styles,l=a.arrow,u=l.color,f=l.display,c=l.length,d=l.margin,p=l.position,h=l.spread,v={display:f,position:p},S,y=h,m=c;return i.startsWith("top")?(S="0,0 ".concat(y/2,",").concat(m," ").concat(y,",0"),v.bottom=0,v.marginLeft=d,v.marginRight=d):i.startsWith("bottom")?(S="".concat(y,",").concat(m," ").concat(y/2,",0 0,").concat(m),v.top=0,v.marginLeft=d,v.marginRight=d):i.startsWith("left")?(m=h,y=c,S="0,0 ".concat(y,",").concat(m/2," 0,").concat(m),v.right=0,v.marginTop=d,v.marginBottom=d):i.startsWith("right")&&(m=h,y=c,S="".concat(y,",").concat(m," ").concat(y,",0 0,").concat(m/2),v.left=0,v.marginTop=d,v.marginBottom=d),w.createElement("div",{className:"__floater__arrow",style:this.parentStyle},w.createElement("span",{ref:s,style:v},w.createElement("svg",{width:y,height:m,version:"1.1",xmlns:"http://www.w3.org/2000/svg"},w.createElement("polygon",{points:S,fill:u}))))}}]),n})(w.Component);te(ao,"propTypes",{placement:T.string.isRequired,setArrowRef:T.func.isRequired,styles:T.object.isRequired});var ul=["color","height","width"];function lo(e){var t=e.handleClick,n=e.styles,r=n.color,o=n.height,i=n.width,s=oo(n,ul);return w.createElement("button",{"aria-label":"close",onClick:t,style:s,type:"button"},w.createElement("svg",{width:"".concat(i,"px"),height:"".concat(o,"px"),viewBox:"0 0 18 18",version:"1.1",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid"},w.createElement("g",null,w.createElement("path",{d:"M8.13911129,9.00268191 L0.171521827,17.0258467 C-0.0498027049,17.248715 -0.0498027049,17.6098394 0.171521827,17.8327545 C0.28204354,17.9443526 0.427188206,17.9998706 0.572051765,17.9998706 C0.71714958,17.9998706 0.862013139,17.9443526 0.972581703,17.8327545 L9.0000937,9.74924618 L17.0276057,17.8327545 C17.1384085,17.9443526 17.2832721,17.9998706 17.4281356,17.9998706 C17.5729992,17.9998706 17.718097,17.9443526 17.8286656,17.8327545 C18.0499901,17.6098862 18.0499901,17.2487618 17.8286656,17.0258467 L9.86135722,9.00268191 L17.8340066,0.973848225 C18.0553311,0.750979934 18.0553311,0.389855532 17.8340066,0.16694039 C17.6126821,-0.0556467968 17.254037,-0.0556467968 17.0329467,0.16694039 L9.00042166,8.25611765 L0.967006424,0.167268345 C0.745681892,-0.0553188426 0.387317931,-0.0553188426 0.165993399,0.167268345 C-0.0553311331,0.390136635 -0.0553311331,0.751261038 0.165993399,0.974176179 L8.13920499,9.00268191 L8.13911129,9.00268191 Z",fill:r}))))}lo.propTypes={handleClick:T.func.isRequired,styles:T.object.isRequired};function co(e){var t=e.content,n=e.footer,r=e.handleClick,o=e.open,i=e.positionWrapper,s=e.showCloseButton,a=e.title,l=e.styles,u={content:w.isValidElement(t)?t:w.createElement("div",{className:"__floater__content",style:l.content},t)};return a&&(u.title=w.isValidElement(a)?a:w.createElement("div",{className:"__floater__title",style:l.title},a)),n&&(u.footer=w.isValidElement(n)?n:w.createElement("div",{className:"__floater__footer",style:l.footer},n)),(s||i)&&!g.boolean(o)&&(u.close=w.createElement(lo,{styles:l.close,handleClick:r})),w.createElement("div",{className:"__floater__container",style:l.container},u.close,u.title,u.content,u.footer)}co.propTypes={content:T.node.isRequired,footer:T.node,handleClick:T.func.isRequired,open:T.bool,positionWrapper:T.bool.isRequired,showCloseButton:T.bool.isRequired,styles:T.object.isRequired,title:T.node};var uo=(function(e){Ct(n,e);var t=Tt(n);function n(){return Et(this,n),t.apply(this,arguments)}return kt(n,[{key:"style",get:function(){var o=this.props,i=o.disableAnimation,s=o.component,a=o.placement,l=o.hideArrow,u=o.status,f=o.styles,c=f.arrow.length,d=f.floater,p=f.floaterCentered,h=f.floaterClosing,v=f.floaterOpening,S=f.floaterWithAnimation,y=f.floaterWithComponent,m={};return l||(a.startsWith("top")?m.padding="0 0 ".concat(c,"px"):a.startsWith("bottom")?m.padding="".concat(c,"px 0 0"):a.startsWith("left")?m.padding="0 ".concat(c,"px 0 0"):a.startsWith("right")&&(m.padding="0 0 0 ".concat(c,"px"))),[z.OPENING,z.OPEN].indexOf(u)!==-1&&(m=K(K({},m),v)),u===z.CLOSING&&(m=K(K({},m),h)),u===z.OPEN&&!i&&(m=K(K({},m),S)),a==="center"&&(m=K(K({},m),p)),s&&(m=K(K({},m),y)),K(K({},d),m)}},{key:"render",value:function(){var o=this.props,i=o.component,s=o.handleClick,a=o.hideArrow,l=o.setFloaterRef,u=o.status,f={},c=["__floater"];return i?w.isValidElement(i)?f.content=w.cloneElement(i,{closeFn:s}):f.content=i({closeFn:s}):f.content=w.createElement(co,this.props),u===z.OPEN&&c.push("__floater__open"),a||(f.arrow=w.createElement(ao,this.props)),w.createElement("div",{ref:l,className:c.join(" "),style:this.style},w.createElement("div",{className:"__floater__body"},f.content,f.arrow))}}]),n})(w.Component);te(uo,"propTypes",{component:T.oneOfType([T.func,T.element]),content:T.node,disableAnimation:T.bool.isRequired,footer:T.node,handleClick:T.func.isRequired,hideArrow:T.bool.isRequired,open:T.bool,placement:T.string.isRequired,positionWrapper:T.bool.isRequired,setArrowRef:T.func.isRequired,setFloaterRef:T.func.isRequired,showCloseButton:T.bool,status:T.string.isRequired,styles:T.object.isRequired,title:T.node});var fo=(function(e){Ct(n,e);var t=Tt(n);function n(){return Et(this,n),t.apply(this,arguments)}return kt(n,[{key:"render",value:function(){var o=this.props,i=o.children,s=o.handleClick,a=o.handleMouseEnter,l=o.handleMouseLeave,u=o.setChildRef,f=o.setWrapperRef,c=o.style,d=o.styles,p;if(i)if(w.Children.count(i)===1)if(!w.isValidElement(i))p=w.createElement("span",null,i);else{var h=g.function(i.type)?"innerRef":"ref";p=w.cloneElement(w.Children.only(i),te({},h,u))}else p=i;return p?w.createElement("span",{ref:f,style:K(K({},d),c),onClick:s,onMouseEnter:a,onMouseLeave:l},p):null}}]),n})(w.Component);te(fo,"propTypes",{children:T.node,handleClick:T.func.isRequired,handleMouseEnter:T.func.isRequired,handleMouseLeave:T.func.isRequired,setChildRef:T.func.isRequired,setWrapperRef:T.func.isRequired,style:T.object,styles:T.object.isRequired});var fl={zIndex:100};function dl(e){var t=ve(fl,e.options||{});return{wrapper:{cursor:"help",display:"inline-flex",flexDirection:"column",zIndex:t.zIndex},wrapperPosition:{left:-1e3,position:"absolute",top:-1e3,visibility:"hidden"},floater:{display:"inline-block",filter:"drop-shadow(0 0 3px rgba(0, 0, 0, 0.3))",maxWidth:300,opacity:0,position:"relative",transition:"opacity 0.3s",visibility:"hidden",zIndex:t.zIndex},floaterOpening:{opacity:1,visibility:"visible"},floaterWithAnimation:{opacity:1,transition:"opacity 0.3s, transform 0.2s",visibility:"visible"},floaterWithComponent:{maxWidth:"100%"},floaterClosing:{opacity:0,visibility:"visible"},floaterCentered:{left:"50%",position:"fixed",top:"50%",transform:"translate(-50%, -50%)"},container:{backgroundColor:"#fff",color:"#666",minHeight:60,minWidth:200,padding:20,position:"relative",zIndex:10},title:{borderBottom:"1px solid #555",color:"#555",fontSize:18,marginBottom:5,paddingBottom:6,paddingRight:18},content:{fontSize:15},close:{backgroundColor:"transparent",border:0,borderRadius:0,color:"#555",fontSize:0,height:15,outline:"none",padding:10,position:"absolute",right:0,top:0,width:15,WebkitAppearance:"none"},footer:{borderTop:"1px solid #ccc",fontSize:13,marginTop:10,paddingTop:5},arrow:{color:"#fff",display:"inline-flex",length:16,margin:8,position:"absolute",spread:32},options:t}}var pl=["arrow","flip","offset"],hl=["position","top","right","bottom","left"],xn=(function(e){Ct(n,e);var t=Tt(n);function n(r){var o;return Et(this,n),o=t.call(this,r),te(Ne(o),"setArrowRef",function(i){o.arrowRef=i}),te(Ne(o),"setChildRef",function(i){o.childRef=i}),te(Ne(o),"setFloaterRef",function(i){o.floaterRef=i}),te(Ne(o),"setWrapperRef",function(i){o.wrapperRef=i}),te(Ne(o),"handleTransitionEnd",function(){var i=o.state.status,s=o.props.callback;o.wrapperPopper&&o.wrapperPopper.instance.update(),o.setState({status:i===z.OPENING?z.OPEN:z.IDLE},function(){var a=o.state.status;s(a===z.OPEN?"open":"close",o.props)})}),te(Ne(o),"handleClick",function(){var i=o.props,s=i.event,a=i.open;if(!g.boolean(a)){var l=o.state,u=l.positionWrapper,f=l.status;(o.event==="click"||o.event==="hover"&&u)&&(xt({title:"click",data:[{event:s,status:f===z.OPEN?"closing":"opening"}],debug:o.debug}),o.toggle())}}),te(Ne(o),"handleMouseEnter",function(){var i=o.props,s=i.event,a=i.open;if(!(g.boolean(a)||an())){var l=o.state.status;o.event==="hover"&&l===z.IDLE&&(xt({title:"mouseEnter",data:[{key:"originalEvent",value:s}],debug:o.debug}),clearTimeout(o.eventDelayTimeout),o.toggle())}}),te(Ne(o),"handleMouseLeave",function(){var i=o.props,s=i.event,a=i.eventDelay,l=i.open;if(!(g.boolean(l)||an())){var u=o.state,f=u.status,c=u.positionWrapper;o.event==="hover"&&(xt({title:"mouseLeave",data:[{key:"originalEvent",value:s}],debug:o.debug}),a?[z.OPENING,z.OPEN].indexOf(f)!==-1&&!c&&!o.eventDelayTimeout&&(o.eventDelayTimeout=setTimeout(function(){delete o.eventDelayTimeout,o.toggle()},a*1e3)):o.toggle(z.IDLE))}}),o.state={currentPlacement:r.placement,needsUpdate:!1,positionWrapper:r.wrapperOptions.position&&!!r.target,status:z.INIT,statusWrapper:z.INIT},o._isMounted=!1,o.hasMounted=!1,Ee()&&window.addEventListener("load",function(){o.popper&&o.popper.instance.update(),o.wrapperPopper&&o.wrapperPopper.instance.update()}),o}return kt(n,[{key:"componentDidMount",value:function(){if(Ee()){var o=this.state.positionWrapper,i=this.props,s=i.children,a=i.open,l=i.target;this._isMounted=!0,xt({title:"init",data:{hasChildren:!!s,hasTarget:!!l,isControlled:g.boolean(a),positionWrapper:o,target:this.target,floater:this.floaterRef},debug:this.debug}),this.hasMounted||(this.initPopper(),this.hasMounted=!0),!s&&l&&g.boolean(a)}}},{key:"componentDidUpdate",value:function(o,i){if(Ee()){var s=this.props,a=s.autoOpen,l=s.open,u=s.target,f=s.wrapperOptions,c=Va(i,this.state),d=c.changedFrom,p=c.changed;if(o.open!==l){var h;g.boolean(l)&&(h=l?z.OPENING:z.CLOSING),this.toggle(h)}(o.wrapperOptions.position!==f.position||o.target!==u)&&this.changeWrapperPosition(this.props),p("status",z.IDLE)&&l?this.toggle(z.OPEN):d("status",z.INIT,z.IDLE)&&a&&this.toggle(z.OPEN),this.popper&&p("status",z.OPENING)&&this.popper.instance.update(),this.floaterRef&&(p("status",z.OPENING)||p("status",z.CLOSING))&&cl(this.floaterRef,"transitionend",this.handleTransitionEnd),p("needsUpdate",!0)&&this.rebuildPopper()}}},{key:"componentWillUnmount",value:function(){Ee()&&(this._isMounted=!1,this.popper&&this.popper.instance.destroy(),this.wrapperPopper&&this.wrapperPopper.instance.destroy())}},{key:"initPopper",value:function(){var o=this,i=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.target,s=this.state.positionWrapper,a=this.props,l=a.disableFlip,u=a.getPopper,f=a.hideArrow,c=a.offset,d=a.placement,p=a.wrapperOptions,h=d==="top"||d==="bottom"?"flip":["right","bottom-end","top-end","left","top-start","bottom-start"];if(d==="center")this.setState({status:z.IDLE});else if(i&&this.floaterRef){var v=this.options,S=v.arrow,y=v.flip,m=v.offset,E=oo(v,pl);new yt(i,this.floaterRef,{placement:d,modifiers:K({arrow:K({enabled:!f,element:this.arrowRef},S),flip:K({enabled:!l,behavior:h},y),offset:K({offset:"0, ".concat(c,"px")},m)},E),onCreate:function(O){var D;if(o.popper=O,!((D=o.floaterRef)!==null&&D!==void 0&&D.isConnected)){o.setState({needsUpdate:!0});return}u(O,"floater"),o._isMounted&&o.setState({currentPlacement:O.placement,status:z.IDLE}),d!==O.placement&&setTimeout(function(){O.instance.update()},1)},onUpdate:function(O){o.popper=O;var D=o.state.currentPlacement;o._isMounted&&O.placement!==D&&o.setState({currentPlacement:O.placement})}})}if(s){var M=g.undefined(p.offset)?0:p.offset;new yt(this.target,this.wrapperRef,{placement:p.placement||d,modifiers:{arrow:{enabled:!1},offset:{offset:"0, ".concat(M,"px")},flip:{enabled:!1}},onCreate:function(O){o.wrapperPopper=O,o._isMounted&&o.setState({statusWrapper:z.IDLE}),u(O,"wrapper"),d!==O.placement&&setTimeout(function(){O.instance.update()},1)}})}}},{key:"rebuildPopper",value:function(){var o=this;this.floaterRefInterval=setInterval(function(){var i;(i=o.floaterRef)!==null&&i!==void 0&&i.isConnected&&(clearInterval(o.floaterRefInterval),o.setState({needsUpdate:!1}),o.initPopper())},50)}},{key:"changeWrapperPosition",value:function(o){var i=o.target,s=o.wrapperOptions;this.setState({positionWrapper:s.position&&!!i})}},{key:"toggle",value:function(o){var i=this.state.status,s=i===z.OPEN?z.CLOSING:z.OPENING;g.undefined(o)||(s=o),this.setState({status:s})}},{key:"debug",get:function(){var o=this.props.debug;return o||Ee()&&"ReactFloaterDebug"in window&&!!window.ReactFloaterDebug}},{key:"event",get:function(){var o=this.props,i=o.disableHoverToClick,s=o.event;return s==="hover"&&an()&&!i?"click":s}},{key:"options",get:function(){var o=this.props.options;return ve(el,o||{})}},{key:"styles",get:function(){var o=this,i=this.state,s=i.status,a=i.positionWrapper,l=i.statusWrapper,u=this.props.styles,f=ve(dl(u),u);if(a){var c;[z.IDLE].indexOf(s)===-1||[z.IDLE].indexOf(l)===-1?c=f.wrapperPosition:c=this.wrapperPopper.styles,f.wrapper=K(K({},f.wrapper),c)}if(this.target){var d=window.getComputedStyle(this.target);this.wrapperStyles?f.wrapper=K(K({},f.wrapper),this.wrapperStyles):["relative","static"].indexOf(d.position)===-1&&(this.wrapperStyles={},a||(hl.forEach(function(p){o.wrapperStyles[p]=d[p]}),f.wrapper=K(K({},f.wrapper),this.wrapperStyles),this.target.style.position="relative",this.target.style.top="auto",this.target.style.right="auto",this.target.style.bottom="auto",this.target.style.left="auto"))}return f}},{key:"target",get:function(){if(!Ee())return null;var o=this.props.target;return o?g.domElement(o)?o:document.querySelector(o):this.childRef||this.wrapperRef}},{key:"render",value:function(){var o=this.state,i=o.currentPlacement,s=o.positionWrapper,a=o.status,l=this.props,u=l.children,f=l.component,c=l.content,d=l.disableAnimation,p=l.footer,h=l.hideArrow,v=l.id,S=l.open,y=l.showCloseButton,m=l.style,E=l.target,M=l.title,C=w.createElement(fo,{handleClick:this.handleClick,handleMouseEnter:this.handleMouseEnter,handleMouseLeave:this.handleMouseLeave,setChildRef:this.setChildRef,setWrapperRef:this.setWrapperRef,style:m,styles:this.styles.wrapper},u),O={};return s?O.wrapperInPortal=C:O.wrapperAsChildren=C,w.createElement("span",null,w.createElement(so,{hasChildren:!!u,id:v,placement:i,setRef:this.setFloaterRef,target:E,zIndex:this.styles.options.zIndex},w.createElement(uo,{component:f,content:c,disableAnimation:d,footer:p,handleClick:this.handleClick,hideArrow:h||i==="center",open:S,placement:i,positionWrapper:s,setArrowRef:this.setArrowRef,setFloaterRef:this.setFloaterRef,showCloseButton:y,status:a,styles:this.styles,title:M}),O.wrapperInPortal),O.wrapperAsChildren)}}]),n})(w.Component);te(xn,"propTypes",{autoOpen:T.bool,callback:T.func,children:T.node,component:mr(T.oneOfType([T.func,T.element]),function(e){return!e.content}),content:mr(T.node,function(e){return!e.component}),debug:T.bool,disableAnimation:T.bool,disableFlip:T.bool,disableHoverToClick:T.bool,event:T.oneOf(["hover","click"]),eventDelay:T.number,footer:T.node,getPopper:T.func,hideArrow:T.bool,id:T.oneOfType([T.string,T.number]),offset:T.number,open:T.bool,options:T.object,placement:T.oneOf(["top","top-start","top-end","bottom","bottom-start","bottom-end","left","left-start","left-end","right","right-start","right-end","auto","center"]),showCloseButton:T.bool,style:T.object,styles:T.object,target:T.oneOfType([T.object,T.string]),title:T.node,wrapperOptions:T.shape({offset:T.number,placement:T.oneOf(["top","top-start","top-end","bottom","bottom-start","bottom-end","left","left-start","left-end","right","right-start","right-end","auto"]),position:T.bool})});te(xn,"defaultProps",{autoOpen:!1,callback:yr,debug:!1,disableAnimation:!1,disableFlip:!1,disableHoverToClick:!1,event:"click",eventDelay:.4,getPopper:yr,hideArrow:!1,offset:15,placement:"bottom",showCloseButton:!1,styles:{},target:null,wrapperOptions:{position:!1}});var ml=Object.defineProperty,yl=(e,t,n)=>t in e?ml(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,N=(e,t,n)=>yl(e,typeof t!="symbol"?t+"":t,n),q={INIT:"init",START:"start",STOP:"stop",RESET:"reset",PREV:"prev",NEXT:"next",GO:"go",CLOSE:"close",SKIP:"skip",UPDATE:"update"},ye={TOUR_START:"tour:start",STEP_BEFORE:"step:before",BEACON:"beacon",TOOLTIP:"tooltip",STEP_AFTER:"step:after",TOUR_END:"tour:end",TOUR_STATUS:"tour:status",TARGET_NOT_FOUND:"error:target_not_found"},A={INIT:"init",READY:"ready",BEACON:"beacon",TOOLTIP:"tooltip",COMPLETE:"complete",ERROR:"error"},L={IDLE:"idle",READY:"ready",WAITING:"waiting",RUNNING:"running",PAUSED:"paused",SKIPPED:"skipped",FINISHED:"finished"};function _e(){var e;return!!(typeof window<"u"&&((e=window.document)!=null&&e.createElement))}function po(e){return e?e.getBoundingClientRect():null}function vl(e=!1){const{body:t,documentElement:n}=document;if(!t||!n)return 0;if(e){const r=[t.scrollHeight,t.offsetHeight,n.clientHeight,n.scrollHeight,n.offsetHeight].sort((i,s)=>i-s),o=Math.floor(r.length/2);return r.length%2===0?(r[o-1]+r[o])/2:r[o]}return Math.max(t.scrollHeight,t.offsetHeight,n.clientHeight,n.scrollHeight,n.offsetHeight)}function De(e){if(typeof e=="string")try{return document.querySelector(e)}catch{return null}return e}function gl(e){return!e||e.nodeType!==1?null:getComputedStyle(e)}function vt(e,t,n){if(!e)return $e();const r=Lr(e);if(r){if(r.isSameNode($e()))return n?document:$e();if(!(r.scrollHeight>r.offsetHeight)&&!t)return r.style.overflow="initial",$e()}return r}function $t(e,t){if(!e)return!1;const n=vt(e,t);return n?!n.isSameNode($e()):!1}function bl(e){return e.offsetParent!==document.body}function et(e,t="fixed"){if(!e||!(e instanceof HTMLElement))return!1;const{nodeName:n}=e,r=gl(e);return n==="BODY"||n==="HTML"?!1:r&&r.position===t?!0:e.parentNode?et(e.parentNode,t):!1}function wl(e){var t;if(!e)return!1;let n=e;for(;n&&n!==document.body;){if(n instanceof HTMLElement){const{display:r,visibility:o}=getComputedStyle(n);if(r==="none"||o==="hidden")return!1}n=(t=n.parentElement)!=null?t:null}return!0}function Ol(e,t,n){var r,o,i;const s=po(e),a=vt(e,n),l=$t(e,n),u=et(e);let f=0,c=(r=s?.top)!=null?r:0;if(l&&u){const d=(o=e?.offsetTop)!=null?o:0,p=(i=a?.scrollTop)!=null?i:0;c=d-p}else a instanceof HTMLElement&&(f=a.scrollTop,!l&&!et(e)&&(c+=f),a.isSameNode($e())||(c+=$e().scrollTop));return Math.floor(c-t)}function Sl(e,t,n){var r;if(!e)return 0;const{offsetTop:o=0,scrollTop:i=0}=(r=Lr(e))!=null?r:{};let s=e.getBoundingClientRect().top+i;o&&($t(e,n)||bl(e))&&(s-=o);const a=Math.floor(s-t);return a<0?0:a}function $e(){var e;return(e=document.scrollingElement)!=null?e:document.documentElement}function El(e,t){const{duration:n,element:r}=t;return new Promise((o,i)=>{const{scrollTop:s}=r,a=e>s?e-s:s-e;js.top(r,e,{duration:a<100?50:n},l=>l&&l.message!=="Element already at target scroll position"?i(l):o())})}var ft=Dt.createPortal!==void 0;function ho(e=navigator.userAgent){let t=e;return typeof window>"u"?t="node":document.documentMode?t="ie":/Edge/.test(e)?t="edge":window.opera||e.includes(" OPR/")?t="opera":typeof window.InstallTrigger<"u"?t="firefox":window.chrome?t="chrome":/(Version\/([\d._]+).*Safari|CriOS|FxiOS| Mobile\/)/.test(e)&&(t="safari"),t}function Wt(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}function ke(e,t={}){const{defaultValue:n,step:r,steps:o}=t;let i=Jn(e);if(i)(i.includes("{step}")||i.includes("{steps}"))&&r&&o&&(i=i.replace("{step}",r.toString()).replace("{steps}",o.toString()));else if(b.isValidElement(e)&&!Object.values(e.props).length&&Wt(e.type)==="function"){const s=e.type({});i=ke(s,t)}else i=Jn(n);return i}function kl(e,t){return!x.plainObject(e)||!x.array(t)?!1:Object.keys(e).every(n=>t.includes(n))}function Cl(e){const t=/^#?([\da-f])([\da-f])([\da-f])$/i,n=e.replace(t,(o,i,s,a)=>i+i+s+s+a+a),r=/^#?([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i.exec(n);return r?[parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16)]:[]}function vr(e){return e.disableBeacon||e.placement==="center"}function gr(){return!["chrome","safari","firefox","opera"].includes(ho())}function Ue({data:e,debug:t=!1,title:n,warn:r=!1}){const o=r?console.warn||console.error:console.log;t&&(n&&e?(console.groupCollapsed(`%creact-joyride: ${n}`,"color: #ff0044; font-weight: bold; font-size: 12px;"),Array.isArray(e)?e.forEach(i=>{x.plainObject(i)&&i.key?o.apply(console,[i.key,i.value]):o.apply(console,[i])}):o.apply(console,[e]),console.groupEnd()):console.error("Missing title or data props"))}function Tl(e){return Object.keys(e)}function mo(e,...t){if(!x.plainObject(e))throw new TypeError("Expected an object");const n={};for(const r in e)({}).hasOwnProperty.call(e,r)&&(t.includes(r)||(n[r]=e[r]));return n}function Ml(e,...t){if(!x.plainObject(e))throw new TypeError("Expected an object");if(!t.length)return e;const n={};for(const r in e)({}).hasOwnProperty.call(e,r)&&t.includes(r)&&(n[r]=e[r]);return n}function bn(e,t,n){const r=i=>i.replace("{step}",String(t)).replace("{steps}",String(n));if(Wt(e)==="string")return r(e);if(!b.isValidElement(e))return e;const{children:o}=e.props;if(Wt(o)==="string"&&o.includes("{step}"))return b.cloneElement(e,{children:r(o)});if(Array.isArray(o))return b.cloneElement(e,{children:o.map(i=>typeof i=="string"?r(i):bn(i,t,n))});if(Wt(e.type)==="function"&&!Object.values(e.props).length){const i=e.type({});return bn(i,t,n)}return e}function Pl(e){const{isFirstStep:t,lifecycle:n,previousLifecycle:r,scrollToFirstStep:o,step:i,target:s}=e;return!i.disableScrolling&&(!t||o||n===A.TOOLTIP)&&i.placement!=="center"&&(!i.isFixed||!et(s))&&r!==n&&[A.BEACON,A.TOOLTIP].includes(n)}var xl={options:{preventOverflow:{boundariesElement:"scrollParent"}},wrapperOptions:{offset:-18,position:!0}},yo={back:"Back",close:"Close",last:"Last",next:"Next",nextLabelWithProgress:"Next (Step {step} of {steps})",open:"Open the dialog",skip:"Skip"},Nl={event:"click",placement:"bottom",offset:10,disableBeacon:!1,disableCloseOnEsc:!1,disableOverlay:!1,disableOverlayClose:!1,disableScrollParentFix:!1,disableScrolling:!1,hideBackButton:!1,hideCloseButton:!1,hideFooter:!1,isFixed:!1,locale:yo,showProgress:!1,showSkipButton:!1,spotlightClicks:!1,spotlightPadding:10},Dl={continuous:!1,debug:!1,disableCloseOnEsc:!1,disableOverlay:!1,disableOverlayClose:!1,disableScrolling:!1,disableScrollParentFix:!1,getHelpers:void 0,hideBackButton:!1,run:!0,scrollOffset:20,scrollDuration:300,scrollToFirstStep:!1,showSkipButton:!1,showProgress:!1,spotlightClicks:!1,spotlightPadding:10,steps:[]},Il={arrowColor:"#fff",backgroundColor:"#fff",beaconSize:36,overlayColor:"rgba(0, 0, 0, 0.5)",primaryColor:"#f04",spotlightShadow:"0 0 15px rgba(0, 0, 0, 0.5)",textColor:"#333",width:380,zIndex:100},dt={backgroundColor:"transparent",border:0,borderRadius:0,color:"#555",cursor:"pointer",fontSize:16,lineHeight:1,padding:8,WebkitAppearance:"none"},br={borderRadius:4,position:"absolute"};function Wl(e,t){var n,r,o,i,s;const{floaterProps:a,styles:l}=e,u=ve((n=t.floaterProps)!=null?n:{},a??{}),f=ve(l??{},(r=t.styles)!=null?r:{}),c=ve(Il,f.options||{}),d=t.placement==="center"||t.disableBeacon;let{width:p}=c;window.innerWidth>480&&(p=380),"width"in c&&(p=typeof c.width=="number"&&window.innerWidthvo(n,t)):(Ue({title:"validateSteps",data:"steps must be an array",warn:!0,debug:t}),!1)}var go={action:"init",controlled:!1,index:0,lifecycle:A.INIT,origin:null,size:0,status:L.IDLE},Or=Tl(mo(go,"controlled","size")),Al=class{constructor(e){N(this,"beaconPopper"),N(this,"tooltipPopper"),N(this,"data",new Map),N(this,"listener"),N(this,"store",new Map),N(this,"addListener",o=>{this.listener=o}),N(this,"setSteps",o=>{const{size:i,status:s}=this.getState(),a={size:o.length,status:s};this.data.set("steps",o),s===L.WAITING&&!i&&o.length&&(a.status=L.RUNNING),this.setState(a)}),N(this,"getPopper",o=>o==="beacon"?this.beaconPopper:this.tooltipPopper),N(this,"setPopper",(o,i)=>{o==="beacon"?this.beaconPopper=i:this.tooltipPopper=i}),N(this,"cleanupPoppers",()=>{this.beaconPopper=null,this.tooltipPopper=null}),N(this,"close",(o=null)=>{const{index:i,status:s}=this.getState();s===L.RUNNING&&this.setState({...this.getNextState({action:q.CLOSE,index:i+1,origin:o})})}),N(this,"go",o=>{const{controlled:i,status:s}=this.getState();if(i||s!==L.RUNNING)return;const a=this.getSteps()[o];this.setState({...this.getNextState({action:q.GO,index:o}),status:a?s:L.FINISHED})}),N(this,"info",()=>this.getState()),N(this,"next",()=>{const{index:o,status:i}=this.getState();i===L.RUNNING&&this.setState(this.getNextState({action:q.NEXT,index:o+1}))}),N(this,"open",()=>{const{status:o}=this.getState();o===L.RUNNING&&this.setState({...this.getNextState({action:q.UPDATE,lifecycle:A.TOOLTIP})})}),N(this,"prev",()=>{const{index:o,status:i}=this.getState();i===L.RUNNING&&this.setState({...this.getNextState({action:q.PREV,index:o-1})})}),N(this,"reset",(o=!1)=>{const{controlled:i}=this.getState();i||this.setState({...this.getNextState({action:q.RESET,index:0}),status:o?L.RUNNING:L.READY})}),N(this,"skip",()=>{const{status:o}=this.getState();o===L.RUNNING&&this.setState({action:q.SKIP,lifecycle:A.INIT,status:L.SKIPPED})}),N(this,"start",o=>{const{index:i,size:s}=this.getState();this.setState({...this.getNextState({action:q.START,index:x.number(o)?o:i},!0),status:s?L.RUNNING:L.WAITING})}),N(this,"stop",(o=!1)=>{const{index:i,status:s}=this.getState();[L.FINISHED,L.SKIPPED].includes(s)||this.setState({...this.getNextState({action:q.STOP,index:i+(o?1:0)}),status:L.PAUSED})}),N(this,"update",o=>{var i,s;if(!kl(o,Or))throw new Error(`State is not valid. Valid keys: ${Or.join(", ")}`);this.setState({...this.getNextState({...this.getState(),...o,action:(i=o.action)!=null?i:q.UPDATE,origin:(s=o.origin)!=null?s:null},!0)})});const{continuous:t=!1,stepIndex:n,steps:r=[]}=e??{};this.setState({action:q.INIT,controlled:x.number(n),continuous:t,index:x.number(n)?n:0,lifecycle:A.INIT,origin:null,status:r.length?L.READY:L.IDLE},!0),this.beaconPopper=null,this.tooltipPopper=null,this.listener=null,this.setSteps(r)}getState(){return this.store.size?{action:this.store.get("action")||"",controlled:this.store.get("controlled")||!1,index:parseInt(this.store.get("index"),10),lifecycle:this.store.get("lifecycle")||"",origin:this.store.get("origin")||null,size:this.store.get("size")||0,status:this.store.get("status")||""}:{...go}}getNextState(e,t=!1){var n,r,o,i,s;const{action:a,controlled:l,index:u,size:f,status:c}=this.getState(),d=x.number(e.index)?e.index:u,p=l&&!t?u:Math.min(Math.max(d,0),f);return{action:(n=e.action)!=null?n:a,controlled:l,index:p,lifecycle:(r=e.lifecycle)!=null?r:A.INIT,origin:(o=e.origin)!=null?o:null,size:(i=e.size)!=null?i:f,status:p===f?L.FINISHED:(s=e.status)!=null?s:c}}getSteps(){const e=this.data.get("steps");return Array.isArray(e)?e:[]}hasUpdatedState(e){const t=JSON.stringify(e),n=JSON.stringify(this.getState());return t!==n}setState(e,t=!1){const n=this.getState(),{action:r,index:o,lifecycle:i,origin:s=null,size:a,status:l}={...n,...e};this.store.set("action",r),this.store.set("index",o),this.store.set("lifecycle",i),this.store.set("origin",s),this.store.set("size",a),this.store.set("status",l),t&&(this.store.set("controlled",e.controlled),this.store.set("continuous",e.continuous)),this.listener&&this.hasUpdatedState(n)&&this.listener(this.getState())}getHelpers(){return{close:this.close,go:this.go,info:this.info,next:this.next,open:this.open,prev:this.prev,reset:this.reset,skip:this.skip}}};function _l(e){return new Al(e)}function Fl({styles:e}){return b.createElement("div",{key:"JoyrideSpotlight",className:"react-joyride__spotlight","data-test-id":"spotlight",style:e})}var jl=Fl,Bl=class extends b.Component{constructor(){super(...arguments),N(this,"isActive",!1),N(this,"resizeTimeout"),N(this,"scrollTimeout"),N(this,"scrollParent"),N(this,"state",{isScrolling:!1,mouseOverSpotlight:!1,showSpotlight:!0}),N(this,"hideSpotlight",()=>{const{continuous:e,disableOverlay:t,lifecycle:n}=this.props,r=[A.INIT,A.BEACON,A.COMPLETE,A.ERROR];return t||(e?r.includes(n):n!==A.TOOLTIP)}),N(this,"handleMouseMove",e=>{const{mouseOverSpotlight:t}=this.state,{height:n,left:r,position:o,top:i,width:s}=this.spotlightStyles,a=o==="fixed"?e.clientY:e.pageY,l=o==="fixed"?e.clientX:e.pageX,u=a>=i&&a<=i+n,c=l>=r&&l<=r+s&&u;c!==t&&this.updateState({mouseOverSpotlight:c})}),N(this,"handleScroll",()=>{const{target:e}=this.props,t=De(e);if(this.scrollParent!==document){const{isScrolling:n}=this.state;n||this.updateState({isScrolling:!0,showSpotlight:!1}),clearTimeout(this.scrollTimeout),this.scrollTimeout=window.setTimeout(()=>{this.updateState({isScrolling:!1,showSpotlight:!0})},50)}else et(t,"sticky")&&this.updateState({})}),N(this,"handleResize",()=>{clearTimeout(this.resizeTimeout),this.resizeTimeout=window.setTimeout(()=>{this.isActive&&this.forceUpdate()},100)})}componentDidMount(){const{debug:e,disableScrolling:t,disableScrollParentFix:n=!1,target:r}=this.props,o=De(r);this.scrollParent=vt(o??document.body,n,!0),this.isActive=!0,window.addEventListener("resize",this.handleResize)}componentDidUpdate(e){var t;const{disableScrollParentFix:n,lifecycle:r,spotlightClicks:o,target:i}=this.props,{changed:s}=Rt(e,this.props);if(s("target")||s("disableScrollParentFix")){const a=De(i);this.scrollParent=vt(a??document.body,n,!0)}s("lifecycle",A.TOOLTIP)&&((t=this.scrollParent)==null||t.addEventListener("scroll",this.handleScroll,{passive:!0}),setTimeout(()=>{const{isScrolling:a}=this.state;a||this.updateState({showSpotlight:!0})},100)),(s("spotlightClicks")||s("disableOverlay")||s("lifecycle"))&&(o&&r===A.TOOLTIP?window.addEventListener("mousemove",this.handleMouseMove,!1):r!==A.TOOLTIP&&window.removeEventListener("mousemove",this.handleMouseMove))}componentWillUnmount(){var e;this.isActive=!1,window.removeEventListener("mousemove",this.handleMouseMove),window.removeEventListener("resize",this.handleResize),clearTimeout(this.resizeTimeout),clearTimeout(this.scrollTimeout),(e=this.scrollParent)==null||e.removeEventListener("scroll",this.handleScroll)}get overlayStyles(){const{mouseOverSpotlight:e}=this.state,{disableOverlayClose:t,placement:n,styles:r}=this.props;let o=r.overlay;return gr()&&(o=n==="center"?r.overlayLegacyCenter:r.overlayLegacy),{cursor:t?"default":"pointer",height:vl(),pointerEvents:e?"none":"auto",...o}}get spotlightStyles(){var e,t,n;const{showSpotlight:r}=this.state,{disableScrollParentFix:o=!1,spotlightClicks:i,spotlightPadding:s=0,styles:a,target:l}=this.props,u=De(l),f=po(u),c=et(u),d=Ol(u,s,o);return{...gr()?a.spotlightLegacy:a.spotlight,height:Math.round(((e=f?.height)!=null?e:0)+s*2),left:Math.round(((t=f?.left)!=null?t:0)-s),opacity:r?1:0,pointerEvents:i?"none":"auto",position:c?"fixed":"absolute",top:d,transition:"opacity 0.2s",width:Math.round(((n=f?.width)!=null?n:0)+s*2)}}updateState(e){this.isActive&&this.setState(t=>({...t,...e}))}render(){const{showSpotlight:e}=this.state,{onClickOverlay:t,placement:n}=this.props,{hideSpotlight:r,overlayStyles:o,spotlightStyles:i}=this;if(r())return null;let s=n!=="center"&&e&&b.createElement(jl,{styles:i});if(ho()==="safari"){const{mixBlendMode:a,zIndex:l,...u}=o;s=b.createElement("div",{style:{...u}},s),delete o.backgroundColor}return b.createElement("div",{className:"react-joyride__overlay","data-test-id":"overlay",onClick:t,role:"presentation",style:o},s)}},Ll=class extends b.Component{constructor(){super(...arguments),N(this,"node",null)}componentDidMount(){const{id:e}=this.props;_e()&&(this.node=document.createElement("div"),this.node.id=e,document.body.appendChild(this.node),ft||this.renderReact15())}componentDidUpdate(){_e()&&(ft||this.renderReact15())}componentWillUnmount(){!_e()||!this.node||(ft||Dt.unmountComponentAtNode(this.node),this.node.parentNode===document.body&&(document.body.removeChild(this.node),this.node=null))}renderReact15(){if(!_e())return;const{children:e}=this.props;this.node&&Dt.unstable_renderSubtreeIntoContainer(this,e,this.node)}renderReact16(){if(!_e()||!ft)return null;const{children:e}=this.props;return this.node?Dt.createPortal(e,this.node):null}render(){return ft?this.renderReact16():null}},$l=class{constructor(e,t){if(N(this,"element"),N(this,"options"),N(this,"canBeTabbed",n=>{const{tabIndex:r}=n;return r===null||r<0?!1:this.canHaveFocus(n)}),N(this,"canHaveFocus",n=>{const r=/input|select|textarea|button|object/,o=n.nodeName.toLowerCase();return(r.test(o)&&!n.getAttribute("disabled")||o==="a"&&!!n.getAttribute("href"))&&this.isVisible(n)}),N(this,"findValidTabElements",()=>[].slice.call(this.element.querySelectorAll("*"),0).filter(this.canBeTabbed)),N(this,"handleKeyDown",n=>{const{code:r="Tab"}=this.options;n.code===r&&this.interceptTab(n)}),N(this,"interceptTab",n=>{n.preventDefault();const r=this.findValidTabElements(),{shiftKey:o}=n;if(!r.length)return;let i=document.activeElement?r.indexOf(document.activeElement):0;i===-1||!o&&i+1===r.length?i=0:o&&i===0?i=r.length-1:i+=o?-1:1,r[i].focus()}),N(this,"isHidden",n=>{const r=n.offsetWidth<=0&&n.offsetHeight<=0,o=window.getComputedStyle(n);return r&&!n.innerHTML?!0:r&&o.getPropertyValue("overflow")!=="visible"||o.getPropertyValue("display")==="none"}),N(this,"isVisible",n=>{let r=n;for(;r;)if(r instanceof HTMLElement){if(r===document.body)break;if(this.isHidden(r))return!1;r=r.parentNode}return!0}),N(this,"removeScope",()=>{window.removeEventListener("keydown",this.handleKeyDown)}),N(this,"checkFocus",n=>{document.activeElement!==n&&(n.focus(),window.requestAnimationFrame(()=>this.checkFocus(n)))}),N(this,"setFocus",()=>{const{selector:n}=this.options;if(!n)return;const r=this.element.querySelector(n);r&&window.requestAnimationFrame(()=>this.checkFocus(r))}),!(e instanceof HTMLElement))throw new TypeError("Invalid parameter: element must be an HTMLElement");this.element=e,this.options=t,window.addEventListener("keydown",this.handleKeyDown,!1),this.setFocus()}},Hl=class extends b.Component{constructor(e){if(super(e),N(this,"beacon",null),N(this,"setBeaconRef",o=>{this.beacon=o}),e.beaconComponent)return;const t=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.id="joyride-beacon-animation",e.nonce&&n.setAttribute("nonce",e.nonce),n.appendChild(document.createTextNode(` + @keyframes joyride-beacon-inner { + 20% { + opacity: 0.9; + } + + 90% { + opacity: 0.7; + } + } + + @keyframes joyride-beacon-outer { + 0% { + transform: scale(1); + } + + 45% { + opacity: 0.7; + transform: scale(0.75); + } + + 100% { + opacity: 0.9; + transform: scale(1); + } + } + `)),t.appendChild(n)}componentDidMount(){const{shouldFocus:e}=this.props;setTimeout(()=>{x.domElement(this.beacon)&&e&&this.beacon.focus()},0)}componentWillUnmount(){const e=document.getElementById("joyride-beacon-animation");e?.parentNode&&e.parentNode.removeChild(e)}render(){const{beaconComponent:e,continuous:t,index:n,isLastStep:r,locale:o,onClickOrHover:i,size:s,step:a,styles:l}=this.props,u=ke(o.open),f={"aria-label":u,onClick:i,onMouseEnter:i,ref:this.setBeaconRef,title:u};let c;if(e){const d=e;c=b.createElement(d,{continuous:t,index:n,isLastStep:r,size:s,step:a,...f})}else c=b.createElement("button",{key:"JoyrideBeacon",className:"react-joyride__beacon","data-test-id":"button-beacon",style:l.beacon,type:"button",...f},b.createElement("span",{style:l.beaconInner}),b.createElement("span",{style:l.beaconOuter}));return c}};function zl({styles:e,...t}){const{color:n,height:r,width:o,...i}=e;return w.createElement("button",{style:i,type:"button",...t},w.createElement("svg",{height:typeof r=="number"?`${r}px`:r,preserveAspectRatio:"xMidYMid",version:"1.1",viewBox:"0 0 18 18",width:typeof o=="number"?`${o}px`:o,xmlns:"http://www.w3.org/2000/svg"},w.createElement("g",null,w.createElement("path",{d:"M8.13911129,9.00268191 L0.171521827,17.0258467 C-0.0498027049,17.248715 -0.0498027049,17.6098394 0.171521827,17.8327545 C0.28204354,17.9443526 0.427188206,17.9998706 0.572051765,17.9998706 C0.71714958,17.9998706 0.862013139,17.9443526 0.972581703,17.8327545 L9.0000937,9.74924618 L17.0276057,17.8327545 C17.1384085,17.9443526 17.2832721,17.9998706 17.4281356,17.9998706 C17.5729992,17.9998706 17.718097,17.9443526 17.8286656,17.8327545 C18.0499901,17.6098862 18.0499901,17.2487618 17.8286656,17.0258467 L9.86135722,9.00268191 L17.8340066,0.973848225 C18.0553311,0.750979934 18.0553311,0.389855532 17.8340066,0.16694039 C17.6126821,-0.0556467968 17.254037,-0.0556467968 17.0329467,0.16694039 L9.00042166,8.25611765 L0.967006424,0.167268345 C0.745681892,-0.0553188426 0.387317931,-0.0553188426 0.165993399,0.167268345 C-0.0553311331,0.390136635 -0.0553311331,0.751261038 0.165993399,0.974176179 L8.13920499,9.00268191 L8.13911129,9.00268191 Z",fill:n}))))}var Ul=zl;function Yl(e){const{backProps:t,closeProps:n,index:r,isLastStep:o,primaryProps:i,skipProps:s,step:a,tooltipProps:l}=e,{content:u,hideBackButton:f,hideCloseButton:c,hideFooter:d,showSkipButton:p,styles:h,title:v}=a,S={};return S.primary=b.createElement("button",{"data-test-id":"button-primary",style:h.buttonNext,type:"button",...i}),p&&!o&&(S.skip=b.createElement("button",{"aria-live":"off","data-test-id":"button-skip",style:h.buttonSkip,type:"button",...s})),!f&&r>0&&(S.back=b.createElement("button",{"data-test-id":"button-back",style:h.buttonBack,type:"button",...t})),S.close=!c&&b.createElement(Ul,{"data-test-id":"button-close",styles:h.buttonClose,...n}),b.createElement("div",{key:"JoyrideTooltip","aria-label":ke(v??u),className:"react-joyride__tooltip",style:h.tooltip,...l},b.createElement("div",{style:h.tooltipContainer},v&&b.createElement("h1",{"aria-label":ke(v),style:h.tooltipTitle},v),b.createElement("div",{style:h.tooltipContent},u)),!d&&b.createElement("div",{style:h.tooltipFooter},b.createElement("div",{style:h.tooltipFooterSpacer},S.skip),S.back,S.primary),S.close)}var ql=Yl,Gl=class extends b.Component{constructor(){super(...arguments),N(this,"handleClickBack",e=>{e.preventDefault();const{helpers:t}=this.props;t.prev()}),N(this,"handleClickClose",e=>{e.preventDefault();const{helpers:t}=this.props;t.close("button_close")}),N(this,"handleClickPrimary",e=>{e.preventDefault();const{continuous:t,helpers:n}=this.props;if(!t){n.close("button_primary");return}n.next()}),N(this,"handleClickSkip",e=>{e.preventDefault();const{helpers:t}=this.props;t.skip()}),N(this,"getElementsProps",()=>{const{continuous:e,index:t,isLastStep:n,setTooltipRef:r,size:o,step:i}=this.props,{back:s,close:a,last:l,next:u,nextLabelWithProgress:f,skip:c}=i.locale,d=ke(s),p=ke(a),h=ke(l),v=ke(u),S=ke(c);let y=a,m=p;if(e){if(y=u,m=v,i.showProgress&&!n){const E=ke(f,{step:t+1,steps:o});y=bn(f,t+1,o),m=E}n&&(y=l,m=h)}return{backProps:{"aria-label":d,children:s,"data-action":"back",onClick:this.handleClickBack,role:"button",title:d},closeProps:{"aria-label":p,children:a,"data-action":"close",onClick:this.handleClickClose,role:"button",title:p},primaryProps:{"aria-label":m,children:y,"data-action":"primary",onClick:this.handleClickPrimary,role:"button",title:m},skipProps:{"aria-label":S,children:c,"data-action":"skip",onClick:this.handleClickSkip,role:"button",title:S},tooltipProps:{"aria-modal":!0,ref:r,role:"alertdialog"}}})}render(){const{continuous:e,index:t,isLastStep:n,setTooltipRef:r,size:o,step:i}=this.props,{beaconComponent:s,tooltipComponent:a,...l}=i;let u;if(a){const f={...this.getElementsProps(),continuous:e,index:t,isLastStep:n,size:o,step:l,setTooltipRef:r},c=a;u=b.createElement(c,{...f})}else u=b.createElement(ql,{...this.getElementsProps(),continuous:e,index:t,isLastStep:n,size:o,step:i});return u}},Vl=class extends b.Component{constructor(){super(...arguments),N(this,"scope",null),N(this,"tooltip",null),N(this,"handleClickHoverBeacon",e=>{const{step:t,store:n}=this.props;e.type==="mouseenter"&&t.event!=="hover"||n.update({lifecycle:A.TOOLTIP})}),N(this,"setTooltipRef",e=>{this.tooltip=e}),N(this,"setPopper",(e,t)=>{var n;const{action:r,lifecycle:o,step:i,store:s}=this.props;t==="wrapper"?s.setPopper("beacon",e):s.setPopper("tooltip",e),s.getPopper("beacon")&&(s.getPopper("tooltip")||i.placement==="center")&&o===A.INIT&&s.update({action:r,lifecycle:A.READY}),(n=i.floaterProps)!=null&&n.getPopper&&i.floaterProps.getPopper(e,t)}),N(this,"renderTooltip",e=>{const{continuous:t,helpers:n,index:r,size:o,step:i}=this.props;return b.createElement(Gl,{continuous:t,helpers:n,index:r,isLastStep:r+1===o,setTooltipRef:this.setTooltipRef,size:o,step:i,...e})})}componentDidMount(){const{debug:e,index:t}=this.props;Ue({title:`step:${t}`,data:[{key:"props",value:this.props}],debug:e})}componentDidUpdate(e){var t;const{action:n,callback:r,continuous:o,controlled:i,debug:s,helpers:a,index:l,lifecycle:u,shouldScroll:f,status:c,step:d,store:p}=this.props,{changed:h,changedFrom:v}=Rt(e,this.props),S=a.info(),y=o&&n!==q.CLOSE&&(l>0||n===q.PREV),m=h("action")||h("index")||h("lifecycle")||h("status"),E=v("lifecycle",[A.TOOLTIP,A.INIT],A.INIT),M=h("action",[q.NEXT,q.PREV,q.SKIP,q.CLOSE]),C=i&&l===e.index;if(M&&(E||C)&&r({...S,index:e.index,lifecycle:A.COMPLETE,step:e.step,type:ye.STEP_AFTER}),d.placement==="center"&&c===L.RUNNING&&h("index")&&n!==q.START&&u===A.INIT&&p.update({lifecycle:A.READY}),m){const O=De(d.target),D=!!O;D&&wl(O)?(v("status",L.READY,L.RUNNING)||v("lifecycle",A.INIT,A.READY))&&r({...S,step:d,type:ye.STEP_BEFORE}):(console.warn(D?"Target not visible":"Target not mounted",d),r({...S,type:ye.TARGET_NOT_FOUND,step:d}),i||p.update({index:l+(n===q.PREV?-1:1)}))}v("lifecycle",A.INIT,A.READY)&&p.update({lifecycle:vr(d)||y?A.TOOLTIP:A.BEACON}),h("index")&&Ue({title:`step:${u}`,data:[{key:"props",value:this.props}],debug:s}),h("lifecycle",A.BEACON)&&r({...S,step:d,type:ye.BEACON}),h("lifecycle",A.TOOLTIP)&&(r({...S,step:d,type:ye.TOOLTIP}),f&&this.tooltip&&(this.scope=new $l(this.tooltip,{selector:"[data-action=primary]"}),this.scope.setFocus())),v("lifecycle",[A.TOOLTIP,A.INIT],A.INIT)&&((t=this.scope)==null||t.removeScope(),p.cleanupPoppers())}componentWillUnmount(){var e;(e=this.scope)==null||e.removeScope()}get open(){const{lifecycle:e,step:t}=this.props;return vr(t)||e===A.TOOLTIP}render(){const{continuous:e,debug:t,index:n,nonce:r,shouldScroll:o,size:i,step:s}=this.props,a=De(s.target);return!vo(s)||!x.domElement(a)?null:b.createElement("div",{key:`JoyrideStep-${n}`,className:"react-joyride__step"},b.createElement(xn,{...s.floaterProps,component:this.renderTooltip,debug:t,getPopper:this.setPopper,id:`react-joyride-step-${n}`,open:this.open,placement:s.placement,target:s.target},b.createElement(Hl,{beaconComponent:s.beaconComponent,continuous:e,index:n,isLastStep:n+1===i,locale:s.locale,nonce:r,onClickOrHover:this.handleClickHoverBeacon,shouldFocus:o,size:i,step:s,styles:s.styles})))}},bo=class extends b.Component{constructor(e){super(e),N(this,"helpers"),N(this,"store"),N(this,"callback",s=>{const{callback:a}=this.props;x.function(a)&&a(s)}),N(this,"handleKeyboard",s=>{const{index:a,lifecycle:l}=this.state,{steps:u}=this.props,f=u[a];l===A.TOOLTIP&&s.code==="Escape"&&f&&!f.disableCloseOnEsc&&this.store.close("keyboard")}),N(this,"handleClickOverlay",()=>{const{index:s}=this.state,{steps:a}=this.props;Ge(this.props,a[s]).disableOverlayClose||this.helpers.close("overlay")}),N(this,"syncState",s=>{this.setState(s)});const{debug:t,getHelpers:n,run:r=!0,stepIndex:o}=e;this.store=_l({...e,controlled:r&&x.number(o)}),this.helpers=this.store.getHelpers();const{addListener:i}=this.store;Ue({title:"init",data:[{key:"props",value:this.props},{key:"state",value:this.state}],debug:t}),i(this.syncState),n&&n(this.helpers),this.state=this.store.getState()}componentDidMount(){if(!_e())return;const{debug:e,disableCloseOnEsc:t,run:n,steps:r}=this.props,{start:o}=this.store;wr(r,e)&&n&&o(),t||document.body.addEventListener("keydown",this.handleKeyboard,{passive:!0})}componentDidUpdate(e,t){if(!_e())return;const{action:n,controlled:r,index:o,status:i}=this.state,{debug:s,run:a,stepIndex:l,steps:u}=this.props,{stepIndex:f,steps:c}=e,{reset:d,setSteps:p,start:h,stop:v,update:S}=this.store,{changed:y}=Rt(e,this.props),{changed:m,changedFrom:E}=Rt(t,this.state),M=Ge(this.props,u[o]),C=!re(c,u),O=x.number(l)&&y("stepIndex"),D=De(M.target);if(C&&(wr(u,s)?p(u):console.warn("Steps are not valid",u)),y("run")&&(a?h(l):v()),O){let $=x.number(f)&&f=0?v:0,r===L.RUNNING&&El(v,{element:h,duration:s}).then(()=>{setTimeout(()=>{var m;(m=this.store.getPopper("tooltip"))==null||m.instance.update()},10)})}}render(){if(!_e())return null;const{index:e,lifecycle:t,status:n}=this.state,{continuous:r=!1,debug:o=!1,nonce:i,scrollToFirstStep:s=!1,steps:a}=this.props,l=n===L.RUNNING,u={};if(l&&a[e]){const f=Ge(this.props,a[e]);u.step=b.createElement(Vl,{...this.state,callback:this.callback,continuous:r,debug:o,helpers:this.helpers,nonce:i,shouldScroll:!f.disableScrolling&&(e!==0||s),step:f,store:this.store}),u.overlay=b.createElement(Ll,{id:"react-joyride-portal"},b.createElement(Bl,{...f,continuous:r,debug:o,lifecycle:t,onClickOverlay:this.handleClickOverlay}))}return b.createElement("div",{className:"react-joyride"},u.step,u.overlay)}};N(bo,"defaultProps",Dl);var rf=bo;function Kl(e,t,n="long"){return new Intl.DateTimeFormat("en-US",{hour:"numeric",timeZone:e,timeZoneName:n}).format(t).split(/\s/g).slice(2).join(" ")}const Zl={},ht={};function He(e,t){try{const r=(Zl[e]||=new Intl.DateTimeFormat("en-US",{timeZone:e,timeZoneName:"longOffset"}).format)(t).split("GMT")[1];return r in ht?ht[r]:Sr(r,r.split(":"))}catch{if(e in ht)return ht[e];const n=e?.match(Jl);return n?Sr(e,n.slice(1)):NaN}}const Jl=/([+-]\d\d):?(\d\d)?/;function Sr(e,t){const n=+(t[0]||0),r=+(t[1]||0),o=+(t[2]||0)/60;return ht[e]=n*60+r>0?n*60+r+o:n*60-r-o}class Me extends Date{constructor(...t){super(),t.length>1&&typeof t[t.length-1]=="string"&&(this.timeZone=t.pop()),this.internal=new Date,isNaN(He(this.timeZone,this))?this.setTime(NaN):t.length?typeof t[0]=="number"&&(t.length===1||t.length===2&&typeof t[1]!="number")?this.setTime(t[0]):typeof t[0]=="string"?this.setTime(+new Date(t[0])):t[0]instanceof Date?this.setTime(+t[0]):(this.setTime(+new Date(...t)),wo(this),wn(this)):this.setTime(Date.now())}static tz(t,...n){return n.length?new Me(...n,t):new Me(Date.now(),t)}withTimeZone(t){return new Me(+this,t)}getTimezoneOffset(){const t=-He(this.timeZone,this);return t>0?Math.floor(t):Math.ceil(t)}setTime(t){return Date.prototype.setTime.apply(this,arguments),wn(this),+this}[Symbol.for("constructDateFrom")](t){return new Me(+new Date(t),this.timeZone)}}const Er=/^(get|set)(?!UTC)/;Object.getOwnPropertyNames(Date.prototype).forEach(e=>{if(!Er.test(e))return;const t=e.replace(Er,"$1UTC");Me.prototype[t]&&(e.startsWith("get")?Me.prototype[e]=function(){return this.internal[t]()}:(Me.prototype[e]=function(){return Date.prototype[t].apply(this.internal,arguments),Xl(this),+this},Me.prototype[t]=function(){return Date.prototype[t].apply(this,arguments),wn(this),+this}))});function wn(e){e.internal.setTime(+e),e.internal.setUTCSeconds(e.internal.getUTCSeconds()-Math.round(-He(e.timeZone,e)*60))}function Xl(e){Date.prototype.setFullYear.call(e,e.internal.getUTCFullYear(),e.internal.getUTCMonth(),e.internal.getUTCDate()),Date.prototype.setHours.call(e,e.internal.getUTCHours(),e.internal.getUTCMinutes(),e.internal.getUTCSeconds(),e.internal.getUTCMilliseconds()),wo(e)}function wo(e){const t=He(e.timeZone,e),n=t>0?Math.floor(t):Math.ceil(t),r=new Date(+e);r.setUTCHours(r.getUTCHours()-1);const o=-new Date(+e).getTimezoneOffset(),i=-new Date(+r).getTimezoneOffset(),s=o-i,a=Date.prototype.getHours.apply(e)!==e.internal.getUTCHours();s&&a&&e.internal.setUTCMinutes(e.internal.getUTCMinutes()+s);const l=o-n;l&&Date.prototype.setUTCMinutes.call(e,Date.prototype.getUTCMinutes.call(e)+l);const u=new Date(+e);u.setUTCSeconds(0);const f=o>0?u.getSeconds():(u.getSeconds()-60)%60,c=Math.round(-(He(e.timeZone,e)*60))%60;(c||f)&&(e.internal.setUTCSeconds(e.internal.getUTCSeconds()+c),Date.prototype.setUTCSeconds.call(e,Date.prototype.getUTCSeconds.call(e)+c+f));const d=He(e.timeZone,e),p=d>0?Math.floor(d):Math.ceil(d),v=-new Date(+e).getTimezoneOffset()-p,S=p!==n,y=v-l;if(S&&y){Date.prototype.setUTCMinutes.call(e,Date.prototype.getUTCMinutes.call(e)+y);const m=He(e.timeZone,e),E=m>0?Math.floor(m):Math.ceil(m),M=p-E;M&&(e.internal.setUTCMinutes(e.internal.getUTCMinutes()+M),Date.prototype.setUTCMinutes.call(e,Date.prototype.getUTCMinutes.call(e)+M))}}class Ie extends Me{static tz(t,...n){return n.length?new Ie(...n,t):new Ie(Date.now(),t)}toISOString(){const[t,n,r]=this.tzComponents(),o=`${t}${n}:${r}`;return this.internal.toISOString().slice(0,-1)+o}toString(){return`${this.toDateString()} ${this.toTimeString()}`}toDateString(){const[t,n,r,o]=this.internal.toUTCString().split(" ");return`${t?.slice(0,-1)} ${r} ${n} ${o}`}toTimeString(){const t=this.internal.toUTCString().split(" ")[4],[n,r,o]=this.tzComponents();return`${t} GMT${n}${r}${o} (${Kl(this.timeZone,this)})`}toLocaleString(t,n){return Date.prototype.toLocaleString.call(this,t,{...n,timeZone:n?.timeZone||this.timeZone})}toLocaleDateString(t,n){return Date.prototype.toLocaleDateString.call(this,t,{...n,timeZone:n?.timeZone||this.timeZone})}toLocaleTimeString(t,n){return Date.prototype.toLocaleTimeString.call(this,t,{...n,timeZone:n?.timeZone||this.timeZone})}tzComponents(){const t=this.getTimezoneOffset(),n=t>0?"-":"+",r=String(Math.floor(Math.abs(t)/60)).padStart(2,"0"),o=String(Math.abs(t)%60).padStart(2,"0");return[n,r,o]}withTimeZone(t){return new Ie(+this,t)}[Symbol.for("constructDateFrom")](t){return new Ie(+new Date(t),this.timeZone)}}const kr=5,Ql=4;function ec(e,t){const n=t.startOfMonth(e),r=n.getDay()>0?n.getDay():7,o=t.addDays(e,-r+1),i=t.addDays(o,kr*7-1);return t.getMonth(e)===t.getMonth(i)?kr:Ql}function Oo(e,t){const n=t.startOfMonth(e),r=n.getDay();return r===1?n:r===0?t.addDays(n,-6):t.addDays(n,-1*(r-1))}function tc(e,t){const n=Oo(e,t),r=ec(e,t);return t.addDays(n,r*7-1)}const nc={lessThanXSeconds:{one:"不到 1 秒",other:"不到 {{count}} 秒"},xSeconds:{one:"1 秒",other:"{{count}} 秒"},halfAMinute:"半分钟",lessThanXMinutes:{one:"不到 1 分钟",other:"不到 {{count}} 分钟"},xMinutes:{one:"1 分钟",other:"{{count}} 分钟"},xHours:{one:"1 小时",other:"{{count}} 小时"},aboutXHours:{one:"大约 1 小时",other:"大约 {{count}} 小时"},xDays:{one:"1 天",other:"{{count}} 天"},aboutXWeeks:{one:"大约 1 个星期",other:"大约 {{count}} 个星期"},xWeeks:{one:"1 个星期",other:"{{count}} 个星期"},aboutXMonths:{one:"大约 1 个月",other:"大约 {{count}} 个月"},xMonths:{one:"1 个月",other:"{{count}} 个月"},aboutXYears:{one:"大约 1 年",other:"大约 {{count}} 年"},xYears:{one:"1 年",other:"{{count}} 年"},overXYears:{one:"超过 1 年",other:"超过 {{count}} 年"},almostXYears:{one:"将近 1 年",other:"将近 {{count}} 年"}},rc=(e,t,n)=>{let r;const o=nc[e];return typeof o=="string"?r=o:t===1?r=o.one:r=o.other.replace("{{count}}",String(t)),n?.addSuffix?n.comparison&&n.comparison>0?r+"内":r+"前":r},oc={full:"y'年'M'月'd'日' EEEE",long:"y'年'M'月'd'日'",medium:"yyyy-MM-dd",short:"yy-MM-dd"},ic={full:"zzzz a h:mm:ss",long:"z a h:mm:ss",medium:"a h:mm:ss",short:"a h:mm"},sc={full:"{{date}} {{time}}",long:"{{date}} {{time}}",medium:"{{date}} {{time}}",short:"{{date}} {{time}}"},ac={date:Vt({formats:oc,defaultWidth:"full"}),time:Vt({formats:ic,defaultWidth:"full"}),dateTime:Vt({formats:sc,defaultWidth:"full"})};function Cr(e,t,n){const r="eeee p";return vi(e,t,n)?r:e.getTime()>t.getTime()?"'下个'"+r:"'上个'"+r}const lc={lastWeek:Cr,yesterday:"'昨天' p",today:"'今天' p",tomorrow:"'明天' p",nextWeek:Cr,other:"PP p"},cc=(e,t,n,r)=>{const o=lc[e];return typeof o=="function"?o(t,n,r):o},uc={narrow:["前","公元"],abbreviated:["前","公元"],wide:["公元前","公元"]},fc={narrow:["1","2","3","4"],abbreviated:["第一季","第二季","第三季","第四季"],wide:["第一季度","第二季度","第三季度","第四季度"]},dc={narrow:["一","二","三","四","五","六","七","八","九","十","十一","十二"],abbreviated:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],wide:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]},pc={narrow:["日","一","二","三","四","五","六"],short:["日","一","二","三","四","五","六"],abbreviated:["周日","周一","周二","周三","周四","周五","周六"],wide:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]},hc={narrow:{am:"上",pm:"下",midnight:"凌晨",noon:"午",morning:"早",afternoon:"下午",evening:"晚",night:"夜"},abbreviated:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"},wide:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"}},mc={narrow:{am:"上",pm:"下",midnight:"凌晨",noon:"午",morning:"早",afternoon:"下午",evening:"晚",night:"夜"},abbreviated:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"},wide:{am:"上午",pm:"下午",midnight:"凌晨",noon:"中午",morning:"早晨",afternoon:"中午",evening:"晚上",night:"夜间"}},yc=(e,t)=>{const n=Number(e);switch(t?.unit){case"date":return n.toString()+"日";case"hour":return n.toString()+"时";case"minute":return n.toString()+"分";case"second":return n.toString()+"秒";default:return"第 "+n.toString()}},vc={ordinalNumber:yc,era:ot({values:uc,defaultWidth:"wide"}),quarter:ot({values:fc,defaultWidth:"wide",argumentCallback:e=>e-1}),month:ot({values:dc,defaultWidth:"wide"}),day:ot({values:pc,defaultWidth:"wide"}),dayPeriod:ot({values:hc,defaultWidth:"wide",formattingValues:mc,defaultFormattingWidth:"wide"})},gc=/^(第\s*)?\d+(日|时|分|秒)?/i,bc=/\d+/i,wc={narrow:/^(前)/i,abbreviated:/^(前)/i,wide:/^(公元前|公元)/i},Oc={any:[/^(前)/i,/^(公元)/i]},Sc={narrow:/^[1234]/i,abbreviated:/^第[一二三四]刻/i,wide:/^第[一二三四]刻钟/i},Ec={any:[/(1|一)/i,/(2|二)/i,/(3|三)/i,/(4|四)/i]},kc={narrow:/^(一|二|三|四|五|六|七|八|九|十[二一])/i,abbreviated:/^(一|二|三|四|五|六|七|八|九|十[二一]|\d|1[12])月/i,wide:/^(一|二|三|四|五|六|七|八|九|十[二一])月/i},Cc={narrow:[/^一/i,/^二/i,/^三/i,/^四/i,/^五/i,/^六/i,/^七/i,/^八/i,/^九/i,/^十(?!(一|二))/i,/^十一/i,/^十二/i],any:[/^一|1/i,/^二|2/i,/^三|3/i,/^四|4/i,/^五|5/i,/^六|6/i,/^七|7/i,/^八|8/i,/^九|9/i,/^十(?!(一|二))|10/i,/^十一|11/i,/^十二|12/i]},Tc={narrow:/^[一二三四五六日]/i,short:/^[一二三四五六日]/i,abbreviated:/^周[一二三四五六日]/i,wide:/^星期[一二三四五六日]/i},Mc={any:[/日/i,/一/i,/二/i,/三/i,/四/i,/五/i,/六/i]},Pc={any:/^(上午?|下午?|午夜|[中正]午|早上?|下午|晚上?|凌晨|)/i},xc={any:{am:/^上午?/i,pm:/^下午?/i,midnight:/^午夜/i,noon:/^[中正]午/i,morning:/^早上/i,afternoon:/^下午/i,evening:/^晚上?/i,night:/^凌晨/i}},Nc={ordinalNumber:gi({matchPattern:gc,parsePattern:bc,valueCallback:e=>parseInt(e,10)}),era:it({matchPatterns:wc,defaultMatchWidth:"wide",parsePatterns:Oc,defaultParseWidth:"any"}),quarter:it({matchPatterns:Sc,defaultMatchWidth:"wide",parsePatterns:Ec,defaultParseWidth:"any",valueCallback:e=>e+1}),month:it({matchPatterns:kc,defaultMatchWidth:"wide",parsePatterns:Cc,defaultParseWidth:"any"}),day:it({matchPatterns:Tc,defaultMatchWidth:"wide",parsePatterns:Mc,defaultParseWidth:"any"}),dayPeriod:it({matchPatterns:Pc,defaultMatchWidth:"any",parsePatterns:xc,defaultParseWidth:"any"})},of={code:"zh-CN",formatDistance:rc,formatLong:ac,formatRelative:cc,localize:vc,match:Nc,options:{weekStartsOn:1,firstWeekContainsDate:4}},So={...st,labels:{labelDayButton:(e,t,n,r)=>{let o;r&&typeof r.format=="function"?o=r.format.bind(r):o=(s,a)=>pt(s,a,{locale:st,...n});let i=o(e,"PPPP");return t.today&&(i=`Today, ${i}`),t.selected&&(i=`${i}, selected`),i},labelMonthDropdown:"Choose the Month",labelNext:"Go to the Next Month",labelPrevious:"Go to the Previous Month",labelWeekNumber:e=>`Week ${e}`,labelYearDropdown:"Choose the Year",labelGrid:(e,t,n)=>{let r;return n&&typeof n.format=="function"?r=n.format.bind(n):r=(o,i)=>pt(o,i,{locale:st,...t}),r(e,"LLLL yyyy")},labelGridcell:(e,t,n,r)=>{let o;r&&typeof r.format=="function"?o=r.format.bind(r):o=(s,a)=>pt(s,a,{locale:st,...n});let i=o(e,"PPPP");return t?.today&&(i=`Today, ${i}`),i},labelNav:"Navigation bar",labelWeekNumberHeader:"Week Number",labelWeekday:(e,t,n)=>{let r;return n&&typeof n.format=="function"?r=n.format.bind(n):r=(o,i)=>pt(o,i,{locale:st,...t}),r(e,"cccc")}}};class ce{constructor(t,n){this.Date=Date,this.today=()=>this.overrides?.today?this.overrides.today():this.options.timeZone?Ie.tz(this.options.timeZone):new this.Date,this.newDate=(r,o,i)=>this.overrides?.newDate?this.overrides.newDate(r,o,i):this.options.timeZone?new Ie(r,o,i,this.options.timeZone):new Date(r,o,i),this.addDays=(r,o)=>this.overrides?.addDays?this.overrides.addDays(r,o):bi(r,o),this.addMonths=(r,o)=>this.overrides?.addMonths?this.overrides.addMonths(r,o):wi(r,o),this.addWeeks=(r,o)=>this.overrides?.addWeeks?this.overrides.addWeeks(r,o):Oi(r,o),this.addYears=(r,o)=>this.overrides?.addYears?this.overrides.addYears(r,o):Si(r,o),this.differenceInCalendarDays=(r,o)=>this.overrides?.differenceInCalendarDays?this.overrides.differenceInCalendarDays(r,o):Ei(r,o),this.differenceInCalendarMonths=(r,o)=>this.overrides?.differenceInCalendarMonths?this.overrides.differenceInCalendarMonths(r,o):ki(r,o),this.eachMonthOfInterval=r=>this.overrides?.eachMonthOfInterval?this.overrides.eachMonthOfInterval(r):Ci(r),this.eachYearOfInterval=r=>{const o=this.overrides?.eachYearOfInterval?this.overrides.eachYearOfInterval(r):Ti(r),i=new Set(o.map(a=>this.getYear(a)));if(i.size===o.length)return o;const s=[];return i.forEach(a=>{s.push(new Date(a,0,1))}),s},this.endOfBroadcastWeek=r=>this.overrides?.endOfBroadcastWeek?this.overrides.endOfBroadcastWeek(r):tc(r,this),this.endOfISOWeek=r=>this.overrides?.endOfISOWeek?this.overrides.endOfISOWeek(r):Mi(r),this.endOfMonth=r=>this.overrides?.endOfMonth?this.overrides.endOfMonth(r):Pi(r),this.endOfWeek=(r,o)=>this.overrides?.endOfWeek?this.overrides.endOfWeek(r,o):xi(r,this.options),this.endOfYear=r=>this.overrides?.endOfYear?this.overrides.endOfYear(r):Ni(r),this.format=(r,o,i)=>{const s=this.overrides?.format?this.overrides.format(r,o,this.options):pt(r,o,this.options);return this.options.numerals&&this.options.numerals!=="latn"?this.replaceDigits(s):s},this.getISOWeek=r=>this.overrides?.getISOWeek?this.overrides.getISOWeek(r):Di(r),this.getMonth=(r,o)=>this.overrides?.getMonth?this.overrides.getMonth(r,this.options):Ii(r,this.options),this.getYear=(r,o)=>this.overrides?.getYear?this.overrides.getYear(r,this.options):Wi(r,this.options),this.getWeek=(r,o)=>this.overrides?.getWeek?this.overrides.getWeek(r,this.options):Ri(r,this.options),this.isAfter=(r,o)=>this.overrides?.isAfter?this.overrides.isAfter(r,o):Ai(r,o),this.isBefore=(r,o)=>this.overrides?.isBefore?this.overrides.isBefore(r,o):_i(r,o),this.isDate=r=>this.overrides?.isDate?this.overrides.isDate(r):Fi(r),this.isSameDay=(r,o)=>this.overrides?.isSameDay?this.overrides.isSameDay(r,o):ji(r,o),this.isSameMonth=(r,o)=>this.overrides?.isSameMonth?this.overrides.isSameMonth(r,o):Bi(r,o),this.isSameYear=(r,o)=>this.overrides?.isSameYear?this.overrides.isSameYear(r,o):Li(r,o),this.max=r=>this.overrides?.max?this.overrides.max(r):$i(r),this.min=r=>this.overrides?.min?this.overrides.min(r):Hi(r),this.setMonth=(r,o)=>this.overrides?.setMonth?this.overrides.setMonth(r,o):zi(r,o),this.setYear=(r,o)=>this.overrides?.setYear?this.overrides.setYear(r,o):Ui(r,o),this.startOfBroadcastWeek=(r,o)=>this.overrides?.startOfBroadcastWeek?this.overrides.startOfBroadcastWeek(r,this):Oo(r,this),this.startOfDay=r=>this.overrides?.startOfDay?this.overrides.startOfDay(r):Yi(r),this.startOfISOWeek=r=>this.overrides?.startOfISOWeek?this.overrides.startOfISOWeek(r):qi(r),this.startOfMonth=r=>this.overrides?.startOfMonth?this.overrides.startOfMonth(r):Gi(r),this.startOfWeek=(r,o)=>this.overrides?.startOfWeek?this.overrides.startOfWeek(r,this.options):Vi(r,this.options),this.startOfYear=r=>this.overrides?.startOfYear?this.overrides.startOfYear(r):Ki(r),this.options={locale:So,...t},this.overrides=n}getDigitMap(){const{numerals:t="latn"}=this.options,n=new Intl.NumberFormat("en-US",{numberingSystem:t}),r={};for(let o=0;o<10;o++)r[o.toString()]=n.format(o);return r}replaceDigits(t){const n=this.getDigitMap();return t.replace(/\d/g,r=>n[r]||r)}formatNumber(t){return this.replaceDigits(t.toString())}getMonthYearOrder(){const t=this.options.locale?.code;return t&&ce.yearFirstLocales.has(t)?"year-first":"month-first"}formatMonthYear(t){const{locale:n,timeZone:r,numerals:o}=this.options,i=n?.code;if(i&&ce.yearFirstLocales.has(i))try{return new Intl.DateTimeFormat(i,{month:"long",year:"numeric",timeZone:r,numberingSystem:o}).format(t)}catch{}const s=this.getMonthYearOrder()==="year-first"?"y LLLL":"LLLL y";return this.format(t,s)}}ce.yearFirstLocales=new Set(["eu","hu","ja","ja-Hira","ja-JP","ko","ko-KR","lt","lt-LT","lv","lv-LV","mn","mn-MN","zh","zh-CN","zh-HK","zh-TW"]);const Pe=new ce;class Eo{constructor(t,n,r=Pe){this.date=t,this.displayMonth=n,this.outside=!!(n&&!r.isSameMonth(t,n)),this.dateLib=r,this.isoDate=r.format(t,"yyyy-MM-dd"),this.displayMonthId=r.format(n,"yyyy-MM"),this.dateMonthId=r.format(t,"yyyy-MM")}isEqualTo(t){return this.dateLib.isSameDay(t.date,this.date)&&this.dateLib.isSameMonth(t.displayMonth,this.displayMonth)}}class Dc{constructor(t,n){this.date=t,this.weeks=n}}class Ic{constructor(t,n){this.days=n,this.weekNumber=t}}function Wc(e){return w.createElement("button",{...e})}function Rc(e){return w.createElement("span",{...e})}function Ac(e){const{size:t=24,orientation:n="left",className:r}=e;return w.createElement("svg",{className:r,width:t,height:t,viewBox:"0 0 24 24"},n==="up"&&w.createElement("polygon",{points:"6.77 17 12.5 11.43 18.24 17 20 15.28 12.5 8 5 15.28"}),n==="down"&&w.createElement("polygon",{points:"6.77 8 12.5 13.57 18.24 8 20 9.72 12.5 17 5 9.72"}),n==="left"&&w.createElement("polygon",{points:"16 18.112 9.81111111 12 16 5.87733333 14.0888889 4 6 12 14.0888889 20"}),n==="right"&&w.createElement("polygon",{points:"8 18.112 14.18888889 12 8 5.87733333 9.91111111 4 18 12 9.91111111 20"}))}function _c(e){const{day:t,modifiers:n,...r}=e;return w.createElement("td",{...r})}function Fc(e){const{day:t,modifiers:n,...r}=e,o=w.useRef(null);return w.useEffect(()=>{n.focused&&o.current?.focus()},[n.focused]),w.createElement("button",{ref:o,...r})}var I;(function(e){e.Root="root",e.Chevron="chevron",e.Day="day",e.DayButton="day_button",e.CaptionLabel="caption_label",e.Dropdowns="dropdowns",e.Dropdown="dropdown",e.DropdownRoot="dropdown_root",e.Footer="footer",e.MonthGrid="month_grid",e.MonthCaption="month_caption",e.MonthsDropdown="months_dropdown",e.Month="month",e.Months="months",e.Nav="nav",e.NextMonthButton="button_next",e.PreviousMonthButton="button_previous",e.Week="week",e.Weeks="weeks",e.Weekday="weekday",e.Weekdays="weekdays",e.WeekNumber="week_number",e.WeekNumberHeader="week_number_header",e.YearsDropdown="years_dropdown"})(I||(I={}));var J;(function(e){e.disabled="disabled",e.hidden="hidden",e.outside="outside",e.focused="focused",e.today="today"})(J||(J={}));var ge;(function(e){e.range_end="range_end",e.range_middle="range_middle",e.range_start="range_start",e.selected="selected"})(ge||(ge={}));var le;(function(e){e.weeks_before_enter="weeks_before_enter",e.weeks_before_exit="weeks_before_exit",e.weeks_after_enter="weeks_after_enter",e.weeks_after_exit="weeks_after_exit",e.caption_after_enter="caption_after_enter",e.caption_after_exit="caption_after_exit",e.caption_before_enter="caption_before_enter",e.caption_before_exit="caption_before_exit"})(le||(le={}));function jc(e){const{options:t,className:n,components:r,classNames:o,...i}=e,s=[o[I.Dropdown],n].join(" "),a=t?.find(({value:l})=>l===i.value);return w.createElement("span",{"data-disabled":i.disabled,className:o[I.DropdownRoot]},w.createElement(r.Select,{className:s,...i},t?.map(({value:l,label:u,disabled:f})=>w.createElement(r.Option,{key:l,value:l,disabled:f},u))),w.createElement("span",{className:o[I.CaptionLabel],"aria-hidden":!0},a?.label,w.createElement(r.Chevron,{orientation:"down",size:18,className:o[I.Chevron]})))}function Bc(e){return w.createElement("div",{...e})}function Lc(e){return w.createElement("div",{...e})}function $c(e){const{calendarMonth:t,displayIndex:n,...r}=e;return w.createElement("div",{...r},e.children)}function Hc(e){const{calendarMonth:t,displayIndex:n,...r}=e;return w.createElement("div",{...r})}function zc(e){return w.createElement("table",{...e})}function Uc(e){return w.createElement("div",{...e})}const ko=b.createContext(void 0);function Mt(){const e=b.useContext(ko);if(e===void 0)throw new Error("useDayPicker() must be used within a custom component.");return e}function Yc(e){const{components:t}=Mt();return w.createElement(t.Dropdown,{...e})}function qc(e){const{onPreviousClick:t,onNextClick:n,previousMonth:r,nextMonth:o,...i}=e,{components:s,classNames:a,labels:{labelPrevious:l,labelNext:u}}=Mt(),f=b.useCallback(d=>{o&&n?.(d)},[o,n]),c=b.useCallback(d=>{r&&t?.(d)},[r,t]);return w.createElement("nav",{...i},w.createElement(s.PreviousMonthButton,{type:"button",className:a[I.PreviousMonthButton],tabIndex:r?void 0:-1,"aria-disabled":r?void 0:!0,"aria-label":l(r),onClick:c},w.createElement(s.Chevron,{disabled:r?void 0:!0,className:a[I.Chevron],orientation:"left"})),w.createElement(s.NextMonthButton,{type:"button",className:a[I.NextMonthButton],tabIndex:o?void 0:-1,"aria-disabled":o?void 0:!0,"aria-label":u(o),onClick:f},w.createElement(s.Chevron,{disabled:o?void 0:!0,orientation:"right",className:a[I.Chevron]})))}function Gc(e){const{components:t}=Mt();return w.createElement(t.Button,{...e})}function Vc(e){return w.createElement("option",{...e})}function Kc(e){const{components:t}=Mt();return w.createElement(t.Button,{...e})}function Zc(e){const{rootRef:t,...n}=e;return w.createElement("div",{...n,ref:t})}function Jc(e){return w.createElement("select",{...e})}function Xc(e){const{week:t,...n}=e;return w.createElement("tr",{...n})}function Qc(e){return w.createElement("th",{...e})}function eu(e){return w.createElement("thead",{"aria-hidden":!0},w.createElement("tr",{...e}))}function tu(e){const{week:t,...n}=e;return w.createElement("th",{...n})}function nu(e){return w.createElement("th",{...e})}function ru(e){return w.createElement("tbody",{...e})}function ou(e){const{components:t}=Mt();return w.createElement(t.Dropdown,{...e})}const iu=Object.freeze(Object.defineProperty({__proto__:null,Button:Wc,CaptionLabel:Rc,Chevron:Ac,Day:_c,DayButton:Fc,Dropdown:jc,DropdownNav:Bc,Footer:Lc,Month:$c,MonthCaption:Hc,MonthGrid:zc,Months:Uc,MonthsDropdown:Yc,Nav:qc,NextMonthButton:Gc,Option:Vc,PreviousMonthButton:Kc,Root:Zc,Select:Jc,Week:Xc,WeekNumber:tu,WeekNumberHeader:nu,Weekday:Qc,Weekdays:eu,Weeks:ru,YearsDropdown:ou},Symbol.toStringTag,{value:"Module"}));function We(e,t,n=!1,r=Pe){let{from:o,to:i}=e;const{differenceInCalendarDays:s,isSameDay:a}=r;return o&&i?(s(i,o)<0&&([o,i]=[i,o]),s(t,o)>=(n?1:0)&&s(i,t)>=(n?1:0)):!n&&i?a(i,t):!n&&o?a(o,t):!1}function Nn(e){return!!(e&&typeof e=="object"&&"before"in e&&"after"in e)}function Ht(e){return!!(e&&typeof e=="object"&&"from"in e)}function Dn(e){return!!(e&&typeof e=="object"&&"after"in e)}function In(e){return!!(e&&typeof e=="object"&&"before"in e)}function Co(e){return!!(e&&typeof e=="object"&&"dayOfWeek"in e)}function To(e,t){return Array.isArray(e)&&e.every(t.isDate)}function Re(e,t,n=Pe){const r=Array.isArray(t)?t:[t],{isSameDay:o,differenceInCalendarDays:i,isAfter:s}=n;return r.some(a=>{if(typeof a=="boolean")return a;if(n.isDate(a))return o(e,a);if(To(a,n))return a.some(l=>o(e,l));if(Ht(a))return We(a,e,!1,n);if(Co(a))return Array.isArray(a.dayOfWeek)?a.dayOfWeek.includes(e.getDay()):a.dayOfWeek===e.getDay();if(Nn(a)){const l=i(a.before,e),u=i(a.after,e),f=l>0,c=u<0;return s(a.before,a.after)?c&&f:f||c}return Dn(a)?i(e,a.after)>0:In(a)?i(a.before,e)>0:typeof a=="function"?a(e):!1})}function su(e,t,n,r,o){const{disabled:i,hidden:s,modifiers:a,showOutsideDays:l,broadcastCalendar:u,today:f=o.today()}=t,{isSameDay:c,isSameMonth:d,startOfMonth:p,isBefore:h,endOfMonth:v,isAfter:S}=o,y=n&&p(n),m=r&&v(r),E={[J.focused]:[],[J.outside]:[],[J.disabled]:[],[J.hidden]:[],[J.today]:[]},M={};for(const C of e){const{date:O,displayMonth:D}=C,j=!!(D&&!d(O,D)),Z=!!(y&&h(O,y)),$=!!(m&&S(O,m)),oe=!!(i&&Re(O,i,o)),ue=!!(s&&Re(O,s,o))||Z||$||!u&&!l&&j||u&&l===!1&&j,fe=c(O,f);j&&E.outside.push(C),oe&&E.disabled.push(C),ue&&E.hidden.push(C),fe&&E.today.push(C),a&&Object.keys(a).forEach(X=>{const de=a?.[X];de&&Re(O,de,o)&&(M[X]?M[X].push(C):M[X]=[C])})}return C=>{const O={[J.focused]:!1,[J.disabled]:!1,[J.hidden]:!1,[J.outside]:!1,[J.today]:!1},D={};for(const j in E){const Z=E[j];O[j]=Z.some($=>$===C)}for(const j in M)D[j]=M[j].some(Z=>Z===C);return{...O,...D}}}function au(e,t,n={}){return Object.entries(e).filter(([,o])=>o===!0).reduce((o,[i])=>(n[i]?o.push(n[i]):t[J[i]]?o.push(t[J[i]]):t[ge[i]]&&o.push(t[ge[i]]),o),[t[I.Day]])}function lu(e){return{...iu,...e}}function cu(e){const t={"data-mode":e.mode??void 0,"data-required":"required"in e?e.required:void 0,"data-multiple-months":e.numberOfMonths&&e.numberOfMonths>1||void 0,"data-week-numbers":e.showWeekNumber||void 0,"data-broadcast-calendar":e.broadcastCalendar||void 0,"data-nav-layout":e.navLayout||void 0};return Object.entries(e).forEach(([n,r])=>{n.startsWith("data-")&&(t[n]=r)}),t}function uu(){const e={};for(const t in I)e[I[t]]=`rdp-${I[t]}`;for(const t in J)e[J[t]]=`rdp-${J[t]}`;for(const t in ge)e[ge[t]]=`rdp-${ge[t]}`;for(const t in le)e[le[t]]=`rdp-${le[t]}`;return e}function Mo(e,t,n){return(n??new ce(t)).formatMonthYear(e)}const fu=Mo;function du(e,t,n){return(n??new ce(t)).format(e,"d")}function pu(e,t=Pe){return t.format(e,"LLLL")}function hu(e,t,n){return(n??new ce(t)).format(e,"cccccc")}function mu(e,t=Pe){return e<10?t.formatNumber(`0${e.toLocaleString()}`):t.formatNumber(`${e.toLocaleString()}`)}function yu(){return""}function Po(e,t=Pe){return t.format(e,"yyyy")}const vu=Po,gu=Object.freeze(Object.defineProperty({__proto__:null,formatCaption:Mo,formatDay:du,formatMonthCaption:fu,formatMonthDropdown:pu,formatWeekNumber:mu,formatWeekNumberHeader:yu,formatWeekdayName:hu,formatYearCaption:vu,formatYearDropdown:Po},Symbol.toStringTag,{value:"Module"}));function bu(e){return e?.formatMonthCaption&&!e.formatCaption&&(e.formatCaption=e.formatMonthCaption),e?.formatYearCaption&&!e.formatYearDropdown&&(e.formatYearDropdown=e.formatYearCaption),{...gu,...e}}function Wn(e,t,n,r){let o=(r??new ce(n)).format(e,"PPPP");return t.today&&(o=`Today, ${o}`),t.selected&&(o=`${o}, selected`),o}const wu=Wn;function Rn(e,t,n){return(n??new ce(t)).formatMonthYear(e)}const Ou=Rn;function xo(e,t,n,r){let o=(r??new ce(n)).format(e,"PPPP");return t?.today&&(o=`Today, ${o}`),o}function No(e){return"Choose the Month"}function Do(){return""}const Su="Go to the Next Month";function Io(e,t){return Su}function Wo(e){return"Go to the Previous Month"}function Ro(e,t,n){return(n??new ce(t)).format(e,"cccc")}function Ao(e,t){return`Week ${e}`}function _o(e){return"Week Number"}function Fo(e){return"Choose the Year"}const Eu=Object.freeze(Object.defineProperty({__proto__:null,labelCaption:Ou,labelDay:wu,labelDayButton:Wn,labelGrid:Rn,labelGridcell:xo,labelMonthDropdown:No,labelNav:Do,labelNext:Io,labelPrevious:Wo,labelWeekNumber:Ao,labelWeekNumberHeader:_o,labelWeekday:Ro,labelYearDropdown:Fo},Symbol.toStringTag,{value:"Module"})),me=(e,t,n)=>t||(n?typeof n=="function"?n:(...r)=>n:e);function ku(e,t){const n=t.locale?.labels??{};return{...Eu,...e??{},labelDayButton:me(Wn,e?.labelDayButton,n.labelDayButton),labelMonthDropdown:me(No,e?.labelMonthDropdown,n.labelMonthDropdown),labelNext:me(Io,e?.labelNext,n.labelNext),labelPrevious:me(Wo,e?.labelPrevious,n.labelPrevious),labelWeekNumber:me(Ao,e?.labelWeekNumber,n.labelWeekNumber),labelYearDropdown:me(Fo,e?.labelYearDropdown,n.labelYearDropdown),labelGrid:me(Rn,e?.labelGrid,n.labelGrid),labelGridcell:me(xo,e?.labelGridcell,n.labelGridcell),labelNav:me(Do,e?.labelNav,n.labelNav),labelWeekNumberHeader:me(_o,e?.labelWeekNumberHeader,n.labelWeekNumberHeader),labelWeekday:me(Ro,e?.labelWeekday,n.labelWeekday)}}function Cu(e,t,n,r,o){const{startOfMonth:i,startOfYear:s,endOfYear:a,eachMonthOfInterval:l,getMonth:u}=o;return l({start:s(e),end:a(e)}).map(d=>{const p=r.formatMonthDropdown(d,o),h=u(d),v=t&&di(n)||!1;return{value:h,label:p,disabled:v}})}function Tu(e,t={},n={}){let r={...t?.[I.Day]};return Object.entries(e).filter(([,o])=>o===!0).forEach(([o])=>{r={...r,...n?.[o]}}),r}function Mu(e,t,n,r){const o=r??e.today(),i=n?e.startOfBroadcastWeek(o,e):t?e.startOfISOWeek(o):e.startOfWeek(o),s=[];for(let a=0;a<7;a++){const l=e.addDays(i,a);s.push(l)}return s}function Pu(e,t,n,r,o=!1){if(!e||!t)return;const{startOfYear:i,endOfYear:s,eachYearOfInterval:a,getYear:l}=r,u=i(e),f=s(t),c=a({start:u,end:f});return o&&c.reverse(),c.map(d=>{const p=n.formatYearDropdown(d,r);return{value:l(d),label:p,disabled:!1}})}const Pt=e=>e instanceof HTMLElement?e:null,ln=e=>[...e.querySelectorAll("[data-animated-month]")??[]],xu=e=>Pt(e.querySelector("[data-animated-month]")),cn=e=>Pt(e.querySelector("[data-animated-caption]")),un=e=>Pt(e.querySelector("[data-animated-weeks]")),Nu=e=>Pt(e.querySelector("[data-animated-nav]")),Du=e=>Pt(e.querySelector("[data-animated-weekdays]"));function Iu(e,t,{classNames:n,months:r,focused:o,dateLib:i}){const s=b.useRef(null),a=b.useRef(r),l=b.useRef(!1);b.useLayoutEffect(()=>{const u=a.current;if(a.current=r,!t||!e.current||!(e.current instanceof HTMLElement)||r.length===0||u.length===0||r.length!==u.length)return;const f=i.isSameMonth(r[0].date,u[0].date),c=i.isAfter(r[0].date,u[0].date),d=c?n[le.caption_after_enter]:n[le.caption_before_enter],p=c?n[le.weeks_after_enter]:n[le.weeks_before_enter],h=s.current,v=e.current.cloneNode(!0);if(v instanceof HTMLElement?(ln(v).forEach(E=>{if(!(E instanceof HTMLElement))return;const M=xu(E);M&&E.contains(M)&&E.removeChild(M);const C=cn(E);C&&C.classList.remove(d);const O=un(E);O&&O.classList.remove(p)}),s.current=v):s.current=null,l.current||f||o)return;const S=h instanceof HTMLElement?ln(h):[],y=ln(e.current);if(y?.every(m=>m instanceof HTMLElement)&&S&&S.every(m=>m instanceof HTMLElement)){l.current=!0,e.current.style.isolation="isolate";const m=Nu(e.current);m&&(m.style.zIndex="1"),y.forEach((E,M)=>{const C=S[M];if(!C)return;E.style.position="relative",E.style.overflow="hidden";const O=cn(E);O&&O.classList.add(d);const D=un(E);D&&D.classList.add(p);const j=()=>{l.current=!1,e.current&&(e.current.style.isolation=""),m&&(m.style.zIndex=""),O&&O.classList.remove(d),D&&D.classList.remove(p),E.style.position="",E.style.overflow="",E.contains(C)&&E.removeChild(C)};C.style.pointerEvents="none",C.style.position="absolute",C.style.overflow="hidden",C.setAttribute("aria-hidden","true");const Z=Du(C);Z&&(Z.style.opacity="0");const $=cn(C);$&&($.classList.add(c?n[le.caption_before_exit]:n[le.caption_after_exit]),$.addEventListener("animationend",j));const oe=un(C);oe&&oe.classList.add(c?n[le.weeks_before_exit]:n[le.weeks_after_exit]),E.insertBefore(C,E.firstChild)})}})}function Wu(e,t,n,r){const o=e[0],i=e[e.length-1],{ISOWeek:s,fixedWeeks:a,broadcastCalendar:l}=n??{},{addDays:u,differenceInCalendarDays:f,differenceInCalendarMonths:c,endOfBroadcastWeek:d,endOfISOWeek:p,endOfMonth:h,endOfWeek:v,isAfter:S,startOfBroadcastWeek:y,startOfISOWeek:m,startOfWeek:E}=r,M=l?y(o,r):s?m(o):E(o),C=l?d(i):s?p(h(i)):v(h(i)),O=t&&(l?d(t):s?p(t):v(t)),D=O&&S(C,O)?O:C,j=f(D,M),Z=c(i,o)+1,$=[];for(let fe=0;fe<=j;fe++){const X=u(M,fe);$.push(X)}const ue=(l?35:42)*Z;if(a&&$.length{const o=r.weeks.reduce((i,s)=>i.concat(s.days.slice()),t.slice());return n.concat(o.slice())},t.slice())}function Au(e,t,n,r){const{numberOfMonths:o=1}=n,i=[];for(let s=0;st)break;i.push(a)}return i}function Tr(e,t,n,r){const{month:o,defaultMonth:i,today:s=r.today(),numberOfMonths:a=1}=e;let l=o||i||s;const{differenceInCalendarMonths:u,addMonths:f,startOfMonth:c}=r;if(n&&u(n,l){const y=n.broadcastCalendar?c(S,r):n.ISOWeek?d(S):p(S),m=n.broadcastCalendar?i(S):n.ISOWeek?s(a(S)):l(a(S)),E=t.filter(D=>D>=y&&D<=m),M=n.broadcastCalendar?35:42;if(n.fixedWeeks&&E.length{const Z=M-E.length;return j>m&&j<=o(m,Z)});E.push(...D)}const C=E.reduce((D,j)=>{const Z=n.ISOWeek?u(j):f(j),$=D.find(ue=>ue.weekNumber===Z),oe=new Eo(j,S,r);return $?$.days.push(oe):D.push(new Ic(Z,[oe])),D},[]),O=new Dc(S,C);return v.push(O),v},[]);return n.reverseMonths?h.reverse():h}function Fu(e,t){let{startMonth:n,endMonth:r}=e;const{startOfYear:o,startOfDay:i,startOfMonth:s,endOfMonth:a,addYears:l,endOfYear:u,newDate:f,today:c}=t,{fromYear:d,toYear:p,fromMonth:h,toMonth:v}=e;!n&&h&&(n=h),!n&&d&&(n=t.newDate(d,0,1)),!r&&v&&(r=v),!r&&p&&(r=f(p,11,31));const S=e.captionLayout==="dropdown"||e.captionLayout==="dropdown-years";return n?n=s(n):d?n=f(d,0,1):!n&&S&&(n=o(l(e.today??c(),-100))),r?r=a(r):p?r=f(p,11,31):!r&&S&&(r=u(e.today??c())),[n&&i(n),r&&i(r)]}function ju(e,t,n,r){if(n.disableNavigation)return;const{pagedNavigation:o,numberOfMonths:i=1}=n,{startOfMonth:s,addMonths:a,differenceInCalendarMonths:l}=r,u=o?i:1,f=s(e);if(!t)return a(f,u);if(!(l(t,e)n.concat(r.weeks.slice()),t.slice())}function zt(e,t){const[n,r]=b.useState(e);return[t===void 0?n:t,r]}function $u(e,t){const[n,r]=Fu(e,t),{startOfMonth:o,endOfMonth:i}=t,s=Tr(e,n,r,t),[a,l]=zt(s,e.month?s:void 0);b.useEffect(()=>{const M=Tr(e,n,r,t);l(M)},[e.timeZone]);const{months:u,weeks:f,days:c,previousMonth:d,nextMonth:p}=b.useMemo(()=>{const M=Au(a,r,{numberOfMonths:e.numberOfMonths},t),C=Wu(M,e.endMonth?i(e.endMonth):void 0,{ISOWeek:e.ISOWeek,fixedWeeks:e.fixedWeeks,broadcastCalendar:e.broadcastCalendar},t),O=_u(M,C,{broadcastCalendar:e.broadcastCalendar,fixedWeeks:e.fixedWeeks,ISOWeek:e.ISOWeek,reverseMonths:e.reverseMonths},t),D=Lu(O),j=Ru(O),Z=Bu(a,n,e,t),$=ju(a,r,e,t);return{months:O,weeks:D,days:j,previousMonth:Z,nextMonth:$}},[t,a.getTime(),r?.getTime(),n?.getTime(),e.disableNavigation,e.broadcastCalendar,e.endMonth?.getTime(),e.fixedWeeks,e.ISOWeek,e.numberOfMonths,e.pagedNavigation,e.reverseMonths]),{disableNavigation:h,onMonthChange:v}=e,S=M=>f.some(C=>C.days.some(O=>O.isEqualTo(M))),y=M=>{if(h)return;let C=o(M);n&&Co(r)&&(C=o(r)),l(C),v?.(C)};return{months:u,weeks:f,days:c,navStart:n,navEnd:r,previousMonth:d,nextMonth:p,goToMonth:y,goToDay:M=>{S(M)||y(M.date)}}}var Se;(function(e){e[e.Today=0]="Today",e[e.Selected=1]="Selected",e[e.LastFocused=2]="LastFocused",e[e.FocusedModifier=3]="FocusedModifier"})(Se||(Se={}));function Mr(e){return!e[J.disabled]&&!e[J.hidden]&&!e[J.outside]}function Hu(e,t,n,r){let o,i=-1;for(const s of e){const a=t(s);Mr(a)&&(a[J.focused]&&iMr(t(s)))),o}function zu(e,t,n,r,o,i,s){const{ISOWeek:a,broadcastCalendar:l}=i,{addDays:u,addMonths:f,addWeeks:c,addYears:d,endOfBroadcastWeek:p,endOfISOWeek:h,endOfWeek:v,max:S,min:y,startOfBroadcastWeek:m,startOfISOWeek:E,startOfWeek:M}=s;let O={day:u,week:c,month:f,year:d,startOfWeek:D=>l?m(D,s):a?E(D):M(D),endOfWeek:D=>l?p(D):a?h(D):v(D)}[e](n,t==="after"?1:-1);return t==="before"&&r?O=S([r,O]):t==="after"&&o&&(O=y([o,O])),O}function jo(e,t,n,r,o,i,s,a=0){if(a>365)return;const l=zu(e,t,n.date,r,o,i,s),u=!!(i.disabled&&Re(l,i.disabled,s)),f=!!(i.hidden&&Re(l,i.hidden,s)),c=l,d=new Eo(l,c,s);return!u&&!f?d:jo(e,t,d,r,o,i,s,a+1)}function Uu(e,t,n,r,o){const{autoFocus:i}=e,[s,a]=b.useState(),l=Hu(t.days,n,r||(()=>!1),s),[u,f]=b.useState(i?l:void 0);return{isFocusTarget:v=>!!l?.isEqualTo(v),setFocused:f,focused:u,blur:()=>{a(u),f(void 0)},moveFocus:(v,S)=>{if(!u)return;const y=jo(v,S,u,t.navStart,t.navEnd,e,o);y&&(e.disableNavigation&&!t.days.some(E=>E.isEqualTo(y))||(t.goToDay(y),f(y)))}}}function Yu(e,t){const{selected:n,required:r,onSelect:o}=e,[i,s]=zt(n,o?n:void 0),a=o?n:i,{isSameDay:l}=t,u=p=>a?.some(h=>l(h,p))??!1,{min:f,max:c}=e;return{selected:a,select:(p,h,v)=>{let S=[...a??[]];if(u(p)){if(a?.length===f||r&&a?.length===1)return;S=a?.filter(y=>!l(y,p))}else a?.length===c?S=[p]:S=[...S,p];return o||s(S),o?.(S,p,h,v),S},isSelected:u}}function qu(e,t,n=0,r=0,o=!1,i=Pe){const{from:s,to:a}=t||{},{isSameDay:l,isAfter:u,isBefore:f}=i;let c;if(!s&&!a)c={from:e,to:n>0?void 0:e};else if(s&&!a)l(s,e)?n===0?c={from:s,to:e}:o?c={from:s,to:void 0}:c=void 0:f(e,s)?c={from:e,to:s}:c={from:s,to:e};else if(s&&a)if(l(s,e)&&l(a,e))o?c={from:s,to:a}:c=void 0;else if(l(s,e))c={from:s,to:n>0?void 0:e};else if(l(a,e))c={from:e,to:n>0?void 0:e};else if(f(e,s))c={from:e,to:a};else if(u(e,s))c={from:s,to:e};else if(u(e,a))c={from:s,to:e};else throw new Error("Invalid range");if(c?.from&&c?.to){const d=i.differenceInCalendarDays(c.to,c.from);r>0&&d>r?c={from:e,to:void 0}:n>1&&dtypeof a!="function").some(a=>typeof a=="boolean"?a:n.isDate(a)?We(e,a,!1,n):To(a,n)?a.some(l=>We(e,l,!1,n)):Ht(a)?a.from&&a.to?Pr(e,{from:a.from,to:a.to},n):!1:Co(a)?Gu(e,a.dayOfWeek,n):Nn(a)?n.isAfter(a.before,a.after)?Pr(e,{from:n.addDays(a.after,1),to:n.addDays(a.before,-1)},n):Re(e.from,a,n)||Re(e.to,a,n):Dn(a)||In(a)?Re(e.from,a,n)||Re(e.to,a,n):!1))return!0;const s=r.filter(a=>typeof a=="function");if(s.length){let a=e.from;const l=n.differenceInCalendarDays(e.to,e.from);for(let u=0;u<=l;u++){if(s.some(f=>f(a)))return!0;a=n.addDays(a,1)}}return!1}function Ku(e,t){const{disabled:n,excludeDisabled:r,selected:o,required:i,onSelect:s}=e,[a,l]=zt(o,s?o:void 0),u=s?o:a;return{selected:u,select:(d,p,h)=>{const{min:v,max:S}=e,y=d?qu(d,u,v,S,i,t):void 0;return r&&n&&y?.from&&y.to&&Vu({from:y.from,to:y.to},n,t)&&(y.from=d,y.to=void 0),s||l(y),s?.(y,d,p,h),y},isSelected:d=>u&&We(u,d,!1,t)}}function Zu(e,t){const{selected:n,required:r,onSelect:o}=e,[i,s]=zt(n,o?n:void 0),a=o?n:i,{isSameDay:l}=t;return{selected:a,select:(c,d,p)=>{let h=c;return!r&&a&&a&&l(c,a)&&(h=void 0),o||s(h),o?.(h,c,d,p),h},isSelected:c=>a?l(a,c):!1}}function Ju(e,t){const n=Zu(e,t),r=Yu(e,t),o=Ku(e,t);switch(e.mode){case"single":return n;case"multiple":return r;case"range":return o;default:return}}function ee(e,t){return e instanceof Ie&&e.timeZone===t?e:new Ie(e,t)}function xr(e,t){return typeof e=="boolean"||typeof e=="function"?e:e instanceof Date?ee(e,t):Array.isArray(e)?e.map(n=>n instanceof Date?ee(n,t):n):Ht(e)?{...e,from:e.from?ee(e.from,t):e.from,to:e.to?ee(e.to,t):e.to}:Nn(e)?{before:ee(e.before,t),after:ee(e.after,t)}:Dn(e)?{after:ee(e.after,t)}:In(e)?{before:ee(e.before,t)}:e}function fn(e,t){return e&&(Array.isArray(e)?e.map(n=>xr(n,t)):xr(e,t))}function sf(e){let t=e;const n=t.timeZone;if(n&&(t={...e,timeZone:n},t.today&&(t.today=ee(t.today,n)),t.month&&(t.month=ee(t.month,n)),t.defaultMonth&&(t.defaultMonth=ee(t.defaultMonth,n)),t.startMonth&&(t.startMonth=ee(t.startMonth,n)),t.endMonth&&(t.endMonth=ee(t.endMonth,n)),t.mode==="single"&&t.selected?t.selected=ee(t.selected,n):t.mode==="multiple"&&t.selected?t.selected=t.selected?.map(F=>ee(F,n)):t.mode==="range"&&t.selected&&(t.selected={from:t.selected.from?ee(t.selected.from,n):t.selected.from,to:t.selected.to?ee(t.selected.to,n):t.selected.to}),t.disabled!==void 0&&(t.disabled=fn(t.disabled,n)),t.hidden!==void 0&&(t.hidden=fn(t.hidden,n)),t.modifiers)){const F={};Object.keys(t.modifiers).forEach(Y=>{F[Y]=fn(t.modifiers?.[Y],n)}),t.modifiers=F}const{components:r,formatters:o,labels:i,dateLib:s,locale:a,classNames:l}=b.useMemo(()=>{const F={...So,...t.locale},Y=new ce({locale:F,weekStartsOn:t.broadcastCalendar?1:t.weekStartsOn,firstWeekContainsDate:t.firstWeekContainsDate,useAdditionalWeekYearTokens:t.useAdditionalWeekYearTokens,useAdditionalDayOfYearTokens:t.useAdditionalDayOfYearTokens,timeZone:t.timeZone,numerals:t.numerals},t.dateLib);return{dateLib:Y,components:lu(t.components),formatters:bu(t.formatters),labels:ku(t.labels,Y.options),locale:F,classNames:{...uu(),...t.classNames}}},[t.locale,t.broadcastCalendar,t.weekStartsOn,t.firstWeekContainsDate,t.useAdditionalWeekYearTokens,t.useAdditionalDayOfYearTokens,t.timeZone,t.numerals,t.dateLib,t.components,t.formatters,t.labels,t.classNames]);t.today||(t={...t,today:s.today()});const{captionLayout:u,mode:f,navLayout:c,numberOfMonths:d=1,onDayBlur:p,onDayClick:h,onDayFocus:v,onDayKeyDown:S,onDayMouseEnter:y,onDayMouseLeave:m,onNextClick:E,onPrevClick:M,showWeekNumber:C,styles:O}=t,{formatCaption:D,formatDay:j,formatMonthDropdown:Z,formatWeekNumber:$,formatWeekNumberHeader:oe,formatWeekdayName:ue,formatYearDropdown:fe}=o,X=$u(t,s),{days:de,months:Ae,navStart:Le,navEnd:qe,previousMonth:ie,nextMonth:se,goToMonth:pe}=X,k=su(de,t,Le,qe,s),{isSelected:R,select:B,selected:W}=Ju(t,s)??{},{blur:U,focused:V,isFocusTarget:ne,moveFocus:Q,setFocused:xe}=Uu(t,X,k,R??(()=>!1),s),{labelDayButton:Bo,labelGridcell:Lo,labelGrid:$o,labelMonthDropdown:Ho,labelNav:An,labelPrevious:zo,labelNext:Uo,labelWeekday:Yo,labelWeekNumber:qo,labelWeekNumberHeader:Go,labelYearDropdown:Vo}=i,Ko=b.useMemo(()=>Mu(s,t.ISOWeek,t.broadcastCalendar,t.today),[s,t.ISOWeek,t.broadcastCalendar,t.today]),_n=f!==void 0||h!==void 0,Ut=b.useCallback(()=>{ie&&(pe(ie),M?.(ie))},[ie,pe,M]),Yt=b.useCallback(()=>{se&&(pe(se),E?.(se))},[pe,se,E]),Zo=b.useCallback((F,Y)=>_=>{_.preventDefault(),_.stopPropagation(),xe(F),!Y.disabled&&(B?.(F.date,Y,_),h?.(F.date,Y,_))},[B,h,xe]),Jo=b.useCallback((F,Y)=>_=>{xe(F),v?.(F.date,Y,_)},[v,xe]),Xo=b.useCallback((F,Y)=>_=>{U(),p?.(F.date,Y,_)},[U,p]),Qo=b.useCallback((F,Y)=>_=>{const G={ArrowLeft:[_.shiftKey?"month":"day",t.dir==="rtl"?"after":"before"],ArrowRight:[_.shiftKey?"month":"day",t.dir==="rtl"?"before":"after"],ArrowDown:[_.shiftKey?"year":"week","after"],ArrowUp:[_.shiftKey?"year":"week","before"],PageUp:[_.shiftKey?"year":"month","before"],PageDown:[_.shiftKey?"year":"month","after"],Home:["startOfWeek","before"],End:["endOfWeek","after"]};if(G[_.key]){_.preventDefault(),_.stopPropagation();const[Oe,H]=G[_.key];Q(Oe,H)}S?.(F.date,Y,_)},[Q,S,t.dir]),ei=b.useCallback((F,Y)=>_=>{y?.(F.date,Y,_)},[y]),ti=b.useCallback((F,Y)=>_=>{m?.(F.date,Y,_)},[m]),ni=b.useCallback(F=>Y=>{const _=Number(Y.target.value),G=s.setMonth(s.startOfMonth(F),_);pe(G)},[s,pe]),ri=b.useCallback(F=>Y=>{const _=Number(Y.target.value),G=s.setYear(s.startOfMonth(F),_);pe(G)},[s,pe]),{className:oi,style:ii}=b.useMemo(()=>({className:[l[I.Root],t.className].filter(Boolean).join(" "),style:{...O?.[I.Root],...t.style}}),[l,t.className,t.style,O]),si=cu(t),Fn=b.useRef(null);Iu(Fn,!!t.animate,{classNames:l,months:Ae,focused:V,dateLib:s});const ai={dayPickerProps:t,selected:W,select:B,isSelected:R,months:Ae,nextMonth:se,previousMonth:ie,goToMonth:pe,getModifiers:k,components:r,classNames:l,styles:O,labels:i,formatters:o};return w.createElement(ko.Provider,{value:ai},w.createElement(r.Root,{rootRef:t.animate?Fn:void 0,className:oi,style:ii,dir:t.dir,id:t.id,lang:t.lang,nonce:t.nonce,title:t.title,role:t.role,"aria-label":t["aria-label"],"aria-labelledby":t["aria-labelledby"],...si},w.createElement(r.Months,{className:l[I.Months],style:O?.[I.Months]},!t.hideNavigation&&!c&&w.createElement(r.Nav,{"data-animated-nav":t.animate?"true":void 0,className:l[I.Nav],style:O?.[I.Nav],"aria-label":An(),onPreviousClick:Ut,onNextClick:Yt,previousMonth:ie,nextMonth:se}),Ae.map((F,Y)=>w.createElement(r.Month,{"data-animated-month":t.animate?"true":void 0,className:l[I.Month],style:O?.[I.Month],key:Y,displayIndex:Y,calendarMonth:F},c==="around"&&!t.hideNavigation&&Y===0&&w.createElement(r.PreviousMonthButton,{type:"button",className:l[I.PreviousMonthButton],tabIndex:ie?void 0:-1,"aria-disabled":ie?void 0:!0,"aria-label":zo(ie),onClick:Ut,"data-animated-button":t.animate?"true":void 0},w.createElement(r.Chevron,{disabled:ie?void 0:!0,className:l[I.Chevron],orientation:t.dir==="rtl"?"right":"left"})),w.createElement(r.MonthCaption,{"data-animated-caption":t.animate?"true":void 0,className:l[I.MonthCaption],style:O?.[I.MonthCaption],calendarMonth:F,displayIndex:Y},u?.startsWith("dropdown")?w.createElement(r.DropdownNav,{className:l[I.Dropdowns],style:O?.[I.Dropdowns]},(()=>{const _=u==="dropdown"||u==="dropdown-months"?w.createElement(r.MonthsDropdown,{key:"month",className:l[I.MonthsDropdown],"aria-label":Ho(),classNames:l,components:r,disabled:!!t.disableNavigation,onChange:ni(F.date),options:Cu(F.date,Le,qe,o,s),style:O?.[I.Dropdown],value:s.getMonth(F.date)}):w.createElement("span",{key:"month"},Z(F.date,s)),G=u==="dropdown"||u==="dropdown-years"?w.createElement(r.YearsDropdown,{key:"year",className:l[I.YearsDropdown],"aria-label":Vo(s.options),classNames:l,components:r,disabled:!!t.disableNavigation,onChange:ri(F.date),options:Pu(Le,qe,o,s,!!t.reverseYears),style:O?.[I.Dropdown],value:s.getYear(F.date)}):w.createElement("span",{key:"year"},fe(F.date,s));return s.getMonthYearOrder()==="year-first"?[G,_]:[_,G]})(),w.createElement("span",{role:"status","aria-live":"polite",style:{border:0,clip:"rect(0 0 0 0)",height:"1px",margin:"-1px",overflow:"hidden",padding:0,position:"absolute",width:"1px",whiteSpace:"nowrap",wordWrap:"normal"}},D(F.date,s.options,s))):w.createElement(r.CaptionLabel,{className:l[I.CaptionLabel],role:"status","aria-live":"polite"},D(F.date,s.options,s))),c==="around"&&!t.hideNavigation&&Y===d-1&&w.createElement(r.NextMonthButton,{type:"button",className:l[I.NextMonthButton],tabIndex:se?void 0:-1,"aria-disabled":se?void 0:!0,"aria-label":Uo(se),onClick:Yt,"data-animated-button":t.animate?"true":void 0},w.createElement(r.Chevron,{disabled:se?void 0:!0,className:l[I.Chevron],orientation:t.dir==="rtl"?"left":"right"})),Y===d-1&&c==="after"&&!t.hideNavigation&&w.createElement(r.Nav,{"data-animated-nav":t.animate?"true":void 0,className:l[I.Nav],style:O?.[I.Nav],"aria-label":An(),onPreviousClick:Ut,onNextClick:Yt,previousMonth:ie,nextMonth:se}),w.createElement(r.MonthGrid,{role:"grid","aria-multiselectable":f==="multiple"||f==="range","aria-label":$o(F.date,s.options,s)||void 0,className:l[I.MonthGrid],style:O?.[I.MonthGrid]},!t.hideWeekdays&&w.createElement(r.Weekdays,{"data-animated-weekdays":t.animate?"true":void 0,className:l[I.Weekdays],style:O?.[I.Weekdays]},C&&w.createElement(r.WeekNumberHeader,{"aria-label":Go(s.options),className:l[I.WeekNumberHeader],style:O?.[I.WeekNumberHeader],scope:"col"},oe()),Ko.map(_=>w.createElement(r.Weekday,{"aria-label":Yo(_,s.options,s),className:l[I.Weekday],key:String(_),style:O?.[I.Weekday],scope:"col"},ue(_,s.options,s)))),w.createElement(r.Weeks,{"data-animated-weeks":t.animate?"true":void 0,className:l[I.Weeks],style:O?.[I.Weeks]},F.weeks.map(_=>w.createElement(r.Week,{className:l[I.Week],key:_.weekNumber,style:O?.[I.Week],week:_},C&&w.createElement(r.WeekNumber,{week:_,style:O?.[I.WeekNumber],"aria-label":qo(_.weekNumber,{locale:a}),className:l[I.WeekNumber],scope:"row",role:"rowheader"},$(_.weekNumber,s)),_.days.map(G=>{const{date:Oe}=G,H=k(G);if(H[J.focused]=!H.hidden&&!!V?.isEqualTo(G),H[ge.selected]=R?.(Oe)||H.selected,Ht(W)){const{from:qt,to:Gt}=W;H[ge.range_start]=!!(qt&&Gt&&s.isSameDay(Oe,qt)),H[ge.range_end]=!!(qt&&Gt&&s.isSameDay(Oe,Gt)),H[ge.range_middle]=We(W,Oe,!0,s)}const li=Tu(H,O,t.modifiersStyles),ci=au(H,l,t.modifiersClassNames),ui=!_n&&!H.hidden?Lo(Oe,H,s.options,s):void 0;return w.createElement(r.Day,{key:`${G.isoDate}_${G.displayMonthId}`,day:G,modifiers:H,className:ci.join(" "),style:li,role:"gridcell","aria-selected":H.selected||void 0,"aria-label":ui,"data-day":G.isoDate,"data-month":G.outside?G.dateMonthId:void 0,"data-selected":H.selected||void 0,"data-disabled":H.disabled||void 0,"data-hidden":H.hidden||void 0,"data-outside":G.outside||void 0,"data-focused":H.focused||void 0,"data-today":H.today||void 0},!H.hidden&&_n?w.createElement(r.DayButton,{className:l[I.DayButton],style:O?.[I.DayButton],type:"button",day:G,modifiers:H,disabled:!H.focused&&H.disabled||void 0,"aria-disabled":H.focused&&H.disabled||void 0,tabIndex:ne(G)?0:-1,"aria-label":Bo(Oe,H,s.options,s),onClick:Zo(G,H),onBlur:Xo(G,H),onFocus:Jo(G,H),onKeyDown:Qo(G,H),onMouseEnter:ei(G,H),onMouseLeave:ti(G,H)},j(Oe,s.options,s)):!H.hidden&&j(G.date,s.options,s))})))))))),t.footer&&w.createElement(r.Footer,{className:l[I.Footer],style:O?.[I.Footer],role:"status","aria-live":"polite"},t.footer)))}export{sf as D,nf as _,rf as c,uu as g,of as z}; diff --git a/webui/dist/assets/radix-core-BdJoVJLV.js b/webui/dist/assets/radix-core-BdJoVJLV.js new file mode 100644 index 00000000..6390eb41 --- /dev/null +++ b/webui/dist/assets/radix-core-BdJoVJLV.js @@ -0,0 +1,45 @@ +import{r as i,j as v,R as Ee,a as sn,b as Ye,c as ds}from"./router-9vIXuQkh.js";function N(e,t,{checkForDefaultPrevented:n=!0}={}){return function(r){if(e?.(r),n===!1||!r.defaultPrevented)return t?.(r)}}function fs(e,t){const n=i.createContext(t),o=s=>{const{children:a,...c}=s,l=i.useMemo(()=>c,Object.values(c));return v.jsx(n.Provider,{value:l,children:a})};o.displayName=e+"Provider";function r(s){const a=i.useContext(n);if(a)return a;if(t!==void 0)return t;throw new Error(`\`${s}\` must be used within \`${e}\``)}return[o,r]}function Oe(e,t=[]){let n=[];function o(s,a){const c=i.createContext(a),l=n.length;n=[...n,a];const u=p=>{const{scope:y,children:h,...x}=p,d=y?.[e]?.[l]||c,m=i.useMemo(()=>x,Object.values(x));return v.jsx(d.Provider,{value:m,children:h})};u.displayName=s+"Provider";function f(p,y){const h=y?.[e]?.[l]||c,x=i.useContext(h);if(x)return x;if(a!==void 0)return a;throw new Error(`\`${p}\` must be used within \`${s}\``)}return[u,f]}const r=()=>{const s=n.map(a=>i.createContext(a));return function(c){const l=c?.[e]||s;return i.useMemo(()=>({[`__scope${e}`]:{...c,[e]:l}}),[c,l])}};return r.scopeName=e,[o,ps(r,...t)]}function ps(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const o=e.map(r=>({useScope:r(),scopeName:r.scopeName}));return function(s){const a=o.reduce((c,{useScope:l,scopeName:u})=>{const p=l(s)[`__scope${u}`];return{...c,...p}},{});return i.useMemo(()=>({[`__scope${t.scopeName}`]:a}),[a])}};return n.scopeName=t.scopeName,n}function Pn(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function $e(...e){return t=>{let n=!1;const o=e.map(r=>{const s=Pn(r,t);return!n&&typeof s=="function"&&(n=!0),s});if(n)return()=>{for(let r=0;r{const{children:s,...a}=o,c=i.Children.toArray(s),l=c.find(vs);if(l){const u=l.props.children,f=c.map(p=>p===l?i.Children.count(u)>1?i.Children.only(null):i.isValidElement(u)?u.props.children:null:p);return v.jsx(t,{...a,ref:r,children:i.isValidElement(u)?i.cloneElement(u,void 0,f):null})}return v.jsx(t,{...a,ref:r,children:s})});return n.displayName=`${e}.Slot`,n}function ms(e){const t=i.forwardRef((n,o)=>{const{children:r,...s}=n;if(i.isValidElement(r)){const a=ys(r),c=gs(s,r.props);return r.type!==i.Fragment&&(c.ref=o?$e(o,a):a),i.cloneElement(r,c)}return i.Children.count(r)>1?i.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var hs=Symbol("radix.slottable");function vs(e){return i.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===hs}function gs(e,t){const n={...t};for(const o in t){const r=e[o],s=t[o];/^on[A-Z]/.test(o)?r&&s?n[o]=(...c)=>{const l=s(...c);return r(...c),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...s}:o==="className"&&(n[o]=[r,s].filter(Boolean).join(" "))}return{...e,...n}}function ys(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function eo(e){const t=e+"CollectionProvider",[n,o]=Oe(t),[r,s]=n(t,{collectionRef:{current:null},itemMap:new Map}),a=d=>{const{scope:m,children:w}=d,g=Ee.useRef(null),C=Ee.useRef(new Map).current;return v.jsx(r,{scope:m,itemMap:C,collectionRef:g,children:w})};a.displayName=t;const c=e+"CollectionSlot",l=An(c),u=Ee.forwardRef((d,m)=>{const{scope:w,children:g}=d,C=s(c,w),b=B(m,C.collectionRef);return v.jsx(l,{ref:b,children:g})});u.displayName=c;const f=e+"CollectionItemSlot",p="data-radix-collection-item",y=An(f),h=Ee.forwardRef((d,m)=>{const{scope:w,children:g,...C}=d,b=Ee.useRef(null),E=B(m,b),R=s(f,w);return Ee.useEffect(()=>(R.itemMap.set(b,{ref:b,...C}),()=>void R.itemMap.delete(b))),v.jsx(y,{[p]:"",ref:E,children:g})});h.displayName=f;function x(d){const m=s(e+"CollectionConsumer",d);return Ee.useCallback(()=>{const g=m.collectionRef.current;if(!g)return[];const C=Array.from(g.querySelectorAll(`[${p}]`));return Array.from(m.itemMap.values()).sort((R,S)=>C.indexOf(R.ref.current)-C.indexOf(S.ref.current))},[m.collectionRef,m.itemMap])}return[{Provider:a,Slot:u,ItemSlot:h},x,o]}var z=globalThis?.document?i.useLayoutEffect:()=>{},ws=sn[" useId ".trim().toString()]||(()=>{}),xs=0;function Se(e){const[t,n]=i.useState(ws());return z(()=>{n(o=>o??String(xs++))},[e]),t?`radix-${t}`:""}function Cs(e){const t=bs(e),n=i.forwardRef((o,r)=>{const{children:s,...a}=o,c=i.Children.toArray(s),l=c.find(Ss);if(l){const u=l.props.children,f=c.map(p=>p===l?i.Children.count(u)>1?i.Children.only(null):i.isValidElement(u)?u.props.children:null:p);return v.jsx(t,{...a,ref:r,children:i.isValidElement(u)?i.cloneElement(u,void 0,f):null})}return v.jsx(t,{...a,ref:r,children:s})});return n.displayName=`${e}.Slot`,n}function bs(e){const t=i.forwardRef((n,o)=>{const{children:r,...s}=n;if(i.isValidElement(r)){const a=Rs(r),c=Ts(s,r.props);return r.type!==i.Fragment&&(c.ref=o?$e(o,a):a),i.cloneElement(r,c)}return i.Children.count(r)>1?i.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var Es=Symbol("radix.slottable");function Ss(e){return i.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Es}function Ts(e,t){const n={...t};for(const o in t){const r=e[o],s=t[o];/^on[A-Z]/.test(o)?r&&s?n[o]=(...c)=>{const l=s(...c);return r(...c),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...s}:o==="className"&&(n[o]=[r,s].filter(Boolean).join(" "))}return{...e,...n}}function Rs(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Ps=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],D=Ps.reduce((e,t)=>{const n=Cs(`Primitive.${t}`),o=i.forwardRef((r,s)=>{const{asChild:a,...c}=r,l=a?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),v.jsx(l,{...c,ref:s})});return o.displayName=`Primitive.${t}`,{...e,[t]:o}},{});function to(e,t){e&&Ye.flushSync(()=>e.dispatchEvent(t))}function ee(e){const t=i.useRef(e);return i.useEffect(()=>{t.current=e}),i.useMemo(()=>(...n)=>t.current?.(...n),[])}var As=sn[" useInsertionEffect ".trim().toString()]||z;function ke({prop:e,defaultProp:t,onChange:n=()=>{},caller:o}){const[r,s,a]=Os({defaultProp:t,onChange:n}),c=e!==void 0,l=c?e:r;{const f=i.useRef(e!==void 0);i.useEffect(()=>{const p=f.current;p!==c&&console.warn(`${o} is changing from ${p?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=c},[c,o])}const u=i.useCallback(f=>{if(c){const p=Is(f)?f(e):f;p!==e&&a.current?.(p)}else s(f)},[c,e,s,a]);return[l,u]}function Os({defaultProp:e,onChange:t}){const[n,o]=i.useState(e),r=i.useRef(n),s=i.useRef(t);return As(()=>{s.current=t},[t]),i.useEffect(()=>{r.current!==n&&(s.current?.(n),r.current=n)},[n,r]),[n,o,s]}function Is(e){return typeof e=="function"}var Ns=i.createContext(void 0);function _s(e){const t=i.useContext(Ns);return e||t||"ltr"}function Ds(e,t){return i.useReducer((n,o)=>t[n][o]??n,e)}var ye=e=>{const{present:t,children:n}=e,o=Ms(t),r=typeof n=="function"?n({present:o.isPresent}):i.Children.only(n),s=B(o.ref,Ls(r));return typeof n=="function"||o.isPresent?i.cloneElement(r,{ref:s}):null};ye.displayName="Presence";function Ms(e){const[t,n]=i.useState(),o=i.useRef(null),r=i.useRef(e),s=i.useRef("none"),a=e?"mounted":"unmounted",[c,l]=Ds(a,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return i.useEffect(()=>{const u=Je(o.current);s.current=c==="mounted"?u:"none"},[c]),z(()=>{const u=o.current,f=r.current;if(f!==e){const y=s.current,h=Je(u);e?l("MOUNT"):h==="none"||u?.display==="none"?l("UNMOUNT"):l(f&&y!==h?"ANIMATION_OUT":"UNMOUNT"),r.current=e}},[e,l]),z(()=>{if(t){let u;const f=t.ownerDocument.defaultView??window,p=h=>{const d=Je(o.current).includes(CSS.escape(h.animationName));if(h.target===t&&d&&(l("ANIMATION_END"),!r.current)){const m=t.style.animationFillMode;t.style.animationFillMode="forwards",u=f.setTimeout(()=>{t.style.animationFillMode==="forwards"&&(t.style.animationFillMode=m)})}},y=h=>{h.target===t&&(s.current=Je(o.current))};return t.addEventListener("animationstart",y),t.addEventListener("animationcancel",p),t.addEventListener("animationend",p),()=>{f.clearTimeout(u),t.removeEventListener("animationstart",y),t.removeEventListener("animationcancel",p),t.removeEventListener("animationend",p)}}else l("ANIMATION_END")},[t,l]),{isPresent:["mounted","unmountSuspended"].includes(c),ref:i.useCallback(u=>{o.current=u?getComputedStyle(u):null,n(u)},[])}}function Je(e){return e?.animationName||"none"}function Ls(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function On(e,[t,n]){return Math.min(n,Math.max(t,e))}var ks=Symbol.for("react.lazy"),lt=sn[" use ".trim().toString()];function js(e){return typeof e=="object"&&e!==null&&"then"in e}function no(e){return e!=null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===ks&&"_payload"in e&&js(e._payload)}function oo(e){const t=Fs(e),n=i.forwardRef((o,r)=>{let{children:s,...a}=o;no(s)&&typeof lt=="function"&&(s=lt(s._payload));const c=i.Children.toArray(s),l=c.find(Ws);if(l){const u=l.props.children,f=c.map(p=>p===l?i.Children.count(u)>1?i.Children.only(null):i.isValidElement(u)?u.props.children:null:p);return v.jsx(t,{...a,ref:r,children:i.isValidElement(u)?i.cloneElement(u,void 0,f):null})}return v.jsx(t,{...a,ref:r,children:s})});return n.displayName=`${e}.Slot`,n}var Ul=oo("Slot");function Fs(e){const t=i.forwardRef((n,o)=>{let{children:r,...s}=n;if(no(r)&&typeof lt=="function"&&(r=lt(r._payload)),i.isValidElement(r)){const a=Vs(r),c=Bs(s,r.props);return r.type!==i.Fragment&&(c.ref=o?$e(o,a):a),i.cloneElement(r,c)}return i.Children.count(r)>1?i.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var $s=Symbol("radix.slottable");function Ws(e){return i.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===$s}function Bs(e,t){const n={...t};for(const o in t){const r=e[o],s=t[o];/^on[A-Z]/.test(o)?r&&s?n[o]=(...c)=>{const l=s(...c);return r(...c),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...s}:o==="className"&&(n[o]=[r,s].filter(Boolean).join(" "))}return{...e,...n}}function Vs(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function ro(e){const t=i.useRef({value:e,previous:e});return i.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}function so(e){const[t,n]=i.useState(void 0);return z(()=>{if(e){n({width:e.offsetWidth,height:e.offsetHeight});const o=new ResizeObserver(r=>{if(!Array.isArray(r)||!r.length)return;const s=r[0];let a,c;if("borderBoxSize"in s){const l=s.borderBoxSize,u=Array.isArray(l)?l[0]:l;a=u.inlineSize,c=u.blockSize}else a=e.offsetWidth,c=e.offsetHeight;n({width:a,height:c})});return o.observe(e,{box:"border-box"}),()=>o.unobserve(e)}else n(void 0)},[e]),t}var Hs=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Us=Hs.reduce((e,t)=>{const n=oo(`Primitive.${t}`),o=i.forwardRef((r,s)=>{const{asChild:a,...c}=r,l=a?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),v.jsx(l,{...c,ref:s})});return o.displayName=`Primitive.${t}`,{...e,[t]:o}},{}),Ks="Label",io=i.forwardRef((e,t)=>v.jsx(Us.label,{...e,ref:t,onMouseDown:n=>{n.target.closest("button, input, select, textarea")||(e.onMouseDown?.(n),!n.defaultPrevented&&n.detail>1&&n.preventDefault())}}));io.displayName=Ks;var Kl=io;function zs(e,t=globalThis?.document){const n=ee(e);i.useEffect(()=>{const o=r=>{r.key==="Escape"&&n(r)};return t.addEventListener("keydown",o,{capture:!0}),()=>t.removeEventListener("keydown",o,{capture:!0})},[n,t])}var Ys="DismissableLayer",Ut="dismissableLayer.update",Xs="dismissableLayer.pointerDownOutside",Gs="dismissableLayer.focusOutside",In,ao=i.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),Xe=i.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:o,onPointerDownOutside:r,onFocusOutside:s,onInteractOutside:a,onDismiss:c,...l}=e,u=i.useContext(ao),[f,p]=i.useState(null),y=f?.ownerDocument??globalThis?.document,[,h]=i.useState({}),x=B(t,S=>p(S)),d=Array.from(u.layers),[m]=[...u.layersWithOutsidePointerEventsDisabled].slice(-1),w=d.indexOf(m),g=f?d.indexOf(f):-1,C=u.layersWithOutsidePointerEventsDisabled.size>0,b=g>=w,E=Zs(S=>{const O=S.target,M=[...u.branches].some(L=>L.contains(O));!b||M||(r?.(S),a?.(S),S.defaultPrevented||c?.())},y),R=Qs(S=>{const O=S.target;[...u.branches].some(L=>L.contains(O))||(s?.(S),a?.(S),S.defaultPrevented||c?.())},y);return zs(S=>{g===u.layers.size-1&&(o?.(S),!S.defaultPrevented&&c&&(S.preventDefault(),c()))},y),i.useEffect(()=>{if(f)return n&&(u.layersWithOutsidePointerEventsDisabled.size===0&&(In=y.body.style.pointerEvents,y.body.style.pointerEvents="none"),u.layersWithOutsidePointerEventsDisabled.add(f)),u.layers.add(f),Nn(),()=>{n&&u.layersWithOutsidePointerEventsDisabled.size===1&&(y.body.style.pointerEvents=In)}},[f,y,n,u]),i.useEffect(()=>()=>{f&&(u.layers.delete(f),u.layersWithOutsidePointerEventsDisabled.delete(f),Nn())},[f,u]),i.useEffect(()=>{const S=()=>h({});return document.addEventListener(Ut,S),()=>document.removeEventListener(Ut,S)},[]),v.jsx(D.div,{...l,ref:x,style:{pointerEvents:C?b?"auto":"none":void 0,...e.style},onFocusCapture:N(e.onFocusCapture,R.onFocusCapture),onBlurCapture:N(e.onBlurCapture,R.onBlurCapture),onPointerDownCapture:N(e.onPointerDownCapture,E.onPointerDownCapture)})});Xe.displayName=Ys;var qs="DismissableLayerBranch",co=i.forwardRef((e,t)=>{const n=i.useContext(ao),o=i.useRef(null),r=B(t,o);return i.useEffect(()=>{const s=o.current;if(s)return n.branches.add(s),()=>{n.branches.delete(s)}},[n.branches]),v.jsx(D.div,{...e,ref:r})});co.displayName=qs;function Zs(e,t=globalThis?.document){const n=ee(e),o=i.useRef(!1),r=i.useRef(()=>{});return i.useEffect(()=>{const s=c=>{if(c.target&&!o.current){let l=function(){lo(Xs,n,u,{discrete:!0})};const u={originalEvent:c};c.pointerType==="touch"?(t.removeEventListener("click",r.current),r.current=l,t.addEventListener("click",r.current,{once:!0})):l()}else t.removeEventListener("click",r.current);o.current=!1},a=window.setTimeout(()=>{t.addEventListener("pointerdown",s)},0);return()=>{window.clearTimeout(a),t.removeEventListener("pointerdown",s),t.removeEventListener("click",r.current)}},[t,n]),{onPointerDownCapture:()=>o.current=!0}}function Qs(e,t=globalThis?.document){const n=ee(e),o=i.useRef(!1);return i.useEffect(()=>{const r=s=>{s.target&&!o.current&&lo(Gs,n,{originalEvent:s},{discrete:!1})};return t.addEventListener("focusin",r),()=>t.removeEventListener("focusin",r)},[t,n]),{onFocusCapture:()=>o.current=!0,onBlurCapture:()=>o.current=!1}}function Nn(){const e=new CustomEvent(Ut);document.dispatchEvent(e)}function lo(e,t,n,{discrete:o}){const r=n.originalEvent.target,s=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&r.addEventListener(e,t,{once:!0}),o?to(r,s):r.dispatchEvent(s)}var Js=Xe,ei=co,Mt="focusScope.autoFocusOnMount",Lt="focusScope.autoFocusOnUnmount",_n={bubbles:!1,cancelable:!0},ti="FocusScope",an=i.forwardRef((e,t)=>{const{loop:n=!1,trapped:o=!1,onMountAutoFocus:r,onUnmountAutoFocus:s,...a}=e,[c,l]=i.useState(null),u=ee(r),f=ee(s),p=i.useRef(null),y=B(t,d=>l(d)),h=i.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;i.useEffect(()=>{if(o){let d=function(C){if(h.paused||!c)return;const b=C.target;c.contains(b)?p.current=b:me(p.current,{select:!0})},m=function(C){if(h.paused||!c)return;const b=C.relatedTarget;b!==null&&(c.contains(b)||me(p.current,{select:!0}))},w=function(C){if(document.activeElement===document.body)for(const E of C)E.removedNodes.length>0&&me(c)};document.addEventListener("focusin",d),document.addEventListener("focusout",m);const g=new MutationObserver(w);return c&&g.observe(c,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",d),document.removeEventListener("focusout",m),g.disconnect()}}},[o,c,h.paused]),i.useEffect(()=>{if(c){Mn.add(h);const d=document.activeElement;if(!c.contains(d)){const w=new CustomEvent(Mt,_n);c.addEventListener(Mt,u),c.dispatchEvent(w),w.defaultPrevented||(ni(ai(uo(c)),{select:!0}),document.activeElement===d&&me(c))}return()=>{c.removeEventListener(Mt,u),setTimeout(()=>{const w=new CustomEvent(Lt,_n);c.addEventListener(Lt,f),c.dispatchEvent(w),w.defaultPrevented||me(d??document.body,{select:!0}),c.removeEventListener(Lt,f),Mn.remove(h)},0)}}},[c,u,f,h]);const x=i.useCallback(d=>{if(!n&&!o||h.paused)return;const m=d.key==="Tab"&&!d.altKey&&!d.ctrlKey&&!d.metaKey,w=document.activeElement;if(m&&w){const g=d.currentTarget,[C,b]=oi(g);C&&b?!d.shiftKey&&w===b?(d.preventDefault(),n&&me(C,{select:!0})):d.shiftKey&&w===C&&(d.preventDefault(),n&&me(b,{select:!0})):w===g&&d.preventDefault()}},[n,o,h.paused]);return v.jsx(D.div,{tabIndex:-1,...a,ref:y,onKeyDown:x})});an.displayName=ti;function ni(e,{select:t=!1}={}){const n=document.activeElement;for(const o of e)if(me(o,{select:t}),document.activeElement!==n)return}function oi(e){const t=uo(e),n=Dn(t,e),o=Dn(t.reverse(),e);return[n,o]}function uo(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:o=>{const r=o.tagName==="INPUT"&&o.type==="hidden";return o.disabled||o.hidden||r?NodeFilter.FILTER_SKIP:o.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function Dn(e,t){for(const n of e)if(!ri(n,{upTo:t}))return n}function ri(e,{upTo:t}){if(getComputedStyle(e).visibility==="hidden")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display==="none")return!0;e=e.parentElement}return!1}function si(e){return e instanceof HTMLInputElement&&"select"in e}function me(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&si(e)&&t&&e.select()}}var Mn=ii();function ii(){let e=[];return{add(t){const n=e[0];t!==n&&n?.pause(),e=Ln(e,t),e.unshift(t)},remove(t){e=Ln(e,t),e[0]?.resume()}}}function Ln(e,t){const n=[...e],o=n.indexOf(t);return o!==-1&&n.splice(o,1),n}function ai(e){return e.filter(t=>t.tagName!=="A")}var ci="Portal",Ge=i.forwardRef((e,t)=>{const{container:n,...o}=e,[r,s]=i.useState(!1);z(()=>s(!0),[]);const a=n||r&&globalThis?.document?.body;return a?ds.createPortal(v.jsx(D.div,{...o,ref:t}),a):null});Ge.displayName=ci;var kt=0;function fo(){i.useEffect(()=>{const e=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",e[0]??kn()),document.body.insertAdjacentElement("beforeend",e[1]??kn()),kt++,()=>{kt===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(t=>t.remove()),kt--}},[])}function kn(){const e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}var se=function(){return se=Object.assign||function(t){for(var n,o=1,r=arguments.length;o"u")return Ti;var t=Ri(e),n=document.documentElement.clientWidth,o=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,o-n+t[2]-t[0])}},Ai=vo(),Me="data-scroll-locked",Oi=function(e,t,n,o){var r=e.left,s=e.top,a=e.right,c=e.gap;return n===void 0&&(n="margin"),` + .`.concat(ui,` { + overflow: hidden `).concat(o,`; + padding-right: `).concat(c,"px ").concat(o,`; + } + body[`).concat(Me,`] { + overflow: hidden `).concat(o,`; + overscroll-behavior: contain; + `).concat([t&&"position: relative ".concat(o,";"),n==="margin"&&` + padding-left: `.concat(r,`px; + padding-top: `).concat(s,`px; + padding-right: `).concat(a,`px; + margin-left:0; + margin-top:0; + margin-right: `).concat(c,"px ").concat(o,`; + `),n==="padding"&&"padding-right: ".concat(c,"px ").concat(o,";")].filter(Boolean).join(""),` + } + + .`).concat(it,` { + right: `).concat(c,"px ").concat(o,`; + } + + .`).concat(at,` { + margin-right: `).concat(c,"px ").concat(o,`; + } + + .`).concat(it," .").concat(it,` { + right: 0 `).concat(o,`; + } + + .`).concat(at," .").concat(at,` { + margin-right: 0 `).concat(o,`; + } + + body[`).concat(Me,`] { + `).concat(di,": ").concat(c,`px; + } +`)},Fn=function(){var e=parseInt(document.body.getAttribute(Me)||"0",10);return isFinite(e)?e:0},Ii=function(){i.useEffect(function(){return document.body.setAttribute(Me,(Fn()+1).toString()),function(){var e=Fn()-1;e<=0?document.body.removeAttribute(Me):document.body.setAttribute(Me,e.toString())}},[])},Ni=function(e){var t=e.noRelative,n=e.noImportant,o=e.gapMode,r=o===void 0?"margin":o;Ii();var s=i.useMemo(function(){return Pi(r)},[r]);return i.createElement(Ai,{styles:Oi(s,!t,r,n?"":"!important")})},Kt=!1;if(typeof window<"u")try{var et=Object.defineProperty({},"passive",{get:function(){return Kt=!0,!0}});window.addEventListener("test",et,et),window.removeEventListener("test",et,et)}catch{Kt=!1}var Ne=Kt?{passive:!1}:!1,_i=function(e){return e.tagName==="TEXTAREA"},go=function(e,t){if(!(e instanceof Element))return!1;var n=window.getComputedStyle(e);return n[t]!=="hidden"&&!(n.overflowY===n.overflowX&&!_i(e)&&n[t]==="visible")},Di=function(e){return go(e,"overflowY")},Mi=function(e){return go(e,"overflowX")},$n=function(e,t){var n=t.ownerDocument,o=t;do{typeof ShadowRoot<"u"&&o instanceof ShadowRoot&&(o=o.host);var r=yo(e,o);if(r){var s=wo(e,o),a=s[1],c=s[2];if(a>c)return!0}o=o.parentNode}while(o&&o!==n.body);return!1},Li=function(e){var t=e.scrollTop,n=e.scrollHeight,o=e.clientHeight;return[t,n,o]},ki=function(e){var t=e.scrollLeft,n=e.scrollWidth,o=e.clientWidth;return[t,n,o]},yo=function(e,t){return e==="v"?Di(t):Mi(t)},wo=function(e,t){return e==="v"?Li(t):ki(t)},ji=function(e,t){return e==="h"&&t==="rtl"?-1:1},Fi=function(e,t,n,o,r){var s=ji(e,window.getComputedStyle(t).direction),a=s*o,c=n.target,l=t.contains(c),u=!1,f=a>0,p=0,y=0;do{if(!c)break;var h=wo(e,c),x=h[0],d=h[1],m=h[2],w=d-m-s*x;(x||w)&&yo(e,c)&&(p+=w,y+=x);var g=c.parentNode;c=g&&g.nodeType===Node.DOCUMENT_FRAGMENT_NODE?g.host:g}while(!l&&c!==document.body||l&&(t.contains(c)||t===c));return(f&&Math.abs(p)<1||!f&&Math.abs(y)<1)&&(u=!0),u},tt=function(e){return"changedTouches"in e?[e.changedTouches[0].clientX,e.changedTouches[0].clientY]:[0,0]},Wn=function(e){return[e.deltaX,e.deltaY]},Bn=function(e){return e&&"current"in e?e.current:e},$i=function(e,t){return e[0]===t[0]&&e[1]===t[1]},Wi=function(e){return` + .block-interactivity-`.concat(e,` {pointer-events: none;} + .allow-interactivity-`).concat(e,` {pointer-events: all;} +`)},Bi=0,_e=[];function Vi(e){var t=i.useRef([]),n=i.useRef([0,0]),o=i.useRef(),r=i.useState(Bi++)[0],s=i.useState(vo)[0],a=i.useRef(e);i.useEffect(function(){a.current=e},[e]),i.useEffect(function(){if(e.inert){document.body.classList.add("block-interactivity-".concat(r));var d=li([e.lockRef.current],(e.shards||[]).map(Bn),!0).filter(Boolean);return d.forEach(function(m){return m.classList.add("allow-interactivity-".concat(r))}),function(){document.body.classList.remove("block-interactivity-".concat(r)),d.forEach(function(m){return m.classList.remove("allow-interactivity-".concat(r))})}}},[e.inert,e.lockRef.current,e.shards]);var c=i.useCallback(function(d,m){if("touches"in d&&d.touches.length===2||d.type==="wheel"&&d.ctrlKey)return!a.current.allowPinchZoom;var w=tt(d),g=n.current,C="deltaX"in d?d.deltaX:g[0]-w[0],b="deltaY"in d?d.deltaY:g[1]-w[1],E,R=d.target,S=Math.abs(C)>Math.abs(b)?"h":"v";if("touches"in d&&S==="h"&&R.type==="range")return!1;var O=$n(S,R);if(!O)return!0;if(O?E=S:(E=S==="v"?"h":"v",O=$n(S,R)),!O)return!1;if(!o.current&&"changedTouches"in d&&(C||b)&&(o.current=E),!E)return!0;var M=o.current||E;return Fi(M,m,d,M==="h"?C:b)},[]),l=i.useCallback(function(d){var m=d;if(!(!_e.length||_e[_e.length-1]!==s)){var w="deltaY"in m?Wn(m):tt(m),g=t.current.filter(function(E){return E.name===m.type&&(E.target===m.target||m.target===E.shadowParent)&&$i(E.delta,w)})[0];if(g&&g.should){m.cancelable&&m.preventDefault();return}if(!g){var C=(a.current.shards||[]).map(Bn).filter(Boolean).filter(function(E){return E.contains(m.target)}),b=C.length>0?c(m,C[0]):!a.current.noIsolation;b&&m.cancelable&&m.preventDefault()}}},[]),u=i.useCallback(function(d,m,w,g){var C={name:d,delta:m,target:w,should:g,shadowParent:Hi(w)};t.current.push(C),setTimeout(function(){t.current=t.current.filter(function(b){return b!==C})},1)},[]),f=i.useCallback(function(d){n.current=tt(d),o.current=void 0},[]),p=i.useCallback(function(d){u(d.type,Wn(d),d.target,c(d,e.lockRef.current))},[]),y=i.useCallback(function(d){u(d.type,tt(d),d.target,c(d,e.lockRef.current))},[]);i.useEffect(function(){return _e.push(s),e.setCallbacks({onScrollCapture:p,onWheelCapture:p,onTouchMoveCapture:y}),document.addEventListener("wheel",l,Ne),document.addEventListener("touchmove",l,Ne),document.addEventListener("touchstart",f,Ne),function(){_e=_e.filter(function(d){return d!==s}),document.removeEventListener("wheel",l,Ne),document.removeEventListener("touchmove",l,Ne),document.removeEventListener("touchstart",f,Ne)}},[]);var h=e.removeScrollBar,x=e.inert;return i.createElement(i.Fragment,null,x?i.createElement(s,{styles:Wi(r)}):null,h?i.createElement(Ni,{noRelative:e.noRelative,gapMode:e.gapMode}):null)}function Hi(e){for(var t=null;e!==null;)e instanceof ShadowRoot&&(t=e.host,e=e.host),e=e.parentNode;return t}const Ui=yi(ho,Vi);var cn=i.forwardRef(function(e,t){return i.createElement(vt,se({},e,{ref:t,sideCar:Ui}))});cn.classNames=vt.classNames;var Ki=function(e){if(typeof document>"u")return null;var t=Array.isArray(e)?e[0]:e;return t.ownerDocument.body},De=new WeakMap,nt=new WeakMap,ot={},Wt=0,xo=function(e){return e&&(e.host||xo(e.parentNode))},zi=function(e,t){return t.map(function(n){if(e.contains(n))return n;var o=xo(n);return o&&e.contains(o)?o:(console.error("aria-hidden",n,"in not contained inside",e,". Doing nothing"),null)}).filter(function(n){return!!n})},Yi=function(e,t,n,o){var r=zi(t,Array.isArray(e)?e:[e]);ot[n]||(ot[n]=new WeakMap);var s=ot[n],a=[],c=new Set,l=new Set(r),u=function(p){!p||c.has(p)||(c.add(p),u(p.parentNode))};r.forEach(u);var f=function(p){!p||l.has(p)||Array.prototype.forEach.call(p.children,function(y){if(c.has(y))f(y);else try{var h=y.getAttribute(o),x=h!==null&&h!=="false",d=(De.get(y)||0)+1,m=(s.get(y)||0)+1;De.set(y,d),s.set(y,m),a.push(y),d===1&&x&&nt.set(y,!0),m===1&&y.setAttribute(n,"true"),x||y.setAttribute(o,"true")}catch(w){console.error("aria-hidden: cannot operate on ",y,w)}})};return f(t),c.clear(),Wt++,function(){a.forEach(function(p){var y=De.get(p)-1,h=s.get(p)-1;De.set(p,y),s.set(p,h),y||(nt.has(p)||p.removeAttribute(o),nt.delete(p)),h||p.removeAttribute(n)}),Wt--,Wt||(De=new WeakMap,De=new WeakMap,nt=new WeakMap,ot={})}},Co=function(e,t,n){n===void 0&&(n="data-aria-hidden");var o=Array.from(Array.isArray(e)?e:[e]),r=Ki(e);return r?(o.push.apply(o,Array.from(r.querySelectorAll("[aria-live], script"))),Yi(o,r,n,"aria-hidden")):function(){return null}};function Xi(e){const t=Gi(e),n=i.forwardRef((o,r)=>{const{children:s,...a}=o,c=i.Children.toArray(s),l=c.find(Zi);if(l){const u=l.props.children,f=c.map(p=>p===l?i.Children.count(u)>1?i.Children.only(null):i.isValidElement(u)?u.props.children:null:p);return v.jsx(t,{...a,ref:r,children:i.isValidElement(u)?i.cloneElement(u,void 0,f):null})}return v.jsx(t,{...a,ref:r,children:s})});return n.displayName=`${e}.Slot`,n}function Gi(e){const t=i.forwardRef((n,o)=>{const{children:r,...s}=n;if(i.isValidElement(r)){const a=Ji(r),c=Qi(s,r.props);return r.type!==i.Fragment&&(c.ref=o?$e(o,a):a),i.cloneElement(r,c)}return i.Children.count(r)>1?i.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var qi=Symbol("radix.slottable");function Zi(e){return i.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===qi}function Qi(e,t){const n={...t};for(const o in t){const r=e[o],s=t[o];/^on[A-Z]/.test(o)?r&&s?n[o]=(...c)=>{const l=s(...c);return r(...c),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...s}:o==="className"&&(n[o]=[r,s].filter(Boolean).join(" "))}return{...e,...n}}function Ji(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var gt="Dialog",[bo,zl]=Oe(gt),[ea,oe]=bo(gt),Eo=e=>{const{__scopeDialog:t,children:n,open:o,defaultOpen:r,onOpenChange:s,modal:a=!0}=e,c=i.useRef(null),l=i.useRef(null),[u,f]=ke({prop:o,defaultProp:r??!1,onChange:s,caller:gt});return v.jsx(ea,{scope:t,triggerRef:c,contentRef:l,contentId:Se(),titleId:Se(),descriptionId:Se(),open:u,onOpenChange:f,onOpenToggle:i.useCallback(()=>f(p=>!p),[f]),modal:a,children:n})};Eo.displayName=gt;var So="DialogTrigger",To=i.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=oe(So,n),s=B(t,r.triggerRef);return v.jsx(D.button,{type:"button","aria-haspopup":"dialog","aria-expanded":r.open,"aria-controls":r.contentId,"data-state":dn(r.open),...o,ref:s,onClick:N(e.onClick,r.onOpenToggle)})});To.displayName=So;var ln="DialogPortal",[ta,Ro]=bo(ln,{forceMount:void 0}),Po=e=>{const{__scopeDialog:t,forceMount:n,children:o,container:r}=e,s=oe(ln,t);return v.jsx(ta,{scope:t,forceMount:n,children:i.Children.map(o,a=>v.jsx(ye,{present:n||s.open,children:v.jsx(Ge,{asChild:!0,container:r,children:a})}))})};Po.displayName=ln;var ut="DialogOverlay",Ao=i.forwardRef((e,t)=>{const n=Ro(ut,e.__scopeDialog),{forceMount:o=n.forceMount,...r}=e,s=oe(ut,e.__scopeDialog);return s.modal?v.jsx(ye,{present:o||s.open,children:v.jsx(oa,{...r,ref:t})}):null});Ao.displayName=ut;var na=Xi("DialogOverlay.RemoveScroll"),oa=i.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=oe(ut,n);return v.jsx(cn,{as:na,allowPinchZoom:!0,shards:[r.contentRef],children:v.jsx(D.div,{"data-state":dn(r.open),...o,ref:t,style:{pointerEvents:"auto",...o.style}})})}),Te="DialogContent",Oo=i.forwardRef((e,t)=>{const n=Ro(Te,e.__scopeDialog),{forceMount:o=n.forceMount,...r}=e,s=oe(Te,e.__scopeDialog);return v.jsx(ye,{present:o||s.open,children:s.modal?v.jsx(ra,{...r,ref:t}):v.jsx(sa,{...r,ref:t})})});Oo.displayName=Te;var ra=i.forwardRef((e,t)=>{const n=oe(Te,e.__scopeDialog),o=i.useRef(null),r=B(t,n.contentRef,o);return i.useEffect(()=>{const s=o.current;if(s)return Co(s)},[]),v.jsx(Io,{...e,ref:r,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:N(e.onCloseAutoFocus,s=>{s.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:N(e.onPointerDownOutside,s=>{const a=s.detail.originalEvent,c=a.button===0&&a.ctrlKey===!0;(a.button===2||c)&&s.preventDefault()}),onFocusOutside:N(e.onFocusOutside,s=>s.preventDefault())})}),sa=i.forwardRef((e,t)=>{const n=oe(Te,e.__scopeDialog),o=i.useRef(!1),r=i.useRef(!1);return v.jsx(Io,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:s=>{e.onCloseAutoFocus?.(s),s.defaultPrevented||(o.current||n.triggerRef.current?.focus(),s.preventDefault()),o.current=!1,r.current=!1},onInteractOutside:s=>{e.onInteractOutside?.(s),s.defaultPrevented||(o.current=!0,s.detail.originalEvent.type==="pointerdown"&&(r.current=!0));const a=s.target;n.triggerRef.current?.contains(a)&&s.preventDefault(),s.detail.originalEvent.type==="focusin"&&r.current&&s.preventDefault()}})}),Io=i.forwardRef((e,t)=>{const{__scopeDialog:n,trapFocus:o,onOpenAutoFocus:r,onCloseAutoFocus:s,...a}=e,c=oe(Te,n),l=i.useRef(null),u=B(t,l);return fo(),v.jsxs(v.Fragment,{children:[v.jsx(an,{asChild:!0,loop:!0,trapped:o,onMountAutoFocus:r,onUnmountAutoFocus:s,children:v.jsx(Xe,{role:"dialog",id:c.contentId,"aria-describedby":c.descriptionId,"aria-labelledby":c.titleId,"data-state":dn(c.open),...a,ref:u,onDismiss:()=>c.onOpenChange(!1)})}),v.jsxs(v.Fragment,{children:[v.jsx(ia,{titleId:c.titleId}),v.jsx(ca,{contentRef:l,descriptionId:c.descriptionId})]})]})}),un="DialogTitle",No=i.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=oe(un,n);return v.jsx(D.h2,{id:r.titleId,...o,ref:t})});No.displayName=un;var _o="DialogDescription",Do=i.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=oe(_o,n);return v.jsx(D.p,{id:r.descriptionId,...o,ref:t})});Do.displayName=_o;var Mo="DialogClose",Lo=i.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=oe(Mo,n);return v.jsx(D.button,{type:"button",...o,ref:t,onClick:N(e.onClick,()=>r.onOpenChange(!1))})});Lo.displayName=Mo;function dn(e){return e?"open":"closed"}var ko="DialogTitleWarning",[Yl,jo]=fs(ko,{contentName:Te,titleName:un,docsSlug:"dialog"}),ia=({titleId:e})=>{const t=jo(ko),n=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users. + +If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component. + +For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return i.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},aa="DialogDescriptionWarning",ca=({contentRef:e,descriptionId:t})=>{const o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${jo(aa).contentName}}.`;return i.useEffect(()=>{const r=e.current?.getAttribute("aria-describedby");t&&r&&(document.getElementById(t)||console.warn(o))},[o,e,t]),null},Xl=Eo,Gl=To,ql=Po,Zl=Ao,Ql=Oo,Jl=No,eu=Do,tu=Lo;const la=["top","right","bottom","left"],ve=Math.min,G=Math.max,dt=Math.round,rt=Math.floor,ae=e=>({x:e,y:e}),ua={left:"right",right:"left",bottom:"top",top:"bottom"},da={start:"end",end:"start"};function zt(e,t,n){return G(e,ve(t,n))}function fe(e,t){return typeof e=="function"?e(t):e}function pe(e){return e.split("-")[0]}function We(e){return e.split("-")[1]}function fn(e){return e==="x"?"y":"x"}function pn(e){return e==="y"?"height":"width"}const fa=new Set(["top","bottom"]);function ie(e){return fa.has(pe(e))?"y":"x"}function mn(e){return fn(ie(e))}function pa(e,t,n){n===void 0&&(n=!1);const o=We(e),r=mn(e),s=pn(r);let a=r==="x"?o===(n?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[s]>t.floating[s]&&(a=ft(a)),[a,ft(a)]}function ma(e){const t=ft(e);return[Yt(e),t,Yt(t)]}function Yt(e){return e.replace(/start|end/g,t=>da[t])}const Vn=["left","right"],Hn=["right","left"],ha=["top","bottom"],va=["bottom","top"];function ga(e,t,n){switch(e){case"top":case"bottom":return n?t?Hn:Vn:t?Vn:Hn;case"left":case"right":return t?ha:va;default:return[]}}function ya(e,t,n,o){const r=We(e);let s=ga(pe(e),n==="start",o);return r&&(s=s.map(a=>a+"-"+r),t&&(s=s.concat(s.map(Yt)))),s}function ft(e){return e.replace(/left|right|bottom|top/g,t=>ua[t])}function wa(e){return{top:0,right:0,bottom:0,left:0,...e}}function Fo(e){return typeof e!="number"?wa(e):{top:e,right:e,bottom:e,left:e}}function pt(e){const{x:t,y:n,width:o,height:r}=e;return{width:o,height:r,top:n,left:t,right:t+o,bottom:n+r,x:t,y:n}}function Un(e,t,n){let{reference:o,floating:r}=e;const s=ie(t),a=mn(t),c=pn(a),l=pe(t),u=s==="y",f=o.x+o.width/2-r.width/2,p=o.y+o.height/2-r.height/2,y=o[c]/2-r[c]/2;let h;switch(l){case"top":h={x:f,y:o.y-r.height};break;case"bottom":h={x:f,y:o.y+o.height};break;case"right":h={x:o.x+o.width,y:p};break;case"left":h={x:o.x-r.width,y:p};break;default:h={x:o.x,y:o.y}}switch(We(t)){case"start":h[a]-=y*(n&&u?-1:1);break;case"end":h[a]+=y*(n&&u?-1:1);break}return h}const xa=async(e,t,n)=>{const{placement:o="bottom",strategy:r="absolute",middleware:s=[],platform:a}=n,c=s.filter(Boolean),l=await(a.isRTL==null?void 0:a.isRTL(t));let u=await a.getElementRects({reference:e,floating:t,strategy:r}),{x:f,y:p}=Un(u,o,l),y=o,h={},x=0;for(let d=0;d({name:"arrow",options:e,async fn(t){const{x:n,y:o,placement:r,rects:s,platform:a,elements:c,middlewareData:l}=t,{element:u,padding:f=0}=fe(e,t)||{};if(u==null)return{};const p=Fo(f),y={x:n,y:o},h=mn(r),x=pn(h),d=await a.getDimensions(u),m=h==="y",w=m?"top":"left",g=m?"bottom":"right",C=m?"clientHeight":"clientWidth",b=s.reference[x]+s.reference[h]-y[h]-s.floating[x],E=y[h]-s.reference[h],R=await(a.getOffsetParent==null?void 0:a.getOffsetParent(u));let S=R?R[C]:0;(!S||!await(a.isElement==null?void 0:a.isElement(R)))&&(S=c.floating[C]||s.floating[x]);const O=b/2-E/2,M=S/2-d[x]/2-1,L=ve(p[w],M),k=ve(p[g],M),$=L,F=S-d[x]-k,T=S/2-d[x]/2+O,j=zt($,T,F),I=!l.arrow&&We(r)!=null&&T!==j&&s.reference[x]/2-(T<$?L:k)-d[x]/2<0,_=I?T<$?T-$:T-F:0;return{[h]:y[h]+_,data:{[h]:j,centerOffset:T-j-_,...I&&{alignmentOffset:_}},reset:I}}}),ba=function(e){return e===void 0&&(e={}),{name:"flip",options:e,async fn(t){var n,o;const{placement:r,middlewareData:s,rects:a,initialPlacement:c,platform:l,elements:u}=t,{mainAxis:f=!0,crossAxis:p=!0,fallbackPlacements:y,fallbackStrategy:h="bestFit",fallbackAxisSideDirection:x="none",flipAlignment:d=!0,...m}=fe(e,t);if((n=s.arrow)!=null&&n.alignmentOffset)return{};const w=pe(r),g=ie(c),C=pe(c)===c,b=await(l.isRTL==null?void 0:l.isRTL(u.floating)),E=y||(C||!d?[ft(c)]:ma(c)),R=x!=="none";!y&&R&&E.push(...ya(c,d,x,b));const S=[c,...E],O=await Ue(t,m),M=[];let L=((o=s.flip)==null?void 0:o.overflows)||[];if(f&&M.push(O[w]),p){const T=pa(r,a,b);M.push(O[T[0]],O[T[1]])}if(L=[...L,{placement:r,overflows:M}],!M.every(T=>T<=0)){var k,$;const T=(((k=s.flip)==null?void 0:k.index)||0)+1,j=S[T];if(j&&(!(p==="alignment"?g!==ie(j):!1)||L.every(P=>ie(P.placement)===g?P.overflows[0]>0:!0)))return{data:{index:T,overflows:L},reset:{placement:j}};let I=($=L.filter(_=>_.overflows[0]<=0).sort((_,P)=>_.overflows[1]-P.overflows[1])[0])==null?void 0:$.placement;if(!I)switch(h){case"bestFit":{var F;const _=(F=L.filter(P=>{if(R){const W=ie(P.placement);return W===g||W==="y"}return!0}).map(P=>[P.placement,P.overflows.filter(W=>W>0).reduce((W,Y)=>W+Y,0)]).sort((P,W)=>P[1]-W[1])[0])==null?void 0:F[0];_&&(I=_);break}case"initialPlacement":I=c;break}if(r!==I)return{reset:{placement:I}}}return{}}}};function Kn(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function zn(e){return la.some(t=>e[t]>=0)}const Ea=function(e){return e===void 0&&(e={}),{name:"hide",options:e,async fn(t){const{rects:n}=t,{strategy:o="referenceHidden",...r}=fe(e,t);switch(o){case"referenceHidden":{const s=await Ue(t,{...r,elementContext:"reference"}),a=Kn(s,n.reference);return{data:{referenceHiddenOffsets:a,referenceHidden:zn(a)}}}case"escaped":{const s=await Ue(t,{...r,altBoundary:!0}),a=Kn(s,n.floating);return{data:{escapedOffsets:a,escaped:zn(a)}}}default:return{}}}}},$o=new Set(["left","top"]);async function Sa(e,t){const{placement:n,platform:o,elements:r}=e,s=await(o.isRTL==null?void 0:o.isRTL(r.floating)),a=pe(n),c=We(n),l=ie(n)==="y",u=$o.has(a)?-1:1,f=s&&l?-1:1,p=fe(t,e);let{mainAxis:y,crossAxis:h,alignmentAxis:x}=typeof p=="number"?{mainAxis:p,crossAxis:0,alignmentAxis:null}:{mainAxis:p.mainAxis||0,crossAxis:p.crossAxis||0,alignmentAxis:p.alignmentAxis};return c&&typeof x=="number"&&(h=c==="end"?x*-1:x),l?{x:h*f,y:y*u}:{x:y*u,y:h*f}}const Ta=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var n,o;const{x:r,y:s,placement:a,middlewareData:c}=t,l=await Sa(t,e);return a===((n=c.offset)==null?void 0:n.placement)&&(o=c.arrow)!=null&&o.alignmentOffset?{}:{x:r+l.x,y:s+l.y,data:{...l,placement:a}}}}},Ra=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){const{x:n,y:o,placement:r}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:c={fn:m=>{let{x:w,y:g}=m;return{x:w,y:g}}},...l}=fe(e,t),u={x:n,y:o},f=await Ue(t,l),p=ie(pe(r)),y=fn(p);let h=u[y],x=u[p];if(s){const m=y==="y"?"top":"left",w=y==="y"?"bottom":"right",g=h+f[m],C=h-f[w];h=zt(g,h,C)}if(a){const m=p==="y"?"top":"left",w=p==="y"?"bottom":"right",g=x+f[m],C=x-f[w];x=zt(g,x,C)}const d=c.fn({...t,[y]:h,[p]:x});return{...d,data:{x:d.x-n,y:d.y-o,enabled:{[y]:s,[p]:a}}}}}},Pa=function(e){return e===void 0&&(e={}),{options:e,fn(t){const{x:n,y:o,placement:r,rects:s,middlewareData:a}=t,{offset:c=0,mainAxis:l=!0,crossAxis:u=!0}=fe(e,t),f={x:n,y:o},p=ie(r),y=fn(p);let h=f[y],x=f[p];const d=fe(c,t),m=typeof d=="number"?{mainAxis:d,crossAxis:0}:{mainAxis:0,crossAxis:0,...d};if(l){const C=y==="y"?"height":"width",b=s.reference[y]-s.floating[C]+m.mainAxis,E=s.reference[y]+s.reference[C]-m.mainAxis;hE&&(h=E)}if(u){var w,g;const C=y==="y"?"width":"height",b=$o.has(pe(r)),E=s.reference[p]-s.floating[C]+(b&&((w=a.offset)==null?void 0:w[p])||0)+(b?0:m.crossAxis),R=s.reference[p]+s.reference[C]+(b?0:((g=a.offset)==null?void 0:g[p])||0)-(b?m.crossAxis:0);xR&&(x=R)}return{[y]:h,[p]:x}}}},Aa=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){var n,o;const{placement:r,rects:s,platform:a,elements:c}=t,{apply:l=()=>{},...u}=fe(e,t),f=await Ue(t,u),p=pe(r),y=We(r),h=ie(r)==="y",{width:x,height:d}=s.floating;let m,w;p==="top"||p==="bottom"?(m=p,w=y===(await(a.isRTL==null?void 0:a.isRTL(c.floating))?"start":"end")?"left":"right"):(w=p,m=y==="end"?"top":"bottom");const g=d-f.top-f.bottom,C=x-f.left-f.right,b=ve(d-f[m],g),E=ve(x-f[w],C),R=!t.middlewareData.shift;let S=b,O=E;if((n=t.middlewareData.shift)!=null&&n.enabled.x&&(O=C),(o=t.middlewareData.shift)!=null&&o.enabled.y&&(S=g),R&&!y){const L=G(f.left,0),k=G(f.right,0),$=G(f.top,0),F=G(f.bottom,0);h?O=x-2*(L!==0||k!==0?L+k:G(f.left,f.right)):S=d-2*($!==0||F!==0?$+F:G(f.top,f.bottom))}await l({...t,availableWidth:O,availableHeight:S});const M=await a.getDimensions(c.floating);return x!==M.width||d!==M.height?{reset:{rects:!0}}:{}}}};function yt(){return typeof window<"u"}function Be(e){return Wo(e)?(e.nodeName||"").toLowerCase():"#document"}function q(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function le(e){var t;return(t=(Wo(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Wo(e){return yt()?e instanceof Node||e instanceof q(e).Node:!1}function te(e){return yt()?e instanceof Element||e instanceof q(e).Element:!1}function ce(e){return yt()?e instanceof HTMLElement||e instanceof q(e).HTMLElement:!1}function Yn(e){return!yt()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof q(e).ShadowRoot}const Oa=new Set(["inline","contents"]);function qe(e){const{overflow:t,overflowX:n,overflowY:o,display:r}=ne(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+n)&&!Oa.has(r)}const Ia=new Set(["table","td","th"]);function Na(e){return Ia.has(Be(e))}const _a=[":popover-open",":modal"];function wt(e){return _a.some(t=>{try{return e.matches(t)}catch{return!1}})}const Da=["transform","translate","scale","rotate","perspective"],Ma=["transform","translate","scale","rotate","perspective","filter"],La=["paint","layout","strict","content"];function hn(e){const t=vn(),n=te(e)?ne(e):e;return Da.some(o=>n[o]?n[o]!=="none":!1)||(n.containerType?n.containerType!=="normal":!1)||!t&&(n.backdropFilter?n.backdropFilter!=="none":!1)||!t&&(n.filter?n.filter!=="none":!1)||Ma.some(o=>(n.willChange||"").includes(o))||La.some(o=>(n.contain||"").includes(o))}function ka(e){let t=ge(e);for(;ce(t)&&!je(t);){if(hn(t))return t;if(wt(t))return null;t=ge(t)}return null}function vn(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}const ja=new Set(["html","body","#document"]);function je(e){return ja.has(Be(e))}function ne(e){return q(e).getComputedStyle(e)}function xt(e){return te(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function ge(e){if(Be(e)==="html")return e;const t=e.assignedSlot||e.parentNode||Yn(e)&&e.host||le(e);return Yn(t)?t.host:t}function Bo(e){const t=ge(e);return je(t)?e.ownerDocument?e.ownerDocument.body:e.body:ce(t)&&qe(t)?t:Bo(t)}function Ke(e,t,n){var o;t===void 0&&(t=[]),n===void 0&&(n=!0);const r=Bo(e),s=r===((o=e.ownerDocument)==null?void 0:o.body),a=q(r);if(s){const c=Xt(a);return t.concat(a,a.visualViewport||[],qe(r)?r:[],c&&n?Ke(c):[])}return t.concat(r,Ke(r,[],n))}function Xt(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Vo(e){const t=ne(e);let n=parseFloat(t.width)||0,o=parseFloat(t.height)||0;const r=ce(e),s=r?e.offsetWidth:n,a=r?e.offsetHeight:o,c=dt(n)!==s||dt(o)!==a;return c&&(n=s,o=a),{width:n,height:o,$:c}}function gn(e){return te(e)?e:e.contextElement}function Le(e){const t=gn(e);if(!ce(t))return ae(1);const n=t.getBoundingClientRect(),{width:o,height:r,$:s}=Vo(t);let a=(s?dt(n.width):n.width)/o,c=(s?dt(n.height):n.height)/r;return(!a||!Number.isFinite(a))&&(a=1),(!c||!Number.isFinite(c))&&(c=1),{x:a,y:c}}const Fa=ae(0);function Ho(e){const t=q(e);return!vn()||!t.visualViewport?Fa:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function $a(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==q(e)?!1:t}function Re(e,t,n,o){t===void 0&&(t=!1),n===void 0&&(n=!1);const r=e.getBoundingClientRect(),s=gn(e);let a=ae(1);t&&(o?te(o)&&(a=Le(o)):a=Le(e));const c=$a(s,n,o)?Ho(s):ae(0);let l=(r.left+c.x)/a.x,u=(r.top+c.y)/a.y,f=r.width/a.x,p=r.height/a.y;if(s){const y=q(s),h=o&&te(o)?q(o):o;let x=y,d=Xt(x);for(;d&&o&&h!==x;){const m=Le(d),w=d.getBoundingClientRect(),g=ne(d),C=w.left+(d.clientLeft+parseFloat(g.paddingLeft))*m.x,b=w.top+(d.clientTop+parseFloat(g.paddingTop))*m.y;l*=m.x,u*=m.y,f*=m.x,p*=m.y,l+=C,u+=b,x=q(d),d=Xt(x)}}return pt({width:f,height:p,x:l,y:u})}function Ct(e,t){const n=xt(e).scrollLeft;return t?t.left+n:Re(le(e)).left+n}function Uo(e,t){const n=e.getBoundingClientRect(),o=n.left+t.scrollLeft-Ct(e,n),r=n.top+t.scrollTop;return{x:o,y:r}}function Wa(e){let{elements:t,rect:n,offsetParent:o,strategy:r}=e;const s=r==="fixed",a=le(o),c=t?wt(t.floating):!1;if(o===a||c&&s)return n;let l={scrollLeft:0,scrollTop:0},u=ae(1);const f=ae(0),p=ce(o);if((p||!p&&!s)&&((Be(o)!=="body"||qe(a))&&(l=xt(o)),ce(o))){const h=Re(o);u=Le(o),f.x=h.x+o.clientLeft,f.y=h.y+o.clientTop}const y=a&&!p&&!s?Uo(a,l):ae(0);return{width:n.width*u.x,height:n.height*u.y,x:n.x*u.x-l.scrollLeft*u.x+f.x+y.x,y:n.y*u.y-l.scrollTop*u.y+f.y+y.y}}function Ba(e){return Array.from(e.getClientRects())}function Va(e){const t=le(e),n=xt(e),o=e.ownerDocument.body,r=G(t.scrollWidth,t.clientWidth,o.scrollWidth,o.clientWidth),s=G(t.scrollHeight,t.clientHeight,o.scrollHeight,o.clientHeight);let a=-n.scrollLeft+Ct(e);const c=-n.scrollTop;return ne(o).direction==="rtl"&&(a+=G(t.clientWidth,o.clientWidth)-r),{width:r,height:s,x:a,y:c}}const Xn=25;function Ha(e,t){const n=q(e),o=le(e),r=n.visualViewport;let s=o.clientWidth,a=o.clientHeight,c=0,l=0;if(r){s=r.width,a=r.height;const f=vn();(!f||f&&t==="fixed")&&(c=r.offsetLeft,l=r.offsetTop)}const u=Ct(o);if(u<=0){const f=o.ownerDocument,p=f.body,y=getComputedStyle(p),h=f.compatMode==="CSS1Compat"&&parseFloat(y.marginLeft)+parseFloat(y.marginRight)||0,x=Math.abs(o.clientWidth-p.clientWidth-h);x<=Xn&&(s-=x)}else u<=Xn&&(s+=u);return{width:s,height:a,x:c,y:l}}const Ua=new Set(["absolute","fixed"]);function Ka(e,t){const n=Re(e,!0,t==="fixed"),o=n.top+e.clientTop,r=n.left+e.clientLeft,s=ce(e)?Le(e):ae(1),a=e.clientWidth*s.x,c=e.clientHeight*s.y,l=r*s.x,u=o*s.y;return{width:a,height:c,x:l,y:u}}function Gn(e,t,n){let o;if(t==="viewport")o=Ha(e,n);else if(t==="document")o=Va(le(e));else if(te(t))o=Ka(t,n);else{const r=Ho(e);o={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return pt(o)}function Ko(e,t){const n=ge(e);return n===t||!te(n)||je(n)?!1:ne(n).position==="fixed"||Ko(n,t)}function za(e,t){const n=t.get(e);if(n)return n;let o=Ke(e,[],!1).filter(c=>te(c)&&Be(c)!=="body"),r=null;const s=ne(e).position==="fixed";let a=s?ge(e):e;for(;te(a)&&!je(a);){const c=ne(a),l=hn(a);!l&&c.position==="fixed"&&(r=null),(s?!l&&!r:!l&&c.position==="static"&&!!r&&Ua.has(r.position)||qe(a)&&!l&&Ko(e,a))?o=o.filter(f=>f!==a):r=c,a=ge(a)}return t.set(e,o),o}function Ya(e){let{element:t,boundary:n,rootBoundary:o,strategy:r}=e;const a=[...n==="clippingAncestors"?wt(t)?[]:za(t,this._c):[].concat(n),o],c=a[0],l=a.reduce((u,f)=>{const p=Gn(t,f,r);return u.top=G(p.top,u.top),u.right=ve(p.right,u.right),u.bottom=ve(p.bottom,u.bottom),u.left=G(p.left,u.left),u},Gn(t,c,r));return{width:l.right-l.left,height:l.bottom-l.top,x:l.left,y:l.top}}function Xa(e){const{width:t,height:n}=Vo(e);return{width:t,height:n}}function Ga(e,t,n){const o=ce(t),r=le(t),s=n==="fixed",a=Re(e,!0,s,t);let c={scrollLeft:0,scrollTop:0};const l=ae(0);function u(){l.x=Ct(r)}if(o||!o&&!s)if((Be(t)!=="body"||qe(r))&&(c=xt(t)),o){const h=Re(t,!0,s,t);l.x=h.x+t.clientLeft,l.y=h.y+t.clientTop}else r&&u();s&&!o&&r&&u();const f=r&&!o&&!s?Uo(r,c):ae(0),p=a.left+c.scrollLeft-l.x-f.x,y=a.top+c.scrollTop-l.y-f.y;return{x:p,y,width:a.width,height:a.height}}function Bt(e){return ne(e).position==="static"}function qn(e,t){if(!ce(e)||ne(e).position==="fixed")return null;if(t)return t(e);let n=e.offsetParent;return le(e)===n&&(n=n.ownerDocument.body),n}function zo(e,t){const n=q(e);if(wt(e))return n;if(!ce(e)){let r=ge(e);for(;r&&!je(r);){if(te(r)&&!Bt(r))return r;r=ge(r)}return n}let o=qn(e,t);for(;o&&Na(o)&&Bt(o);)o=qn(o,t);return o&&je(o)&&Bt(o)&&!hn(o)?n:o||ka(e)||n}const qa=async function(e){const t=this.getOffsetParent||zo,n=this.getDimensions,o=await n(e.floating);return{reference:Ga(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}};function Za(e){return ne(e).direction==="rtl"}const Qa={convertOffsetParentRelativeRectToViewportRelativeRect:Wa,getDocumentElement:le,getClippingRect:Ya,getOffsetParent:zo,getElementRects:qa,getClientRects:Ba,getDimensions:Xa,getScale:Le,isElement:te,isRTL:Za};function Yo(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function Ja(e,t){let n=null,o;const r=le(e);function s(){var c;clearTimeout(o),(c=n)==null||c.disconnect(),n=null}function a(c,l){c===void 0&&(c=!1),l===void 0&&(l=1),s();const u=e.getBoundingClientRect(),{left:f,top:p,width:y,height:h}=u;if(c||t(),!y||!h)return;const x=rt(p),d=rt(r.clientWidth-(f+y)),m=rt(r.clientHeight-(p+h)),w=rt(f),C={rootMargin:-x+"px "+-d+"px "+-m+"px "+-w+"px",threshold:G(0,ve(1,l))||1};let b=!0;function E(R){const S=R[0].intersectionRatio;if(S!==l){if(!b)return a();S?a(!1,S):o=setTimeout(()=>{a(!1,1e-7)},1e3)}S===1&&!Yo(u,e.getBoundingClientRect())&&a(),b=!1}try{n=new IntersectionObserver(E,{...C,root:r.ownerDocument})}catch{n=new IntersectionObserver(E,C)}n.observe(e)}return a(!0),s}function ec(e,t,n,o){o===void 0&&(o={});const{ancestorScroll:r=!0,ancestorResize:s=!0,elementResize:a=typeof ResizeObserver=="function",layoutShift:c=typeof IntersectionObserver=="function",animationFrame:l=!1}=o,u=gn(e),f=r||s?[...u?Ke(u):[],...Ke(t)]:[];f.forEach(w=>{r&&w.addEventListener("scroll",n,{passive:!0}),s&&w.addEventListener("resize",n)});const p=u&&c?Ja(u,n):null;let y=-1,h=null;a&&(h=new ResizeObserver(w=>{let[g]=w;g&&g.target===u&&h&&(h.unobserve(t),cancelAnimationFrame(y),y=requestAnimationFrame(()=>{var C;(C=h)==null||C.observe(t)})),n()}),u&&!l&&h.observe(u),h.observe(t));let x,d=l?Re(e):null;l&&m();function m(){const w=Re(e);d&&!Yo(d,w)&&n(),d=w,x=requestAnimationFrame(m)}return n(),()=>{var w;f.forEach(g=>{r&&g.removeEventListener("scroll",n),s&&g.removeEventListener("resize",n)}),p?.(),(w=h)==null||w.disconnect(),h=null,l&&cancelAnimationFrame(x)}}const tc=Ta,nc=Ra,oc=ba,rc=Aa,sc=Ea,Zn=Ca,ic=Pa,ac=(e,t,n)=>{const o=new Map,r={platform:Qa,...n},s={...r.platform,_c:o};return xa(e,t,{...r,platform:s})};var cc=typeof document<"u",lc=function(){},ct=cc?i.useLayoutEffect:lc;function mt(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let n,o,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(o=n;o--!==0;)if(!mt(e[o],t[o]))return!1;return!0}if(r=Object.keys(e),n=r.length,n!==Object.keys(t).length)return!1;for(o=n;o--!==0;)if(!{}.hasOwnProperty.call(t,r[o]))return!1;for(o=n;o--!==0;){const s=r[o];if(!(s==="_owner"&&e.$$typeof)&&!mt(e[s],t[s]))return!1}return!0}return e!==e&&t!==t}function Xo(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function Qn(e,t){const n=Xo(e);return Math.round(t*n)/n}function Vt(e){const t=i.useRef(e);return ct(()=>{t.current=e}),t}function uc(e){e===void 0&&(e={});const{placement:t="bottom",strategy:n="absolute",middleware:o=[],platform:r,elements:{reference:s,floating:a}={},transform:c=!0,whileElementsMounted:l,open:u}=e,[f,p]=i.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[y,h]=i.useState(o);mt(y,o)||h(o);const[x,d]=i.useState(null),[m,w]=i.useState(null),g=i.useCallback(P=>{P!==R.current&&(R.current=P,d(P))},[]),C=i.useCallback(P=>{P!==S.current&&(S.current=P,w(P))},[]),b=s||x,E=a||m,R=i.useRef(null),S=i.useRef(null),O=i.useRef(f),M=l!=null,L=Vt(l),k=Vt(r),$=Vt(u),F=i.useCallback(()=>{if(!R.current||!S.current)return;const P={placement:t,strategy:n,middleware:y};k.current&&(P.platform=k.current),ac(R.current,S.current,P).then(W=>{const Y={...W,isPositioned:$.current!==!1};T.current&&!mt(O.current,Y)&&(O.current=Y,Ye.flushSync(()=>{p(Y)}))})},[y,t,n,k,$]);ct(()=>{u===!1&&O.current.isPositioned&&(O.current.isPositioned=!1,p(P=>({...P,isPositioned:!1})))},[u]);const T=i.useRef(!1);ct(()=>(T.current=!0,()=>{T.current=!1}),[]),ct(()=>{if(b&&(R.current=b),E&&(S.current=E),b&&E){if(L.current)return L.current(b,E,F);F()}},[b,E,F,L,M]);const j=i.useMemo(()=>({reference:R,floating:S,setReference:g,setFloating:C}),[g,C]),I=i.useMemo(()=>({reference:b,floating:E}),[b,E]),_=i.useMemo(()=>{const P={position:n,left:0,top:0};if(!I.floating)return P;const W=Qn(I.floating,f.x),Y=Qn(I.floating,f.y);return c?{...P,transform:"translate("+W+"px, "+Y+"px)",...Xo(I.floating)>=1.5&&{willChange:"transform"}}:{position:n,left:W,top:Y}},[n,c,I.floating,f.x,f.y]);return i.useMemo(()=>({...f,update:F,refs:j,elements:I,floatingStyles:_}),[f,F,j,I,_])}const dc=e=>{function t(n){return{}.hasOwnProperty.call(n,"current")}return{name:"arrow",options:e,fn(n){const{element:o,padding:r}=typeof e=="function"?e(n):e;return o&&t(o)?o.current!=null?Zn({element:o.current,padding:r}).fn(n):{}:o?Zn({element:o,padding:r}).fn(n):{}}}},fc=(e,t)=>({...tc(e),options:[e,t]}),pc=(e,t)=>({...nc(e),options:[e,t]}),mc=(e,t)=>({...ic(e),options:[e,t]}),hc=(e,t)=>({...oc(e),options:[e,t]}),vc=(e,t)=>({...rc(e),options:[e,t]}),gc=(e,t)=>({...sc(e),options:[e,t]}),yc=(e,t)=>({...dc(e),options:[e,t]});var wc="Arrow",Go=i.forwardRef((e,t)=>{const{children:n,width:o=10,height:r=5,...s}=e;return v.jsx(D.svg,{...s,ref:t,width:o,height:r,viewBox:"0 0 30 10",preserveAspectRatio:"none",children:e.asChild?n:v.jsx("polygon",{points:"0,0 30,0 15,10"})})});Go.displayName=wc;var xc=Go,yn="Popper",[qo,bt]=Oe(yn),[Cc,Zo]=qo(yn),Qo=e=>{const{__scopePopper:t,children:n}=e,[o,r]=i.useState(null);return v.jsx(Cc,{scope:t,anchor:o,onAnchorChange:r,children:n})};Qo.displayName=yn;var Jo="PopperAnchor",er=i.forwardRef((e,t)=>{const{__scopePopper:n,virtualRef:o,...r}=e,s=Zo(Jo,n),a=i.useRef(null),c=B(t,a),l=i.useRef(null);return i.useEffect(()=>{const u=l.current;l.current=o?.current||a.current,u!==l.current&&s.onAnchorChange(l.current)}),o?null:v.jsx(D.div,{...r,ref:c})});er.displayName=Jo;var wn="PopperContent",[bc,Ec]=qo(wn),tr=i.forwardRef((e,t)=>{const{__scopePopper:n,side:o="bottom",sideOffset:r=0,align:s="center",alignOffset:a=0,arrowPadding:c=0,avoidCollisions:l=!0,collisionBoundary:u=[],collisionPadding:f=0,sticky:p="partial",hideWhenDetached:y=!1,updatePositionStrategy:h="optimized",onPlaced:x,...d}=e,m=Zo(wn,n),[w,g]=i.useState(null),C=B(t,A=>g(A)),[b,E]=i.useState(null),R=so(b),S=R?.width??0,O=R?.height??0,M=o+(s!=="center"?"-"+s:""),L=typeof f=="number"?f:{top:0,right:0,bottom:0,left:0,...f},k=Array.isArray(u)?u:[u],$=k.length>0,F={padding:L,boundary:k.filter(Tc),altBoundary:$},{refs:T,floatingStyles:j,placement:I,isPositioned:_,middlewareData:P}=uc({strategy:"fixed",placement:M,whileElementsMounted:(...A)=>ec(...A,{animationFrame:h==="always"}),elements:{reference:m.anchor},middleware:[fc({mainAxis:r+O,alignmentAxis:a}),l&&pc({mainAxis:!0,crossAxis:!1,limiter:p==="partial"?mc():void 0,...F}),l&&hc({...F}),vc({...F,apply:({elements:A,rects:U,availableWidth:X,availableHeight:V})=>{const{width:H,height:K}=U.reference,Z=A.floating.style;Z.setProperty("--radix-popper-available-width",`${X}px`),Z.setProperty("--radix-popper-available-height",`${V}px`),Z.setProperty("--radix-popper-anchor-width",`${H}px`),Z.setProperty("--radix-popper-anchor-height",`${K}px`)}}),b&&yc({element:b,padding:c}),Rc({arrowWidth:S,arrowHeight:O}),y&&gc({strategy:"referenceHidden",...F})]}),[W,Y]=rr(I),ue=ee(x);z(()=>{_&&ue?.()},[_,ue]);const de=P.arrow?.x,re=P.arrow?.y,Q=P.arrow?.centerOffset!==0,[Ie,Ce]=i.useState();return z(()=>{w&&Ce(window.getComputedStyle(w).zIndex)},[w]),v.jsx("div",{ref:T.setFloating,"data-radix-popper-content-wrapper":"",style:{...j,transform:_?j.transform:"translate(0, -200%)",minWidth:"max-content",zIndex:Ie,"--radix-popper-transform-origin":[P.transformOrigin?.x,P.transformOrigin?.y].join(" "),...P.hide?.referenceHidden&&{visibility:"hidden",pointerEvents:"none"}},dir:e.dir,children:v.jsx(bc,{scope:n,placedSide:W,onArrowChange:E,arrowX:de,arrowY:re,shouldHideArrow:Q,children:v.jsx(D.div,{"data-side":W,"data-align":Y,...d,ref:C,style:{...d.style,animation:_?void 0:"none"}})})})});tr.displayName=wn;var nr="PopperArrow",Sc={top:"bottom",right:"left",bottom:"top",left:"right"},or=i.forwardRef(function(t,n){const{__scopePopper:o,...r}=t,s=Ec(nr,o),a=Sc[s.placedSide];return v.jsx("span",{ref:s.onArrowChange,style:{position:"absolute",left:s.arrowX,top:s.arrowY,[a]:0,transformOrigin:{top:"",right:"0 0",bottom:"center 0",left:"100% 0"}[s.placedSide],transform:{top:"translateY(100%)",right:"translateY(50%) rotate(90deg) translateX(-50%)",bottom:"rotate(180deg)",left:"translateY(50%) rotate(-90deg) translateX(50%)"}[s.placedSide],visibility:s.shouldHideArrow?"hidden":void 0},children:v.jsx(xc,{...r,ref:n,style:{...r.style,display:"block"}})})});or.displayName=nr;function Tc(e){return e!==null}var Rc=e=>({name:"transformOrigin",options:e,fn(t){const{placement:n,rects:o,middlewareData:r}=t,a=r.arrow?.centerOffset!==0,c=a?0:e.arrowWidth,l=a?0:e.arrowHeight,[u,f]=rr(n),p={start:"0%",center:"50%",end:"100%"}[f],y=(r.arrow?.x??0)+c/2,h=(r.arrow?.y??0)+l/2;let x="",d="";return u==="bottom"?(x=a?p:`${y}px`,d=`${-l}px`):u==="top"?(x=a?p:`${y}px`,d=`${o.floating.height+l}px`):u==="right"?(x=`${-l}px`,d=a?p:`${h}px`):u==="left"&&(x=`${o.floating.width+l}px`,d=a?p:`${h}px`),{data:{x,y:d}}}});function rr(e){const[t,n="center"]=e.split("-");return[t,n]}var sr=Qo,ir=er,ar=tr,cr=or;function Pc(e){const t=Ac(e),n=i.forwardRef((o,r)=>{const{children:s,...a}=o,c=i.Children.toArray(s),l=c.find(Ic);if(l){const u=l.props.children,f=c.map(p=>p===l?i.Children.count(u)>1?i.Children.only(null):i.isValidElement(u)?u.props.children:null:p);return v.jsx(t,{...a,ref:r,children:i.isValidElement(u)?i.cloneElement(u,void 0,f):null})}return v.jsx(t,{...a,ref:r,children:s})});return n.displayName=`${e}.Slot`,n}function Ac(e){const t=i.forwardRef((n,o)=>{const{children:r,...s}=n;if(i.isValidElement(r)){const a=_c(r),c=Nc(s,r.props);return r.type!==i.Fragment&&(c.ref=o?$e(o,a):a),i.cloneElement(r,c)}return i.Children.count(r)>1?i.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var Oc=Symbol("radix.slottable");function Ic(e){return i.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Oc}function Nc(e,t){const n={...t};for(const o in t){const r=e[o],s=t[o];/^on[A-Z]/.test(o)?r&&s?n[o]=(...c)=>{const l=s(...c);return r(...c),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...s}:o==="className"&&(n[o]=[r,s].filter(Boolean).join(" "))}return{...e,...n}}function _c(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var lr=Object.freeze({position:"absolute",border:0,width:1,height:1,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",wordWrap:"normal"}),Dc="VisuallyHidden",Et=i.forwardRef((e,t)=>v.jsx(D.span,{...e,ref:t,style:{...lr,...e.style}}));Et.displayName=Dc;var Mc=Et,Lc=[" ","Enter","ArrowUp","ArrowDown"],kc=[" ","Enter"],Pe="Select",[St,Tt,jc]=eo(Pe),[Ve]=Oe(Pe,[jc,bt]),Rt=bt(),[Fc,we]=Ve(Pe),[$c,Wc]=Ve(Pe),ur=e=>{const{__scopeSelect:t,children:n,open:o,defaultOpen:r,onOpenChange:s,value:a,defaultValue:c,onValueChange:l,dir:u,name:f,autoComplete:p,disabled:y,required:h,form:x}=e,d=Rt(t),[m,w]=i.useState(null),[g,C]=i.useState(null),[b,E]=i.useState(!1),R=_s(u),[S,O]=ke({prop:o,defaultProp:r??!1,onChange:s,caller:Pe}),[M,L]=ke({prop:a,defaultProp:c,onChange:l,caller:Pe}),k=i.useRef(null),$=m?x||!!m.closest("form"):!0,[F,T]=i.useState(new Set),j=Array.from(F).map(I=>I.props.value).join(";");return v.jsx(sr,{...d,children:v.jsxs(Fc,{required:h,scope:t,trigger:m,onTriggerChange:w,valueNode:g,onValueNodeChange:C,valueNodeHasChildren:b,onValueNodeHasChildrenChange:E,contentId:Se(),value:M,onValueChange:L,open:S,onOpenChange:O,dir:R,triggerPointerDownPosRef:k,disabled:y,children:[v.jsx(St.Provider,{scope:t,children:v.jsx($c,{scope:e.__scopeSelect,onNativeOptionAdd:i.useCallback(I=>{T(_=>new Set(_).add(I))},[]),onNativeOptionRemove:i.useCallback(I=>{T(_=>{const P=new Set(_);return P.delete(I),P})},[]),children:n})}),$?v.jsxs(Mr,{"aria-hidden":!0,required:h,tabIndex:-1,name:f,autoComplete:p,value:M,onChange:I=>L(I.target.value),disabled:y,form:x,children:[M===void 0?v.jsx("option",{value:""}):null,Array.from(F)]},j):null]})})};ur.displayName=Pe;var dr="SelectTrigger",fr=i.forwardRef((e,t)=>{const{__scopeSelect:n,disabled:o=!1,...r}=e,s=Rt(n),a=we(dr,n),c=a.disabled||o,l=B(t,a.onTriggerChange),u=Tt(n),f=i.useRef("touch"),[p,y,h]=kr(d=>{const m=u().filter(C=>!C.disabled),w=m.find(C=>C.value===a.value),g=jr(m,d,w);g!==void 0&&a.onValueChange(g.value)}),x=d=>{c||(a.onOpenChange(!0),h()),d&&(a.triggerPointerDownPosRef.current={x:Math.round(d.pageX),y:Math.round(d.pageY)})};return v.jsx(ir,{asChild:!0,...s,children:v.jsx(D.button,{type:"button",role:"combobox","aria-controls":a.contentId,"aria-expanded":a.open,"aria-required":a.required,"aria-autocomplete":"none",dir:a.dir,"data-state":a.open?"open":"closed",disabled:c,"data-disabled":c?"":void 0,"data-placeholder":Lr(a.value)?"":void 0,...r,ref:l,onClick:N(r.onClick,d=>{d.currentTarget.focus(),f.current!=="mouse"&&x(d)}),onPointerDown:N(r.onPointerDown,d=>{f.current=d.pointerType;const m=d.target;m.hasPointerCapture(d.pointerId)&&m.releasePointerCapture(d.pointerId),d.button===0&&d.ctrlKey===!1&&d.pointerType==="mouse"&&(x(d),d.preventDefault())}),onKeyDown:N(r.onKeyDown,d=>{const m=p.current!=="";!(d.ctrlKey||d.altKey||d.metaKey)&&d.key.length===1&&y(d.key),!(m&&d.key===" ")&&Lc.includes(d.key)&&(x(),d.preventDefault())})})})});fr.displayName=dr;var pr="SelectValue",mr=i.forwardRef((e,t)=>{const{__scopeSelect:n,className:o,style:r,children:s,placeholder:a="",...c}=e,l=we(pr,n),{onValueNodeHasChildrenChange:u}=l,f=s!==void 0,p=B(t,l.onValueNodeChange);return z(()=>{u(f)},[u,f]),v.jsx(D.span,{...c,ref:p,style:{pointerEvents:"none"},children:Lr(l.value)?v.jsx(v.Fragment,{children:a}):s})});mr.displayName=pr;var Bc="SelectIcon",hr=i.forwardRef((e,t)=>{const{__scopeSelect:n,children:o,...r}=e;return v.jsx(D.span,{"aria-hidden":!0,...r,ref:t,children:o||"▼"})});hr.displayName=Bc;var Vc="SelectPortal",vr=e=>v.jsx(Ge,{asChild:!0,...e});vr.displayName=Vc;var Ae="SelectContent",gr=i.forwardRef((e,t)=>{const n=we(Ae,e.__scopeSelect),[o,r]=i.useState();if(z(()=>{r(new DocumentFragment)},[]),!n.open){const s=o;return s?Ye.createPortal(v.jsx(yr,{scope:e.__scopeSelect,children:v.jsx(St.Slot,{scope:e.__scopeSelect,children:v.jsx("div",{children:e.children})})}),s):null}return v.jsx(wr,{...e,ref:t})});gr.displayName=Ae;var J=10,[yr,xe]=Ve(Ae),Hc="SelectContentImpl",Uc=Pc("SelectContent.RemoveScroll"),wr=i.forwardRef((e,t)=>{const{__scopeSelect:n,position:o="item-aligned",onCloseAutoFocus:r,onEscapeKeyDown:s,onPointerDownOutside:a,side:c,sideOffset:l,align:u,alignOffset:f,arrowPadding:p,collisionBoundary:y,collisionPadding:h,sticky:x,hideWhenDetached:d,avoidCollisions:m,...w}=e,g=we(Ae,n),[C,b]=i.useState(null),[E,R]=i.useState(null),S=B(t,A=>b(A)),[O,M]=i.useState(null),[L,k]=i.useState(null),$=Tt(n),[F,T]=i.useState(!1),j=i.useRef(!1);i.useEffect(()=>{if(C)return Co(C)},[C]),fo();const I=i.useCallback(A=>{const[U,...X]=$().map(K=>K.ref.current),[V]=X.slice(-1),H=document.activeElement;for(const K of A)if(K===H||(K?.scrollIntoView({block:"nearest"}),K===U&&E&&(E.scrollTop=0),K===V&&E&&(E.scrollTop=E.scrollHeight),K?.focus(),document.activeElement!==H))return},[$,E]),_=i.useCallback(()=>I([O,C]),[I,O,C]);i.useEffect(()=>{F&&_()},[F,_]);const{onOpenChange:P,triggerPointerDownPosRef:W}=g;i.useEffect(()=>{if(C){let A={x:0,y:0};const U=V=>{A={x:Math.abs(Math.round(V.pageX)-(W.current?.x??0)),y:Math.abs(Math.round(V.pageY)-(W.current?.y??0))}},X=V=>{A.x<=10&&A.y<=10?V.preventDefault():C.contains(V.target)||P(!1),document.removeEventListener("pointermove",U),W.current=null};return W.current!==null&&(document.addEventListener("pointermove",U),document.addEventListener("pointerup",X,{capture:!0,once:!0})),()=>{document.removeEventListener("pointermove",U),document.removeEventListener("pointerup",X,{capture:!0})}}},[C,P,W]),i.useEffect(()=>{const A=()=>P(!1);return window.addEventListener("blur",A),window.addEventListener("resize",A),()=>{window.removeEventListener("blur",A),window.removeEventListener("resize",A)}},[P]);const[Y,ue]=kr(A=>{const U=$().filter(H=>!H.disabled),X=U.find(H=>H.ref.current===document.activeElement),V=jr(U,A,X);V&&setTimeout(()=>V.ref.current.focus())}),de=i.useCallback((A,U,X)=>{const V=!j.current&&!X;(g.value!==void 0&&g.value===U||V)&&(M(A),V&&(j.current=!0))},[g.value]),re=i.useCallback(()=>C?.focus(),[C]),Q=i.useCallback((A,U,X)=>{const V=!j.current&&!X;(g.value!==void 0&&g.value===U||V)&&k(A)},[g.value]),Ie=o==="popper"?Gt:xr,Ce=Ie===Gt?{side:c,sideOffset:l,align:u,alignOffset:f,arrowPadding:p,collisionBoundary:y,collisionPadding:h,sticky:x,hideWhenDetached:d,avoidCollisions:m}:{};return v.jsx(yr,{scope:n,content:C,viewport:E,onViewportChange:R,itemRefCallback:de,selectedItem:O,onItemLeave:re,itemTextRefCallback:Q,focusSelectedItem:_,selectedItemText:L,position:o,isPositioned:F,searchRef:Y,children:v.jsx(cn,{as:Uc,allowPinchZoom:!0,children:v.jsx(an,{asChild:!0,trapped:g.open,onMountAutoFocus:A=>{A.preventDefault()},onUnmountAutoFocus:N(r,A=>{g.trigger?.focus({preventScroll:!0}),A.preventDefault()}),children:v.jsx(Xe,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:s,onPointerDownOutside:a,onFocusOutside:A=>A.preventDefault(),onDismiss:()=>g.onOpenChange(!1),children:v.jsx(Ie,{role:"listbox",id:g.contentId,"data-state":g.open?"open":"closed",dir:g.dir,onContextMenu:A=>A.preventDefault(),...w,...Ce,onPlaced:()=>T(!0),ref:S,style:{display:"flex",flexDirection:"column",outline:"none",...w.style},onKeyDown:N(w.onKeyDown,A=>{const U=A.ctrlKey||A.altKey||A.metaKey;if(A.key==="Tab"&&A.preventDefault(),!U&&A.key.length===1&&ue(A.key),["ArrowUp","ArrowDown","Home","End"].includes(A.key)){let V=$().filter(H=>!H.disabled).map(H=>H.ref.current);if(["ArrowUp","End"].includes(A.key)&&(V=V.slice().reverse()),["ArrowUp","ArrowDown"].includes(A.key)){const H=A.target,K=V.indexOf(H);V=V.slice(K+1)}setTimeout(()=>I(V)),A.preventDefault()}})})})})})})});wr.displayName=Hc;var Kc="SelectItemAlignedPosition",xr=i.forwardRef((e,t)=>{const{__scopeSelect:n,onPlaced:o,...r}=e,s=we(Ae,n),a=xe(Ae,n),[c,l]=i.useState(null),[u,f]=i.useState(null),p=B(t,S=>f(S)),y=Tt(n),h=i.useRef(!1),x=i.useRef(!0),{viewport:d,selectedItem:m,selectedItemText:w,focusSelectedItem:g}=a,C=i.useCallback(()=>{if(s.trigger&&s.valueNode&&c&&u&&d&&m&&w){const S=s.trigger.getBoundingClientRect(),O=u.getBoundingClientRect(),M=s.valueNode.getBoundingClientRect(),L=w.getBoundingClientRect();if(s.dir!=="rtl"){const H=L.left-O.left,K=M.left-H,Z=S.left-K,be=S.width+Z,Nt=Math.max(be,O.width),_t=window.innerWidth-J,Dt=On(K,[J,Math.max(J,_t-Nt)]);c.style.minWidth=be+"px",c.style.left=Dt+"px"}else{const H=O.right-L.right,K=window.innerWidth-M.right-H,Z=window.innerWidth-S.right-K,be=S.width+Z,Nt=Math.max(be,O.width),_t=window.innerWidth-J,Dt=On(K,[J,Math.max(J,_t-Nt)]);c.style.minWidth=be+"px",c.style.right=Dt+"px"}const k=y(),$=window.innerHeight-J*2,F=d.scrollHeight,T=window.getComputedStyle(u),j=parseInt(T.borderTopWidth,10),I=parseInt(T.paddingTop,10),_=parseInt(T.borderBottomWidth,10),P=parseInt(T.paddingBottom,10),W=j+I+F+P+_,Y=Math.min(m.offsetHeight*5,W),ue=window.getComputedStyle(d),de=parseInt(ue.paddingTop,10),re=parseInt(ue.paddingBottom,10),Q=S.top+S.height/2-J,Ie=$-Q,Ce=m.offsetHeight/2,A=m.offsetTop+Ce,U=j+I+A,X=W-U;if(U<=Q){const H=k.length>0&&m===k[k.length-1].ref.current;c.style.bottom="0px";const K=u.clientHeight-d.offsetTop-d.offsetHeight,Z=Math.max(Ie,Ce+(H?re:0)+K+_),be=U+Z;c.style.height=be+"px"}else{const H=k.length>0&&m===k[0].ref.current;c.style.top="0px";const Z=Math.max(Q,j+d.offsetTop+(H?de:0)+Ce)+X;c.style.height=Z+"px",d.scrollTop=U-Q+d.offsetTop}c.style.margin=`${J}px 0`,c.style.minHeight=Y+"px",c.style.maxHeight=$+"px",o?.(),requestAnimationFrame(()=>h.current=!0)}},[y,s.trigger,s.valueNode,c,u,d,m,w,s.dir,o]);z(()=>C(),[C]);const[b,E]=i.useState();z(()=>{u&&E(window.getComputedStyle(u).zIndex)},[u]);const R=i.useCallback(S=>{S&&x.current===!0&&(C(),g?.(),x.current=!1)},[C,g]);return v.jsx(Yc,{scope:n,contentWrapper:c,shouldExpandOnScrollRef:h,onScrollButtonChange:R,children:v.jsx("div",{ref:l,style:{display:"flex",flexDirection:"column",position:"fixed",zIndex:b},children:v.jsx(D.div,{...r,ref:p,style:{boxSizing:"border-box",maxHeight:"100%",...r.style}})})})});xr.displayName=Kc;var zc="SelectPopperPosition",Gt=i.forwardRef((e,t)=>{const{__scopeSelect:n,align:o="start",collisionPadding:r=J,...s}=e,a=Rt(n);return v.jsx(ar,{...a,...s,ref:t,align:o,collisionPadding:r,style:{boxSizing:"border-box",...s.style,"--radix-select-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-select-content-available-width":"var(--radix-popper-available-width)","--radix-select-content-available-height":"var(--radix-popper-available-height)","--radix-select-trigger-width":"var(--radix-popper-anchor-width)","--radix-select-trigger-height":"var(--radix-popper-anchor-height)"}})});Gt.displayName=zc;var[Yc,xn]=Ve(Ae,{}),qt="SelectViewport",Cr=i.forwardRef((e,t)=>{const{__scopeSelect:n,nonce:o,...r}=e,s=xe(qt,n),a=xn(qt,n),c=B(t,s.onViewportChange),l=i.useRef(0);return v.jsxs(v.Fragment,{children:[v.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}"},nonce:o}),v.jsx(St.Slot,{scope:n,children:v.jsx(D.div,{"data-radix-select-viewport":"",role:"presentation",...r,ref:c,style:{position:"relative",flex:1,overflow:"hidden auto",...r.style},onScroll:N(r.onScroll,u=>{const f=u.currentTarget,{contentWrapper:p,shouldExpandOnScrollRef:y}=a;if(y?.current&&p){const h=Math.abs(l.current-f.scrollTop);if(h>0){const x=window.innerHeight-J*2,d=parseFloat(p.style.minHeight),m=parseFloat(p.style.height),w=Math.max(d,m);if(w0?b:0,p.style.justifyContent="flex-end")}}}l.current=f.scrollTop})})})]})});Cr.displayName=qt;var br="SelectGroup",[Xc,Gc]=Ve(br),qc=i.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e,r=Se();return v.jsx(Xc,{scope:n,id:r,children:v.jsx(D.div,{role:"group","aria-labelledby":r,...o,ref:t})})});qc.displayName=br;var Er="SelectLabel",Sr=i.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e,r=Gc(Er,n);return v.jsx(D.div,{id:r.id,...o,ref:t})});Sr.displayName=Er;var ht="SelectItem",[Zc,Tr]=Ve(ht),Rr=i.forwardRef((e,t)=>{const{__scopeSelect:n,value:o,disabled:r=!1,textValue:s,...a}=e,c=we(ht,n),l=xe(ht,n),u=c.value===o,[f,p]=i.useState(s??""),[y,h]=i.useState(!1),x=B(t,g=>l.itemRefCallback?.(g,o,r)),d=Se(),m=i.useRef("touch"),w=()=>{r||(c.onValueChange(o),c.onOpenChange(!1))};if(o==="")throw new Error("A must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder.");return v.jsx(Zc,{scope:n,value:o,disabled:r,textId:d,isSelected:u,onItemTextChange:i.useCallback(g=>{p(C=>C||(g?.textContent??"").trim())},[]),children:v.jsx(St.ItemSlot,{scope:n,value:o,disabled:r,textValue:f,children:v.jsx(D.div,{role:"option","aria-labelledby":d,"data-highlighted":y?"":void 0,"aria-selected":u&&y,"data-state":u?"checked":"unchecked","aria-disabled":r||void 0,"data-disabled":r?"":void 0,tabIndex:r?void 0:-1,...a,ref:x,onFocus:N(a.onFocus,()=>h(!0)),onBlur:N(a.onBlur,()=>h(!1)),onClick:N(a.onClick,()=>{m.current!=="mouse"&&w()}),onPointerUp:N(a.onPointerUp,()=>{m.current==="mouse"&&w()}),onPointerDown:N(a.onPointerDown,g=>{m.current=g.pointerType}),onPointerMove:N(a.onPointerMove,g=>{m.current=g.pointerType,r?l.onItemLeave?.():m.current==="mouse"&&g.currentTarget.focus({preventScroll:!0})}),onPointerLeave:N(a.onPointerLeave,g=>{g.currentTarget===document.activeElement&&l.onItemLeave?.()}),onKeyDown:N(a.onKeyDown,g=>{l.searchRef?.current!==""&&g.key===" "||(kc.includes(g.key)&&w(),g.key===" "&&g.preventDefault())})})})})});Rr.displayName=ht;var He="SelectItemText",Pr=i.forwardRef((e,t)=>{const{__scopeSelect:n,className:o,style:r,...s}=e,a=we(He,n),c=xe(He,n),l=Tr(He,n),u=Wc(He,n),[f,p]=i.useState(null),y=B(t,w=>p(w),l.onItemTextChange,w=>c.itemTextRefCallback?.(w,l.value,l.disabled)),h=f?.textContent,x=i.useMemo(()=>v.jsx("option",{value:l.value,disabled:l.disabled,children:h},l.value),[l.disabled,l.value,h]),{onNativeOptionAdd:d,onNativeOptionRemove:m}=u;return z(()=>(d(x),()=>m(x)),[d,m,x]),v.jsxs(v.Fragment,{children:[v.jsx(D.span,{id:l.textId,...s,ref:y}),l.isSelected&&a.valueNode&&!a.valueNodeHasChildren?Ye.createPortal(s.children,a.valueNode):null]})});Pr.displayName=He;var Ar="SelectItemIndicator",Or=i.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e;return Tr(Ar,n).isSelected?v.jsx(D.span,{"aria-hidden":!0,...o,ref:t}):null});Or.displayName=Ar;var Zt="SelectScrollUpButton",Ir=i.forwardRef((e,t)=>{const n=xe(Zt,e.__scopeSelect),o=xn(Zt,e.__scopeSelect),[r,s]=i.useState(!1),a=B(t,o.onScrollButtonChange);return z(()=>{if(n.viewport&&n.isPositioned){let c=function(){const u=l.scrollTop>0;s(u)};const l=n.viewport;return c(),l.addEventListener("scroll",c),()=>l.removeEventListener("scroll",c)}},[n.viewport,n.isPositioned]),r?v.jsx(_r,{...e,ref:a,onAutoScroll:()=>{const{viewport:c,selectedItem:l}=n;c&&l&&(c.scrollTop=c.scrollTop-l.offsetHeight)}}):null});Ir.displayName=Zt;var Qt="SelectScrollDownButton",Nr=i.forwardRef((e,t)=>{const n=xe(Qt,e.__scopeSelect),o=xn(Qt,e.__scopeSelect),[r,s]=i.useState(!1),a=B(t,o.onScrollButtonChange);return z(()=>{if(n.viewport&&n.isPositioned){let c=function(){const u=l.scrollHeight-l.clientHeight,f=Math.ceil(l.scrollTop)l.removeEventListener("scroll",c)}},[n.viewport,n.isPositioned]),r?v.jsx(_r,{...e,ref:a,onAutoScroll:()=>{const{viewport:c,selectedItem:l}=n;c&&l&&(c.scrollTop=c.scrollTop+l.offsetHeight)}}):null});Nr.displayName=Qt;var _r=i.forwardRef((e,t)=>{const{__scopeSelect:n,onAutoScroll:o,...r}=e,s=xe("SelectScrollButton",n),a=i.useRef(null),c=Tt(n),l=i.useCallback(()=>{a.current!==null&&(window.clearInterval(a.current),a.current=null)},[]);return i.useEffect(()=>()=>l(),[l]),z(()=>{c().find(f=>f.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:"nearest"})},[c]),v.jsx(D.div,{"aria-hidden":!0,...r,ref:t,style:{flexShrink:0,...r.style},onPointerDown:N(r.onPointerDown,()=>{a.current===null&&(a.current=window.setInterval(o,50))}),onPointerMove:N(r.onPointerMove,()=>{s.onItemLeave?.(),a.current===null&&(a.current=window.setInterval(o,50))}),onPointerLeave:N(r.onPointerLeave,()=>{l()})})}),Qc="SelectSeparator",Dr=i.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e;return v.jsx(D.div,{"aria-hidden":!0,...o,ref:t})});Dr.displayName=Qc;var Jt="SelectArrow",Jc=i.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e,r=Rt(n),s=we(Jt,n),a=xe(Jt,n);return s.open&&a.position==="popper"?v.jsx(cr,{...r,...o,ref:t}):null});Jc.displayName=Jt;var el="SelectBubbleInput",Mr=i.forwardRef(({__scopeSelect:e,value:t,...n},o)=>{const r=i.useRef(null),s=B(o,r),a=ro(t);return i.useEffect(()=>{const c=r.current;if(!c)return;const l=window.HTMLSelectElement.prototype,f=Object.getOwnPropertyDescriptor(l,"value").set;if(a!==t&&f){const p=new Event("change",{bubbles:!0});f.call(c,t),c.dispatchEvent(p)}},[a,t]),v.jsx(D.select,{...n,style:{...lr,...n.style},ref:s,defaultValue:t})});Mr.displayName=el;function Lr(e){return e===""||e===void 0}function kr(e){const t=ee(e),n=i.useRef(""),o=i.useRef(0),r=i.useCallback(a=>{const c=n.current+a;t(c),(function l(u){n.current=u,window.clearTimeout(o.current),u!==""&&(o.current=window.setTimeout(()=>l(""),1e3))})(c)},[t]),s=i.useCallback(()=>{n.current="",window.clearTimeout(o.current)},[]);return i.useEffect(()=>()=>window.clearTimeout(o.current),[]),[n,r,s]}function jr(e,t,n){const r=t.length>1&&Array.from(t).every(u=>u===t[0])?t[0]:t,s=n?e.indexOf(n):-1;let a=tl(e,Math.max(s,0));r.length===1&&(a=a.filter(u=>u!==n));const l=a.find(u=>u.textValue.toLowerCase().startsWith(r.toLowerCase()));return l!==n?l:void 0}function tl(e,t){return e.map((n,o)=>e[(t+o)%e.length])}var nu=ur,ou=fr,ru=mr,su=hr,iu=vr,au=gr,cu=Cr,lu=Sr,uu=Rr,du=Pr,fu=Or,pu=Ir,mu=Nr,hu=Dr,Pt="Checkbox",[nl]=Oe(Pt),[ol,Cn]=nl(Pt);function rl(e){const{__scopeCheckbox:t,checked:n,children:o,defaultChecked:r,disabled:s,form:a,name:c,onCheckedChange:l,required:u,value:f="on",internal_do_not_use_render:p}=e,[y,h]=ke({prop:n,defaultProp:r??!1,onChange:l,caller:Pt}),[x,d]=i.useState(null),[m,w]=i.useState(null),g=i.useRef(!1),C=x?!!a||!!x.closest("form"):!0,b={checked:y,disabled:s,setChecked:h,control:x,setControl:d,name:c,form:a,value:f,hasConsumerStoppedPropagationRef:g,required:u,defaultChecked:he(r)?!1:r,isFormControl:C,bubbleInput:m,setBubbleInput:w};return v.jsx(ol,{scope:t,...b,children:al(p)?p(b):o})}var Fr="CheckboxTrigger",$r=i.forwardRef(({__scopeCheckbox:e,onKeyDown:t,onClick:n,...o},r)=>{const{control:s,value:a,disabled:c,checked:l,required:u,setControl:f,setChecked:p,hasConsumerStoppedPropagationRef:y,isFormControl:h,bubbleInput:x}=Cn(Fr,e),d=B(r,f),m=i.useRef(l);return i.useEffect(()=>{const w=s?.form;if(w){const g=()=>p(m.current);return w.addEventListener("reset",g),()=>w.removeEventListener("reset",g)}},[s,p]),v.jsx(D.button,{type:"button",role:"checkbox","aria-checked":he(l)?"mixed":l,"aria-required":u,"data-state":Hr(l),"data-disabled":c?"":void 0,disabled:c,value:a,...o,ref:d,onKeyDown:N(t,w=>{w.key==="Enter"&&w.preventDefault()}),onClick:N(n,w=>{p(g=>he(g)?!0:!g),x&&h&&(y.current=w.isPropagationStopped(),y.current||w.stopPropagation())})})});$r.displayName=Fr;var sl=i.forwardRef((e,t)=>{const{__scopeCheckbox:n,name:o,checked:r,defaultChecked:s,required:a,disabled:c,value:l,onCheckedChange:u,form:f,...p}=e;return v.jsx(rl,{__scopeCheckbox:n,checked:r,defaultChecked:s,disabled:c,required:a,onCheckedChange:u,name:o,form:f,value:l,internal_do_not_use_render:({isFormControl:y})=>v.jsxs(v.Fragment,{children:[v.jsx($r,{...p,ref:t,__scopeCheckbox:n}),y&&v.jsx(Vr,{__scopeCheckbox:n})]})})});sl.displayName=Pt;var Wr="CheckboxIndicator",il=i.forwardRef((e,t)=>{const{__scopeCheckbox:n,forceMount:o,...r}=e,s=Cn(Wr,n);return v.jsx(ye,{present:o||he(s.checked)||s.checked===!0,children:v.jsx(D.span,{"data-state":Hr(s.checked),"data-disabled":s.disabled?"":void 0,...r,ref:t,style:{pointerEvents:"none",...e.style}})})});il.displayName=Wr;var Br="CheckboxBubbleInput",Vr=i.forwardRef(({__scopeCheckbox:e,...t},n)=>{const{control:o,hasConsumerStoppedPropagationRef:r,checked:s,defaultChecked:a,required:c,disabled:l,name:u,value:f,form:p,bubbleInput:y,setBubbleInput:h}=Cn(Br,e),x=B(n,h),d=ro(s),m=so(o);i.useEffect(()=>{const g=y;if(!g)return;const C=window.HTMLInputElement.prototype,E=Object.getOwnPropertyDescriptor(C,"checked").set,R=!r.current;if(d!==s&&E){const S=new Event("click",{bubbles:R});g.indeterminate=he(s),E.call(g,he(s)?!1:s),g.dispatchEvent(S)}},[y,d,s,r]);const w=i.useRef(he(s)?!1:s);return v.jsx(D.input,{type:"checkbox","aria-hidden":!0,defaultChecked:a??w.current,required:c,disabled:l,name:u,value:f,form:p,...t,tabIndex:-1,ref:x,style:{...t.style,...m,position:"absolute",pointerEvents:"none",opacity:0,margin:0,transform:"translateX(-100%)"}})});Vr.displayName=Br;function al(e){return typeof e=="function"}function he(e){return e==="indeterminate"}function Hr(e){return he(e)?"indeterminate":e?"checked":"unchecked"}var cl=Symbol("radix.slottable");function ll(e){const t=({children:n})=>v.jsx(v.Fragment,{children:n});return t.displayName=`${e}.Slottable`,t.__radixId=cl,t}var[At]=Oe("Tooltip",[bt]),Ot=bt(),Ur="TooltipProvider",ul=700,en="tooltip.open",[dl,bn]=At(Ur),Kr=e=>{const{__scopeTooltip:t,delayDuration:n=ul,skipDelayDuration:o=300,disableHoverableContent:r=!1,children:s}=e,a=i.useRef(!0),c=i.useRef(!1),l=i.useRef(0);return i.useEffect(()=>{const u=l.current;return()=>window.clearTimeout(u)},[]),v.jsx(dl,{scope:t,isOpenDelayedRef:a,delayDuration:n,onOpen:i.useCallback(()=>{window.clearTimeout(l.current),a.current=!1},[]),onClose:i.useCallback(()=>{window.clearTimeout(l.current),l.current=window.setTimeout(()=>a.current=!0,o)},[o]),isPointerInTransitRef:c,onPointerInTransitChange:i.useCallback(u=>{c.current=u},[]),disableHoverableContent:r,children:s})};Kr.displayName=Ur;var ze="Tooltip",[fl,Ze]=At(ze),zr=e=>{const{__scopeTooltip:t,children:n,open:o,defaultOpen:r,onOpenChange:s,disableHoverableContent:a,delayDuration:c}=e,l=bn(ze,e.__scopeTooltip),u=Ot(t),[f,p]=i.useState(null),y=Se(),h=i.useRef(0),x=a??l.disableHoverableContent,d=c??l.delayDuration,m=i.useRef(!1),[w,g]=ke({prop:o,defaultProp:r??!1,onChange:S=>{S?(l.onOpen(),document.dispatchEvent(new CustomEvent(en))):l.onClose(),s?.(S)},caller:ze}),C=i.useMemo(()=>w?m.current?"delayed-open":"instant-open":"closed",[w]),b=i.useCallback(()=>{window.clearTimeout(h.current),h.current=0,m.current=!1,g(!0)},[g]),E=i.useCallback(()=>{window.clearTimeout(h.current),h.current=0,g(!1)},[g]),R=i.useCallback(()=>{window.clearTimeout(h.current),h.current=window.setTimeout(()=>{m.current=!0,g(!0),h.current=0},d)},[d,g]);return i.useEffect(()=>()=>{h.current&&(window.clearTimeout(h.current),h.current=0)},[]),v.jsx(sr,{...u,children:v.jsx(fl,{scope:t,contentId:y,open:w,stateAttribute:C,trigger:f,onTriggerChange:p,onTriggerEnter:i.useCallback(()=>{l.isOpenDelayedRef.current?R():b()},[l.isOpenDelayedRef,R,b]),onTriggerLeave:i.useCallback(()=>{x?E():(window.clearTimeout(h.current),h.current=0)},[E,x]),onOpen:b,onClose:E,disableHoverableContent:x,children:n})})};zr.displayName=ze;var tn="TooltipTrigger",Yr=i.forwardRef((e,t)=>{const{__scopeTooltip:n,...o}=e,r=Ze(tn,n),s=bn(tn,n),a=Ot(n),c=i.useRef(null),l=B(t,c,r.onTriggerChange),u=i.useRef(!1),f=i.useRef(!1),p=i.useCallback(()=>u.current=!1,[]);return i.useEffect(()=>()=>document.removeEventListener("pointerup",p),[p]),v.jsx(ir,{asChild:!0,...a,children:v.jsx(D.button,{"aria-describedby":r.open?r.contentId:void 0,"data-state":r.stateAttribute,...o,ref:l,onPointerMove:N(e.onPointerMove,y=>{y.pointerType!=="touch"&&!f.current&&!s.isPointerInTransitRef.current&&(r.onTriggerEnter(),f.current=!0)}),onPointerLeave:N(e.onPointerLeave,()=>{r.onTriggerLeave(),f.current=!1}),onPointerDown:N(e.onPointerDown,()=>{r.open&&r.onClose(),u.current=!0,document.addEventListener("pointerup",p,{once:!0})}),onFocus:N(e.onFocus,()=>{u.current||r.onOpen()}),onBlur:N(e.onBlur,r.onClose),onClick:N(e.onClick,r.onClose)})})});Yr.displayName=tn;var En="TooltipPortal",[pl,ml]=At(En,{forceMount:void 0}),Xr=e=>{const{__scopeTooltip:t,forceMount:n,children:o,container:r}=e,s=Ze(En,t);return v.jsx(pl,{scope:t,forceMount:n,children:v.jsx(ye,{present:n||s.open,children:v.jsx(Ge,{asChild:!0,container:r,children:o})})})};Xr.displayName=En;var Fe="TooltipContent",Gr=i.forwardRef((e,t)=>{const n=ml(Fe,e.__scopeTooltip),{forceMount:o=n.forceMount,side:r="top",...s}=e,a=Ze(Fe,e.__scopeTooltip);return v.jsx(ye,{present:o||a.open,children:a.disableHoverableContent?v.jsx(qr,{side:r,...s,ref:t}):v.jsx(hl,{side:r,...s,ref:t})})}),hl=i.forwardRef((e,t)=>{const n=Ze(Fe,e.__scopeTooltip),o=bn(Fe,e.__scopeTooltip),r=i.useRef(null),s=B(t,r),[a,c]=i.useState(null),{trigger:l,onClose:u}=n,f=r.current,{onPointerInTransitChange:p}=o,y=i.useCallback(()=>{c(null),p(!1)},[p]),h=i.useCallback((x,d)=>{const m=x.currentTarget,w={x:x.clientX,y:x.clientY},g=xl(w,m.getBoundingClientRect()),C=Cl(w,g),b=bl(d.getBoundingClientRect()),E=Sl([...C,...b]);c(E),p(!0)},[p]);return i.useEffect(()=>()=>y(),[y]),i.useEffect(()=>{if(l&&f){const x=m=>h(m,f),d=m=>h(m,l);return l.addEventListener("pointerleave",x),f.addEventListener("pointerleave",d),()=>{l.removeEventListener("pointerleave",x),f.removeEventListener("pointerleave",d)}}},[l,f,h,y]),i.useEffect(()=>{if(a){const x=d=>{const m=d.target,w={x:d.clientX,y:d.clientY},g=l?.contains(m)||f?.contains(m),C=!El(w,a);g?y():C&&(y(),u())};return document.addEventListener("pointermove",x),()=>document.removeEventListener("pointermove",x)}},[l,f,a,u,y]),v.jsx(qr,{...e,ref:s})}),[vl,gl]=At(ze,{isInside:!1}),yl=ll("TooltipContent"),qr=i.forwardRef((e,t)=>{const{__scopeTooltip:n,children:o,"aria-label":r,onEscapeKeyDown:s,onPointerDownOutside:a,...c}=e,l=Ze(Fe,n),u=Ot(n),{onClose:f}=l;return i.useEffect(()=>(document.addEventListener(en,f),()=>document.removeEventListener(en,f)),[f]),i.useEffect(()=>{if(l.trigger){const p=y=>{y.target?.contains(l.trigger)&&f()};return window.addEventListener("scroll",p,{capture:!0}),()=>window.removeEventListener("scroll",p,{capture:!0})}},[l.trigger,f]),v.jsx(Xe,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:s,onPointerDownOutside:a,onFocusOutside:p=>p.preventDefault(),onDismiss:f,children:v.jsxs(ar,{"data-state":l.stateAttribute,...u,...c,ref:t,style:{...c.style,"--radix-tooltip-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-tooltip-content-available-width":"var(--radix-popper-available-width)","--radix-tooltip-content-available-height":"var(--radix-popper-available-height)","--radix-tooltip-trigger-width":"var(--radix-popper-anchor-width)","--radix-tooltip-trigger-height":"var(--radix-popper-anchor-height)"},children:[v.jsx(yl,{children:o}),v.jsx(vl,{scope:n,isInside:!0,children:v.jsx(Mc,{id:l.contentId,role:"tooltip",children:r||o})})]})})});Gr.displayName=Fe;var Zr="TooltipArrow",wl=i.forwardRef((e,t)=>{const{__scopeTooltip:n,...o}=e,r=Ot(n);return gl(Zr,n).isInside?null:v.jsx(cr,{...r,...o,ref:t})});wl.displayName=Zr;function xl(e,t){const n=Math.abs(t.top-e.y),o=Math.abs(t.bottom-e.y),r=Math.abs(t.right-e.x),s=Math.abs(t.left-e.x);switch(Math.min(n,o,r,s)){case s:return"left";case r:return"right";case n:return"top";case o:return"bottom";default:throw new Error("unreachable")}}function Cl(e,t,n=5){const o=[];switch(t){case"top":o.push({x:e.x-n,y:e.y+n},{x:e.x+n,y:e.y+n});break;case"bottom":o.push({x:e.x-n,y:e.y-n},{x:e.x+n,y:e.y-n});break;case"left":o.push({x:e.x+n,y:e.y-n},{x:e.x+n,y:e.y+n});break;case"right":o.push({x:e.x-n,y:e.y-n},{x:e.x-n,y:e.y+n});break}return o}function bl(e){const{top:t,right:n,bottom:o,left:r}=e;return[{x:r,y:t},{x:n,y:t},{x:n,y:o},{x:r,y:o}]}function El(e,t){const{x:n,y:o}=e;let r=!1;for(let s=0,a=t.length-1;so!=y>o&&n<(p-u)*(o-f)/(y-f)+u&&(r=!r)}return r}function Sl(e){const t=e.slice();return t.sort((n,o)=>n.xo.x?1:n.yo.y?1:0),Tl(t)}function Tl(e){if(e.length<=1)return e.slice();const t=[];for(let o=0;o=2;){const s=t[t.length-1],a=t[t.length-2];if((s.x-a.x)*(r.y-a.y)>=(s.y-a.y)*(r.x-a.x))t.pop();else break}t.push(r)}t.pop();const n=[];for(let o=e.length-1;o>=0;o--){const r=e[o];for(;n.length>=2;){const s=n[n.length-1],a=n[n.length-2];if((s.x-a.x)*(r.y-a.y)>=(s.y-a.y)*(r.x-a.x))n.pop();else break}n.push(r)}return n.pop(),t.length===1&&n.length===1&&t[0].x===n[0].x&&t[0].y===n[0].y?t:t.concat(n)}var vu=Kr,gu=zr,yu=Yr,wu=Xr,xu=Gr,Sn="ToastProvider",[Tn,Rl,Pl]=eo("Toast"),[Qr]=Oe("Toast",[Pl]),[Al,It]=Qr(Sn),Jr=e=>{const{__scopeToast:t,label:n="Notification",duration:o=5e3,swipeDirection:r="right",swipeThreshold:s=50,children:a}=e,[c,l]=i.useState(null),[u,f]=i.useState(0),p=i.useRef(!1),y=i.useRef(!1);return n.trim()||console.error(`Invalid prop \`label\` supplied to \`${Sn}\`. Expected non-empty \`string\`.`),v.jsx(Tn.Provider,{scope:t,children:v.jsx(Al,{scope:t,label:n,duration:o,swipeDirection:r,swipeThreshold:s,toastCount:u,viewport:c,onViewportChange:l,onToastAdd:i.useCallback(()=>f(h=>h+1),[]),onToastRemove:i.useCallback(()=>f(h=>h-1),[]),isFocusedToastEscapeKeyDownRef:p,isClosePausedRef:y,children:a})})};Jr.displayName=Sn;var es="ToastViewport",Ol=["F8"],nn="toast.viewportPause",on="toast.viewportResume",ts=i.forwardRef((e,t)=>{const{__scopeToast:n,hotkey:o=Ol,label:r="Notifications ({hotkey})",...s}=e,a=It(es,n),c=Rl(n),l=i.useRef(null),u=i.useRef(null),f=i.useRef(null),p=i.useRef(null),y=B(t,p,a.onViewportChange),h=o.join("+").replace(/Key/g,"").replace(/Digit/g,""),x=a.toastCount>0;i.useEffect(()=>{const m=w=>{o.length!==0&&o.every(C=>w[C]||w.code===C)&&p.current?.focus()};return document.addEventListener("keydown",m),()=>document.removeEventListener("keydown",m)},[o]),i.useEffect(()=>{const m=l.current,w=p.current;if(x&&m&&w){const g=()=>{if(!a.isClosePausedRef.current){const R=new CustomEvent(nn);w.dispatchEvent(R),a.isClosePausedRef.current=!0}},C=()=>{if(a.isClosePausedRef.current){const R=new CustomEvent(on);w.dispatchEvent(R),a.isClosePausedRef.current=!1}},b=R=>{!m.contains(R.relatedTarget)&&C()},E=()=>{m.contains(document.activeElement)||C()};return m.addEventListener("focusin",g),m.addEventListener("focusout",b),m.addEventListener("pointermove",g),m.addEventListener("pointerleave",E),window.addEventListener("blur",g),window.addEventListener("focus",C),()=>{m.removeEventListener("focusin",g),m.removeEventListener("focusout",b),m.removeEventListener("pointermove",g),m.removeEventListener("pointerleave",E),window.removeEventListener("blur",g),window.removeEventListener("focus",C)}}},[x,a.isClosePausedRef]);const d=i.useCallback(({tabbingDirection:m})=>{const g=c().map(C=>{const b=C.ref.current,E=[b,...Vl(b)];return m==="forwards"?E:E.reverse()});return(m==="forwards"?g.reverse():g).flat()},[c]);return i.useEffect(()=>{const m=p.current;if(m){const w=g=>{const C=g.altKey||g.ctrlKey||g.metaKey;if(g.key==="Tab"&&!C){const E=document.activeElement,R=g.shiftKey;if(g.target===m&&R){u.current?.focus();return}const M=d({tabbingDirection:R?"backwards":"forwards"}),L=M.findIndex(k=>k===E);Ht(M.slice(L+1))?g.preventDefault():R?u.current?.focus():f.current?.focus()}};return m.addEventListener("keydown",w),()=>m.removeEventListener("keydown",w)}},[c,d]),v.jsxs(ei,{ref:l,role:"region","aria-label":r.replace("{hotkey}",h),tabIndex:-1,style:{pointerEvents:x?void 0:"none"},children:[x&&v.jsx(rn,{ref:u,onFocusFromOutsideViewport:()=>{const m=d({tabbingDirection:"forwards"});Ht(m)}}),v.jsx(Tn.Slot,{scope:n,children:v.jsx(D.ol,{tabIndex:-1,...s,ref:y})}),x&&v.jsx(rn,{ref:f,onFocusFromOutsideViewport:()=>{const m=d({tabbingDirection:"backwards"});Ht(m)}})]})});ts.displayName=es;var ns="ToastFocusProxy",rn=i.forwardRef((e,t)=>{const{__scopeToast:n,onFocusFromOutsideViewport:o,...r}=e,s=It(ns,n);return v.jsx(Et,{tabIndex:0,...r,ref:t,style:{position:"fixed"},onFocus:a=>{const c=a.relatedTarget;!s.viewport?.contains(c)&&o()}})});rn.displayName=ns;var Qe="Toast",Il="toast.swipeStart",Nl="toast.swipeMove",_l="toast.swipeCancel",Dl="toast.swipeEnd",os=i.forwardRef((e,t)=>{const{forceMount:n,open:o,defaultOpen:r,onOpenChange:s,...a}=e,[c,l]=ke({prop:o,defaultProp:r??!0,onChange:s,caller:Qe});return v.jsx(ye,{present:n||c,children:v.jsx(kl,{open:c,...a,ref:t,onClose:()=>l(!1),onPause:ee(e.onPause),onResume:ee(e.onResume),onSwipeStart:N(e.onSwipeStart,u=>{u.currentTarget.setAttribute("data-swipe","start")}),onSwipeMove:N(e.onSwipeMove,u=>{const{x:f,y:p}=u.detail.delta;u.currentTarget.setAttribute("data-swipe","move"),u.currentTarget.style.setProperty("--radix-toast-swipe-move-x",`${f}px`),u.currentTarget.style.setProperty("--radix-toast-swipe-move-y",`${p}px`)}),onSwipeCancel:N(e.onSwipeCancel,u=>{u.currentTarget.setAttribute("data-swipe","cancel"),u.currentTarget.style.removeProperty("--radix-toast-swipe-move-x"),u.currentTarget.style.removeProperty("--radix-toast-swipe-move-y"),u.currentTarget.style.removeProperty("--radix-toast-swipe-end-x"),u.currentTarget.style.removeProperty("--radix-toast-swipe-end-y")}),onSwipeEnd:N(e.onSwipeEnd,u=>{const{x:f,y:p}=u.detail.delta;u.currentTarget.setAttribute("data-swipe","end"),u.currentTarget.style.removeProperty("--radix-toast-swipe-move-x"),u.currentTarget.style.removeProperty("--radix-toast-swipe-move-y"),u.currentTarget.style.setProperty("--radix-toast-swipe-end-x",`${f}px`),u.currentTarget.style.setProperty("--radix-toast-swipe-end-y",`${p}px`),l(!1)})})})});os.displayName=Qe;var[Ml,Ll]=Qr(Qe,{onClose(){}}),kl=i.forwardRef((e,t)=>{const{__scopeToast:n,type:o="foreground",duration:r,open:s,onClose:a,onEscapeKeyDown:c,onPause:l,onResume:u,onSwipeStart:f,onSwipeMove:p,onSwipeCancel:y,onSwipeEnd:h,...x}=e,d=It(Qe,n),[m,w]=i.useState(null),g=B(t,T=>w(T)),C=i.useRef(null),b=i.useRef(null),E=r||d.duration,R=i.useRef(0),S=i.useRef(E),O=i.useRef(0),{onToastAdd:M,onToastRemove:L}=d,k=ee(()=>{m?.contains(document.activeElement)&&d.viewport?.focus(),a()}),$=i.useCallback(T=>{!T||T===1/0||(window.clearTimeout(O.current),R.current=new Date().getTime(),O.current=window.setTimeout(k,T))},[k]);i.useEffect(()=>{const T=d.viewport;if(T){const j=()=>{$(S.current),u?.()},I=()=>{const _=new Date().getTime()-R.current;S.current=S.current-_,window.clearTimeout(O.current),l?.()};return T.addEventListener(nn,I),T.addEventListener(on,j),()=>{T.removeEventListener(nn,I),T.removeEventListener(on,j)}}},[d.viewport,E,l,u,$]),i.useEffect(()=>{s&&!d.isClosePausedRef.current&&$(E)},[s,E,d.isClosePausedRef,$]),i.useEffect(()=>(M(),()=>L()),[M,L]);const F=i.useMemo(()=>m?us(m):null,[m]);return d.viewport?v.jsxs(v.Fragment,{children:[F&&v.jsx(jl,{__scopeToast:n,role:"status","aria-live":o==="foreground"?"assertive":"polite",children:F}),v.jsx(Ml,{scope:n,onClose:k,children:Ye.createPortal(v.jsx(Tn.ItemSlot,{scope:n,children:v.jsx(Js,{asChild:!0,onEscapeKeyDown:N(c,()=>{d.isFocusedToastEscapeKeyDownRef.current||k(),d.isFocusedToastEscapeKeyDownRef.current=!1}),children:v.jsx(D.li,{tabIndex:0,"data-state":s?"open":"closed","data-swipe-direction":d.swipeDirection,...x,ref:g,style:{userSelect:"none",touchAction:"none",...e.style},onKeyDown:N(e.onKeyDown,T=>{T.key==="Escape"&&(c?.(T.nativeEvent),T.nativeEvent.defaultPrevented||(d.isFocusedToastEscapeKeyDownRef.current=!0,k()))}),onPointerDown:N(e.onPointerDown,T=>{T.button===0&&(C.current={x:T.clientX,y:T.clientY})}),onPointerMove:N(e.onPointerMove,T=>{if(!C.current)return;const j=T.clientX-C.current.x,I=T.clientY-C.current.y,_=!!b.current,P=["left","right"].includes(d.swipeDirection),W=["left","up"].includes(d.swipeDirection)?Math.min:Math.max,Y=P?W(0,j):0,ue=P?0:W(0,I),de=T.pointerType==="touch"?10:2,re={x:Y,y:ue},Q={originalEvent:T,delta:re};_?(b.current=re,st(Nl,p,Q,{discrete:!1})):Jn(re,d.swipeDirection,de)?(b.current=re,st(Il,f,Q,{discrete:!1}),T.target.setPointerCapture(T.pointerId)):(Math.abs(j)>de||Math.abs(I)>de)&&(C.current=null)}),onPointerUp:N(e.onPointerUp,T=>{const j=b.current,I=T.target;if(I.hasPointerCapture(T.pointerId)&&I.releasePointerCapture(T.pointerId),b.current=null,C.current=null,j){const _=T.currentTarget,P={originalEvent:T,delta:j};Jn(j,d.swipeDirection,d.swipeThreshold)?st(Dl,h,P,{discrete:!0}):st(_l,y,P,{discrete:!0}),_.addEventListener("click",W=>W.preventDefault(),{once:!0})}})})})}),d.viewport)})]}):null}),jl=e=>{const{__scopeToast:t,children:n,...o}=e,r=It(Qe,t),[s,a]=i.useState(!1),[c,l]=i.useState(!1);return Wl(()=>a(!0)),i.useEffect(()=>{const u=window.setTimeout(()=>l(!0),1e3);return()=>window.clearTimeout(u)},[]),c?null:v.jsx(Ge,{asChild:!0,children:v.jsx(Et,{...o,children:s&&v.jsxs(v.Fragment,{children:[r.label," ",n]})})})},Fl="ToastTitle",rs=i.forwardRef((e,t)=>{const{__scopeToast:n,...o}=e;return v.jsx(D.div,{...o,ref:t})});rs.displayName=Fl;var $l="ToastDescription",ss=i.forwardRef((e,t)=>{const{__scopeToast:n,...o}=e;return v.jsx(D.div,{...o,ref:t})});ss.displayName=$l;var is="ToastAction",as=i.forwardRef((e,t)=>{const{altText:n,...o}=e;return n.trim()?v.jsx(ls,{altText:n,asChild:!0,children:v.jsx(Rn,{...o,ref:t})}):(console.error(`Invalid prop \`altText\` supplied to \`${is}\`. Expected non-empty \`string\`.`),null)});as.displayName=is;var cs="ToastClose",Rn=i.forwardRef((e,t)=>{const{__scopeToast:n,...o}=e,r=Ll(cs,n);return v.jsx(ls,{asChild:!0,children:v.jsx(D.button,{type:"button",...o,ref:t,onClick:N(e.onClick,r.onClose)})})});Rn.displayName=cs;var ls=i.forwardRef((e,t)=>{const{__scopeToast:n,altText:o,...r}=e;return v.jsx(D.div,{"data-radix-toast-announce-exclude":"","data-radix-toast-announce-alt":o||void 0,...r,ref:t})});function us(e){const t=[];return Array.from(e.childNodes).forEach(o=>{if(o.nodeType===o.TEXT_NODE&&o.textContent&&t.push(o.textContent),Bl(o)){const r=o.ariaHidden||o.hidden||o.style.display==="none",s=o.dataset.radixToastAnnounceExclude==="";if(!r)if(s){const a=o.dataset.radixToastAnnounceAlt;a&&t.push(a)}else t.push(...us(o))}}),t}function st(e,t,n,{discrete:o}){const r=n.originalEvent.currentTarget,s=new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:n});t&&r.addEventListener(e,t,{once:!0}),o?to(r,s):r.dispatchEvent(s)}var Jn=(e,t,n=0)=>{const o=Math.abs(e.x),r=Math.abs(e.y),s=o>r;return t==="left"||t==="right"?s&&o>n:!s&&r>n};function Wl(e=()=>{}){const t=ee(e);z(()=>{let n=0,o=0;return n=window.requestAnimationFrame(()=>o=window.requestAnimationFrame(t)),()=>{window.cancelAnimationFrame(n),window.cancelAnimationFrame(o)}},[t])}function Bl(e){return e.nodeType===e.ELEMENT_NODE}function Vl(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:o=>{const r=o.tagName==="INPUT"&&o.type==="hidden";return o.disabled||o.hidden||r?NodeFilter.FILTER_SKIP:o.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function Ht(e){const t=document.activeElement;return e.some(n=>n===t?!0:(n.focus(),document.activeElement!==t))}var Cu=Jr,bu=ts,Eu=os,Su=rs,Tu=ss,Ru=as,Pu=Rn;export{ru as $,sr as A,ir as B,Ql as C,eu as D,cr as E,an as F,to as G,Kl as H,ou as I,su as J,pu as K,mu as L,iu as M,au as N,Zl as O,D as P,lu as Q,Xl as R,Ul as S,Jl as T,uu as U,cu as V,Yl as W,fu as X,du as Y,hu as Z,nu as _,eo as a,sl as a0,il as a1,wu as a2,xu as a3,vu as a4,gu as a5,yu as a6,bu as a7,Eu as a8,Ru as a9,Pu as aa,Su as ab,Tu as ac,Cu as ad,N as b,Oe as c,B as d,_s as e,ke as f,ee as g,ye as h,z as i,On as j,oo as k,ro as l,so as m,zl as n,ql as o,tu as p,Gl as q,$e as r,Ge as s,bt as t,Se as u,Co as v,cn as w,fo as x,Xe as y,ar as z}; diff --git a/webui/dist/assets/radix-extra-CTMrA3du.js b/webui/dist/assets/radix-extra-CTMrA3du.js new file mode 100644 index 00000000..083183b4 --- /dev/null +++ b/webui/dist/assets/radix-extra-CTMrA3du.js @@ -0,0 +1,12 @@ +import{r as s,j as u,d as jr}from"./router-9vIXuQkh.js";import{c as G,a as Be,u as Ce,P as E,b,d as T,e as de,f as re,g as B,h as $,i as ce,j as Ke,k as Ge,l as xt,m as Ct,n as wt,O as Or,o as Lr,W as Fr,C as kr,T as $r,D as Vr,p as Pt,R as Br,q as Kr,r as He,s as Rt,t as we,v as Et,w as _t,x as yt,F as At,y as Tt,z as Mt,A as It,B as Ue,E as Dt,G as Gr}from"./radix-core-BdJoVJLV.js";var Oe="rovingFocusGroup.onEntryFocus",Hr={bubbles:!1,cancelable:!0},fe="RovingFocusGroup",[Le,Nt,Ur]=Be(fe),[Wr,Pe]=G(fe,[Ur]),[zr,Yr]=Wr(fe),jt=s.forwardRef((e,t)=>u.jsx(Le.Provider,{scope:e.__scopeRovingFocusGroup,children:u.jsx(Le.Slot,{scope:e.__scopeRovingFocusGroup,children:u.jsx(Xr,{...e,ref:t})})}));jt.displayName=fe;var Xr=s.forwardRef((e,t)=>{const{__scopeRovingFocusGroup:o,orientation:r,loop:n=!1,dir:a,currentTabStopId:i,defaultCurrentTabStopId:c,onCurrentTabStopIdChange:l,onEntryFocus:p,preventScrollOnEntryFocus:f=!1,...d}=e,v=s.useRef(null),m=T(t,v),h=de(a),[x,g]=re({prop:i,defaultProp:c??null,onChange:l,caller:fe}),[S,R]=s.useState(!1),w=B(p),P=Nt(o),I=s.useRef(!1),[j,D]=s.useState(0);return s.useEffect(()=>{const M=v.current;if(M)return M.addEventListener(Oe,w),()=>M.removeEventListener(Oe,w)},[w]),u.jsx(zr,{scope:o,orientation:r,dir:h,loop:n,currentTabStopId:x,onItemFocus:s.useCallback(M=>g(M),[g]),onItemShiftTab:s.useCallback(()=>R(!0),[]),onFocusableItemAdd:s.useCallback(()=>D(M=>M+1),[]),onFocusableItemRemove:s.useCallback(()=>D(M=>M-1),[]),children:u.jsx(E.div,{tabIndex:S||j===0?-1:0,"data-orientation":r,...d,ref:m,style:{outline:"none",...e.style},onMouseDown:b(e.onMouseDown,()=>{I.current=!0}),onFocus:b(e.onFocus,M=>{const _=!I.current;if(M.target===M.currentTarget&&_&&!S){const A=new CustomEvent(Oe,Hr);if(M.currentTarget.dispatchEvent(A),!A.defaultPrevented){const y=P().filter(N=>N.focusable),O=y.find(N=>N.active),U=y.find(N=>N.id===x),X=[O,U,...y].filter(Boolean).map(N=>N.ref.current);Ft(X,f)}}I.current=!1}),onBlur:b(e.onBlur,()=>R(!1))})})}),Ot="RovingFocusGroupItem",Lt=s.forwardRef((e,t)=>{const{__scopeRovingFocusGroup:o,focusable:r=!0,active:n=!1,tabStopId:a,children:i,...c}=e,l=Ce(),p=a||l,f=Yr(Ot,o),d=f.currentTabStopId===p,v=Nt(o),{onFocusableItemAdd:m,onFocusableItemRemove:h,currentTabStopId:x}=f;return s.useEffect(()=>{if(r)return m(),()=>h()},[r,m,h]),u.jsx(Le.ItemSlot,{scope:o,id:p,focusable:r,active:n,children:u.jsx(E.span,{tabIndex:d?0:-1,"data-orientation":f.orientation,...c,ref:t,onMouseDown:b(e.onMouseDown,g=>{r?f.onItemFocus(p):g.preventDefault()}),onFocus:b(e.onFocus,()=>f.onItemFocus(p)),onKeyDown:b(e.onKeyDown,g=>{if(g.key==="Tab"&&g.shiftKey){f.onItemShiftTab();return}if(g.target!==g.currentTarget)return;const S=Jr(g,f.orientation,f.dir);if(S!==void 0){if(g.metaKey||g.ctrlKey||g.altKey||g.shiftKey)return;g.preventDefault();let w=v().filter(P=>P.focusable).map(P=>P.ref.current);if(S==="last")w.reverse();else if(S==="prev"||S==="next"){S==="prev"&&w.reverse();const P=w.indexOf(g.currentTarget);w=f.loop?Qr(w,P+1):w.slice(P+1)}setTimeout(()=>Ft(w))}}),children:typeof i=="function"?i({isCurrentTabStop:d,hasTabStop:x!=null}):i})})});Lt.displayName=Ot;var qr={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function Zr(e,t){return t!=="rtl"?e:e==="ArrowLeft"?"ArrowRight":e==="ArrowRight"?"ArrowLeft":e}function Jr(e,t,o){const r=Zr(e.key,o);if(!(t==="vertical"&&["ArrowLeft","ArrowRight"].includes(r))&&!(t==="horizontal"&&["ArrowUp","ArrowDown"].includes(r)))return qr[r]}function Ft(e,t=!1){const o=document.activeElement;for(const r of e)if(r===o||(r.focus({preventScroll:t}),document.activeElement!==o))return}function Qr(e,t){return e.map((o,r)=>e[(t+r)%e.length])}var kt=jt,$t=Lt,Re="Tabs",[en]=G(Re,[Pe]),Vt=Pe(),[tn,We]=en(Re),Bt=s.forwardRef((e,t)=>{const{__scopeTabs:o,value:r,onValueChange:n,defaultValue:a,orientation:i="horizontal",dir:c,activationMode:l="automatic",...p}=e,f=de(c),[d,v]=re({prop:r,onChange:n,defaultProp:a??"",caller:Re});return u.jsx(tn,{scope:o,baseId:Ce(),value:d,onValueChange:v,orientation:i,dir:f,activationMode:l,children:u.jsx(E.div,{dir:f,"data-orientation":i,...p,ref:t})})});Bt.displayName=Re;var Kt="TabsList",Gt=s.forwardRef((e,t)=>{const{__scopeTabs:o,loop:r=!0,...n}=e,a=We(Kt,o),i=Vt(o);return u.jsx(kt,{asChild:!0,...i,orientation:a.orientation,dir:a.dir,loop:r,children:u.jsx(E.div,{role:"tablist","aria-orientation":a.orientation,...n,ref:t})})});Gt.displayName=Kt;var Ht="TabsTrigger",Ut=s.forwardRef((e,t)=>{const{__scopeTabs:o,value:r,disabled:n=!1,...a}=e,i=We(Ht,o),c=Vt(o),l=Yt(i.baseId,r),p=Xt(i.baseId,r),f=r===i.value;return u.jsx($t,{asChild:!0,...c,focusable:!n,active:f,children:u.jsx(E.button,{type:"button",role:"tab","aria-selected":f,"aria-controls":p,"data-state":f?"active":"inactive","data-disabled":n?"":void 0,disabled:n,id:l,...a,ref:t,onMouseDown:b(e.onMouseDown,d=>{!n&&d.button===0&&d.ctrlKey===!1?i.onValueChange(r):d.preventDefault()}),onKeyDown:b(e.onKeyDown,d=>{[" ","Enter"].includes(d.key)&&i.onValueChange(r)}),onFocus:b(e.onFocus,()=>{const d=i.activationMode!=="manual";!f&&!n&&d&&i.onValueChange(r)})})})});Ut.displayName=Ht;var Wt="TabsContent",zt=s.forwardRef((e,t)=>{const{__scopeTabs:o,value:r,forceMount:n,children:a,...i}=e,c=We(Wt,o),l=Yt(c.baseId,r),p=Xt(c.baseId,r),f=r===c.value,d=s.useRef(f);return s.useEffect(()=>{const v=requestAnimationFrame(()=>d.current=!1);return()=>cancelAnimationFrame(v)},[]),u.jsx($,{present:n||f,children:({present:v})=>u.jsx(E.div,{"data-state":f?"active":"inactive","data-orientation":c.orientation,role:"tabpanel","aria-labelledby":l,hidden:!v,id:p,tabIndex:0,...i,ref:t,style:{...e.style,animationDuration:d.current?"0s":void 0},children:v&&a})})});zt.displayName=Wt;function Yt(e,t){return`${e}-trigger-${t}`}function Xt(e,t){return`${e}-content-${t}`}var hs=Bt,gs=Gt,Ss=Ut,bs=zt;function on(e,t){return s.useReducer((o,r)=>t[o][r]??o,e)}var ze="ScrollArea",[qt]=G(ze),[rn,V]=qt(ze),Zt=s.forwardRef((e,t)=>{const{__scopeScrollArea:o,type:r="hover",dir:n,scrollHideDelay:a=600,...i}=e,[c,l]=s.useState(null),[p,f]=s.useState(null),[d,v]=s.useState(null),[m,h]=s.useState(null),[x,g]=s.useState(null),[S,R]=s.useState(0),[w,P]=s.useState(0),[I,j]=s.useState(!1),[D,M]=s.useState(!1),_=T(t,y=>l(y)),A=de(n);return u.jsx(rn,{scope:o,type:r,dir:A,scrollHideDelay:a,scrollArea:c,viewport:p,onViewportChange:f,content:d,onContentChange:v,scrollbarX:m,onScrollbarXChange:h,scrollbarXEnabled:I,onScrollbarXEnabledChange:j,scrollbarY:x,onScrollbarYChange:g,scrollbarYEnabled:D,onScrollbarYEnabledChange:M,onCornerWidthChange:R,onCornerHeightChange:P,children:u.jsx(E.div,{dir:A,...i,ref:_,style:{position:"relative","--radix-scroll-area-corner-width":S+"px","--radix-scroll-area-corner-height":w+"px",...e.style}})})});Zt.displayName=ze;var Jt="ScrollAreaViewport",Qt=s.forwardRef((e,t)=>{const{__scopeScrollArea:o,children:r,nonce:n,...a}=e,i=V(Jt,o),c=s.useRef(null),l=T(t,c,i.onViewportChange);return u.jsxs(u.Fragment,{children:[u.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce:n}),u.jsx(E.div,{"data-radix-scroll-area-viewport":"",...a,ref:l,style:{overflowX:i.scrollbarXEnabled?"scroll":"hidden",overflowY:i.scrollbarYEnabled?"scroll":"hidden",...e.style},children:u.jsx("div",{ref:i.onContentChange,style:{minWidth:"100%",display:"table"},children:r})})]})});Qt.displayName=Jt;var K="ScrollAreaScrollbar",nn=s.forwardRef((e,t)=>{const{forceMount:o,...r}=e,n=V(K,e.__scopeScrollArea),{onScrollbarXEnabledChange:a,onScrollbarYEnabledChange:i}=n,c=e.orientation==="horizontal";return s.useEffect(()=>(c?a(!0):i(!0),()=>{c?a(!1):i(!1)}),[c,a,i]),n.type==="hover"?u.jsx(an,{...r,ref:t,forceMount:o}):n.type==="scroll"?u.jsx(sn,{...r,ref:t,forceMount:o}):n.type==="auto"?u.jsx(eo,{...r,ref:t,forceMount:o}):n.type==="always"?u.jsx(Ye,{...r,ref:t}):null});nn.displayName=K;var an=s.forwardRef((e,t)=>{const{forceMount:o,...r}=e,n=V(K,e.__scopeScrollArea),[a,i]=s.useState(!1);return s.useEffect(()=>{const c=n.scrollArea;let l=0;if(c){const p=()=>{window.clearTimeout(l),i(!0)},f=()=>{l=window.setTimeout(()=>i(!1),n.scrollHideDelay)};return c.addEventListener("pointerenter",p),c.addEventListener("pointerleave",f),()=>{window.clearTimeout(l),c.removeEventListener("pointerenter",p),c.removeEventListener("pointerleave",f)}}},[n.scrollArea,n.scrollHideDelay]),u.jsx($,{present:o||a,children:u.jsx(eo,{"data-state":a?"visible":"hidden",...r,ref:t})})}),sn=s.forwardRef((e,t)=>{const{forceMount:o,...r}=e,n=V(K,e.__scopeScrollArea),a=e.orientation==="horizontal",i=_e(()=>l("SCROLL_END"),100),[c,l]=on("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return s.useEffect(()=>{if(c==="idle"){const p=window.setTimeout(()=>l("HIDE"),n.scrollHideDelay);return()=>window.clearTimeout(p)}},[c,n.scrollHideDelay,l]),s.useEffect(()=>{const p=n.viewport,f=a?"scrollLeft":"scrollTop";if(p){let d=p[f];const v=()=>{const m=p[f];d!==m&&(l("SCROLL"),i()),d=m};return p.addEventListener("scroll",v),()=>p.removeEventListener("scroll",v)}},[n.viewport,a,l,i]),u.jsx($,{present:o||c!=="hidden",children:u.jsx(Ye,{"data-state":c==="hidden"?"hidden":"visible",...r,ref:t,onPointerEnter:b(e.onPointerEnter,()=>l("POINTER_ENTER")),onPointerLeave:b(e.onPointerLeave,()=>l("POINTER_LEAVE"))})})}),eo=s.forwardRef((e,t)=>{const o=V(K,e.__scopeScrollArea),{forceMount:r,...n}=e,[a,i]=s.useState(!1),c=e.orientation==="horizontal",l=_e(()=>{if(o.viewport){const p=o.viewport.offsetWidth{const{orientation:o="vertical",...r}=e,n=V(K,e.__scopeScrollArea),a=s.useRef(null),i=s.useRef(0),[c,l]=s.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),p=no(c.viewport,c.content),f={...r,sizes:c,onSizesChange:l,hasThumb:p>0&&p<1,onThumbChange:v=>a.current=v,onThumbPointerUp:()=>i.current=0,onThumbPointerDown:v=>i.current=v};function d(v,m){return vn(v,i.current,c,m)}return o==="horizontal"?u.jsx(cn,{...f,ref:t,onThumbPositionChange:()=>{if(n.viewport&&a.current){const v=n.viewport.scrollLeft,m=vt(v,c,n.dir);a.current.style.transform=`translate3d(${m}px, 0, 0)`}},onWheelScroll:v=>{n.viewport&&(n.viewport.scrollLeft=v)},onDragScroll:v=>{n.viewport&&(n.viewport.scrollLeft=d(v,n.dir))}}):o==="vertical"?u.jsx(ln,{...f,ref:t,onThumbPositionChange:()=>{if(n.viewport&&a.current){const v=n.viewport.scrollTop,m=vt(v,c);a.current.style.transform=`translate3d(0, ${m}px, 0)`}},onWheelScroll:v=>{n.viewport&&(n.viewport.scrollTop=v)},onDragScroll:v=>{n.viewport&&(n.viewport.scrollTop=d(v))}}):null}),cn=s.forwardRef((e,t)=>{const{sizes:o,onSizesChange:r,...n}=e,a=V(K,e.__scopeScrollArea),[i,c]=s.useState(),l=s.useRef(null),p=T(t,l,a.onScrollbarXChange);return s.useEffect(()=>{l.current&&c(getComputedStyle(l.current))},[l]),u.jsx(oo,{"data-orientation":"horizontal",...n,ref:p,sizes:o,style:{bottom:0,left:a.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:a.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":Ee(o)+"px",...e.style},onThumbPointerDown:f=>e.onThumbPointerDown(f.x),onDragScroll:f=>e.onDragScroll(f.x),onWheelScroll:(f,d)=>{if(a.viewport){const v=a.viewport.scrollLeft+f.deltaX;e.onWheelScroll(v),so(v,d)&&f.preventDefault()}},onResize:()=>{l.current&&a.viewport&&i&&r({content:a.viewport.scrollWidth,viewport:a.viewport.offsetWidth,scrollbar:{size:l.current.clientWidth,paddingStart:ge(i.paddingLeft),paddingEnd:ge(i.paddingRight)}})}})}),ln=s.forwardRef((e,t)=>{const{sizes:o,onSizesChange:r,...n}=e,a=V(K,e.__scopeScrollArea),[i,c]=s.useState(),l=s.useRef(null),p=T(t,l,a.onScrollbarYChange);return s.useEffect(()=>{l.current&&c(getComputedStyle(l.current))},[l]),u.jsx(oo,{"data-orientation":"vertical",...n,ref:p,sizes:o,style:{top:0,right:a.dir==="ltr"?0:void 0,left:a.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":Ee(o)+"px",...e.style},onThumbPointerDown:f=>e.onThumbPointerDown(f.y),onDragScroll:f=>e.onDragScroll(f.y),onWheelScroll:(f,d)=>{if(a.viewport){const v=a.viewport.scrollTop+f.deltaY;e.onWheelScroll(v),so(v,d)&&f.preventDefault()}},onResize:()=>{l.current&&a.viewport&&i&&r({content:a.viewport.scrollHeight,viewport:a.viewport.offsetHeight,scrollbar:{size:l.current.clientHeight,paddingStart:ge(i.paddingTop),paddingEnd:ge(i.paddingBottom)}})}})}),[un,to]=qt(K),oo=s.forwardRef((e,t)=>{const{__scopeScrollArea:o,sizes:r,hasThumb:n,onThumbChange:a,onThumbPointerUp:i,onThumbPointerDown:c,onThumbPositionChange:l,onDragScroll:p,onWheelScroll:f,onResize:d,...v}=e,m=V(K,o),[h,x]=s.useState(null),g=T(t,_=>x(_)),S=s.useRef(null),R=s.useRef(""),w=m.viewport,P=r.content-r.viewport,I=B(f),j=B(l),D=_e(d,10);function M(_){if(S.current){const A=_.clientX-S.current.left,y=_.clientY-S.current.top;p({x:A,y})}}return s.useEffect(()=>{const _=A=>{const y=A.target;h?.contains(y)&&I(A,P)};return document.addEventListener("wheel",_,{passive:!1}),()=>document.removeEventListener("wheel",_,{passive:!1})},[w,h,P,I]),s.useEffect(j,[r,j]),te(h,D),te(m.content,D),u.jsx(un,{scope:o,scrollbar:h,hasThumb:n,onThumbChange:B(a),onThumbPointerUp:B(i),onThumbPositionChange:j,onThumbPointerDown:B(c),children:u.jsx(E.div,{...v,ref:g,style:{position:"absolute",...v.style},onPointerDown:b(e.onPointerDown,_=>{_.button===0&&(_.target.setPointerCapture(_.pointerId),S.current=h.getBoundingClientRect(),R.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",m.viewport&&(m.viewport.style.scrollBehavior="auto"),M(_))}),onPointerMove:b(e.onPointerMove,M),onPointerUp:b(e.onPointerUp,_=>{const A=_.target;A.hasPointerCapture(_.pointerId)&&A.releasePointerCapture(_.pointerId),document.body.style.webkitUserSelect=R.current,m.viewport&&(m.viewport.style.scrollBehavior=""),S.current=null})})})}),he="ScrollAreaThumb",dn=s.forwardRef((e,t)=>{const{forceMount:o,...r}=e,n=to(he,e.__scopeScrollArea);return u.jsx($,{present:o||n.hasThumb,children:u.jsx(fn,{ref:t,...r})})}),fn=s.forwardRef((e,t)=>{const{__scopeScrollArea:o,style:r,...n}=e,a=V(he,o),i=to(he,o),{onThumbPositionChange:c}=i,l=T(t,d=>i.onThumbChange(d)),p=s.useRef(void 0),f=_e(()=>{p.current&&(p.current(),p.current=void 0)},100);return s.useEffect(()=>{const d=a.viewport;if(d){const v=()=>{if(f(),!p.current){const m=mn(d,c);p.current=m,c()}};return c(),d.addEventListener("scroll",v),()=>d.removeEventListener("scroll",v)}},[a.viewport,f,c]),u.jsx(E.div,{"data-state":i.hasThumb?"visible":"hidden",...n,ref:l,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...r},onPointerDownCapture:b(e.onPointerDownCapture,d=>{const m=d.target.getBoundingClientRect(),h=d.clientX-m.left,x=d.clientY-m.top;i.onThumbPointerDown({x:h,y:x})}),onPointerUp:b(e.onPointerUp,i.onThumbPointerUp)})});dn.displayName=he;var Xe="ScrollAreaCorner",ro=s.forwardRef((e,t)=>{const o=V(Xe,e.__scopeScrollArea),r=!!(o.scrollbarX&&o.scrollbarY);return o.type!=="scroll"&&r?u.jsx(pn,{...e,ref:t}):null});ro.displayName=Xe;var pn=s.forwardRef((e,t)=>{const{__scopeScrollArea:o,...r}=e,n=V(Xe,o),[a,i]=s.useState(0),[c,l]=s.useState(0),p=!!(a&&c);return te(n.scrollbarX,()=>{const f=n.scrollbarX?.offsetHeight||0;n.onCornerHeightChange(f),l(f)}),te(n.scrollbarY,()=>{const f=n.scrollbarY?.offsetWidth||0;n.onCornerWidthChange(f),i(f)}),p?u.jsx(E.div,{...r,ref:t,style:{width:a,height:c,position:"absolute",right:n.dir==="ltr"?0:void 0,left:n.dir==="rtl"?0:void 0,bottom:0,...e.style}}):null});function ge(e){return e?parseInt(e,10):0}function no(e,t){const o=e/t;return isNaN(o)?0:o}function Ee(e){const t=no(e.viewport,e.content),o=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,r=(e.scrollbar.size-o)*t;return Math.max(r,18)}function vn(e,t,o,r="ltr"){const n=Ee(o),a=n/2,i=t||a,c=n-i,l=o.scrollbar.paddingStart+i,p=o.scrollbar.size-o.scrollbar.paddingEnd-c,f=o.content-o.viewport,d=r==="ltr"?[0,f]:[f*-1,0];return ao([l,p],d)(e)}function vt(e,t,o="ltr"){const r=Ee(t),n=t.scrollbar.paddingStart+t.scrollbar.paddingEnd,a=t.scrollbar.size-n,i=t.content-t.viewport,c=a-r,l=o==="ltr"?[0,i]:[i*-1,0],p=Ke(e,l);return ao([0,i],[0,c])(p)}function ao(e,t){return o=>{if(e[0]===e[1]||t[0]===t[1])return t[0];const r=(t[1]-t[0])/(e[1]-e[0]);return t[0]+r*(o-e[0])}}function so(e,t){return e>0&&e{})=>{let o={left:e.scrollLeft,top:e.scrollTop},r=0;return(function n(){const a={left:e.scrollLeft,top:e.scrollTop},i=o.left!==a.left,c=o.top!==a.top;(i||c)&&t(),o=a,r=window.requestAnimationFrame(n)})(),()=>window.cancelAnimationFrame(r)};function _e(e,t){const o=B(e),r=s.useRef(0);return s.useEffect(()=>()=>window.clearTimeout(r.current),[]),s.useCallback(()=>{window.clearTimeout(r.current),r.current=window.setTimeout(o,t)},[o,t])}function te(e,t){const o=B(t);ce(()=>{let r=0;if(e){const n=new ResizeObserver(()=>{cancelAnimationFrame(r),r=window.requestAnimationFrame(o)});return n.observe(e),()=>{window.cancelAnimationFrame(r),n.unobserve(e)}}},[e,o])}var xs=Zt,Cs=Qt,ws=ro;function hn(e,t=[]){let o=[];function r(a,i){const c=s.createContext(i);c.displayName=a+"Context";const l=o.length;o=[...o,i];const p=d=>{const{scope:v,children:m,...h}=d,x=v?.[e]?.[l]||c,g=s.useMemo(()=>h,Object.values(h));return u.jsx(x.Provider,{value:g,children:m})};p.displayName=a+"Provider";function f(d,v){const m=v?.[e]?.[l]||c,h=s.useContext(m);if(h)return h;if(i!==void 0)return i;throw new Error(`\`${d}\` must be used within \`${a}\``)}return[p,f]}const n=()=>{const a=o.map(i=>s.createContext(i));return function(c){const l=c?.[e]||a;return s.useMemo(()=>({[`__scope${e}`]:{...c,[e]:l}}),[c,l])}};return n.scopeName=e,[r,gn(n,...t)]}function gn(...e){const t=e[0];if(e.length===1)return t;const o=()=>{const r=e.map(n=>({useScope:n(),scopeName:n.scopeName}));return function(a){const i=r.reduce((c,{useScope:l,scopeName:p})=>{const d=l(a)[`__scope${p}`];return{...c,...d}},{});return s.useMemo(()=>({[`__scope${t.scopeName}`]:i}),[i])}};return o.scopeName=t.scopeName,o}var Sn=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],io=Sn.reduce((e,t)=>{const o=Ge(`Primitive.${t}`),r=s.forwardRef((n,a)=>{const{asChild:i,...c}=n,l=i?o:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),u.jsx(l,{...c,ref:a})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{}),qe="Progress",Ze=100,[bn]=hn(qe),[xn,Cn]=bn(qe),co=s.forwardRef((e,t)=>{const{__scopeProgress:o,value:r=null,max:n,getValueLabel:a=wn,...i}=e;(n||n===0)&&!mt(n)&&console.error(Pn(`${n}`,"Progress"));const c=mt(n)?n:Ze;r!==null&&!ht(r,c)&&console.error(Rn(`${r}`,"Progress"));const l=ht(r,c)?r:null,p=Se(l)?a(l,c):void 0;return u.jsx(xn,{scope:o,value:l,max:c,children:u.jsx(io.div,{"aria-valuemax":c,"aria-valuemin":0,"aria-valuenow":Se(l)?l:void 0,"aria-valuetext":p,role:"progressbar","data-state":fo(l,c),"data-value":l??void 0,"data-max":c,...i,ref:t})})});co.displayName=qe;var lo="ProgressIndicator",uo=s.forwardRef((e,t)=>{const{__scopeProgress:o,...r}=e,n=Cn(lo,o);return u.jsx(io.div,{"data-state":fo(n.value,n.max),"data-value":n.value??void 0,"data-max":n.max,...r,ref:t})});uo.displayName=lo;function wn(e,t){return`${Math.round(e/t*100)}%`}function fo(e,t){return e==null?"indeterminate":e===t?"complete":"loading"}function Se(e){return typeof e=="number"}function mt(e){return Se(e)&&!isNaN(e)&&e>0}function ht(e,t){return Se(e)&&!isNaN(e)&&e<=t&&e>=0}function Pn(e,t){return`Invalid prop \`max\` of value \`${e}\` supplied to \`${t}\`. Only numbers greater than 0 are valid max values. Defaulting to \`${Ze}\`.`}function Rn(e,t){return`Invalid prop \`value\` of value \`${e}\` supplied to \`${t}\`. The \`value\` prop must be: + - a positive number + - less than the value passed to \`max\` (or ${Ze} if no \`max\` prop is set) + - \`null\` or \`undefined\` if the progress is indeterminate. + +Defaulting to \`null\`.`}var Ps=co,Rs=uo,ye="Switch",[En]=G(ye),[_n,yn]=En(ye),po=s.forwardRef((e,t)=>{const{__scopeSwitch:o,name:r,checked:n,defaultChecked:a,required:i,disabled:c,value:l="on",onCheckedChange:p,form:f,...d}=e,[v,m]=s.useState(null),h=T(t,w=>m(w)),x=s.useRef(!1),g=v?f||!!v.closest("form"):!0,[S,R]=re({prop:n,defaultProp:a??!1,onChange:p,caller:ye});return u.jsxs(_n,{scope:o,checked:S,disabled:c,children:[u.jsx(E.button,{type:"button",role:"switch","aria-checked":S,"aria-required":i,"data-state":go(S),"data-disabled":c?"":void 0,disabled:c,value:l,...d,ref:h,onClick:b(e.onClick,w=>{R(P=>!P),g&&(x.current=w.isPropagationStopped(),x.current||w.stopPropagation())})}),g&&u.jsx(ho,{control:v,bubbles:!x.current,name:r,value:l,checked:S,required:i,disabled:c,form:f,style:{transform:"translateX(-100%)"}})]})});po.displayName=ye;var vo="SwitchThumb",mo=s.forwardRef((e,t)=>{const{__scopeSwitch:o,...r}=e,n=yn(vo,o);return u.jsx(E.span,{"data-state":go(n.checked),"data-disabled":n.disabled?"":void 0,...r,ref:t})});mo.displayName=vo;var An="SwitchBubbleInput",ho=s.forwardRef(({__scopeSwitch:e,control:t,checked:o,bubbles:r=!0,...n},a)=>{const i=s.useRef(null),c=T(i,a),l=xt(o),p=Ct(t);return s.useEffect(()=>{const f=i.current;if(!f)return;const d=window.HTMLInputElement.prototype,m=Object.getOwnPropertyDescriptor(d,"checked").set;if(l!==o&&m){const h=new Event("click",{bubbles:r});m.call(f,o),f.dispatchEvent(h)}},[l,o,r]),u.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:o,...n,tabIndex:-1,ref:c,style:{...n.style,...p,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});ho.displayName=An;function go(e){return e?"checked":"unchecked"}var Es=po,_s=mo,So=["PageUp","PageDown"],bo=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],xo={"from-left":["Home","PageDown","ArrowDown","ArrowLeft"],"from-right":["Home","PageDown","ArrowDown","ArrowRight"],"from-bottom":["Home","PageDown","ArrowDown","ArrowLeft"],"from-top":["Home","PageDown","ArrowUp","ArrowLeft"]},ne="Slider",[Fe,Tn,Mn]=Be(ne),[Co]=G(ne,[Mn]),[In,Ae]=Co(ne),wo=s.forwardRef((e,t)=>{const{name:o,min:r=0,max:n=100,step:a=1,orientation:i="horizontal",disabled:c=!1,minStepsBetweenThumbs:l=0,defaultValue:p=[r],value:f,onValueChange:d=()=>{},onValueCommit:v=()=>{},inverted:m=!1,form:h,...x}=e,g=s.useRef(new Set),S=s.useRef(0),w=i==="horizontal"?Dn:Nn,[P=[],I]=re({prop:f,defaultProp:p,onChange:y=>{[...g.current][S.current]?.focus(),d(y)}}),j=s.useRef(P);function D(y){const O=kn(P,y);A(y,O)}function M(y){A(y,S.current)}function _(){const y=j.current[S.current];P[S.current]!==y&&v(P)}function A(y,O,{commit:U}={commit:!1}){const Y=Kn(a),X=Gn(Math.round((y-r)/a)*a+r,Y),N=Ke(X,[r,n]);I((W=[])=>{const L=Ln(W,N,O);if(Bn(L,l*a)){S.current=L.indexOf(N);const C=String(L)!==String(W);return C&&U&&v(L),C?L:W}else return W})}return u.jsx(In,{scope:e.__scopeSlider,name:o,disabled:c,min:r,max:n,valueIndexToChangeRef:S,thumbs:g.current,values:P,orientation:i,form:h,children:u.jsx(Fe.Provider,{scope:e.__scopeSlider,children:u.jsx(Fe.Slot,{scope:e.__scopeSlider,children:u.jsx(w,{"aria-disabled":c,"data-disabled":c?"":void 0,...x,ref:t,onPointerDown:b(x.onPointerDown,()=>{c||(j.current=P)}),min:r,max:n,inverted:m,onSlideStart:c?void 0:D,onSlideMove:c?void 0:M,onSlideEnd:c?void 0:_,onHomeKeyDown:()=>!c&&A(r,0,{commit:!0}),onEndKeyDown:()=>!c&&A(n,P.length-1,{commit:!0}),onStepKeyDown:({event:y,direction:O})=>{if(!c){const X=So.includes(y.key)||y.shiftKey&&bo.includes(y.key)?10:1,N=S.current,W=P[N],L=a*X*O;A(W+L,N,{commit:!0})}}})})})})});wo.displayName=ne;var[Po,Ro]=Co(ne,{startEdge:"left",endEdge:"right",size:"width",direction:1}),Dn=s.forwardRef((e,t)=>{const{min:o,max:r,dir:n,inverted:a,onSlideStart:i,onSlideMove:c,onSlideEnd:l,onStepKeyDown:p,...f}=e,[d,v]=s.useState(null),m=T(t,w=>v(w)),h=s.useRef(void 0),x=de(n),g=x==="ltr",S=g&&!a||!g&&a;function R(w){const P=h.current||d.getBoundingClientRect(),I=[0,P.width],D=Je(I,S?[o,r]:[r,o]);return h.current=P,D(w-P.left)}return u.jsx(Po,{scope:e.__scopeSlider,startEdge:S?"left":"right",endEdge:S?"right":"left",direction:S?1:-1,size:"width",children:u.jsx(Eo,{dir:x,"data-orientation":"horizontal",...f,ref:m,style:{...f.style,"--radix-slider-thumb-transform":"translateX(-50%)"},onSlideStart:w=>{const P=R(w.clientX);i?.(P)},onSlideMove:w=>{const P=R(w.clientX);c?.(P)},onSlideEnd:()=>{h.current=void 0,l?.()},onStepKeyDown:w=>{const I=xo[S?"from-left":"from-right"].includes(w.key);p?.({event:w,direction:I?-1:1})}})})}),Nn=s.forwardRef((e,t)=>{const{min:o,max:r,inverted:n,onSlideStart:a,onSlideMove:i,onSlideEnd:c,onStepKeyDown:l,...p}=e,f=s.useRef(null),d=T(t,f),v=s.useRef(void 0),m=!n;function h(x){const g=v.current||f.current.getBoundingClientRect(),S=[0,g.height],w=Je(S,m?[r,o]:[o,r]);return v.current=g,w(x-g.top)}return u.jsx(Po,{scope:e.__scopeSlider,startEdge:m?"bottom":"top",endEdge:m?"top":"bottom",size:"height",direction:m?1:-1,children:u.jsx(Eo,{"data-orientation":"vertical",...p,ref:d,style:{...p.style,"--radix-slider-thumb-transform":"translateY(50%)"},onSlideStart:x=>{const g=h(x.clientY);a?.(g)},onSlideMove:x=>{const g=h(x.clientY);i?.(g)},onSlideEnd:()=>{v.current=void 0,c?.()},onStepKeyDown:x=>{const S=xo[m?"from-bottom":"from-top"].includes(x.key);l?.({event:x,direction:S?-1:1})}})})}),Eo=s.forwardRef((e,t)=>{const{__scopeSlider:o,onSlideStart:r,onSlideMove:n,onSlideEnd:a,onHomeKeyDown:i,onEndKeyDown:c,onStepKeyDown:l,...p}=e,f=Ae(ne,o);return u.jsx(E.span,{...p,ref:t,onKeyDown:b(e.onKeyDown,d=>{d.key==="Home"?(i(d),d.preventDefault()):d.key==="End"?(c(d),d.preventDefault()):So.concat(bo).includes(d.key)&&(l(d),d.preventDefault())}),onPointerDown:b(e.onPointerDown,d=>{const v=d.target;v.setPointerCapture(d.pointerId),d.preventDefault(),f.thumbs.has(v)?v.focus():r(d)}),onPointerMove:b(e.onPointerMove,d=>{d.target.hasPointerCapture(d.pointerId)&&n(d)}),onPointerUp:b(e.onPointerUp,d=>{const v=d.target;v.hasPointerCapture(d.pointerId)&&(v.releasePointerCapture(d.pointerId),a(d))})})}),_o="SliderTrack",yo=s.forwardRef((e,t)=>{const{__scopeSlider:o,...r}=e,n=Ae(_o,o);return u.jsx(E.span,{"data-disabled":n.disabled?"":void 0,"data-orientation":n.orientation,...r,ref:t})});yo.displayName=_o;var ke="SliderRange",Ao=s.forwardRef((e,t)=>{const{__scopeSlider:o,...r}=e,n=Ae(ke,o),a=Ro(ke,o),i=s.useRef(null),c=T(t,i),l=n.values.length,p=n.values.map(v=>Io(v,n.min,n.max)),f=l>1?Math.min(...p):0,d=100-Math.max(...p);return u.jsx(E.span,{"data-orientation":n.orientation,"data-disabled":n.disabled?"":void 0,...r,ref:c,style:{...e.style,[a.startEdge]:f+"%",[a.endEdge]:d+"%"}})});Ao.displayName=ke;var $e="SliderThumb",To=s.forwardRef((e,t)=>{const o=Tn(e.__scopeSlider),[r,n]=s.useState(null),a=T(t,c=>n(c)),i=s.useMemo(()=>r?o().findIndex(c=>c.ref.current===r):-1,[o,r]);return u.jsx(jn,{...e,ref:a,index:i})}),jn=s.forwardRef((e,t)=>{const{__scopeSlider:o,index:r,name:n,...a}=e,i=Ae($e,o),c=Ro($e,o),[l,p]=s.useState(null),f=T(t,R=>p(R)),d=l?i.form||!!l.closest("form"):!0,v=Ct(l),m=i.values[r],h=m===void 0?0:Io(m,i.min,i.max),x=Fn(r,i.values.length),g=v?.[c.size],S=g?$n(g,h,c.direction):0;return s.useEffect(()=>{if(l)return i.thumbs.add(l),()=>{i.thumbs.delete(l)}},[l,i.thumbs]),u.jsxs("span",{style:{transform:"var(--radix-slider-thumb-transform)",position:"absolute",[c.startEdge]:`calc(${h}% + ${S}px)`},children:[u.jsx(Fe.ItemSlot,{scope:e.__scopeSlider,children:u.jsx(E.span,{role:"slider","aria-label":e["aria-label"]||x,"aria-valuemin":i.min,"aria-valuenow":m,"aria-valuemax":i.max,"aria-orientation":i.orientation,"data-orientation":i.orientation,"data-disabled":i.disabled?"":void 0,tabIndex:i.disabled?void 0:0,...a,ref:f,style:m===void 0?{display:"none"}:e.style,onFocus:b(e.onFocus,()=>{i.valueIndexToChangeRef.current=r})})}),d&&u.jsx(Mo,{name:n??(i.name?i.name+(i.values.length>1?"[]":""):void 0),form:i.form,value:m},r)]})});To.displayName=$e;var On="RadioBubbleInput",Mo=s.forwardRef(({__scopeSlider:e,value:t,...o},r)=>{const n=s.useRef(null),a=T(n,r),i=xt(t);return s.useEffect(()=>{const c=n.current;if(!c)return;const l=window.HTMLInputElement.prototype,f=Object.getOwnPropertyDescriptor(l,"value").set;if(i!==t&&f){const d=new Event("input",{bubbles:!0});f.call(c,t),c.dispatchEvent(d)}},[i,t]),u.jsx(E.input,{style:{display:"none"},...o,ref:a,defaultValue:t})});Mo.displayName=On;function Ln(e=[],t,o){const r=[...e];return r[o]=t,r.sort((n,a)=>n-a)}function Io(e,t,o){const a=100/(o-t)*(e-t);return Ke(a,[0,100])}function Fn(e,t){return t>2?`Value ${e+1} of ${t}`:t===2?["Minimum","Maximum"][e]:void 0}function kn(e,t){if(e.length===1)return 0;const o=e.map(n=>Math.abs(n-t)),r=Math.min(...o);return o.indexOf(r)}function $n(e,t,o){const r=e/2,a=Je([0,50],[0,r]);return(r-a(t)*o)*o}function Vn(e){return e.slice(0,-1).map((t,o)=>e[o+1]-t)}function Bn(e,t){if(t>0){const o=Vn(e);return Math.min(...o)>=t}return!0}function Je(e,t){return o=>{if(e[0]===e[1]||t[0]===t[1])return t[0];const r=(t[1]-t[0])/(e[1]-e[0]);return t[0]+r*(o-e[0])}}function Kn(e){return(String(e).split(".")[1]||"").length}function Gn(e,t){const o=Math.pow(10,t);return Math.round(e*o)/o}var ys=wo,As=yo,Ts=Ao,Ms=To,Hn=Symbol("radix.slottable");function Un(e){const t=({children:o})=>u.jsx(u.Fragment,{children:o});return t.displayName=`${e}.Slottable`,t.__radixId=Hn,t}var Do="AlertDialog",[Wn]=G(Do,[wt]),H=wt(),No=e=>{const{__scopeAlertDialog:t,...o}=e,r=H(t);return u.jsx(Br,{...r,...o,modal:!0})};No.displayName=Do;var zn="AlertDialogTrigger",jo=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,...r}=e,n=H(o);return u.jsx(Kr,{...n,...r,ref:t})});jo.displayName=zn;var Yn="AlertDialogPortal",Oo=e=>{const{__scopeAlertDialog:t,...o}=e,r=H(t);return u.jsx(Lr,{...r,...o})};Oo.displayName=Yn;var Xn="AlertDialogOverlay",Lo=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,...r}=e,n=H(o);return u.jsx(Or,{...n,...r,ref:t})});Lo.displayName=Xn;var ee="AlertDialogContent",[qn,Zn]=Wn(ee),Jn=Un("AlertDialogContent"),Fo=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,children:r,...n}=e,a=H(o),i=s.useRef(null),c=T(t,i),l=s.useRef(null);return u.jsx(Fr,{contentName:ee,titleName:ko,docsSlug:"alert-dialog",children:u.jsx(qn,{scope:o,cancelRef:l,children:u.jsxs(kr,{role:"alertdialog",...a,...n,ref:c,onOpenAutoFocus:b(n.onOpenAutoFocus,p=>{p.preventDefault(),l.current?.focus({preventScroll:!0})}),onPointerDownOutside:p=>p.preventDefault(),onInteractOutside:p=>p.preventDefault(),children:[u.jsx(Jn,{children:r}),u.jsx(ea,{contentRef:i})]})})})});Fo.displayName=ee;var ko="AlertDialogTitle",$o=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,...r}=e,n=H(o);return u.jsx($r,{...n,...r,ref:t})});$o.displayName=ko;var Vo="AlertDialogDescription",Bo=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,...r}=e,n=H(o);return u.jsx(Vr,{...n,...r,ref:t})});Bo.displayName=Vo;var Qn="AlertDialogAction",Ko=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,...r}=e,n=H(o);return u.jsx(Pt,{...n,...r,ref:t})});Ko.displayName=Qn;var Go="AlertDialogCancel",Ho=s.forwardRef((e,t)=>{const{__scopeAlertDialog:o,...r}=e,{cancelRef:n}=Zn(Go,o),a=H(o),i=T(t,n);return u.jsx(Pt,{...a,...r,ref:i})});Ho.displayName=Go;var ea=({contentRef:e})=>{const t=`\`${ee}\` requires a description for the component to be accessible for screen reader users. + +You can add a description to the \`${ee}\` by passing a \`${Vo}\` component as a child, which also benefits sighted users by adding visible context to the dialog. + +Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${ee}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component. + +For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;return s.useEffect(()=>{document.getElementById(e.current?.getAttribute("aria-describedby"))||console.warn(t)},[t,e]),null},Is=No,Ds=jo,Ns=Oo,js=Lo,Os=Fo,Ls=Ko,Fs=Ho,ks=$o,$s=Bo,ta=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],oa=ta.reduce((e,t)=>{const o=Ge(`Primitive.${t}`),r=s.forwardRef((n,a)=>{const{asChild:i,...c}=n,l=i?o:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),u.jsx(l,{...c,ref:a})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{}),ra="Separator",gt="horizontal",na=["horizontal","vertical"],Uo=s.forwardRef((e,t)=>{const{decorative:o,orientation:r=gt,...n}=e,a=aa(r)?r:gt,c=o?{role:"none"}:{"aria-orientation":a==="vertical"?a:void 0,role:"separator"};return u.jsx(oa.div,{"data-orientation":a,...c,...n,ref:t})});Uo.displayName=ra;function aa(e){return na.includes(e)}var Vs=Uo;function sa(e){const t=ia(e),o=s.forwardRef((r,n)=>{const{children:a,...i}=r,c=s.Children.toArray(a),l=c.find(la);if(l){const p=l.props.children,f=c.map(d=>d===l?s.Children.count(p)>1?s.Children.only(null):s.isValidElement(p)?p.props.children:null:d);return u.jsx(t,{...i,ref:n,children:s.isValidElement(p)?s.cloneElement(p,void 0,f):null})}return u.jsx(t,{...i,ref:n,children:a})});return o.displayName=`${e}.Slot`,o}function ia(e){const t=s.forwardRef((o,r)=>{const{children:n,...a}=o;if(s.isValidElement(n)){const i=da(n),c=ua(a,n.props);return n.type!==s.Fragment&&(c.ref=r?He(r,i):i),s.cloneElement(n,c)}return s.Children.count(n)>1?s.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var ca=Symbol("radix.slottable");function la(e){return s.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===ca}function ua(e,t){const o={...t};for(const r in t){const n=e[r],a=t[r];/^on[A-Z]/.test(r)?n&&a?o[r]=(...c)=>{const l=a(...c);return n(...c),l}:n&&(o[r]=n):r==="style"?o[r]={...n,...a}:r==="className"&&(o[r]=[n,a].filter(Boolean).join(" "))}return{...e,...o}}function da(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,o=t&&"isReactWarning"in t&&t.isReactWarning;return o?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,o=t&&"isReactWarning"in t&&t.isReactWarning,o?e.props.ref:e.props.ref||e.ref)}var Te="Popover",[Wo]=G(Te,[we]),pe=we(),[fa,z]=Wo(Te),zo=e=>{const{__scopePopover:t,children:o,open:r,defaultOpen:n,onOpenChange:a,modal:i=!1}=e,c=pe(t),l=s.useRef(null),[p,f]=s.useState(!1),[d,v]=re({prop:r,defaultProp:n??!1,onChange:a,caller:Te});return u.jsx(It,{...c,children:u.jsx(fa,{scope:t,contentId:Ce(),triggerRef:l,open:d,onOpenChange:v,onOpenToggle:s.useCallback(()=>v(m=>!m),[v]),hasCustomAnchor:p,onCustomAnchorAdd:s.useCallback(()=>f(!0),[]),onCustomAnchorRemove:s.useCallback(()=>f(!1),[]),modal:i,children:o})})};zo.displayName=Te;var Yo="PopoverAnchor",pa=s.forwardRef((e,t)=>{const{__scopePopover:o,...r}=e,n=z(Yo,o),a=pe(o),{onCustomAnchorAdd:i,onCustomAnchorRemove:c}=n;return s.useEffect(()=>(i(),()=>c()),[i,c]),u.jsx(Ue,{...a,...r,ref:t})});pa.displayName=Yo;var Xo="PopoverTrigger",qo=s.forwardRef((e,t)=>{const{__scopePopover:o,...r}=e,n=z(Xo,o),a=pe(o),i=T(t,n.triggerRef),c=u.jsx(E.button,{type:"button","aria-haspopup":"dialog","aria-expanded":n.open,"aria-controls":n.contentId,"data-state":tr(n.open),...r,ref:i,onClick:b(e.onClick,n.onOpenToggle)});return n.hasCustomAnchor?c:u.jsx(Ue,{asChild:!0,...a,children:c})});qo.displayName=Xo;var Qe="PopoverPortal",[va,ma]=Wo(Qe,{forceMount:void 0}),Zo=e=>{const{__scopePopover:t,forceMount:o,children:r,container:n}=e,a=z(Qe,t);return u.jsx(va,{scope:t,forceMount:o,children:u.jsx($,{present:o||a.open,children:u.jsx(Rt,{asChild:!0,container:n,children:r})})})};Zo.displayName=Qe;var oe="PopoverContent",Jo=s.forwardRef((e,t)=>{const o=ma(oe,e.__scopePopover),{forceMount:r=o.forceMount,...n}=e,a=z(oe,e.__scopePopover);return u.jsx($,{present:r||a.open,children:a.modal?u.jsx(ga,{...n,ref:t}):u.jsx(Sa,{...n,ref:t})})});Jo.displayName=oe;var ha=sa("PopoverContent.RemoveScroll"),ga=s.forwardRef((e,t)=>{const o=z(oe,e.__scopePopover),r=s.useRef(null),n=T(t,r),a=s.useRef(!1);return s.useEffect(()=>{const i=r.current;if(i)return Et(i)},[]),u.jsx(_t,{as:ha,allowPinchZoom:!0,children:u.jsx(Qo,{...e,ref:n,trapFocus:o.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:b(e.onCloseAutoFocus,i=>{i.preventDefault(),a.current||o.triggerRef.current?.focus()}),onPointerDownOutside:b(e.onPointerDownOutside,i=>{const c=i.detail.originalEvent,l=c.button===0&&c.ctrlKey===!0,p=c.button===2||l;a.current=p},{checkForDefaultPrevented:!1}),onFocusOutside:b(e.onFocusOutside,i=>i.preventDefault(),{checkForDefaultPrevented:!1})})})}),Sa=s.forwardRef((e,t)=>{const o=z(oe,e.__scopePopover),r=s.useRef(!1),n=s.useRef(!1);return u.jsx(Qo,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:a=>{e.onCloseAutoFocus?.(a),a.defaultPrevented||(r.current||o.triggerRef.current?.focus(),a.preventDefault()),r.current=!1,n.current=!1},onInteractOutside:a=>{e.onInteractOutside?.(a),a.defaultPrevented||(r.current=!0,a.detail.originalEvent.type==="pointerdown"&&(n.current=!0));const i=a.target;o.triggerRef.current?.contains(i)&&a.preventDefault(),a.detail.originalEvent.type==="focusin"&&n.current&&a.preventDefault()}})}),Qo=s.forwardRef((e,t)=>{const{__scopePopover:o,trapFocus:r,onOpenAutoFocus:n,onCloseAutoFocus:a,disableOutsidePointerEvents:i,onEscapeKeyDown:c,onPointerDownOutside:l,onFocusOutside:p,onInteractOutside:f,...d}=e,v=z(oe,o),m=pe(o);return yt(),u.jsx(At,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:n,onUnmountAutoFocus:a,children:u.jsx(Tt,{asChild:!0,disableOutsidePointerEvents:i,onInteractOutside:f,onEscapeKeyDown:c,onPointerDownOutside:l,onFocusOutside:p,onDismiss:()=>v.onOpenChange(!1),children:u.jsx(Mt,{"data-state":tr(v.open),role:"dialog",id:v.contentId,...m,...d,ref:t,style:{...d.style,"--radix-popover-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-popover-content-available-width":"var(--radix-popper-available-width)","--radix-popover-content-available-height":"var(--radix-popper-available-height)","--radix-popover-trigger-width":"var(--radix-popper-anchor-width)","--radix-popover-trigger-height":"var(--radix-popper-anchor-height)"}})})})}),er="PopoverClose",ba=s.forwardRef((e,t)=>{const{__scopePopover:o,...r}=e,n=z(er,o);return u.jsx(E.button,{type:"button",...r,ref:t,onClick:b(e.onClick,()=>n.onOpenChange(!1))})});ba.displayName=er;var xa="PopoverArrow",Ca=s.forwardRef((e,t)=>{const{__scopePopover:o,...r}=e,n=pe(o);return u.jsx(Dt,{...n,...r,ref:t})});Ca.displayName=xa;function tr(e){return e?"open":"closed"}var Bs=zo,Ks=qo,Gs=Zo,Hs=Jo,Me="Collapsible",[wa,Us]=G(Me),[Pa,et]=wa(Me),or=s.forwardRef((e,t)=>{const{__scopeCollapsible:o,open:r,defaultOpen:n,disabled:a,onOpenChange:i,...c}=e,[l,p]=re({prop:r,defaultProp:n??!1,onChange:i,caller:Me});return u.jsx(Pa,{scope:o,disabled:a,contentId:Ce(),open:l,onOpenToggle:s.useCallback(()=>p(f=>!f),[p]),children:u.jsx(E.div,{"data-state":ot(l),"data-disabled":a?"":void 0,...c,ref:t})})});or.displayName=Me;var rr="CollapsibleTrigger",nr=s.forwardRef((e,t)=>{const{__scopeCollapsible:o,...r}=e,n=et(rr,o);return u.jsx(E.button,{type:"button","aria-controls":n.contentId,"aria-expanded":n.open||!1,"data-state":ot(n.open),"data-disabled":n.disabled?"":void 0,disabled:n.disabled,...r,ref:t,onClick:b(e.onClick,n.onOpenToggle)})});nr.displayName=rr;var tt="CollapsibleContent",ar=s.forwardRef((e,t)=>{const{forceMount:o,...r}=e,n=et(tt,e.__scopeCollapsible);return u.jsx($,{present:o||n.open,children:({present:a})=>u.jsx(Ra,{...r,ref:t,present:a})})});ar.displayName=tt;var Ra=s.forwardRef((e,t)=>{const{__scopeCollapsible:o,present:r,children:n,...a}=e,i=et(tt,o),[c,l]=s.useState(r),p=s.useRef(null),f=T(t,p),d=s.useRef(0),v=d.current,m=s.useRef(0),h=m.current,x=i.open||c,g=s.useRef(x),S=s.useRef(void 0);return s.useEffect(()=>{const R=requestAnimationFrame(()=>g.current=!1);return()=>cancelAnimationFrame(R)},[]),ce(()=>{const R=p.current;if(R){S.current=S.current||{transitionDuration:R.style.transitionDuration,animationName:R.style.animationName},R.style.transitionDuration="0s",R.style.animationName="none";const w=R.getBoundingClientRect();d.current=w.height,m.current=w.width,g.current||(R.style.transitionDuration=S.current.transitionDuration,R.style.animationName=S.current.animationName),l(r)}},[i.open,r]),u.jsx(E.div,{"data-state":ot(i.open),"data-disabled":i.disabled?"":void 0,id:i.contentId,hidden:!x,...a,ref:f,style:{"--radix-collapsible-content-height":v?`${v}px`:void 0,"--radix-collapsible-content-width":h?`${h}px`:void 0,...e.style},children:x&&n})});function ot(e){return e?"open":"closed"}var Ws=or,zs=nr,Ys=ar;function Ea(e,t=[]){let o=[];function r(a,i){const c=s.createContext(i);c.displayName=a+"Context";const l=o.length;o=[...o,i];const p=d=>{const{scope:v,children:m,...h}=d,x=v?.[e]?.[l]||c,g=s.useMemo(()=>h,Object.values(h));return u.jsx(x.Provider,{value:g,children:m})};p.displayName=a+"Provider";function f(d,v){const m=v?.[e]?.[l]||c,h=s.useContext(m);if(h)return h;if(i!==void 0)return i;throw new Error(`\`${d}\` must be used within \`${a}\``)}return[p,f]}const n=()=>{const a=o.map(i=>s.createContext(i));return function(c){const l=c?.[e]||a;return s.useMemo(()=>({[`__scope${e}`]:{...c,[e]:l}}),[c,l])}};return n.scopeName=e,[r,_a(n,...t)]}function _a(...e){const t=e[0];if(e.length===1)return t;const o=()=>{const r=e.map(n=>({useScope:n(),scopeName:n.scopeName}));return function(a){const i=r.reduce((c,{useScope:l,scopeName:p})=>{const d=l(a)[`__scope${p}`];return{...c,...d}},{});return s.useMemo(()=>({[`__scope${t.scopeName}`]:i}),[i])}};return o.scopeName=t.scopeName,o}var ya=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],rt=ya.reduce((e,t)=>{const o=Ge(`Primitive.${t}`),r=s.forwardRef((n,a)=>{const{asChild:i,...c}=n,l=i?o:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),u.jsx(l,{...c,ref:a})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{}),Aa=jr();function Ta(){return Aa.useSyncExternalStore(Ma,()=>!0,()=>!1)}function Ma(){return()=>{}}var nt="Avatar",[Ia]=Ea(nt),[Da,sr]=Ia(nt),ir=s.forwardRef((e,t)=>{const{__scopeAvatar:o,...r}=e,[n,a]=s.useState("idle");return u.jsx(Da,{scope:o,imageLoadingStatus:n,onImageLoadingStatusChange:a,children:u.jsx(rt.span,{...r,ref:t})})});ir.displayName=nt;var cr="AvatarImage",lr=s.forwardRef((e,t)=>{const{__scopeAvatar:o,src:r,onLoadingStatusChange:n=()=>{},...a}=e,i=sr(cr,o),c=Na(r,a),l=B(p=>{n(p),i.onImageLoadingStatusChange(p)});return ce(()=>{c!=="idle"&&l(c)},[c,l]),c==="loaded"?u.jsx(rt.img,{...a,ref:t,src:r}):null});lr.displayName=cr;var ur="AvatarFallback",dr=s.forwardRef((e,t)=>{const{__scopeAvatar:o,delayMs:r,...n}=e,a=sr(ur,o),[i,c]=s.useState(r===void 0);return s.useEffect(()=>{if(r!==void 0){const l=window.setTimeout(()=>c(!0),r);return()=>window.clearTimeout(l)}},[r]),i&&a.imageLoadingStatus!=="loaded"?u.jsx(rt.span,{...n,ref:t}):null});dr.displayName=ur;function St(e,t){return e?t?(e.src!==t&&(e.src=t),e.complete&&e.naturalWidth>0?"loaded":"loading"):"error":"idle"}function Na(e,{referrerPolicy:t,crossOrigin:o}){const r=Ta(),n=s.useRef(null),a=r?(n.current||(n.current=new window.Image),n.current):null,[i,c]=s.useState(()=>St(a,e));return ce(()=>{c(St(a,e))},[a,e]),ce(()=>{const l=d=>()=>{c(d)};if(!a)return;const p=l("loaded"),f=l("error");return a.addEventListener("load",p),a.addEventListener("error",f),t&&(a.referrerPolicy=t),typeof o=="string"&&(a.crossOrigin=o),()=>{a.removeEventListener("load",p),a.removeEventListener("error",f)}},[a,o,t]),i}var Xs=ir,qs=lr,Zs=dr;function ja(e){const t=Oa(e),o=s.forwardRef((r,n)=>{const{children:a,...i}=r,c=s.Children.toArray(a),l=c.find(Fa);if(l){const p=l.props.children,f=c.map(d=>d===l?s.Children.count(p)>1?s.Children.only(null):s.isValidElement(p)?p.props.children:null:d);return u.jsx(t,{...i,ref:n,children:s.isValidElement(p)?s.cloneElement(p,void 0,f):null})}return u.jsx(t,{...i,ref:n,children:a})});return o.displayName=`${e}.Slot`,o}function Oa(e){const t=s.forwardRef((o,r)=>{const{children:n,...a}=o;if(s.isValidElement(n)){const i=$a(n),c=ka(a,n.props);return n.type!==s.Fragment&&(c.ref=r?He(r,i):i),s.cloneElement(n,c)}return s.Children.count(n)>1?s.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var La=Symbol("radix.slottable");function Fa(e){return s.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===La}function ka(e,t){const o={...t};for(const r in t){const n=e[r],a=t[r];/^on[A-Z]/.test(r)?n&&a?o[r]=(...c)=>{const l=a(...c);return n(...c),l}:n&&(o[r]=n):r==="style"?o[r]={...n,...a}:r==="className"&&(o[r]=[n,a].filter(Boolean).join(" "))}return{...e,...o}}function $a(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,o=t&&"isReactWarning"in t&&t.isReactWarning;return o?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,o=t&&"isReactWarning"in t&&t.isReactWarning,o?e.props.ref:e.props.ref||e.ref)}var Ve=["Enter"," "],Va=["ArrowDown","PageUp","Home"],fr=["ArrowUp","PageDown","End"],Ba=[...Va,...fr],Ka={ltr:[...Ve,"ArrowRight"],rtl:[...Ve,"ArrowLeft"]},Ga={ltr:["ArrowLeft"],rtl:["ArrowRight"]},ve="Menu",[le,Ha,Ua]=Be(ve),[Z,Js]=G(ve,[Ua,we,Pe]),Ie=we(),pr=Pe(),[Wa,J]=Z(ve),[za,me]=Z(ve),vr=e=>{const{__scopeMenu:t,open:o=!1,children:r,dir:n,onOpenChange:a,modal:i=!0}=e,c=Ie(t),[l,p]=s.useState(null),f=s.useRef(!1),d=B(a),v=de(n);return s.useEffect(()=>{const m=()=>{f.current=!0,document.addEventListener("pointerdown",h,{capture:!0,once:!0}),document.addEventListener("pointermove",h,{capture:!0,once:!0})},h=()=>f.current=!1;return document.addEventListener("keydown",m,{capture:!0}),()=>{document.removeEventListener("keydown",m,{capture:!0}),document.removeEventListener("pointerdown",h,{capture:!0}),document.removeEventListener("pointermove",h,{capture:!0})}},[]),u.jsx(It,{...c,children:u.jsx(Wa,{scope:t,open:o,onOpenChange:d,content:l,onContentChange:p,children:u.jsx(za,{scope:t,onClose:s.useCallback(()=>d(!1),[d]),isUsingKeyboardRef:f,dir:v,modal:i,children:r})})})};vr.displayName=ve;var Ya="MenuAnchor",at=s.forwardRef((e,t)=>{const{__scopeMenu:o,...r}=e,n=Ie(o);return u.jsx(Ue,{...n,...r,ref:t})});at.displayName=Ya;var st="MenuPortal",[Xa,mr]=Z(st,{forceMount:void 0}),hr=e=>{const{__scopeMenu:t,forceMount:o,children:r,container:n}=e,a=J(st,t);return u.jsx(Xa,{scope:t,forceMount:o,children:u.jsx($,{present:o||a.open,children:u.jsx(Rt,{asChild:!0,container:n,children:r})})})};hr.displayName=st;var k="MenuContent",[qa,it]=Z(k),gr=s.forwardRef((e,t)=>{const o=mr(k,e.__scopeMenu),{forceMount:r=o.forceMount,...n}=e,a=J(k,e.__scopeMenu),i=me(k,e.__scopeMenu);return u.jsx(le.Provider,{scope:e.__scopeMenu,children:u.jsx($,{present:r||a.open,children:u.jsx(le.Slot,{scope:e.__scopeMenu,children:i.modal?u.jsx(Za,{...n,ref:t}):u.jsx(Ja,{...n,ref:t})})})})}),Za=s.forwardRef((e,t)=>{const o=J(k,e.__scopeMenu),r=s.useRef(null),n=T(t,r);return s.useEffect(()=>{const a=r.current;if(a)return Et(a)},[]),u.jsx(ct,{...e,ref:n,trapFocus:o.open,disableOutsidePointerEvents:o.open,disableOutsideScroll:!0,onFocusOutside:b(e.onFocusOutside,a=>a.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:()=>o.onOpenChange(!1)})}),Ja=s.forwardRef((e,t)=>{const o=J(k,e.__scopeMenu);return u.jsx(ct,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:()=>o.onOpenChange(!1)})}),Qa=ja("MenuContent.ScrollLock"),ct=s.forwardRef((e,t)=>{const{__scopeMenu:o,loop:r=!1,trapFocus:n,onOpenAutoFocus:a,onCloseAutoFocus:i,disableOutsidePointerEvents:c,onEntryFocus:l,onEscapeKeyDown:p,onPointerDownOutside:f,onFocusOutside:d,onInteractOutside:v,onDismiss:m,disableOutsideScroll:h,...x}=e,g=J(k,o),S=me(k,o),R=Ie(o),w=pr(o),P=Ha(o),[I,j]=s.useState(null),D=s.useRef(null),M=T(t,D,g.onContentChange),_=s.useRef(0),A=s.useRef(""),y=s.useRef(0),O=s.useRef(null),U=s.useRef("right"),Y=s.useRef(0),X=h?_t:s.Fragment,N=h?{as:Qa,allowPinchZoom:!0}:void 0,W=C=>{const Q=A.current+C,q=P().filter(F=>!F.disabled),ae=document.activeElement,Ne=q.find(F=>F.ref.current===ae)?.textValue,je=q.map(F=>F.textValue),ft=ds(je,Q,Ne),se=q.find(F=>F.textValue===ft)?.ref.current;(function F(pt){A.current=pt,window.clearTimeout(_.current),pt!==""&&(_.current=window.setTimeout(()=>F(""),1e3))})(Q),se&&setTimeout(()=>se.focus())};s.useEffect(()=>()=>window.clearTimeout(_.current),[]),yt();const L=s.useCallback(C=>U.current===O.current?.side&&ps(C,O.current?.area),[]);return u.jsx(qa,{scope:o,searchRef:A,onItemEnter:s.useCallback(C=>{L(C)&&C.preventDefault()},[L]),onItemLeave:s.useCallback(C=>{L(C)||(D.current?.focus(),j(null))},[L]),onTriggerLeave:s.useCallback(C=>{L(C)&&C.preventDefault()},[L]),pointerGraceTimerRef:y,onPointerGraceIntentChange:s.useCallback(C=>{O.current=C},[]),children:u.jsx(X,{...N,children:u.jsx(At,{asChild:!0,trapped:n,onMountAutoFocus:b(a,C=>{C.preventDefault(),D.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:i,children:u.jsx(Tt,{asChild:!0,disableOutsidePointerEvents:c,onEscapeKeyDown:p,onPointerDownOutside:f,onFocusOutside:d,onInteractOutside:v,onDismiss:m,children:u.jsx(kt,{asChild:!0,...w,dir:S.dir,orientation:"vertical",loop:r,currentTabStopId:I,onCurrentTabStopIdChange:j,onEntryFocus:b(l,C=>{S.isUsingKeyboardRef.current||C.preventDefault()}),preventScrollOnEntryFocus:!0,children:u.jsx(Mt,{role:"menu","aria-orientation":"vertical","data-state":Nr(g.open),"data-radix-menu-content":"",dir:S.dir,...R,...x,ref:M,style:{outline:"none",...x.style},onKeyDown:b(x.onKeyDown,C=>{const q=C.target.closest("[data-radix-menu-content]")===C.currentTarget,ae=C.ctrlKey||C.altKey||C.metaKey,Ne=C.key.length===1;q&&(C.key==="Tab"&&C.preventDefault(),!ae&&Ne&&W(C.key));const je=D.current;if(C.target!==je||!Ba.includes(C.key))return;C.preventDefault();const se=P().filter(F=>!F.disabled).map(F=>F.ref.current);fr.includes(C.key)&&se.reverse(),ls(se)}),onBlur:b(e.onBlur,C=>{C.currentTarget.contains(C.target)||(window.clearTimeout(_.current),A.current="")}),onPointerMove:b(e.onPointerMove,ue(C=>{const Q=C.target,q=Y.current!==C.clientX;if(C.currentTarget.contains(Q)&&q){const ae=C.clientX>Y.current?"right":"left";U.current=ae,Y.current=C.clientX}}))})})})})})})});gr.displayName=k;var es="MenuGroup",lt=s.forwardRef((e,t)=>{const{__scopeMenu:o,...r}=e;return u.jsx(E.div,{role:"group",...r,ref:t})});lt.displayName=es;var ts="MenuLabel",Sr=s.forwardRef((e,t)=>{const{__scopeMenu:o,...r}=e;return u.jsx(E.div,{...r,ref:t})});Sr.displayName=ts;var be="MenuItem",bt="menu.itemSelect",De=s.forwardRef((e,t)=>{const{disabled:o=!1,onSelect:r,...n}=e,a=s.useRef(null),i=me(be,e.__scopeMenu),c=it(be,e.__scopeMenu),l=T(t,a),p=s.useRef(!1),f=()=>{const d=a.current;if(!o&&d){const v=new CustomEvent(bt,{bubbles:!0,cancelable:!0});d.addEventListener(bt,m=>r?.(m),{once:!0}),Gr(d,v),v.defaultPrevented?p.current=!1:i.onClose()}};return u.jsx(br,{...n,ref:l,disabled:o,onClick:b(e.onClick,f),onPointerDown:d=>{e.onPointerDown?.(d),p.current=!0},onPointerUp:b(e.onPointerUp,d=>{p.current||d.currentTarget?.click()}),onKeyDown:b(e.onKeyDown,d=>{const v=c.searchRef.current!=="";o||v&&d.key===" "||Ve.includes(d.key)&&(d.currentTarget.click(),d.preventDefault())})})});De.displayName=be;var br=s.forwardRef((e,t)=>{const{__scopeMenu:o,disabled:r=!1,textValue:n,...a}=e,i=it(be,o),c=pr(o),l=s.useRef(null),p=T(t,l),[f,d]=s.useState(!1),[v,m]=s.useState("");return s.useEffect(()=>{const h=l.current;h&&m((h.textContent??"").trim())},[a.children]),u.jsx(le.ItemSlot,{scope:o,disabled:r,textValue:n??v,children:u.jsx($t,{asChild:!0,...c,focusable:!r,children:u.jsx(E.div,{role:"menuitem","data-highlighted":f?"":void 0,"aria-disabled":r||void 0,"data-disabled":r?"":void 0,...a,ref:p,onPointerMove:b(e.onPointerMove,ue(h=>{r?i.onItemLeave(h):(i.onItemEnter(h),h.defaultPrevented||h.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:b(e.onPointerLeave,ue(h=>i.onItemLeave(h))),onFocus:b(e.onFocus,()=>d(!0)),onBlur:b(e.onBlur,()=>d(!1))})})})}),os="MenuCheckboxItem",xr=s.forwardRef((e,t)=>{const{checked:o=!1,onCheckedChange:r,...n}=e;return u.jsx(Er,{scope:e.__scopeMenu,checked:o,children:u.jsx(De,{role:"menuitemcheckbox","aria-checked":xe(o)?"mixed":o,...n,ref:t,"data-state":dt(o),onSelect:b(n.onSelect,()=>r?.(xe(o)?!0:!o),{checkForDefaultPrevented:!1})})})});xr.displayName=os;var Cr="MenuRadioGroup",[rs,ns]=Z(Cr,{value:void 0,onValueChange:()=>{}}),wr=s.forwardRef((e,t)=>{const{value:o,onValueChange:r,...n}=e,a=B(r);return u.jsx(rs,{scope:e.__scopeMenu,value:o,onValueChange:a,children:u.jsx(lt,{...n,ref:t})})});wr.displayName=Cr;var Pr="MenuRadioItem",Rr=s.forwardRef((e,t)=>{const{value:o,...r}=e,n=ns(Pr,e.__scopeMenu),a=o===n.value;return u.jsx(Er,{scope:e.__scopeMenu,checked:a,children:u.jsx(De,{role:"menuitemradio","aria-checked":a,...r,ref:t,"data-state":dt(a),onSelect:b(r.onSelect,()=>n.onValueChange?.(o),{checkForDefaultPrevented:!1})})})});Rr.displayName=Pr;var ut="MenuItemIndicator",[Er,as]=Z(ut,{checked:!1}),_r=s.forwardRef((e,t)=>{const{__scopeMenu:o,forceMount:r,...n}=e,a=as(ut,o);return u.jsx($,{present:r||xe(a.checked)||a.checked===!0,children:u.jsx(E.span,{...n,ref:t,"data-state":dt(a.checked)})})});_r.displayName=ut;var ss="MenuSeparator",yr=s.forwardRef((e,t)=>{const{__scopeMenu:o,...r}=e;return u.jsx(E.div,{role:"separator","aria-orientation":"horizontal",...r,ref:t})});yr.displayName=ss;var is="MenuArrow",Ar=s.forwardRef((e,t)=>{const{__scopeMenu:o,...r}=e,n=Ie(o);return u.jsx(Dt,{...n,...r,ref:t})});Ar.displayName=is;var cs="MenuSub",[Qs,Tr]=Z(cs),ie="MenuSubTrigger",Mr=s.forwardRef((e,t)=>{const o=J(ie,e.__scopeMenu),r=me(ie,e.__scopeMenu),n=Tr(ie,e.__scopeMenu),a=it(ie,e.__scopeMenu),i=s.useRef(null),{pointerGraceTimerRef:c,onPointerGraceIntentChange:l}=a,p={__scopeMenu:e.__scopeMenu},f=s.useCallback(()=>{i.current&&window.clearTimeout(i.current),i.current=null},[]);return s.useEffect(()=>f,[f]),s.useEffect(()=>{const d=c.current;return()=>{window.clearTimeout(d),l(null)}},[c,l]),u.jsx(at,{asChild:!0,...p,children:u.jsx(br,{id:n.triggerId,"aria-haspopup":"menu","aria-expanded":o.open,"aria-controls":n.contentId,"data-state":Nr(o.open),...e,ref:He(t,n.onTriggerChange),onClick:d=>{e.onClick?.(d),!(e.disabled||d.defaultPrevented)&&(d.currentTarget.focus(),o.open||o.onOpenChange(!0))},onPointerMove:b(e.onPointerMove,ue(d=>{a.onItemEnter(d),!d.defaultPrevented&&!e.disabled&&!o.open&&!i.current&&(a.onPointerGraceIntentChange(null),i.current=window.setTimeout(()=>{o.onOpenChange(!0),f()},100))})),onPointerLeave:b(e.onPointerLeave,ue(d=>{f();const v=o.content?.getBoundingClientRect();if(v){const m=o.content?.dataset.side,h=m==="right",x=h?-5:5,g=v[h?"left":"right"],S=v[h?"right":"left"];a.onPointerGraceIntentChange({area:[{x:d.clientX+x,y:d.clientY},{x:g,y:v.top},{x:S,y:v.top},{x:S,y:v.bottom},{x:g,y:v.bottom}],side:m}),window.clearTimeout(c.current),c.current=window.setTimeout(()=>a.onPointerGraceIntentChange(null),300)}else{if(a.onTriggerLeave(d),d.defaultPrevented)return;a.onPointerGraceIntentChange(null)}})),onKeyDown:b(e.onKeyDown,d=>{const v=a.searchRef.current!=="";e.disabled||v&&d.key===" "||Ka[r.dir].includes(d.key)&&(o.onOpenChange(!0),o.content?.focus(),d.preventDefault())})})})});Mr.displayName=ie;var Ir="MenuSubContent",Dr=s.forwardRef((e,t)=>{const o=mr(k,e.__scopeMenu),{forceMount:r=o.forceMount,...n}=e,a=J(k,e.__scopeMenu),i=me(k,e.__scopeMenu),c=Tr(Ir,e.__scopeMenu),l=s.useRef(null),p=T(t,l);return u.jsx(le.Provider,{scope:e.__scopeMenu,children:u.jsx($,{present:r||a.open,children:u.jsx(le.Slot,{scope:e.__scopeMenu,children:u.jsx(ct,{id:c.contentId,"aria-labelledby":c.triggerId,...n,ref:p,align:"start",side:i.dir==="rtl"?"left":"right",disableOutsidePointerEvents:!1,disableOutsideScroll:!1,trapFocus:!1,onOpenAutoFocus:f=>{i.isUsingKeyboardRef.current&&l.current?.focus(),f.preventDefault()},onCloseAutoFocus:f=>f.preventDefault(),onFocusOutside:b(e.onFocusOutside,f=>{f.target!==c.trigger&&a.onOpenChange(!1)}),onEscapeKeyDown:b(e.onEscapeKeyDown,f=>{i.onClose(),f.preventDefault()}),onKeyDown:b(e.onKeyDown,f=>{const d=f.currentTarget.contains(f.target),v=Ga[i.dir].includes(f.key);d&&v&&(a.onOpenChange(!1),c.trigger?.focus(),f.preventDefault())})})})})})});Dr.displayName=Ir;function Nr(e){return e?"open":"closed"}function xe(e){return e==="indeterminate"}function dt(e){return xe(e)?"indeterminate":e?"checked":"unchecked"}function ls(e){const t=document.activeElement;for(const o of e)if(o===t||(o.focus(),document.activeElement!==t))return}function us(e,t){return e.map((o,r)=>e[(t+r)%e.length])}function ds(e,t,o){const n=t.length>1&&Array.from(t).every(p=>p===t[0])?t[0]:t,a=o?e.indexOf(o):-1;let i=us(e,Math.max(a,0));n.length===1&&(i=i.filter(p=>p!==o));const l=i.find(p=>p.toLowerCase().startsWith(n.toLowerCase()));return l!==o?l:void 0}function fs(e,t){const{x:o,y:r}=e;let n=!1;for(let a=0,i=t.length-1;ar!=v>r&&o<(d-p)*(r-f)/(v-f)+p&&(n=!n)}return n}function ps(e,t){if(!t)return!1;const o={x:e.clientX,y:e.clientY};return fs(o,t)}function ue(e){return t=>t.pointerType==="mouse"?e(t):void 0}var ei=vr,ti=at,oi=hr,ri=gr,ni=lt,ai=Sr,si=De,ii=xr,ci=wr,li=Rr,ui=_r,di=yr,fi=Ar,pi=Mr,vi=Dr;export{ni as $,Ls as A,kt as B,bs as C,$s as D,$t as E,Zs as F,Js as G,pi as H,Rs as I,vi as J,oi as K,gs as L,ri as M,si as N,js as O,Ns as P,ii as Q,hs as R,nn as S,Ss as T,ui as U,Cs as V,li as W,ai as X,di as Y,ei as Z,ti as _,xs as a,ci as a0,fi as a1,Us as a2,zs as a3,Ys as a4,ws as b,dn as c,Ps as d,Es as e,_s as f,ys as g,As as h,Ts as i,Ms as j,Os as k,ks as l,Fs as m,Is as n,Ds as o,Vs as p,Gs as q,Hs as r,Bs as s,Ks as t,Ws as u,nr as v,ar as w,Xs as x,qs as y,Pe as z}; diff --git a/webui/dist/assets/react-vendor-Dtc2IqVY.js b/webui/dist/assets/react-vendor-BmxF9s7Q.js similarity index 98% rename from webui/dist/assets/react-vendor-Dtc2IqVY.js rename to webui/dist/assets/react-vendor-BmxF9s7Q.js index 087b3f14..97721520 100644 --- a/webui/dist/assets/react-vendor-Dtc2IqVY.js +++ b/webui/dist/assets/react-vendor-BmxF9s7Q.js @@ -1 +1 @@ -var ce=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ae(_){return _&&_.__esModule&&Object.prototype.hasOwnProperty.call(_,"default")?_.default:_}var $={exports:{}},P={};var W;function oe(){if(W)return P;W=1;var _=Symbol.for("react.transitional.element"),O=Symbol.for("react.fragment");function v(y,E,g){var R=null;if(g!==void 0&&(R=""+g),E.key!==void 0&&(R=""+E.key),"key"in E){g={};for(var m in E)m!=="key"&&(g[m]=E[m])}else g=E;return E=g.ref,{$$typeof:_,type:y,key:R,ref:E!==void 0?E:null,props:g}}return P.Fragment=O,P.jsx=v,P.jsxs=v,P}var X;function le(){return X||(X=1,$.exports=oe()),$.exports}var k={exports:{}},n={};var F;function ie(){if(F)return n;F=1;var _=Symbol.for("react.transitional.element"),O=Symbol.for("react.portal"),v=Symbol.for("react.fragment"),y=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),g=Symbol.for("react.consumer"),R=Symbol.for("react.context"),m=Symbol.for("react.forward_ref"),i=Symbol.for("react.suspense"),t=Symbol.for("react.memo"),c=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),h=Symbol.iterator;function w(e){return e===null||typeof e!="object"?null:(e=h&&e[h]||e["@@iterator"],typeof e=="function"?e:null)}var Y={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},U=Object.assign,q={};function C(e,r,o){this.props=e,this.context=r,this.refs=q,this.updater=o||Y}C.prototype.isReactComponent={},C.prototype.setState=function(e,r){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,r,"setState")},C.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function b(){}b.prototype=C.prototype;function N(e,r,o){this.props=e,this.context=r,this.refs=q,this.updater=o||Y}var j=N.prototype=new b;j.constructor=N,U(j,C.prototype),j.isPureReactComponent=!0;var G=Array.isArray;function D(){}var a={H:null,A:null,T:null,S:null},z=Object.prototype.hasOwnProperty;function L(e,r,o){var u=o.ref;return{$$typeof:_,type:e,key:r,ref:u!==void 0?u:null,props:o}}function V(e,r){return L(e.type,r,e.props)}function x(e){return typeof e=="object"&&e!==null&&e.$$typeof===_}function ee(e){var r={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(o){return r[o]})}var B=/\/+/g;function M(e,r){return typeof e=="object"&&e!==null&&e.key!=null?ee(""+e.key):r.toString(36)}function te(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch(typeof e.status=="string"?e.then(D,D):(e.status="pending",e.then(function(r){e.status==="pending"&&(e.status="fulfilled",e.value=r)},function(r){e.status==="pending"&&(e.status="rejected",e.reason=r)})),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}function A(e,r,o,u,s){var f=typeof e;(f==="undefined"||f==="boolean")&&(e=null);var l=!1;if(e===null)l=!0;else switch(f){case"bigint":case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case _:case O:l=!0;break;case c:return l=e._init,A(l(e._payload),r,o,u,s)}}if(l)return s=s(e),l=u===""?"."+M(e,0):u,G(s)?(o="",l!=null&&(o=l.replace(B,"$&/")+"/"),A(s,r,o,"",function(ue){return ue})):s!=null&&(x(s)&&(s=V(s,o+(s.key==null||e&&e.key===s.key?"":(""+s.key).replace(B,"$&/")+"/")+l)),r.push(s)),1;l=0;var T=u===""?".":u+":";if(G(e))for(var d=0;d"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(_)}catch(O){console.error(O)}}return _(),I.exports=fe(),I.exports}export{se as a,ye as b,ce as c,ae as g,le as r}; +var ce=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ae(_){return _&&_.__esModule&&Object.prototype.hasOwnProperty.call(_,"default")?_.default:_}var $={exports:{}},P={};var W;function oe(){if(W)return P;W=1;var _=Symbol.for("react.transitional.element"),O=Symbol.for("react.fragment");function v(y,E,g){var R=null;if(g!==void 0&&(R=""+g),E.key!==void 0&&(R=""+E.key),"key"in E){g={};for(var m in E)m!=="key"&&(g[m]=E[m])}else g=E;return E=g.ref,{$$typeof:_,type:y,key:R,ref:E!==void 0?E:null,props:g}}return P.Fragment=O,P.jsx=v,P.jsxs=v,P}var X;function le(){return X||(X=1,$.exports=oe()),$.exports}var k={exports:{}},n={};var F;function ie(){if(F)return n;F=1;var _=Symbol.for("react.transitional.element"),O=Symbol.for("react.portal"),v=Symbol.for("react.fragment"),y=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),g=Symbol.for("react.consumer"),R=Symbol.for("react.context"),m=Symbol.for("react.forward_ref"),i=Symbol.for("react.suspense"),t=Symbol.for("react.memo"),c=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),h=Symbol.iterator;function w(e){return e===null||typeof e!="object"?null:(e=h&&e[h]||e["@@iterator"],typeof e=="function"?e:null)}var Y={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},U=Object.assign,q={};function C(e,r,o){this.props=e,this.context=r,this.refs=q,this.updater=o||Y}C.prototype.isReactComponent={},C.prototype.setState=function(e,r){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,r,"setState")},C.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function b(){}b.prototype=C.prototype;function N(e,r,o){this.props=e,this.context=r,this.refs=q,this.updater=o||Y}var j=N.prototype=new b;j.constructor=N,U(j,C.prototype),j.isPureReactComponent=!0;var G=Array.isArray;function D(){}var a={H:null,A:null,T:null,S:null},z=Object.prototype.hasOwnProperty;function L(e,r,o){var u=o.ref;return{$$typeof:_,type:e,key:r,ref:u!==void 0?u:null,props:o}}function V(e,r){return L(e.type,r,e.props)}function x(e){return typeof e=="object"&&e!==null&&e.$$typeof===_}function ee(e){var r={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(o){return r[o]})}var B=/\/+/g;function M(e,r){return typeof e=="object"&&e!==null&&e.key!=null?ee(""+e.key):r.toString(36)}function te(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch(typeof e.status=="string"?e.then(D,D):(e.status="pending",e.then(function(r){e.status==="pending"&&(e.status="fulfilled",e.value=r)},function(r){e.status==="pending"&&(e.status="rejected",e.reason=r)})),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}function A(e,r,o,u,s){var f=typeof e;(f==="undefined"||f==="boolean")&&(e=null);var l=!1;if(e===null)l=!0;else switch(f){case"bigint":case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case _:case O:l=!0;break;case c:return l=e._init,A(l(e._payload),r,o,u,s)}}if(l)return s=s(e),l=u===""?"."+M(e,0):u,G(s)?(o="",l!=null&&(o=l.replace(B,"$&/")+"/"),A(s,r,o,"",function(ue){return ue})):s!=null&&(x(s)&&(s=V(s,o+(s.key==null||e&&e.key===s.key?"":(""+s.key).replace(B,"$&/")+"/")+l)),r.push(s)),1;l=0;var T=u===""?".":u+":";if(G(e))for(var d=0;d"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(_)}catch(O){console.error(O)}}return _(),I.exports=fe(),I.exports}export{se as a,ye as b,ce as c,ae as g,le as r}; diff --git a/webui/dist/assets/reactflow-DtsZHOR4.js b/webui/dist/assets/reactflow-DtsZHOR4.js new file mode 100644 index 00000000..dbf46732 --- /dev/null +++ b/webui/dist/assets/reactflow-DtsZHOR4.js @@ -0,0 +1,2 @@ +import{u as hm,R as L,r as k}from"./router-9vIXuQkh.js";import{i as pm,a as vc,b as vm,c as gc,d as gm,e as ym,f as mm}from"./charts-simvewUa.js";import{c as Xt}from"./react-vendor-BmxF9s7Q.js";var Ur,yc;function qe(){if(yc)return Ur;yc=1;function e(t){var r=typeof t;return t!=null&&(r=="object"||r=="function")}return Ur=e,Ur}var jr,mc;function gv(){if(mc)return jr;mc=1;var e=typeof Xt=="object"&&Xt&&Xt.Object===Object&&Xt;return jr=e,jr}var Kr,_c;function Me(){if(_c)return Kr;_c=1;var e=gv(),t=typeof self=="object"&&self&&self.Object===Object&&self,r=e||t||Function("return this")();return Kr=r,Kr}var Yr,bc;function _m(){if(bc)return Yr;bc=1;var e=Me(),t=function(){return e.Date.now()};return Yr=t,Yr}var Wr,wc;function bm(){if(wc)return Wr;wc=1;var e=/\s/;function t(r){for(var n=r.length;n--&&e.test(r.charAt(n)););return n}return Wr=t,Wr}var Zr,Ec;function wm(){if(Ec)return Zr;Ec=1;var e=bm(),t=/^\s+/;function r(n){return n&&n.slice(0,e(n)+1).replace(t,"")}return Zr=r,Zr}var Xr,xc;function Et(){if(xc)return Xr;xc=1;var e=Me(),t=e.Symbol;return Xr=t,Xr}var Jr,Sc;function Em(){if(Sc)return Jr;Sc=1;var e=Et(),t=Object.prototype,r=t.hasOwnProperty,n=t.toString,i=e?e.toStringTag:void 0;function a(o){var s=r.call(o,i),u=o[i];try{o[i]=void 0;var l=!0}catch{}var c=n.call(o);return l&&(s?o[i]=u:delete o[i]),c}return Jr=a,Jr}var Qr,qc;function xm(){if(qc)return Qr;qc=1;var e=Object.prototype,t=e.toString;function r(n){return t.call(n)}return Qr=r,Qr}var en,Rc;function st(){if(Rc)return en;Rc=1;var e=Et(),t=Em(),r=xm(),n="[object Null]",i="[object Undefined]",a=e?e.toStringTag:void 0;function o(s){return s==null?s===void 0?i:n:a&&a in Object(s)?t(s):r(s)}return en=o,en}var tn,Cc;function Le(){if(Cc)return tn;Cc=1;function e(t){return t!=null&&typeof t=="object"}return tn=e,tn}var rn,Ac;function xt(){if(Ac)return rn;Ac=1;var e=st(),t=Le(),r="[object Symbol]";function n(i){return typeof i=="symbol"||t(i)&&e(i)==r}return rn=n,rn}var nn,Nc;function Sm(){if(Nc)return nn;Nc=1;var e=wm(),t=qe(),r=xt(),n=NaN,i=/^[-+]0x[0-9a-f]+$/i,a=/^0b[01]+$/i,o=/^0o[0-7]+$/i,s=parseInt;function u(l){if(typeof l=="number")return l;if(r(l))return n;if(t(l)){var c=typeof l.valueOf=="function"?l.valueOf():l;l=t(c)?c+"":c}if(typeof l!="string")return l===0?l:+l;l=e(l);var f=a.test(l);return f||o.test(l)?s(l.slice(2),f?2:8):i.test(l)?n:+l}return nn=u,nn}function pe(e){if(typeof e=="string"||typeof e=="number")return""+e;let t="";if(Array.isArray(e))for(let r=0,n;r{let t;const r=new Set,n=(c,f)=>{const d=typeof c=="function"?c(t):c;if(!Object.is(d,t)){const h=t;t=f??(typeof d!="object"||d===null)?d:Object.assign({},t,d),r.forEach(_=>_(t,h))}},i=()=>t,u={setState:n,getState:i,getInitialState:()=>l,subscribe:c=>(r.add(c),()=>r.delete(c)),destroy:()=>{(qm?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),r.clear()}},l=t=e(n,i,u);return u},Rm=e=>e?Ic(e):Ic,{useDebugValue:Cm}=L,{useSyncExternalStoreWithSelector:Am}=hm,Nm=e=>e;function yv(e,t=Nm,r){const n=Am(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,r);return Cm(n),n}const Tc=(e,t)=>{const r=Rm(e),n=(i,a=t)=>yv(r,i,a);return Object.assign(n,r),n},Im=(e,t)=>e?Tc(e,t):Tc;function he(e,t){if(Object.is(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(const[n,i]of e)if(!Object.is(i,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}const r=Object.keys(e);if(r.length!==Object.keys(t).length)return!1;for(const n of r)if(!Object.prototype.hasOwnProperty.call(t,n)||!Object.is(e[n],t[n]))return!1;return!0}var Tm={value:()=>{}};function yr(){for(var e=0,t=arguments.length,r={},n;e=0&&(n=r.slice(i+1),r=r.slice(0,i)),r&&!t.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}ir.prototype=yr.prototype={constructor:ir,on:function(e,t){var r=this._,n=Mm(e+"",r),i,a=-1,o=n.length;if(arguments.length<2){for(;++a0)for(var r=new Array(i),n=0,i,a;n=0&&(t=e.slice(0,r))!=="xmlns"&&(e=e.slice(r+1)),Pc.hasOwnProperty(t)?{space:Pc[t],local:e}:e}function Om(e){return function(){var t=this.ownerDocument,r=this.namespaceURI;return r===mu&&t.documentElement.namespaceURI===mu?t.createElement(e):t.createElementNS(r,e)}}function km(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function mv(e){var t=mr(e);return(t.local?km:Om)(t)}function Dm(){}function Tu(e){return e==null?Dm:function(){return this.querySelector(e)}}function Lm(e){typeof e!="function"&&(e=Tu(e));for(var t=this._groups,r=t.length,n=new Array(r),i=0;i=b&&(b=y+1);!(E=v[b])&&++b<_;);m._next=E||null}}return o=new Ee(o,n),o._enter=s,o._exit=u,o}function n_(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function i_(){return new Ee(this._exit||this._groups.map(Ev),this._parents)}function a_(e,t,r){var n=this.enter(),i=this,a=this.exit();return typeof e=="function"?(n=e(n),n&&(n=n.selection())):n=n.append(e+""),t!=null&&(i=t(i),i&&(i=i.selection())),r==null?a.remove():r(a),n&&i?n.merge(i).order():i}function o_(e){for(var t=e.selection?e.selection():e,r=this._groups,n=t._groups,i=r.length,a=n.length,o=Math.min(i,a),s=new Array(i),u=0;u=0;)(o=n[i])&&(a&&o.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(o,a),a=o);return this}function u_(e){e||(e=c_);function t(f,d){return f&&d?e(f.__data__,d.__data__):!f-!d}for(var r=this._groups,n=r.length,i=new Array(n),a=0;at?1:e>=t?0:NaN}function l_(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function f_(){return Array.from(this)}function d_(){for(var e=this._groups,t=0,r=e.length;t1?this.each((t==null?x_:typeof t=="function"?q_:S_)(e,t,r??"")):_t(this.node(),e)}function _t(e,t){return e.style.getPropertyValue(t)||xv(e).getComputedStyle(e,null).getPropertyValue(t)}function C_(e){return function(){delete this[e]}}function A_(e,t){return function(){this[e]=t}}function N_(e,t){return function(){var r=t.apply(this,arguments);r==null?delete this[e]:this[e]=r}}function I_(e,t){return arguments.length>1?this.each((t==null?C_:typeof t=="function"?N_:A_)(e,t)):this.node()[e]}function Sv(e){return e.trim().split(/^|\s+/)}function Mu(e){return e.classList||new qv(e)}function qv(e){this._node=e,this._names=Sv(e.getAttribute("class")||"")}qv.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function Rv(e,t){for(var r=Mu(e),n=-1,i=t.length;++n=0&&(r=t.slice(n+1),t=t.slice(0,n)),{type:t,name:r}})}function ib(e){return function(){var t=this.__on;if(t){for(var r=0,n=-1,i=t.length,a;r()=>e;function _u(e,{sourceEvent:t,subject:r,target:n,identifier:i,active:a,x:o,y:s,dx:u,dy:l,dispatch:c}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:r,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},identifier:{value:i,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:s,enumerable:!0,configurable:!0},dx:{value:u,enumerable:!0,configurable:!0},dy:{value:l,enumerable:!0,configurable:!0},_:{value:c}})}_u.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function pb(e){return!e.ctrlKey&&!e.button}function vb(){return this.parentNode}function gb(e,t){return t??{x:e.x,y:e.y}}function yb(){return navigator.maxTouchPoints||"ontouchstart"in this}function mb(){var e=pb,t=vb,r=gb,n=yb,i={},a=yr("start","drag","end"),o=0,s,u,l,c,f=0;function d(m){m.on("mousedown.drag",h).filter(n).on("touchstart.drag",v).on("touchmove.drag",p,hb).on("touchend.drag touchcancel.drag",y).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function h(m,E){if(!(c||!e.call(this,m,E))){var x=b(this,t.call(this,m,E),m,E,"mouse");x&&(xe(m.view).on("mousemove.drag",_,zt).on("mouseup.drag",g,zt),Iv(m.view),an(m),l=!1,s=m.clientX,u=m.clientY,x("start",m))}}function _(m){if(yt(m),!l){var E=m.clientX-s,x=m.clientY-u;l=E*E+x*x>f}i.mouse("drag",m)}function g(m){xe(m.view).on("mousemove.drag mouseup.drag",null),Tv(m.view,l),yt(m),i.mouse("end",m)}function v(m,E){if(e.call(this,m,E)){var x=m.changedTouches,S=t.call(this,m,E),N=x.length,q,A;for(q=0;q=0&&e._call.call(void 0,t),e=e._next;--bt}function Oc(){at=(lr=Bt.now())+_r,bt=Pt=0;try{bb()}finally{bt=0,Eb(),at=0}}function wb(){var e=Bt.now(),t=e-lr;t>Mv&&(_r-=t,lr=e)}function Eb(){for(var e,t=cr,r,n=1/0;t;)t._call?(n>t._time&&(n=t._time),e=t,t=t._next):(r=t._next,t._next=null,t=e?e._next=r:cr=r);Ot=e,bu(n)}function bu(e){if(!bt){Pt&&(Pt=clearTimeout(Pt));var t=e-at;t>24?(e<1/0&&(Pt=setTimeout(Oc,e-Bt.now()-_r)),At&&(At=clearInterval(At))):(At||(lr=Bt.now(),At=setInterval(wb,Mv)),bt=1,Pv(Oc))}}function kc(e,t,r){var n=new fr;return t=t==null?0:+t,n.restart(i=>{n.stop(),e(i+t)},t,r),n}var xb=yr("start","end","cancel","interrupt"),Sb=[],kv=0,Dc=1,wu=2,ar=3,Lc=4,Eu=5,or=6;function br(e,t,r,n,i,a){var o=e.__transition;if(!o)e.__transition={};else if(r in o)return;qb(e,r,{name:t,index:n,group:i,on:xb,tween:Sb,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:kv})}function Ou(e,t){var r=Pe(e,t);if(r.state>kv)throw new Error("too late; already scheduled");return r}function Fe(e,t){var r=Pe(e,t);if(r.state>ar)throw new Error("too late; already running");return r}function Pe(e,t){var r=e.__transition;if(!r||!(r=r[t]))throw new Error("transition not found");return r}function qb(e,t,r){var n=e.__transition,i;n[t]=r,r.timer=Ov(a,0,r.time);function a(l){r.state=Dc,r.timer.restart(o,r.delay,r.time),r.delay<=l&&o(l-r.delay)}function o(l){var c,f,d,h;if(r.state!==Dc)return u();for(c in n)if(h=n[c],h.name===r.name){if(h.state===ar)return kc(o);h.state===Lc?(h.state=or,h.timer.stop(),h.on.call("interrupt",e,e.__data__,h.index,h.group),delete n[c]):+cwu&&n.state=0&&(t=t.slice(0,r)),!t||t==="start"})}function t0(e,t,r){var n,i,a=e0(t)?Ou:Fe;return function(){var o=a(this,e),s=o.on;s!==n&&(i=(n=s).copy()).on(t,r),o.on=i}}function r0(e,t){var r=this._id;return arguments.length<2?Pe(this.node(),r).on.on(e):this.each(t0(r,e,t))}function n0(e){return function(){var t=this.parentNode;for(var r in this.__transition)if(+r!==e)return;t&&t.removeChild(this)}}function i0(){return this.on("end.remove",n0(this._id))}function a0(e){var t=this._name,r=this._id;typeof e!="function"&&(e=Tu(e));for(var n=this._groups,i=n.length,a=new Array(i),o=0;o()=>e;function I0(e,{sourceEvent:t,target:r,transform:n,dispatch:i}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},transform:{value:n,enumerable:!0,configurable:!0},_:{value:i}})}function $e(e,t,r){this.k=e,this.x=t,this.y=r}$e.prototype={constructor:$e,scale:function(e){return e===1?this:new $e(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new $e(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Ge=new $e(1,0,0);$e.prototype;function on(e){e.stopImmediatePropagation()}function Nt(e){e.preventDefault(),e.stopImmediatePropagation()}function T0(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function M0(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function Fc(){return this.__zoom||Ge}function P0(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function O0(){return navigator.maxTouchPoints||"ontouchstart"in this}function k0(e,t,r){var n=e.invertX(t[0][0])-r[0][0],i=e.invertX(t[1][0])-r[1][0],a=e.invertY(t[0][1])-r[0][1],o=e.invertY(t[1][1])-r[1][1];return e.translate(i>n?(n+i)/2:Math.min(0,n)||Math.max(0,i),o>a?(a+o)/2:Math.min(0,a)||Math.max(0,o))}function zv(){var e=T0,t=M0,r=k0,n=P0,i=O0,a=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],s=250,u=mm,l=yr("start","zoom","end"),c,f,d,h=500,_=150,g=0,v=10;function p(w){w.property("__zoom",Fc).on("wheel.zoom",N,{passive:!1}).on("mousedown.zoom",q).on("dblclick.zoom",A).filter(i).on("touchstart.zoom",I).on("touchmove.zoom",D).on("touchend.zoom touchcancel.zoom",O).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}p.transform=function(w,T,C,z){var H=w.selection?w.selection():w;H.property("__zoom",Fc),w!==H?E(w,T,C,z):H.interrupt().each(function(){x(this,arguments).event(z).start().zoom(null,typeof T=="function"?T.apply(this,arguments):T).end()})},p.scaleBy=function(w,T,C,z){p.scaleTo(w,function(){var H=this.__zoom.k,M=typeof T=="function"?T.apply(this,arguments):T;return H*M},C,z)},p.scaleTo=function(w,T,C,z){p.transform(w,function(){var H=t.apply(this,arguments),M=this.__zoom,B=C==null?m(H):typeof C=="function"?C.apply(this,arguments):C,G=M.invert(B),V=typeof T=="function"?T.apply(this,arguments):T;return r(b(y(M,V),B,G),H,o)},C,z)},p.translateBy=function(w,T,C,z){p.transform(w,function(){return r(this.__zoom.translate(typeof T=="function"?T.apply(this,arguments):T,typeof C=="function"?C.apply(this,arguments):C),t.apply(this,arguments),o)},null,z)},p.translateTo=function(w,T,C,z,H){p.transform(w,function(){var M=t.apply(this,arguments),B=this.__zoom,G=z==null?m(M):typeof z=="function"?z.apply(this,arguments):z;return r(Ge.translate(G[0],G[1]).scale(B.k).translate(typeof T=="function"?-T.apply(this,arguments):-T,typeof C=="function"?-C.apply(this,arguments):-C),M,o)},z,H)};function y(w,T){return T=Math.max(a[0],Math.min(a[1],T)),T===w.k?w:new $e(T,w.x,w.y)}function b(w,T,C){var z=T[0]-C[0]*w.k,H=T[1]-C[1]*w.k;return z===w.x&&H===w.y?w:new $e(w.k,z,H)}function m(w){return[(+w[0][0]+ +w[1][0])/2,(+w[0][1]+ +w[1][1])/2]}function E(w,T,C,z){w.on("start.zoom",function(){x(this,arguments).event(z).start()}).on("interrupt.zoom end.zoom",function(){x(this,arguments).event(z).end()}).tween("zoom",function(){var H=this,M=arguments,B=x(H,M).event(z),G=t.apply(H,M),V=C==null?m(G):typeof C=="function"?C.apply(H,M):C,U=Math.max(G[1][0]-G[0][0],G[1][1]-G[0][1]),R=H.__zoom,P=typeof T=="function"?T.apply(H,M):T,F=u(R.invert(V).concat(U/R.k),P.invert(V).concat(U/P.k));return function($){if($===1)$=P;else{var j=F($),W=U/j[2];$=new $e(W,V[0]-j[0]*W,V[1]-j[1]*W)}B.zoom(null,$)}})}function x(w,T,C){return!C&&w.__zooming||new S(w,T)}function S(w,T){this.that=w,this.args=T,this.active=0,this.sourceEvent=null,this.extent=t.apply(w,T),this.taps=0}S.prototype={event:function(w){return w&&(this.sourceEvent=w),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(w,T){return this.mouse&&w!=="mouse"&&(this.mouse[1]=T.invert(this.mouse[0])),this.touch0&&w!=="touch"&&(this.touch0[1]=T.invert(this.touch0[0])),this.touch1&&w!=="touch"&&(this.touch1[1]=T.invert(this.touch1[0])),this.that.__zoom=T,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(w){var T=xe(this.that).datum();l.call(w,this.that,new I0(w,{sourceEvent:this.sourceEvent,target:p,transform:this.that.__zoom,dispatch:l}),T)}};function N(w,...T){if(!e.apply(this,arguments))return;var C=x(this,T).event(w),z=this.__zoom,H=Math.max(a[0],Math.min(a[1],z.k*Math.pow(2,n.apply(this,arguments)))),M=Ne(w);if(C.wheel)(C.mouse[0][0]!==M[0]||C.mouse[0][1]!==M[1])&&(C.mouse[1]=z.invert(C.mouse[0]=M)),clearTimeout(C.wheel);else{if(z.k===H)return;C.mouse=[M,z.invert(M)],sr(this),C.start()}Nt(w),C.wheel=setTimeout(B,_),C.zoom("mouse",r(b(y(z,H),C.mouse[0],C.mouse[1]),C.extent,o));function B(){C.wheel=null,C.end()}}function q(w,...T){if(d||!e.apply(this,arguments))return;var C=w.currentTarget,z=x(this,T,!0).event(w),H=xe(w.view).on("mousemove.zoom",V,!0).on("mouseup.zoom",U,!0),M=Ne(w,C),B=w.clientX,G=w.clientY;Iv(w.view),on(w),z.mouse=[M,this.__zoom.invert(M)],sr(this),z.start();function V(R){if(Nt(R),!z.moved){var P=R.clientX-B,F=R.clientY-G;z.moved=P*P+F*F>g}z.event(R).zoom("mouse",r(b(z.that.__zoom,z.mouse[0]=Ne(R,C),z.mouse[1]),z.extent,o))}function U(R){H.on("mousemove.zoom mouseup.zoom",null),Tv(R.view,z.moved),Nt(R),z.event(R).end()}}function A(w,...T){if(e.apply(this,arguments)){var C=this.__zoom,z=Ne(w.changedTouches?w.changedTouches[0]:w,this),H=C.invert(z),M=C.k*(w.shiftKey?.5:2),B=r(b(y(C,M),z,H),t.apply(this,T),o);Nt(w),s>0?xe(this).transition().duration(s).call(E,B,z,w):xe(this).call(p.transform,B,z,w)}}function I(w,...T){if(e.apply(this,arguments)){var C=w.touches,z=C.length,H=x(this,T,w.changedTouches.length===z).event(w),M,B,G,V;for(on(w),B=0;B"[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001",error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>"The React Flow parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,t)=>`Couldn't create edge for ${e?"target":"source"} handle id: "${e?t.targetHandle:t.sourceHandle}", edge id: ${t.id}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`},Bv=Ue.error001();function ne(e,t){const r=k.useContext(wr);if(r===null)throw new Error(Bv);return yv(r,e,t)}const fe=()=>{const e=k.useContext(wr);if(e===null)throw new Error(Bv);return k.useMemo(()=>({getState:e.getState,setState:e.setState,subscribe:e.subscribe,destroy:e.destroy}),[e])},L0=e=>e.userSelectionActive?"none":"all";function Du({position:e,children:t,className:r,style:n,...i}){const a=ne(L0),o=`${e}`.split("-");return L.createElement("div",{className:pe(["react-flow__panel",r,...o]),style:{...n,pointerEvents:a},...i},t)}function F0({proOptions:e,position:t="bottom-right"}){return e?.hideAttribution?null:L.createElement(Du,{position:t,className:"react-flow__attribution","data-message":"Please only hide this attribution when you are subscribed to React Flow Pro: https://reactflow.dev/pro"},L.createElement("a",{href:"https://reactflow.dev",target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution"},"React Flow"))}const z0=({x:e,y:t,label:r,labelStyle:n={},labelShowBg:i=!0,labelBgStyle:a={},labelBgPadding:o=[2,4],labelBgBorderRadius:s=2,children:u,className:l,...c})=>{const f=k.useRef(null),[d,h]=k.useState({x:0,y:0,width:0,height:0}),_=pe(["react-flow__edge-textwrapper",l]);return k.useEffect(()=>{if(f.current){const g=f.current.getBBox();h({x:g.x,y:g.y,width:g.width,height:g.height})}},[r]),typeof r>"u"||!r?null:L.createElement("g",{transform:`translate(${e-d.width/2} ${t-d.height/2})`,className:_,visibility:d.width?"visible":"hidden",...c},i&&L.createElement("rect",{width:d.width+2*o[0],x:-o[0],y:-o[1],height:d.height+2*o[1],className:"react-flow__edge-textbg",style:a,rx:s,ry:s}),L.createElement("text",{className:"react-flow__edge-text",y:d.height/2,dy:"0.3em",ref:f,style:n},r),u)};var B0=k.memo(z0);const Lu=e=>({width:e.offsetWidth,height:e.offsetHeight}),wt=(e,t=0,r=1)=>Math.min(Math.max(e,t),r),Fu=(e={x:0,y:0},t)=>({x:wt(e.x,t[0][0],t[1][0]),y:wt(e.y,t[0][1],t[1][1])}),zc=(e,t,r)=>er?-wt(Math.abs(e-r),1,50)/50:0,Hv=(e,t)=>{const r=zc(e.x,35,t.width-35)*20,n=zc(e.y,35,t.height-35)*20;return[r,n]},$v=e=>e.getRootNode?.()||window?.document,Gv=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),Ht=({x:e,y:t,width:r,height:n})=>({x:e,y:t,x2:e+r,y2:t+n}),Vv=({x:e,y:t,x2:r,y2:n})=>({x:e,y:t,width:r-e,height:n-t}),Bc=e=>({...e.positionAbsolute||{x:0,y:0},width:e.width||0,height:e.height||0}),H0=(e,t)=>Vv(Gv(Ht(e),Ht(t))),xu=(e,t)=>{const r=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),n=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(r*n)},$0=e=>Se(e.width)&&Se(e.height)&&Se(e.x)&&Se(e.y),Se=e=>!isNaN(e)&&isFinite(e),se=Symbol.for("internals"),Uv=["Enter"," ","Escape"],G0=(e,t)=>{},V0=e=>"nativeEvent"in e;function Su(e){const r=(V0(e)?e.nativeEvent:e).composedPath?.()?.[0]||e.target;return["INPUT","SELECT","TEXTAREA"].includes(r?.nodeName)||r?.hasAttribute("contenteditable")||!!r?.closest(".nokey")}const jv=e=>"clientX"in e,Je=(e,t)=>{const r=jv(e),n=r?e.clientX:e.touches?.[0].clientX,i=r?e.clientY:e.touches?.[0].clientY;return{x:n-(t?.left??0),y:i-(t?.top??0)}},dr=()=>typeof navigator<"u"&&navigator?.userAgent?.indexOf("Mac")>=0,Ut=({id:e,path:t,labelX:r,labelY:n,label:i,labelStyle:a,labelShowBg:o,labelBgStyle:s,labelBgPadding:u,labelBgBorderRadius:l,style:c,markerEnd:f,markerStart:d,interactionWidth:h=20})=>L.createElement(L.Fragment,null,L.createElement("path",{id:e,style:c,d:t,fill:"none",className:"react-flow__edge-path",markerEnd:f,markerStart:d}),h&&L.createElement("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:h,className:"react-flow__edge-interaction"}),i&&Se(r)&&Se(n)?L.createElement(B0,{x:r,y:n,label:i,labelStyle:a,labelShowBg:o,labelBgStyle:s,labelBgPadding:u,labelBgBorderRadius:l}):null);Ut.displayName="BaseEdge";function It(e,t,r){return r===void 0?r:n=>{const i=t().edges.find(a=>a.id===e);i&&r(n,{...i})}}function Kv({sourceX:e,sourceY:t,targetX:r,targetY:n}){const i=Math.abs(r-e)/2,a=r{const[v,p,y]=Wv({sourceX:e,sourceY:t,sourcePosition:i,targetX:r,targetY:n,targetPosition:a});return L.createElement(Ut,{path:v,labelX:p,labelY:y,label:o,labelStyle:s,labelShowBg:u,labelBgStyle:l,labelBgPadding:c,labelBgBorderRadius:f,style:d,markerEnd:h,markerStart:_,interactionWidth:g})});zu.displayName="SimpleBezierEdge";const $c={[J.Left]:{x:-1,y:0},[J.Right]:{x:1,y:0},[J.Top]:{x:0,y:-1},[J.Bottom]:{x:0,y:1}},U0=({source:e,sourcePosition:t=J.Bottom,target:r})=>t===J.Left||t===J.Right?e.xMath.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));function j0({source:e,sourcePosition:t=J.Bottom,target:r,targetPosition:n=J.Top,center:i,offset:a}){const o=$c[t],s=$c[n],u={x:e.x+o.x*a,y:e.y+o.y*a},l={x:r.x+s.x*a,y:r.y+s.y*a},c=U0({source:u,sourcePosition:t,target:l}),f=c.x!==0?"x":"y",d=c[f];let h=[],_,g;const v={x:0,y:0},p={x:0,y:0},[y,b,m,E]=Kv({sourceX:e.x,sourceY:e.y,targetX:r.x,targetY:r.y});if(o[f]*s[f]===-1){_=i.x??y,g=i.y??b;const S=[{x:_,y:u.y},{x:_,y:l.y}],N=[{x:u.x,y:g},{x:l.x,y:g}];o[f]===d?h=f==="x"?S:N:h=f==="x"?N:S}else{const S=[{x:u.x,y:l.y}],N=[{x:l.x,y:u.y}];if(f==="x"?h=o.x===d?N:S:h=o.y===d?S:N,t===n){const O=Math.abs(e[f]-r[f]);if(O<=a){const w=Math.min(a-1,a-O);o[f]===d?v[f]=(u[f]>e[f]?-1:1)*w:p[f]=(l[f]>r[f]?-1:1)*w}}if(t!==n){const O=f==="x"?"y":"x",w=o[f]===s[O],T=u[O]>l[O],C=u[O]=D?(_=(q.x+A.x)/2,g=h[0].y):(_=h[0].x,g=(q.y+A.y)/2)}return[[e,{x:u.x+v.x,y:u.y+v.y},...h,{x:l.x+p.x,y:l.y+p.y},r],_,g,m,E]}function K0(e,t,r,n){const i=Math.min(Gc(e,t)/2,Gc(t,r)/2,n),{x:a,y:o}=t;if(e.x===a&&a===r.x||e.y===o&&o===r.y)return`L${a} ${o}`;if(e.y===o){const l=e.x{let b="";return y>0&&y{const[p,y,b]=qu({sourceX:e,sourceY:t,sourcePosition:f,targetX:r,targetY:n,targetPosition:d,borderRadius:g?.borderRadius,offset:g?.offset});return L.createElement(Ut,{path:p,labelX:y,labelY:b,label:i,labelStyle:a,labelShowBg:o,labelBgStyle:s,labelBgPadding:u,labelBgBorderRadius:l,style:c,markerEnd:h,markerStart:_,interactionWidth:v})});Er.displayName="SmoothStepEdge";const Bu=k.memo(e=>L.createElement(Er,{...e,pathOptions:k.useMemo(()=>({borderRadius:0,offset:e.pathOptions?.offset}),[e.pathOptions?.offset])}));Bu.displayName="StepEdge";function Y0({sourceX:e,sourceY:t,targetX:r,targetY:n}){const[i,a,o,s]=Kv({sourceX:e,sourceY:t,targetX:r,targetY:n});return[`M ${e},${t}L ${r},${n}`,i,a,o,s]}const Hu=k.memo(({sourceX:e,sourceY:t,targetX:r,targetY:n,label:i,labelStyle:a,labelShowBg:o,labelBgStyle:s,labelBgPadding:u,labelBgBorderRadius:l,style:c,markerEnd:f,markerStart:d,interactionWidth:h})=>{const[_,g,v]=Y0({sourceX:e,sourceY:t,targetX:r,targetY:n});return L.createElement(Ut,{path:_,labelX:g,labelY:v,label:i,labelStyle:a,labelShowBg:o,labelBgStyle:s,labelBgPadding:u,labelBgBorderRadius:l,style:c,markerEnd:f,markerStart:d,interactionWidth:h})});Hu.displayName="StraightEdge";function er(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function Vc({pos:e,x1:t,y1:r,x2:n,y2:i,c:a}){switch(e){case J.Left:return[t-er(t-n,a),r];case J.Right:return[t+er(n-t,a),r];case J.Top:return[t,r-er(r-i,a)];case J.Bottom:return[t,r+er(i-r,a)]}}function Zv({sourceX:e,sourceY:t,sourcePosition:r=J.Bottom,targetX:n,targetY:i,targetPosition:a=J.Top,curvature:o=.25}){const[s,u]=Vc({pos:r,x1:e,y1:t,x2:n,y2:i,c:o}),[l,c]=Vc({pos:a,x1:n,y1:i,x2:e,y2:t,c:o}),[f,d,h,_]=Yv({sourceX:e,sourceY:t,targetX:n,targetY:i,sourceControlX:s,sourceControlY:u,targetControlX:l,targetControlY:c});return[`M${e},${t} C${s},${u} ${l},${c} ${n},${i}`,f,d,h,_]}const pr=k.memo(({sourceX:e,sourceY:t,targetX:r,targetY:n,sourcePosition:i=J.Bottom,targetPosition:a=J.Top,label:o,labelStyle:s,labelShowBg:u,labelBgStyle:l,labelBgPadding:c,labelBgBorderRadius:f,style:d,markerEnd:h,markerStart:_,pathOptions:g,interactionWidth:v})=>{const[p,y,b]=Zv({sourceX:e,sourceY:t,sourcePosition:i,targetX:r,targetY:n,targetPosition:a,curvature:g?.curvature});return L.createElement(Ut,{path:p,labelX:y,labelY:b,label:o,labelStyle:s,labelShowBg:u,labelBgStyle:l,labelBgPadding:c,labelBgBorderRadius:f,style:d,markerEnd:h,markerStart:_,interactionWidth:v})});pr.displayName="BezierEdge";const $u=k.createContext(null),W0=$u.Provider;$u.Consumer;const Z0=()=>k.useContext($u),X0=e=>"id"in e&&"source"in e&&"target"in e,J0=({source:e,sourceHandle:t,target:r,targetHandle:n})=>`reactflow__edge-${e}${t||""}-${r}${n||""}`,Ru=(e,t)=>typeof e>"u"?"":typeof e=="string"?e:`${t?`${t}__`:""}${Object.keys(e).sort().map(n=>`${n}=${e[n]}`).join("&")}`,Q0=(e,t)=>t.some(r=>r.source===e.source&&r.target===e.target&&(r.sourceHandle===e.sourceHandle||!r.sourceHandle&&!e.sourceHandle)&&(r.targetHandle===e.targetHandle||!r.targetHandle&&!e.targetHandle)),ew=(e,t)=>{if(!e.source||!e.target)return t;let r;return X0(e)?r={...e}:r={...e,id:J0(e)},Q0(r,t)?t:t.concat(r)},Cu=({x:e,y:t},[r,n,i],a,[o,s])=>{const u={x:(e-r)/i,y:(t-n)/i};return a?{x:o*Math.round(u.x/o),y:s*Math.round(u.y/s)}:u},Xv=({x:e,y:t},[r,n,i])=>({x:e*i+r,y:t*i+n}),it=(e,t=[0,0])=>{if(!e)return{x:0,y:0,positionAbsolute:{x:0,y:0}};const r=(e.width??0)*t[0],n=(e.height??0)*t[1],i={x:e.position.x-r,y:e.position.y-n};return{...i,positionAbsolute:e.positionAbsolute?{x:e.positionAbsolute.x-r,y:e.positionAbsolute.y-n}:i}},xr=(e,t=[0,0])=>{if(e.length===0)return{x:0,y:0,width:0,height:0};const r=e.reduce((n,i)=>{const{x:a,y:o}=it(i,t).positionAbsolute;return Gv(n,Ht({x:a,y:o,width:i.width||0,height:i.height||0}))},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return Vv(r)},Jv=(e,t,[r,n,i]=[0,0,1],a=!1,o=!1,s=[0,0])=>{const u={x:(t.x-r)/i,y:(t.y-n)/i,width:t.width/i,height:t.height/i},l=[];return e.forEach(c=>{const{width:f,height:d,selectable:h=!0,hidden:_=!1}=c;if(o&&!h||_)return!1;const{positionAbsolute:g}=it(c,s),v={x:g.x,y:g.y,width:f||0,height:d||0},p=xu(u,v),y=typeof f>"u"||typeof d>"u"||f===null||d===null,b=a&&p>0,m=(f||0)*(d||0);(y||b||p>=m||c.dragging)&&l.push(c)}),l},Qv=(e,t)=>{const r=e.map(n=>n.id);return t.filter(n=>r.includes(n.source)||r.includes(n.target))},eg=(e,t,r,n,i,a=.1)=>{const o=t/(e.width*(1+a)),s=r/(e.height*(1+a)),u=Math.min(o,s),l=wt(u,n,i),c=e.x+e.width/2,f=e.y+e.height/2,d=t/2-c*l,h=r/2-f*l;return{x:d,y:h,zoom:l}},rt=(e,t=0)=>e.transition().duration(t);function Uc(e,t,r,n){return(t[r]||[]).reduce((i,a)=>(`${e.id}-${a.id}-${r}`!==n&&i.push({id:a.id||null,type:r,nodeId:e.id,x:(e.positionAbsolute?.x??0)+a.x+a.width/2,y:(e.positionAbsolute?.y??0)+a.y+a.height/2}),i),[])}function tw(e,t,r,n,i,a){const{x:o,y:s}=Je(e),l=t.elementsFromPoint(o,s).find(_=>_.classList.contains("react-flow__handle"));if(l){const _=l.getAttribute("data-nodeid");if(_){const g=Gu(void 0,l),v=l.getAttribute("data-handleid"),p=a({nodeId:_,id:v,type:g});if(p){const y=i.find(b=>b.nodeId===_&&b.type===g&&b.id===v);return{handle:{id:v,type:g,nodeId:_,x:y?.x||r.x,y:y?.y||r.y},validHandleResult:p}}}}let c=[],f=1/0;if(i.forEach(_=>{const g=Math.sqrt((_.x-r.x)**2+(_.y-r.y)**2);if(g<=n){const v=a(_);g<=f&&(g_.isValid),h=c.some(({handle:_})=>_.type==="target");return c.find(({handle:_,validHandleResult:g})=>h?_.type==="target":d?g.isValid:!0)||c[0]}const rw={source:null,target:null,sourceHandle:null,targetHandle:null},tg=()=>({handleDomNode:null,isValid:!1,connection:rw,endHandle:null});function rg(e,t,r,n,i,a,o){const s=i==="target",u=o.querySelector(`.react-flow__handle[data-id="${e?.nodeId}-${e?.id}-${e?.type}"]`),l={...tg(),handleDomNode:u};if(u){const c=Gu(void 0,u),f=u.getAttribute("data-nodeid"),d=u.getAttribute("data-handleid"),h=u.classList.contains("connectable"),_=u.classList.contains("connectableend"),g={source:s?f:r,sourceHandle:s?d:n,target:s?r:f,targetHandle:s?n:d};l.connection=g,h&&_&&(t===ot.Strict?s&&c==="source"||!s&&c==="target":f!==r||d!==n)&&(l.endHandle={nodeId:f,handleId:d,type:c},l.isValid=a(g))}return l}function nw({nodes:e,nodeId:t,handleId:r,handleType:n}){return e.reduce((i,a)=>{if(a[se]){const{handleBounds:o}=a[se];let s=[],u=[];o&&(s=Uc(a,o,"source",`${t}-${r}-${n}`),u=Uc(a,o,"target",`${t}-${r}-${n}`)),i.push(...s,...u)}return i},[])}function Gu(e,t){return e||(t?.classList.contains("target")?"target":t?.classList.contains("source")?"source":null)}function sn(e){e?.classList.remove("valid","connecting","react-flow__handle-valid","react-flow__handle-connecting")}function iw(e,t){let r=null;return t?r="valid":e&&!t&&(r="invalid"),r}function ng({event:e,handleId:t,nodeId:r,onConnect:n,isTarget:i,getState:a,setState:o,isValidConnection:s,edgeUpdaterType:u,onReconnectEnd:l}){const c=$v(e.target),{connectionMode:f,domNode:d,autoPanOnConnect:h,connectionRadius:_,onConnectStart:g,panBy:v,getNodes:p,cancelConnection:y}=a();let b=0,m;const{x:E,y:x}=Je(e),S=c?.elementFromPoint(E,x),N=Gu(u,S),q=d?.getBoundingClientRect();if(!q||!N)return;let A,I=Je(e,q),D=!1,O=null,w=!1,T=null;const C=nw({nodes:p(),nodeId:r,handleId:t,handleType:N}),z=()=>{if(!h)return;const[B,G]=Hv(I,q);v({x:B,y:G}),b=requestAnimationFrame(z)};o({connectionPosition:I,connectionStatus:null,connectionNodeId:r,connectionHandleId:t,connectionHandleType:N,connectionStartHandle:{nodeId:r,handleId:t,type:N},connectionEndHandle:null}),g?.(e,{nodeId:r,handleId:t,handleType:N});function H(B){const{transform:G}=a();I=Je(B,q);const{handle:V,validHandleResult:U}=tw(B,c,Cu(I,G,!1,[1,1]),_,C,R=>rg(R,f,r,t,i?"target":"source",s,c));if(m=V,D||(z(),D=!0),T=U.handleDomNode,O=U.connection,w=U.isValid,o({connectionPosition:m&&w?Xv({x:m.x,y:m.y},G):I,connectionStatus:iw(!!m,w),connectionEndHandle:U.endHandle}),!m&&!w&&!T)return sn(A);O.source!==O.target&&T&&(sn(A),A=T,T.classList.add("connecting","react-flow__handle-connecting"),T.classList.toggle("valid",w),T.classList.toggle("react-flow__handle-valid",w))}function M(B){(m||T)&&O&&w&&n?.(O),a().onConnectEnd?.(B),u&&l?.(B),sn(A),y(),cancelAnimationFrame(b),D=!1,w=!1,O=null,T=null,c.removeEventListener("mousemove",H),c.removeEventListener("mouseup",M),c.removeEventListener("touchmove",H),c.removeEventListener("touchend",M)}c.addEventListener("mousemove",H),c.addEventListener("mouseup",M),c.addEventListener("touchmove",H),c.addEventListener("touchend",M)}const jc=()=>!0,aw=e=>({connectionStartHandle:e.connectionStartHandle,connectOnClick:e.connectOnClick,noPanClassName:e.noPanClassName}),ow=(e,t,r)=>n=>{const{connectionStartHandle:i,connectionEndHandle:a,connectionClickStartHandle:o}=n;return{connecting:i?.nodeId===e&&i?.handleId===t&&i?.type===r||a?.nodeId===e&&a?.handleId===t&&a?.type===r,clickConnecting:o?.nodeId===e&&o?.handleId===t&&o?.type===r}},ig=k.forwardRef(({type:e="source",position:t=J.Top,isValidConnection:r,isConnectable:n=!0,isConnectableStart:i=!0,isConnectableEnd:a=!0,id:o,onConnect:s,children:u,className:l,onMouseDown:c,onTouchStart:f,...d},h)=>{const _=o||null,g=e==="target",v=fe(),p=Z0(),{connectOnClick:y,noPanClassName:b}=ne(aw,he),{connecting:m,clickConnecting:E}=ne(ow(p,_,e),he);p||v.getState().onError?.("010",Ue.error010());const x=q=>{const{defaultEdgeOptions:A,onConnect:I,hasDefaultEdges:D}=v.getState(),O={...A,...q};if(D){const{edges:w,setEdges:T}=v.getState();T(ew(O,w))}I?.(O),s?.(O)},S=q=>{if(!p)return;const A=jv(q);i&&(A&&q.button===0||!A)&&ng({event:q,handleId:_,nodeId:p,onConnect:x,isTarget:g,getState:v.getState,setState:v.setState,isValidConnection:r||v.getState().isValidConnection||jc}),A?c?.(q):f?.(q)},N=q=>{const{onClickConnectStart:A,onClickConnectEnd:I,connectionClickStartHandle:D,connectionMode:O,isValidConnection:w}=v.getState();if(!p||!D&&!i)return;if(!D){A?.(q,{nodeId:p,handleId:_,handleType:e}),v.setState({connectionClickStartHandle:{nodeId:p,type:e,handleId:_}});return}const T=$v(q.target),C=r||w||jc,{connection:z,isValid:H}=rg({nodeId:p,id:_,type:e},O,D.nodeId,D.handleId||null,D.type,C,T);H&&x(z),I?.(q),v.setState({connectionClickStartHandle:null})};return L.createElement("div",{"data-handleid":_,"data-nodeid":p,"data-handlepos":t,"data-id":`${p}-${_}-${e}`,className:pe(["react-flow__handle",`react-flow__handle-${t}`,"nodrag",b,l,{source:!g,target:g,connectable:n,connectablestart:i,connectableend:a,connecting:E,connectionindicator:n&&(i&&!m||a&&m)}]),onMouseDown:S,onTouchStart:S,onClick:y?N:void 0,ref:h,...d},u)});ig.displayName="Handle";var vr=k.memo(ig);const ag=({data:e,isConnectable:t,targetPosition:r=J.Top,sourcePosition:n=J.Bottom})=>L.createElement(L.Fragment,null,L.createElement(vr,{type:"target",position:r,isConnectable:t}),e?.label,L.createElement(vr,{type:"source",position:n,isConnectable:t}));ag.displayName="DefaultNode";var Au=k.memo(ag);const og=({data:e,isConnectable:t,sourcePosition:r=J.Bottom})=>L.createElement(L.Fragment,null,e?.label,L.createElement(vr,{type:"source",position:r,isConnectable:t}));og.displayName="InputNode";var sg=k.memo(og);const ug=({data:e,isConnectable:t,targetPosition:r=J.Top})=>L.createElement(L.Fragment,null,L.createElement(vr,{type:"target",position:r,isConnectable:t}),e?.label);ug.displayName="OutputNode";var cg=k.memo(ug);const Vu=()=>null;Vu.displayName="GroupNode";const sw=e=>({selectedNodes:e.getNodes().filter(t=>t.selected),selectedEdges:e.edges.filter(t=>t.selected).map(t=>({...t}))}),tr=e=>e.id;function uw(e,t){return he(e.selectedNodes.map(tr),t.selectedNodes.map(tr))&&he(e.selectedEdges.map(tr),t.selectedEdges.map(tr))}const lg=k.memo(({onSelectionChange:e})=>{const t=fe(),{selectedNodes:r,selectedEdges:n}=ne(sw,uw);return k.useEffect(()=>{const i={nodes:r,edges:n};e?.(i),t.getState().onSelectionChange.forEach(a=>a(i))},[r,n,e]),null});lg.displayName="SelectionListener";const cw=e=>!!e.onSelectionChange;function lw({onSelectionChange:e}){const t=ne(cw);return e||t?L.createElement(lg,{onSelectionChange:e}):null}const fw=e=>({setNodes:e.setNodes,setEdges:e.setEdges,setDefaultNodesAndEdges:e.setDefaultNodesAndEdges,setMinZoom:e.setMinZoom,setMaxZoom:e.setMaxZoom,setTranslateExtent:e.setTranslateExtent,setNodeExtent:e.setNodeExtent,reset:e.reset});function dt(e,t){k.useEffect(()=>{typeof e<"u"&&t(e)},[e])}function Q(e,t,r){k.useEffect(()=>{typeof t<"u"&&r({[e]:t})},[t])}const dw=({nodes:e,edges:t,defaultNodes:r,defaultEdges:n,onConnect:i,onConnectStart:a,onConnectEnd:o,onClickConnectStart:s,onClickConnectEnd:u,nodesDraggable:l,nodesConnectable:c,nodesFocusable:f,edgesFocusable:d,edgesUpdatable:h,elevateNodesOnSelect:_,minZoom:g,maxZoom:v,nodeExtent:p,onNodesChange:y,onEdgesChange:b,elementsSelectable:m,connectionMode:E,snapGrid:x,snapToGrid:S,translateExtent:N,connectOnClick:q,defaultEdgeOptions:A,fitView:I,fitViewOptions:D,onNodesDelete:O,onEdgesDelete:w,onNodeDrag:T,onNodeDragStart:C,onNodeDragStop:z,onSelectionDrag:H,onSelectionDragStart:M,onSelectionDragStop:B,noPanClassName:G,nodeOrigin:V,rfId:U,autoPanOnConnect:R,autoPanOnNodeDrag:P,onError:F,connectionRadius:$,isValidConnection:j,nodeDragThreshold:W})=>{const{setNodes:Z,setEdges:te,setDefaultNodesAndEdges:ie,setMinZoom:re,setMaxZoom:ee,setTranslateExtent:X,setNodeExtent:ue,reset:K}=ne(fw,he),Y=fe();return k.useEffect(()=>{const oe=n?.map(Ce=>({...Ce,...A}));return ie(r,oe),()=>{K()}},[]),Q("defaultEdgeOptions",A,Y.setState),Q("connectionMode",E,Y.setState),Q("onConnect",i,Y.setState),Q("onConnectStart",a,Y.setState),Q("onConnectEnd",o,Y.setState),Q("onClickConnectStart",s,Y.setState),Q("onClickConnectEnd",u,Y.setState),Q("nodesDraggable",l,Y.setState),Q("nodesConnectable",c,Y.setState),Q("nodesFocusable",f,Y.setState),Q("edgesFocusable",d,Y.setState),Q("edgesUpdatable",h,Y.setState),Q("elementsSelectable",m,Y.setState),Q("elevateNodesOnSelect",_,Y.setState),Q("snapToGrid",S,Y.setState),Q("snapGrid",x,Y.setState),Q("onNodesChange",y,Y.setState),Q("onEdgesChange",b,Y.setState),Q("connectOnClick",q,Y.setState),Q("fitViewOnInit",I,Y.setState),Q("fitViewOnInitOptions",D,Y.setState),Q("onNodesDelete",O,Y.setState),Q("onEdgesDelete",w,Y.setState),Q("onNodeDrag",T,Y.setState),Q("onNodeDragStart",C,Y.setState),Q("onNodeDragStop",z,Y.setState),Q("onSelectionDrag",H,Y.setState),Q("onSelectionDragStart",M,Y.setState),Q("onSelectionDragStop",B,Y.setState),Q("noPanClassName",G,Y.setState),Q("nodeOrigin",V,Y.setState),Q("rfId",U,Y.setState),Q("autoPanOnConnect",R,Y.setState),Q("autoPanOnNodeDrag",P,Y.setState),Q("onError",F,Y.setState),Q("connectionRadius",$,Y.setState),Q("isValidConnection",j,Y.setState),Q("nodeDragThreshold",W,Y.setState),dt(e,Z),dt(t,te),dt(g,re),dt(v,ee),dt(N,X),dt(p,ue),null},Kc={display:"none"},hw={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},fg="react-flow__node-desc",dg="react-flow__edge-desc",pw="react-flow__aria-live",vw=e=>e.ariaLiveMessage;function gw({rfId:e}){const t=ne(vw);return L.createElement("div",{id:`${pw}-${e}`,"aria-live":"assertive","aria-atomic":"true",style:hw},t)}function yw({rfId:e,disableKeyboardA11y:t}){return L.createElement(L.Fragment,null,L.createElement("div",{id:`${fg}-${e}`,style:Kc},"Press enter or space to select a node.",!t&&"You can then use the arrow keys to move the node around."," Press delete to remove it and escape to cancel."," "),L.createElement("div",{id:`${dg}-${e}`,style:Kc},"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel."),!t&&L.createElement(gw,{rfId:e}))}var Gt=(e=null,t={actInsideInputWithModifier:!0})=>{const[r,n]=k.useState(!1),i=k.useRef(!1),a=k.useRef(new Set([])),[o,s]=k.useMemo(()=>{if(e!==null){const l=(Array.isArray(e)?e:[e]).filter(f=>typeof f=="string").map(f=>f.split("+")),c=l.reduce((f,d)=>f.concat(...d),[]);return[l,c]}return[[],[]]},[e]);return k.useEffect(()=>{const u=typeof document<"u"?document:null,l=t?.target||u;if(e!==null){const c=h=>{if(i.current=h.ctrlKey||h.metaKey||h.shiftKey,(!i.current||i.current&&!t.actInsideInputWithModifier)&&Su(h))return!1;const g=Wc(h.code,s);a.current.add(h[g]),Yc(o,a.current,!1)&&(h.preventDefault(),n(!0))},f=h=>{if((!i.current||i.current&&!t.actInsideInputWithModifier)&&Su(h))return!1;const g=Wc(h.code,s);Yc(o,a.current,!0)?(n(!1),a.current.clear()):a.current.delete(h[g]),h.key==="Meta"&&a.current.clear(),i.current=!1},d=()=>{a.current.clear(),n(!1)};return l?.addEventListener("keydown",c),l?.addEventListener("keyup",f),window.addEventListener("blur",d),()=>{l?.removeEventListener("keydown",c),l?.removeEventListener("keyup",f),window.removeEventListener("blur",d)}}},[e,n]),r};function Yc(e,t,r){return e.filter(n=>r||n.length===t.size).some(n=>n.every(i=>t.has(i)))}function Wc(e,t){return t.includes(e)?"code":"key"}function hg(e,t,r,n){const i=e.parentNode||e.parentId;if(!i)return r;const a=t.get(i),o=it(a,n);return hg(a,t,{x:(r.x??0)+o.x,y:(r.y??0)+o.y,z:(a[se]?.z??0)>(r.z??0)?a[se]?.z??0:r.z??0},n)}function pg(e,t,r){e.forEach(n=>{const i=n.parentNode||n.parentId;if(i&&!e.has(i))throw new Error(`Parent node ${i} not found`);if(i||r?.[n.id]){const{x:a,y:o,z:s}=hg(n,e,{...n.position,z:n[se]?.z??0},t);n.positionAbsolute={x:a,y:o},n[se].z=s,r?.[n.id]&&(n[se].isParent=!0)}})}function un(e,t,r,n){const i=new Map,a={},o=n?1e3:0;return e.forEach(s=>{const u=(Se(s.zIndex)?s.zIndex:0)+(s.selected?o:0),l=t.get(s.id),c={...s,positionAbsolute:{x:s.position.x,y:s.position.y}},f=s.parentNode||s.parentId;f&&(a[f]=!0);const d=l?.type&&l?.type!==s.type;Object.defineProperty(c,se,{enumerable:!1,value:{handleBounds:d?void 0:l?.[se]?.handleBounds,z:u}}),i.set(s.id,c)}),pg(i,r,a),i}function vg(e,t={}){const{getNodes:r,width:n,height:i,minZoom:a,maxZoom:o,d3Zoom:s,d3Selection:u,fitViewOnInitDone:l,fitViewOnInit:c,nodeOrigin:f}=e(),d=t.initial&&!l&&c;if(s&&u&&(d||!t.initial)){const _=r().filter(v=>{const p=t.includeHiddenNodes?v.width&&v.height:!v.hidden;return t.nodes?.length?p&&t.nodes.some(y=>y.id===v.id):p}),g=_.every(v=>v.width&&v.height);if(_.length>0&&g){const v=xr(_,f),{x:p,y,zoom:b}=eg(v,n,i,t.minZoom??a,t.maxZoom??o,t.padding??.1),m=Ge.translate(p,y).scale(b);return typeof t.duration=="number"&&t.duration>0?s.transform(rt(u,t.duration),m):s.transform(u,m),!0}}return!1}function mw(e,t){return e.forEach(r=>{const n=t.get(r.id);n&&t.set(n.id,{...n,[se]:n[se],selected:r.selected})}),new Map(t)}function _w(e,t){return t.map(r=>{const n=e.find(i=>i.id===r.id);return n&&(r.selected=n.selected),r})}function rr({changedNodes:e,changedEdges:t,get:r,set:n}){const{nodeInternals:i,edges:a,onNodesChange:o,onEdgesChange:s,hasDefaultNodes:u,hasDefaultEdges:l}=r();e?.length&&(u&&n({nodeInternals:mw(e,i)}),o?.(e)),t?.length&&(l&&n({edges:_w(t,a)}),s?.(t))}const ht=()=>{},bw={zoomIn:ht,zoomOut:ht,zoomTo:ht,getZoom:()=>1,setViewport:ht,getViewport:()=>({x:0,y:0,zoom:1}),fitView:()=>!1,setCenter:ht,fitBounds:ht,project:e=>e,screenToFlowPosition:e=>e,flowToScreenPosition:e=>e,viewportInitialized:!1},ww=e=>({d3Zoom:e.d3Zoom,d3Selection:e.d3Selection}),Ew=()=>{const e=fe(),{d3Zoom:t,d3Selection:r}=ne(ww,he);return k.useMemo(()=>r&&t?{zoomIn:i=>t.scaleBy(rt(r,i?.duration),1.2),zoomOut:i=>t.scaleBy(rt(r,i?.duration),1/1.2),zoomTo:(i,a)=>t.scaleTo(rt(r,a?.duration),i),getZoom:()=>e.getState().transform[2],setViewport:(i,a)=>{const[o,s,u]=e.getState().transform,l=Ge.translate(i.x??o,i.y??s).scale(i.zoom??u);t.transform(rt(r,a?.duration),l)},getViewport:()=>{const[i,a,o]=e.getState().transform;return{x:i,y:a,zoom:o}},fitView:i=>vg(e.getState,i),setCenter:(i,a,o)=>{const{width:s,height:u,maxZoom:l}=e.getState(),c=typeof o?.zoom<"u"?o.zoom:l,f=s/2-i*c,d=u/2-a*c,h=Ge.translate(f,d).scale(c);t.transform(rt(r,o?.duration),h)},fitBounds:(i,a)=>{const{width:o,height:s,minZoom:u,maxZoom:l}=e.getState(),{x:c,y:f,zoom:d}=eg(i,o,s,u,l,a?.padding??.1),h=Ge.translate(c,f).scale(d);t.transform(rt(r,a?.duration),h)},project:i=>{const{transform:a,snapToGrid:o,snapGrid:s}=e.getState();return console.warn("[DEPRECATED] `project` is deprecated. Instead use `screenToFlowPosition`. There is no need to subtract the react flow bounds anymore! https://reactflow.dev/api-reference/types/react-flow-instance#screen-to-flow-position"),Cu(i,a,o,s)},screenToFlowPosition:i=>{const{transform:a,snapToGrid:o,snapGrid:s,domNode:u}=e.getState();if(!u)return i;const{x:l,y:c}=u.getBoundingClientRect(),f={x:i.x-l,y:i.y-c};return Cu(f,a,o,s)},flowToScreenPosition:i=>{const{transform:a,domNode:o}=e.getState();if(!o)return i;const{x:s,y:u}=o.getBoundingClientRect(),l=Xv(i,a);return{x:l.x+s,y:l.y+u}},viewportInitialized:!0}:bw,[t,r])};function Uu(){const e=Ew(),t=fe(),r=k.useCallback(()=>t.getState().getNodes().map(g=>({...g})),[]),n=k.useCallback(g=>t.getState().nodeInternals.get(g),[]),i=k.useCallback(()=>{const{edges:g=[]}=t.getState();return g.map(v=>({...v}))},[]),a=k.useCallback(g=>{const{edges:v=[]}=t.getState();return v.find(p=>p.id===g)},[]),o=k.useCallback(g=>{const{getNodes:v,setNodes:p,hasDefaultNodes:y,onNodesChange:b}=t.getState(),m=v(),E=typeof g=="function"?g(m):g;if(y)p(E);else if(b){const x=E.length===0?m.map(S=>({type:"remove",id:S.id})):E.map(S=>({item:S,type:"reset"}));b(x)}},[]),s=k.useCallback(g=>{const{edges:v=[],setEdges:p,hasDefaultEdges:y,onEdgesChange:b}=t.getState(),m=typeof g=="function"?g(v):g;if(y)p(m);else if(b){const E=m.length===0?v.map(x=>({type:"remove",id:x.id})):m.map(x=>({item:x,type:"reset"}));b(E)}},[]),u=k.useCallback(g=>{const v=Array.isArray(g)?g:[g],{getNodes:p,setNodes:y,hasDefaultNodes:b,onNodesChange:m}=t.getState();if(b){const x=[...p(),...v];y(x)}else if(m){const E=v.map(x=>({item:x,type:"add"}));m(E)}},[]),l=k.useCallback(g=>{const v=Array.isArray(g)?g:[g],{edges:p=[],setEdges:y,hasDefaultEdges:b,onEdgesChange:m}=t.getState();if(b)y([...p,...v]);else if(m){const E=v.map(x=>({item:x,type:"add"}));m(E)}},[]),c=k.useCallback(()=>{const{getNodes:g,edges:v=[],transform:p}=t.getState(),[y,b,m]=p;return{nodes:g().map(E=>({...E})),edges:v.map(E=>({...E})),viewport:{x:y,y:b,zoom:m}}},[]),f=k.useCallback(({nodes:g,edges:v})=>{const{nodeInternals:p,getNodes:y,edges:b,hasDefaultNodes:m,hasDefaultEdges:E,onNodesDelete:x,onEdgesDelete:S,onNodesChange:N,onEdgesChange:q}=t.getState(),A=(g||[]).map(T=>T.id),I=(v||[]).map(T=>T.id),D=y().reduce((T,C)=>{const z=C.parentNode||C.parentId,H=!A.includes(C.id)&&z&&T.find(B=>B.id===z);return(typeof C.deletable=="boolean"?C.deletable:!0)&&(A.includes(C.id)||H)&&T.push(C),T},[]),O=b.filter(T=>typeof T.deletable=="boolean"?T.deletable:!0),w=O.filter(T=>I.includes(T.id));if(D||w){const T=Qv(D,O),C=[...w,...T],z=C.reduce((H,M)=>(H.includes(M.id)||H.push(M.id),H),[]);if((E||m)&&(E&&t.setState({edges:b.filter(H=>!z.includes(H.id))}),m&&(D.forEach(H=>{p.delete(H.id)}),t.setState({nodeInternals:new Map(p)}))),z.length>0&&(S?.(C),q&&q(z.map(H=>({id:H,type:"remove"})))),D.length>0&&(x?.(D),N)){const H=D.map(M=>({id:M.id,type:"remove"}));N(H)}}},[]),d=k.useCallback(g=>{const v=$0(g),p=v?null:t.getState().nodeInternals.get(g.id);return!v&&!p?[null,null,v]:[v?g:Bc(p),p,v]},[]),h=k.useCallback((g,v=!0,p)=>{const[y,b,m]=d(g);return y?(p||t.getState().getNodes()).filter(E=>{if(!m&&(E.id===b.id||!E.positionAbsolute))return!1;const x=Bc(E),S=xu(x,y);return v&&S>0||S>=y.width*y.height}):[]},[]),_=k.useCallback((g,v,p=!0)=>{const[y]=d(g);if(!y)return!1;const b=xu(y,v);return p&&b>0||b>=y.width*y.height},[]);return k.useMemo(()=>({...e,getNodes:r,getNode:n,getEdges:i,getEdge:a,setNodes:o,setEdges:s,addNodes:u,addEdges:l,toObject:c,deleteElements:f,getIntersectingNodes:h,isNodeIntersecting:_}),[e,r,n,i,a,o,s,u,l,c,f,h,_])}const xw={actInsideInputWithModifier:!1};var Sw=({deleteKeyCode:e,multiSelectionKeyCode:t})=>{const r=fe(),{deleteElements:n}=Uu(),i=Gt(e,xw),a=Gt(t);k.useEffect(()=>{if(i){const{edges:o,getNodes:s}=r.getState(),u=s().filter(c=>c.selected),l=o.filter(c=>c.selected);n({nodes:u,edges:l}),r.setState({nodesSelectionActive:!1})}},[i]),k.useEffect(()=>{r.setState({multiSelectionActive:a})},[a])};function qw(e){const t=fe();k.useEffect(()=>{let r;const n=()=>{if(!e.current)return;const i=Lu(e.current);(i.height===0||i.width===0)&&t.getState().onError?.("004",Ue.error004()),t.setState({width:i.width||500,height:i.height||500})};return n(),window.addEventListener("resize",n),e.current&&(r=new ResizeObserver(()=>n()),r.observe(e.current)),()=>{window.removeEventListener("resize",n),r&&e.current&&r.unobserve(e.current)}},[])}const ju={position:"absolute",width:"100%",height:"100%",top:0,left:0},Rw=(e,t)=>e.x!==t.x||e.y!==t.y||e.zoom!==t.k,nr=e=>({x:e.x,y:e.y,zoom:e.k}),pt=(e,t)=>e.target.closest(`.${t}`),Zc=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),Xc=e=>{const t=e.ctrlKey&&dr()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t},Cw=e=>({d3Zoom:e.d3Zoom,d3Selection:e.d3Selection,d3ZoomHandler:e.d3ZoomHandler,userSelectionActive:e.userSelectionActive}),Aw=({onMove:e,onMoveStart:t,onMoveEnd:r,onPaneContextMenu:n,zoomOnScroll:i=!0,zoomOnPinch:a=!0,panOnScroll:o=!1,panOnScrollSpeed:s=.5,panOnScrollMode:u=nt.Free,zoomOnDoubleClick:l=!0,elementsSelectable:c,panOnDrag:f=!0,defaultViewport:d,translateExtent:h,minZoom:_,maxZoom:g,zoomActivationKeyCode:v,preventScrolling:p=!0,children:y,noWheelClassName:b,noPanClassName:m})=>{const E=k.useRef(),x=fe(),S=k.useRef(!1),N=k.useRef(!1),q=k.useRef(null),A=k.useRef({x:0,y:0,zoom:0}),{d3Zoom:I,d3Selection:D,d3ZoomHandler:O,userSelectionActive:w}=ne(Cw,he),T=Gt(v),C=k.useRef(0),z=k.useRef(!1),H=k.useRef();return qw(q),k.useEffect(()=>{if(q.current){const M=q.current.getBoundingClientRect(),B=zv().scaleExtent([_,g]).translateExtent(h),G=xe(q.current).call(B),V=Ge.translate(d.x,d.y).scale(wt(d.zoom,_,g)),U=[[0,0],[M.width,M.height]],R=B.constrain()(V,U,h);B.transform(G,R),B.wheelDelta(Xc),x.setState({d3Zoom:B,d3Selection:G,d3ZoomHandler:G.on("wheel.zoom"),transform:[R.x,R.y,R.k],domNode:q.current.closest(".react-flow")})}},[]),k.useEffect(()=>{D&&I&&(o&&!T&&!w?D.on("wheel.zoom",M=>{if(pt(M,b))return!1;M.preventDefault(),M.stopImmediatePropagation();const B=D.property("__zoom").k||1;if(M.ctrlKey&&a){const j=Ne(M),W=Xc(M),Z=B*Math.pow(2,W);I.scaleTo(D,Z,j,M);return}const G=M.deltaMode===1?20:1;let V=u===nt.Vertical?0:M.deltaX*G,U=u===nt.Horizontal?0:M.deltaY*G;!dr()&&M.shiftKey&&u!==nt.Vertical&&(V=M.deltaY*G,U=0),I.translateBy(D,-(V/B)*s,-(U/B)*s,{internal:!0});const R=nr(D.property("__zoom")),{onViewportChangeStart:P,onViewportChange:F,onViewportChangeEnd:$}=x.getState();clearTimeout(H.current),z.current||(z.current=!0,t?.(M,R),P?.(R)),z.current&&(e?.(M,R),F?.(R),H.current=setTimeout(()=>{r?.(M,R),$?.(R),z.current=!1},150))},{passive:!1}):typeof O<"u"&&D.on("wheel.zoom",function(M,B){if(!p&&M.type==="wheel"&&!M.ctrlKey||pt(M,b))return null;M.preventDefault(),O.call(this,M,B)},{passive:!1}))},[w,o,u,D,I,O,T,a,p,b,t,e,r]),k.useEffect(()=>{I&&I.on("start",M=>{if(!M.sourceEvent||M.sourceEvent.internal)return null;C.current=M.sourceEvent?.button;const{onViewportChangeStart:B}=x.getState(),G=nr(M.transform);S.current=!0,A.current=G,M.sourceEvent?.type==="mousedown"&&x.setState({paneDragging:!0}),B?.(G),t?.(M.sourceEvent,G)})},[I,t]),k.useEffect(()=>{I&&(w&&!S.current?I.on("zoom",null):w||I.on("zoom",M=>{const{onViewportChange:B}=x.getState();if(x.setState({transform:[M.transform.x,M.transform.y,M.transform.k]}),N.current=!!(n&&Zc(f,C.current??0)),(e||B)&&!M.sourceEvent?.internal){const G=nr(M.transform);B?.(G),e?.(M.sourceEvent,G)}}))},[w,I,e,f,n]),k.useEffect(()=>{I&&I.on("end",M=>{if(!M.sourceEvent||M.sourceEvent.internal)return null;const{onViewportChangeEnd:B}=x.getState();if(S.current=!1,x.setState({paneDragging:!1}),n&&Zc(f,C.current??0)&&!N.current&&n(M.sourceEvent),N.current=!1,(r||B)&&Rw(A.current,M.transform)){const G=nr(M.transform);A.current=G,clearTimeout(E.current),E.current=setTimeout(()=>{B?.(G),r?.(M.sourceEvent,G)},o?150:0)}})},[I,o,f,r,n]),k.useEffect(()=>{I&&I.filter(M=>{const B=T||i,G=a&&M.ctrlKey;if((f===!0||Array.isArray(f)&&f.includes(1))&&M.button===1&&M.type==="mousedown"&&(pt(M,"react-flow__node")||pt(M,"react-flow__edge")))return!0;if(!f&&!B&&!o&&!l&&!a||w||!l&&M.type==="dblclick"||pt(M,b)&&M.type==="wheel"||pt(M,m)&&(M.type!=="wheel"||o&&M.type==="wheel"&&!T)||!a&&M.ctrlKey&&M.type==="wheel"||!B&&!o&&!G&&M.type==="wheel"||!f&&(M.type==="mousedown"||M.type==="touchstart")||Array.isArray(f)&&!f.includes(M.button)&&M.type==="mousedown")return!1;const V=Array.isArray(f)&&f.includes(M.button)||!M.button||M.button<=1;return(!M.ctrlKey||M.type==="wheel")&&V})},[w,I,i,a,o,l,f,c,T]),L.createElement("div",{className:"react-flow__renderer",ref:q,style:ju},y)},Nw=e=>({userSelectionActive:e.userSelectionActive,userSelectionRect:e.userSelectionRect});function Iw(){const{userSelectionActive:e,userSelectionRect:t}=ne(Nw,he);return e&&t?L.createElement("div",{className:"react-flow__selection react-flow__container",style:{width:t.width,height:t.height,transform:`translate(${t.x}px, ${t.y}px)`}}):null}function Jc(e,t){const r=t.parentNode||t.parentId,n=e.find(i=>i.id===r);if(n){const i=t.position.x+t.width-n.width,a=t.position.y+t.height-n.height;if(i>0||a>0||t.position.x<0||t.position.y<0){if(n.style={...n.style},n.style.width=n.style.width??n.width,n.style.height=n.style.height??n.height,i>0&&(n.style.width+=i),a>0&&(n.style.height+=a),t.position.x<0){const o=Math.abs(t.position.x);n.position.x=n.position.x-o,n.style.width+=o,t.position.x=0}if(t.position.y<0){const o=Math.abs(t.position.y);n.position.y=n.position.y-o,n.style.height+=o,t.position.y=0}n.width=n.style.width,n.height=n.style.height}}}function gg(e,t){if(e.some(n=>n.type==="reset"))return e.filter(n=>n.type==="reset").map(n=>n.item);const r=e.filter(n=>n.type==="add").map(n=>n.item);return t.reduce((n,i)=>{const a=e.filter(s=>s.id===i.id);if(a.length===0)return n.push(i),n;const o={...i};for(const s of a)if(s)switch(s.type){case"select":{o.selected=s.selected;break}case"position":{typeof s.position<"u"&&(o.position=s.position),typeof s.positionAbsolute<"u"&&(o.positionAbsolute=s.positionAbsolute),typeof s.dragging<"u"&&(o.dragging=s.dragging),o.expandParent&&Jc(n,o);break}case"dimensions":{typeof s.dimensions<"u"&&(o.width=s.dimensions.width,o.height=s.dimensions.height),typeof s.updateStyle<"u"&&(o.style={...o.style||{},...s.dimensions}),typeof s.resizing=="boolean"&&(o.resizing=s.resizing),o.expandParent&&Jc(n,o);break}case"remove":return n}return n.push(o),n},r)}function yg(e,t){return gg(e,t)}function Tw(e,t){return gg(e,t)}const Ze=(e,t)=>({id:e,type:"select",selected:t});function gt(e,t){return e.reduce((r,n)=>{const i=t.includes(n.id);return!n.selected&&i?(n.selected=!0,r.push(Ze(n.id,!0))):n.selected&&!i&&(n.selected=!1,r.push(Ze(n.id,!1))),r},[])}const cn=(e,t)=>r=>{r.target===t.current&&e?.(r)},Mw=e=>({userSelectionActive:e.userSelectionActive,elementsSelectable:e.elementsSelectable,dragging:e.paneDragging}),mg=k.memo(({isSelecting:e,selectionMode:t=$t.Full,panOnDrag:r,onSelectionStart:n,onSelectionEnd:i,onPaneClick:a,onPaneContextMenu:o,onPaneScroll:s,onPaneMouseEnter:u,onPaneMouseMove:l,onPaneMouseLeave:c,children:f})=>{const d=k.useRef(null),h=fe(),_=k.useRef(0),g=k.useRef(0),v=k.useRef(),{userSelectionActive:p,elementsSelectable:y,dragging:b}=ne(Mw,he),m=()=>{h.setState({userSelectionActive:!1,userSelectionRect:null}),_.current=0,g.current=0},E=O=>{a?.(O),h.getState().resetSelectedElements(),h.setState({nodesSelectionActive:!1})},x=O=>{if(Array.isArray(r)&&r?.includes(2)){O.preventDefault();return}o?.(O)},S=s?O=>s(O):void 0,N=O=>{const{resetSelectedElements:w,domNode:T}=h.getState();if(v.current=T?.getBoundingClientRect(),!y||!e||O.button!==0||O.target!==d.current||!v.current)return;const{x:C,y:z}=Je(O,v.current);w(),h.setState({userSelectionRect:{width:0,height:0,startX:C,startY:z,x:C,y:z}}),n?.(O)},q=O=>{const{userSelectionRect:w,nodeInternals:T,edges:C,transform:z,onNodesChange:H,onEdgesChange:M,nodeOrigin:B,getNodes:G}=h.getState();if(!e||!v.current||!w)return;h.setState({userSelectionActive:!0,nodesSelectionActive:!1});const V=Je(O,v.current),U=w.startX??0,R=w.startY??0,P={...w,x:V.xZ.id),W=$.map(Z=>Z.id);if(_.current!==W.length){_.current=W.length;const Z=gt(F,W);Z.length&&H?.(Z)}if(g.current!==j.length){g.current=j.length;const Z=gt(C,j);Z.length&&M?.(Z)}h.setState({userSelectionRect:P})},A=O=>{if(O.button!==0)return;const{userSelectionRect:w}=h.getState();!p&&w&&O.target===d.current&&E?.(O),h.setState({nodesSelectionActive:_.current>0}),m(),i?.(O)},I=O=>{p&&(h.setState({nodesSelectionActive:_.current>0}),i?.(O)),m()},D=y&&(e||p);return L.createElement("div",{className:pe(["react-flow__pane",{dragging:b,selection:e}]),onClick:D?void 0:cn(E,d),onContextMenu:cn(x,d),onWheel:cn(S,d),onMouseEnter:D?void 0:u,onMouseDown:D?N:void 0,onMouseMove:D?q:l,onMouseUp:D?A:void 0,onMouseLeave:D?I:c,ref:d,style:ju},f,L.createElement(Iw,null))});mg.displayName="Pane";function _g(e,t){const r=e.parentNode||e.parentId;if(!r)return!1;const n=t.get(r);return n?n.selected?!0:_g(n,t):!1}function Qc(e,t,r){let n=e;do{if(n?.matches(t))return!0;if(n===r.current)return!1;n=n.parentElement}while(n);return!1}function Pw(e,t,r,n){return Array.from(e.values()).filter(i=>(i.selected||i.id===n)&&(!i.parentNode||i.parentId||!_g(i,e))&&(i.draggable||t&&typeof i.draggable>"u")).map(i=>({id:i.id,position:i.position||{x:0,y:0},positionAbsolute:i.positionAbsolute||{x:0,y:0},distance:{x:r.x-(i.positionAbsolute?.x??0),y:r.y-(i.positionAbsolute?.y??0)},delta:{x:0,y:0},extent:i.extent,parentNode:i.parentNode||i.parentId,parentId:i.parentNode||i.parentId,width:i.width,height:i.height,expandParent:i.expandParent}))}function Ow(e,t){return!t||t==="parent"?t:[t[0],[t[1][0]-(e.width||0),t[1][1]-(e.height||0)]]}function bg(e,t,r,n,i=[0,0],a){const o=Ow(e,e.extent||n);let s=o;const u=e.parentNode||e.parentId;if(e.extent==="parent"&&!e.expandParent)if(u&&e.width&&e.height){const f=r.get(u),{x:d,y:h}=it(f,i).positionAbsolute;s=f&&Se(d)&&Se(h)&&Se(f.width)&&Se(f.height)?[[d+e.width*i[0],h+e.height*i[1]],[d+f.width-e.width+e.width*i[0],h+f.height-e.height+e.height*i[1]]]:s}else a?.("005",Ue.error005()),s=o;else if(e.extent&&u&&e.extent!=="parent"){const f=r.get(u),{x:d,y:h}=it(f,i).positionAbsolute;s=[[e.extent[0][0]+d,e.extent[0][1]+h],[e.extent[1][0]+d,e.extent[1][1]+h]]}let l={x:0,y:0};if(u){const f=r.get(u);l=it(f,i).positionAbsolute}const c=s&&s!=="parent"?Fu(t,s):t;return{position:{x:c.x-l.x,y:c.y-l.y},positionAbsolute:c}}function ln({nodeId:e,dragItems:t,nodeInternals:r}){const n=t.map(i=>({...r.get(i.id),position:i.position,positionAbsolute:i.positionAbsolute}));return[e?n.find(i=>i.id===e):n[0],n]}const el=(e,t,r,n)=>{const i=t.querySelectorAll(e);if(!i||!i.length)return null;const a=Array.from(i),o=t.getBoundingClientRect(),s={x:o.width*n[0],y:o.height*n[1]};return a.map(u=>{const l=u.getBoundingClientRect();return{id:u.getAttribute("data-handleid"),position:u.getAttribute("data-handlepos"),x:(l.left-o.left-s.x)/r,y:(l.top-o.top-s.y)/r,...Lu(u)}})};function Tt(e,t,r){return r===void 0?r:n=>{const i=t().nodeInternals.get(e);i&&r(n,{...i})}}function Nu({id:e,store:t,unselect:r=!1,nodeRef:n}){const{addSelectedNodes:i,unselectNodesAndEdges:a,multiSelectionActive:o,nodeInternals:s,onError:u}=t.getState(),l=s.get(e);if(!l){u?.("012",Ue.error012(e));return}t.setState({nodesSelectionActive:!1}),l.selected?(r||l.selected&&o)&&(a({nodes:[l],edges:[]}),requestAnimationFrame(()=>n?.current?.blur())):i([e])}function kw(){const e=fe();return k.useCallback(({sourceEvent:r})=>{const{transform:n,snapGrid:i,snapToGrid:a}=e.getState(),o=r.touches?r.touches[0].clientX:r.clientX,s=r.touches?r.touches[0].clientY:r.clientY,u={x:(o-n[0])/n[2],y:(s-n[1])/n[2]};return{xSnapped:a?i[0]*Math.round(u.x/i[0]):u.x,ySnapped:a?i[1]*Math.round(u.y/i[1]):u.y,...u}},[])}function fn(e){return(t,r,n)=>e?.(t,n)}function wg({nodeRef:e,disabled:t=!1,noDragClassName:r,handleSelector:n,nodeId:i,isSelectable:a,selectNodesOnDrag:o}){const s=fe(),[u,l]=k.useState(!1),c=k.useRef([]),f=k.useRef({x:null,y:null}),d=k.useRef(0),h=k.useRef(null),_=k.useRef({x:0,y:0}),g=k.useRef(null),v=k.useRef(!1),p=k.useRef(!1),y=k.useRef(!1),b=kw();return k.useEffect(()=>{if(e?.current){const m=xe(e.current),E=({x:N,y:q})=>{const{nodeInternals:A,onNodeDrag:I,onSelectionDrag:D,updateNodePositions:O,nodeExtent:w,snapGrid:T,snapToGrid:C,nodeOrigin:z,onError:H}=s.getState();f.current={x:N,y:q};let M=!1,B={x:0,y:0,x2:0,y2:0};if(c.current.length>1&&w){const V=xr(c.current,z);B=Ht(V)}if(c.current=c.current.map(V=>{const U={x:N-V.distance.x,y:q-V.distance.y};C&&(U.x=T[0]*Math.round(U.x/T[0]),U.y=T[1]*Math.round(U.y/T[1]));const R=[[w[0][0],w[0][1]],[w[1][0],w[1][1]]];c.current.length>1&&w&&!V.extent&&(R[0][0]=V.positionAbsolute.x-B.x+w[0][0],R[1][0]=V.positionAbsolute.x+(V.width??0)-B.x2+w[1][0],R[0][1]=V.positionAbsolute.y-B.y+w[0][1],R[1][1]=V.positionAbsolute.y+(V.height??0)-B.y2+w[1][1]);const P=bg(V,U,A,R,z,H);return M=M||V.position.x!==P.position.x||V.position.y!==P.position.y,V.position=P.position,V.positionAbsolute=P.positionAbsolute,V}),!M)return;O(c.current,!0,!0),l(!0);const G=i?I:fn(D);if(G&&g.current){const[V,U]=ln({nodeId:i,dragItems:c.current,nodeInternals:A});G(g.current,V,U)}},x=()=>{if(!h.current)return;const[N,q]=Hv(_.current,h.current);if(N!==0||q!==0){const{transform:A,panBy:I}=s.getState();f.current.x=(f.current.x??0)-N/A[2],f.current.y=(f.current.y??0)-q/A[2],I({x:N,y:q})&&E(f.current)}d.current=requestAnimationFrame(x)},S=N=>{const{nodeInternals:q,multiSelectionActive:A,nodesDraggable:I,unselectNodesAndEdges:D,onNodeDragStart:O,onSelectionDragStart:w}=s.getState();p.current=!0;const T=i?O:fn(w);(!o||!a)&&!A&&i&&(q.get(i)?.selected||D()),i&&a&&o&&Nu({id:i,store:s,nodeRef:e});const C=b(N);if(f.current=C,c.current=Pw(q,I,C,i),T&&c.current){const[z,H]=ln({nodeId:i,dragItems:c.current,nodeInternals:q});T(N.sourceEvent,z,H)}};if(t)m.on(".drag",null);else{const N=mb().on("start",q=>{const{domNode:A,nodeDragThreshold:I}=s.getState();I===0&&S(q),y.current=!1;const D=b(q);f.current=D,h.current=A?.getBoundingClientRect()||null,_.current=Je(q.sourceEvent,h.current)}).on("drag",q=>{const A=b(q),{autoPanOnNodeDrag:I,nodeDragThreshold:D}=s.getState();if(q.sourceEvent.type==="touchmove"&&q.sourceEvent.touches.length>1&&(y.current=!0),!y.current){if(!v.current&&p.current&&I&&(v.current=!0,x()),!p.current){const O=A.xSnapped-(f?.current?.x??0),w=A.ySnapped-(f?.current?.y??0);Math.sqrt(O*O+w*w)>D&&S(q)}(f.current.x!==A.xSnapped||f.current.y!==A.ySnapped)&&c.current&&p.current&&(g.current=q.sourceEvent,_.current=Je(q.sourceEvent,h.current),E(A))}}).on("end",q=>{if(!(!p.current||y.current)&&(l(!1),v.current=!1,p.current=!1,cancelAnimationFrame(d.current),c.current)){const{updateNodePositions:A,nodeInternals:I,onNodeDragStop:D,onSelectionDragStop:O}=s.getState(),w=i?D:fn(O);if(A(c.current,!1,!1),w){const[T,C]=ln({nodeId:i,dragItems:c.current,nodeInternals:I});w(q.sourceEvent,T,C)}}}).filter(q=>{const A=q.target;return!q.button&&(!r||!Qc(A,`.${r}`,e))&&(!n||Qc(A,n,e))});return m.call(N),()=>{m.on(".drag",null)}}}},[e,t,r,n,a,s,i,o,b]),u}function Eg(){const e=fe();return k.useCallback(r=>{const{nodeInternals:n,nodeExtent:i,updateNodePositions:a,getNodes:o,snapToGrid:s,snapGrid:u,onError:l,nodesDraggable:c}=e.getState(),f=o().filter(y=>y.selected&&(y.draggable||c&&typeof y.draggable>"u")),d=s?u[0]:5,h=s?u[1]:5,_=r.isShiftPressed?4:1,g=r.x*d*_,v=r.y*h*_,p=f.map(y=>{if(y.positionAbsolute){const b={x:y.positionAbsolute.x+g,y:y.positionAbsolute.y+v};s&&(b.x=u[0]*Math.round(b.x/u[0]),b.y=u[1]*Math.round(b.y/u[1]));const{positionAbsolute:m,position:E}=bg(y,b,n,i,void 0,l);y.position=E,y.positionAbsolute=m}return y});a(p,!0,!1)},[])}const mt={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}};var Mt=e=>{const t=({id:r,type:n,data:i,xPos:a,yPos:o,xPosOrigin:s,yPosOrigin:u,selected:l,onClick:c,onMouseEnter:f,onMouseMove:d,onMouseLeave:h,onContextMenu:_,onDoubleClick:g,style:v,className:p,isDraggable:y,isSelectable:b,isConnectable:m,isFocusable:E,selectNodesOnDrag:x,sourcePosition:S,targetPosition:N,hidden:q,resizeObserver:A,dragHandle:I,zIndex:D,isParent:O,noDragClassName:w,noPanClassName:T,initialized:C,disableKeyboardA11y:z,ariaLabel:H,rfId:M,hasHandleBounds:B})=>{const G=fe(),V=k.useRef(null),U=k.useRef(null),R=k.useRef(S),P=k.useRef(N),F=k.useRef(n),$=b||y||c||f||d||h,j=Eg(),W=Tt(r,G.getState,f),Z=Tt(r,G.getState,d),te=Tt(r,G.getState,h),ie=Tt(r,G.getState,_),re=Tt(r,G.getState,g),ee=K=>{const{nodeDragThreshold:Y}=G.getState();if(b&&(!x||!y||Y>0)&&Nu({id:r,store:G,nodeRef:V}),c){const oe=G.getState().nodeInternals.get(r);oe&&c(K,{...oe})}},X=K=>{if(!Su(K)&&!z)if(Uv.includes(K.key)&&b){const Y=K.key==="Escape";Nu({id:r,store:G,unselect:Y,nodeRef:V})}else y&&l&&Object.prototype.hasOwnProperty.call(mt,K.key)&&(G.setState({ariaLiveMessage:`Moved selected node ${K.key.replace("Arrow","").toLowerCase()}. New position, x: ${~~a}, y: ${~~o}`}),j({x:mt[K.key].x,y:mt[K.key].y,isShiftPressed:K.shiftKey}))};k.useEffect(()=>()=>{U.current&&(A?.unobserve(U.current),U.current=null)},[]),k.useEffect(()=>{if(V.current&&!q){const K=V.current;(!C||!B||U.current!==K)&&(U.current&&A?.unobserve(U.current),A?.observe(K),U.current=K)}},[q,C,B]),k.useEffect(()=>{const K=F.current!==n,Y=R.current!==S,oe=P.current!==N;V.current&&(K||Y||oe)&&(K&&(F.current=n),Y&&(R.current=S),oe&&(P.current=N),G.getState().updateNodeDimensions([{id:r,nodeElement:V.current,forceUpdate:!0}]))},[r,n,S,N]);const ue=wg({nodeRef:V,disabled:q||!y,noDragClassName:w,handleSelector:I,nodeId:r,isSelectable:b,selectNodesOnDrag:x});return q?null:L.createElement("div",{className:pe(["react-flow__node",`react-flow__node-${n}`,{[T]:y},p,{selected:l,selectable:b,parent:O,dragging:ue}]),ref:V,style:{zIndex:D,transform:`translate(${s}px,${u}px)`,pointerEvents:$?"all":"none",visibility:C?"visible":"hidden",...v},"data-id":r,"data-testid":`rf__node-${r}`,onMouseEnter:W,onMouseMove:Z,onMouseLeave:te,onContextMenu:ie,onClick:ee,onDoubleClick:re,onKeyDown:E?X:void 0,tabIndex:E?0:void 0,role:E?"button":void 0,"aria-describedby":z?void 0:`${fg}-${M}`,"aria-label":H},L.createElement(W0,{value:r},L.createElement(e,{id:r,data:i,type:n,xPos:a,yPos:o,selected:l,isConnectable:m,sourcePosition:S,targetPosition:N,dragging:ue,dragHandle:I,zIndex:D})))};return t.displayName="NodeWrapper",k.memo(t)};const Dw=e=>{const t=e.getNodes().filter(r=>r.selected);return{...xr(t,e.nodeOrigin),transformString:`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]})`,userSelectionActive:e.userSelectionActive}};function Lw({onSelectionContextMenu:e,noPanClassName:t,disableKeyboardA11y:r}){const n=fe(),{width:i,height:a,x:o,y:s,transformString:u,userSelectionActive:l}=ne(Dw,he),c=Eg(),f=k.useRef(null);if(k.useEffect(()=>{r||f.current?.focus({preventScroll:!0})},[r]),wg({nodeRef:f}),l||!i||!a)return null;const d=e?_=>{const g=n.getState().getNodes().filter(v=>v.selected);e(_,g)}:void 0,h=_=>{Object.prototype.hasOwnProperty.call(mt,_.key)&&c({x:mt[_.key].x,y:mt[_.key].y,isShiftPressed:_.shiftKey})};return L.createElement("div",{className:pe(["react-flow__nodesselection","react-flow__container",t]),style:{transform:u}},L.createElement("div",{ref:f,className:"react-flow__nodesselection-rect",onContextMenu:d,tabIndex:r?void 0:-1,onKeyDown:r?void 0:h,style:{width:i,height:a,top:s,left:o}}))}var Fw=k.memo(Lw);const zw=e=>e.nodesSelectionActive,xg=({children:e,onPaneClick:t,onPaneMouseEnter:r,onPaneMouseMove:n,onPaneMouseLeave:i,onPaneContextMenu:a,onPaneScroll:o,deleteKeyCode:s,onMove:u,onMoveStart:l,onMoveEnd:c,selectionKeyCode:f,selectionOnDrag:d,selectionMode:h,onSelectionStart:_,onSelectionEnd:g,multiSelectionKeyCode:v,panActivationKeyCode:p,zoomActivationKeyCode:y,elementsSelectable:b,zoomOnScroll:m,zoomOnPinch:E,panOnScroll:x,panOnScrollSpeed:S,panOnScrollMode:N,zoomOnDoubleClick:q,panOnDrag:A,defaultViewport:I,translateExtent:D,minZoom:O,maxZoom:w,preventScrolling:T,onSelectionContextMenu:C,noWheelClassName:z,noPanClassName:H,disableKeyboardA11y:M})=>{const B=ne(zw),G=Gt(f),V=Gt(p),U=V||A,R=V||x,P=G||d&&U!==!0;return Sw({deleteKeyCode:s,multiSelectionKeyCode:v}),L.createElement(Aw,{onMove:u,onMoveStart:l,onMoveEnd:c,onPaneContextMenu:a,elementsSelectable:b,zoomOnScroll:m,zoomOnPinch:E,panOnScroll:R,panOnScrollSpeed:S,panOnScrollMode:N,zoomOnDoubleClick:q,panOnDrag:!G&&U,defaultViewport:I,translateExtent:D,minZoom:O,maxZoom:w,zoomActivationKeyCode:y,preventScrolling:T,noWheelClassName:z,noPanClassName:H},L.createElement(mg,{onSelectionStart:_,onSelectionEnd:g,onPaneClick:t,onPaneMouseEnter:r,onPaneMouseMove:n,onPaneMouseLeave:i,onPaneContextMenu:a,onPaneScroll:o,panOnDrag:U,isSelecting:!!P,selectionMode:h},e,B&&L.createElement(Fw,{onSelectionContextMenu:C,noPanClassName:H,disableKeyboardA11y:M})))};xg.displayName="FlowRenderer";var Bw=k.memo(xg);function Hw(e){return ne(k.useCallback(r=>e?Jv(r.nodeInternals,{x:0,y:0,width:r.width,height:r.height},r.transform,!0):r.getNodes(),[e]))}function $w(e){const t={input:Mt(e.input||sg),default:Mt(e.default||Au),output:Mt(e.output||cg),group:Mt(e.group||Vu)},r={},n=Object.keys(e).filter(i=>!["input","default","output","group"].includes(i)).reduce((i,a)=>(i[a]=Mt(e[a]||Au),i),r);return{...t,...n}}const Gw=({x:e,y:t,width:r,height:n,origin:i})=>!r||!n?{x:e,y:t}:i[0]<0||i[1]<0||i[0]>1||i[1]>1?{x:e,y:t}:{x:e-r*i[0],y:t-n*i[1]},Vw=e=>({nodesDraggable:e.nodesDraggable,nodesConnectable:e.nodesConnectable,nodesFocusable:e.nodesFocusable,elementsSelectable:e.elementsSelectable,updateNodeDimensions:e.updateNodeDimensions,onError:e.onError}),Sg=e=>{const{nodesDraggable:t,nodesConnectable:r,nodesFocusable:n,elementsSelectable:i,updateNodeDimensions:a,onError:o}=ne(Vw,he),s=Hw(e.onlyRenderVisibleElements),u=k.useRef(),l=k.useMemo(()=>{if(typeof ResizeObserver>"u")return null;const c=new ResizeObserver(f=>{const d=f.map(h=>({id:h.target.getAttribute("data-id"),nodeElement:h.target,forceUpdate:!0}));a(d)});return u.current=c,c},[]);return k.useEffect(()=>()=>{u?.current?.disconnect()},[]),L.createElement("div",{className:"react-flow__nodes",style:ju},s.map(c=>{let f=c.type||"default";e.nodeTypes[f]||(o?.("003",Ue.error003(f)),f="default");const d=e.nodeTypes[f]||e.nodeTypes.default,h=!!(c.draggable||t&&typeof c.draggable>"u"),_=!!(c.selectable||i&&typeof c.selectable>"u"),g=!!(c.connectable||r&&typeof c.connectable>"u"),v=!!(c.focusable||n&&typeof c.focusable>"u"),p=e.nodeExtent?Fu(c.positionAbsolute,e.nodeExtent):c.positionAbsolute,y=p?.x??0,b=p?.y??0,m=Gw({x:y,y:b,width:c.width??0,height:c.height??0,origin:e.nodeOrigin});return L.createElement(d,{key:c.id,id:c.id,className:c.className,style:c.style,type:f,data:c.data,sourcePosition:c.sourcePosition||J.Bottom,targetPosition:c.targetPosition||J.Top,hidden:c.hidden,xPos:y,yPos:b,xPosOrigin:m.x,yPosOrigin:m.y,selectNodesOnDrag:e.selectNodesOnDrag,onClick:e.onNodeClick,onMouseEnter:e.onNodeMouseEnter,onMouseMove:e.onNodeMouseMove,onMouseLeave:e.onNodeMouseLeave,onContextMenu:e.onNodeContextMenu,onDoubleClick:e.onNodeDoubleClick,selected:!!c.selected,isDraggable:h,isSelectable:_,isConnectable:g,isFocusable:v,resizeObserver:l,dragHandle:c.dragHandle,zIndex:c[se]?.z??0,isParent:!!c[se]?.isParent,noDragClassName:e.noDragClassName,noPanClassName:e.noPanClassName,initialized:!!c.width&&!!c.height,rfId:e.rfId,disableKeyboardA11y:e.disableKeyboardA11y,ariaLabel:c.ariaLabel,hasHandleBounds:!!c[se]?.handleBounds})}))};Sg.displayName="NodeRenderer";var Uw=k.memo(Sg);const jw=(e,t,r)=>r===J.Left?e-t:r===J.Right?e+t:e,Kw=(e,t,r)=>r===J.Top?e-t:r===J.Bottom?e+t:e,tl="react-flow__edgeupdater",rl=({position:e,centerX:t,centerY:r,radius:n=10,onMouseDown:i,onMouseEnter:a,onMouseOut:o,type:s})=>L.createElement("circle",{onMouseDown:i,onMouseEnter:a,onMouseOut:o,className:pe([tl,`${tl}-${s}`]),cx:jw(t,n,e),cy:Kw(r,n,e),r:n,stroke:"transparent",fill:"transparent"}),Yw=()=>!0;var vt=e=>{const t=({id:r,className:n,type:i,data:a,onClick:o,onEdgeDoubleClick:s,selected:u,animated:l,label:c,labelStyle:f,labelShowBg:d,labelBgStyle:h,labelBgPadding:_,labelBgBorderRadius:g,style:v,source:p,target:y,sourceX:b,sourceY:m,targetX:E,targetY:x,sourcePosition:S,targetPosition:N,elementsSelectable:q,hidden:A,sourceHandleId:I,targetHandleId:D,onContextMenu:O,onMouseEnter:w,onMouseMove:T,onMouseLeave:C,reconnectRadius:z,onReconnect:H,onReconnectStart:M,onReconnectEnd:B,markerEnd:G,markerStart:V,rfId:U,ariaLabel:R,isFocusable:P,isReconnectable:F,pathOptions:$,interactionWidth:j,disableKeyboardA11y:W})=>{const Z=k.useRef(null),[te,ie]=k.useState(!1),[re,ee]=k.useState(!1),X=fe(),ue=k.useMemo(()=>`url('#${Ru(V,U)}')`,[V,U]),K=k.useMemo(()=>`url('#${Ru(G,U)}')`,[G,U]);if(A)return null;const Y=de=>{const{edges:we,addSelectedEdges:ve,unselectNodesAndEdges:ye,multiSelectionActive:ft}=X.getState(),De=we.find(et=>et.id===r);De&&(q&&(X.setState({nodesSelectionActive:!1}),De.selected&&ft?(ye({nodes:[],edges:[De]}),Z.current?.blur()):ve([r])),o&&o(de,De))},oe=It(r,X.getState,s),Ce=It(r,X.getState,O),Oe=It(r,X.getState,w),ge=It(r,X.getState,T),ce=It(r,X.getState,C),me=(de,we)=>{if(de.button!==0)return;const{edges:ve,isValidConnection:ye}=X.getState(),ft=we?y:p,De=(we?D:I)||null,et=we?"target":"source",Hr=ye||Yw,$r=we,Ct=ve.find(tt=>tt.id===r);ee(!0),M?.(de,Ct,et);const Gr=tt=>{ee(!1),B?.(tt,Ct,et)};ng({event:de,handleId:De,nodeId:ft,onConnect:tt=>H?.(Ct,tt),isTarget:$r,getState:X.getState,setState:X.setState,isValidConnection:Hr,edgeUpdaterType:et,onReconnectEnd:Gr})},Ae=de=>me(de,!0),ze=de=>me(de,!1),ke=()=>ie(!0),be=()=>ie(!1),Be=!q&&!o,Ye=de=>{if(!W&&Uv.includes(de.key)&&q){const{unselectNodesAndEdges:we,addSelectedEdges:ve,edges:ye}=X.getState();de.key==="Escape"?(Z.current?.blur(),we({edges:[ye.find(De=>De.id===r)]})):ve([r])}};return L.createElement("g",{className:pe(["react-flow__edge",`react-flow__edge-${i}`,n,{selected:u,animated:l,inactive:Be,updating:te}]),onClick:Y,onDoubleClick:oe,onContextMenu:Ce,onMouseEnter:Oe,onMouseMove:ge,onMouseLeave:ce,onKeyDown:P?Ye:void 0,tabIndex:P?0:void 0,role:P?"button":"img","data-testid":`rf__edge-${r}`,"aria-label":R===null?void 0:R||`Edge from ${p} to ${y}`,"aria-describedby":P?`${dg}-${U}`:void 0,ref:Z},!re&&L.createElement(e,{id:r,source:p,target:y,selected:u,animated:l,label:c,labelStyle:f,labelShowBg:d,labelBgStyle:h,labelBgPadding:_,labelBgBorderRadius:g,data:a,style:v,sourceX:b,sourceY:m,targetX:E,targetY:x,sourcePosition:S,targetPosition:N,sourceHandleId:I,targetHandleId:D,markerStart:ue,markerEnd:K,pathOptions:$,interactionWidth:j}),F&&L.createElement(L.Fragment,null,(F==="source"||F===!0)&&L.createElement(rl,{position:S,centerX:b,centerY:m,radius:z,onMouseDown:Ae,onMouseEnter:ke,onMouseOut:be,type:"source"}),(F==="target"||F===!0)&&L.createElement(rl,{position:N,centerX:E,centerY:x,radius:z,onMouseDown:ze,onMouseEnter:ke,onMouseOut:be,type:"target"})))};return t.displayName="EdgeWrapper",k.memo(t)};function Ww(e){const t={default:vt(e.default||pr),straight:vt(e.bezier||Hu),step:vt(e.step||Bu),smoothstep:vt(e.step||Er),simplebezier:vt(e.simplebezier||zu)},r={},n=Object.keys(e).filter(i=>!["default","bezier"].includes(i)).reduce((i,a)=>(i[a]=vt(e[a]||pr),i),r);return{...t,...n}}function nl(e,t,r=null){const n=(r?.x||0)+t.x,i=(r?.y||0)+t.y,a=r?.width||t.width,o=r?.height||t.height;switch(e){case J.Top:return{x:n+a/2,y:i};case J.Right:return{x:n+a,y:i+o/2};case J.Bottom:return{x:n+a/2,y:i+o};case J.Left:return{x:n,y:i+o/2}}}function il(e,t){return e?e.length===1||!t?e[0]:t&&e.find(r=>r.id===t)||null:null}const Zw=(e,t,r,n,i,a)=>{const o=nl(r,e,t),s=nl(a,n,i);return{sourceX:o.x,sourceY:o.y,targetX:s.x,targetY:s.y}};function Xw({sourcePos:e,targetPos:t,sourceWidth:r,sourceHeight:n,targetWidth:i,targetHeight:a,width:o,height:s,transform:u}){const l={x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x+r,t.x+i),y2:Math.max(e.y+n,t.y+a)};l.x===l.x2&&(l.x2+=1),l.y===l.y2&&(l.y2+=1);const c=Ht({x:(0-u[0])/u[2],y:(0-u[1])/u[2],width:o/u[2],height:s/u[2]}),f=Math.max(0,Math.min(c.x2,l.x2)-Math.max(c.x,l.x)),d=Math.max(0,Math.min(c.y2,l.y2)-Math.max(c.y,l.y));return Math.ceil(f*d)>0}function al(e){const t=e?.[se]?.handleBounds||null,r=t&&e?.width&&e?.height&&typeof e?.positionAbsolute?.x<"u"&&typeof e?.positionAbsolute?.y<"u";return[{x:e?.positionAbsolute?.x||0,y:e?.positionAbsolute?.y||0,width:e?.width||0,height:e?.height||0},t,!!r]}const Jw=[{level:0,isMaxLevel:!0,edges:[]}];function Qw(e,t,r=!1){let n=-1;const i=e.reduce((o,s)=>{const u=Se(s.zIndex);let l=u?s.zIndex:0;if(r){const c=t.get(s.target),f=t.get(s.source),d=s.selected||c?.selected||f?.selected,h=Math.max(f?.[se]?.z||0,c?.[se]?.z||0,1e3);l=(u?s.zIndex:0)+(d?h:0)}return o[l]?o[l].push(s):o[l]=[s],n=l>n?l:n,o},{}),a=Object.entries(i).map(([o,s])=>{const u=+o;return{edges:s,level:u,isMaxLevel:u===n}});return a.length===0?Jw:a}function e1(e,t,r){const n=ne(k.useCallback(i=>e?i.edges.filter(a=>{const o=t.get(a.source),s=t.get(a.target);return o?.width&&o?.height&&s?.width&&s?.height&&Xw({sourcePos:o.positionAbsolute||{x:0,y:0},targetPos:s.positionAbsolute||{x:0,y:0},sourceWidth:o.width,sourceHeight:o.height,targetWidth:s.width,targetHeight:s.height,width:i.width,height:i.height,transform:i.transform})}):i.edges,[e,t]));return Qw(n,t,r)}const t1=({color:e="none",strokeWidth:t=1})=>L.createElement("polyline",{style:{stroke:e,strokeWidth:t},strokeLinecap:"round",strokeLinejoin:"round",fill:"none",points:"-5,-4 0,0 -5,4"}),r1=({color:e="none",strokeWidth:t=1})=>L.createElement("polyline",{style:{stroke:e,fill:e,strokeWidth:t},strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"}),ol={[hr.Arrow]:t1,[hr.ArrowClosed]:r1};function n1(e){const t=fe();return k.useMemo(()=>Object.prototype.hasOwnProperty.call(ol,e)?ol[e]:(t.getState().onError?.("009",Ue.error009(e)),null),[e])}const i1=({id:e,type:t,color:r,width:n=12.5,height:i=12.5,markerUnits:a="strokeWidth",strokeWidth:o,orient:s="auto-start-reverse"})=>{const u=n1(t);return u?L.createElement("marker",{className:"react-flow__arrowhead",id:e,markerWidth:`${n}`,markerHeight:`${i}`,viewBox:"-10 -10 20 20",markerUnits:a,orient:s,refX:"0",refY:"0"},L.createElement(u,{color:r,strokeWidth:o})):null},a1=({defaultColor:e,rfId:t})=>r=>{const n=[];return r.edges.reduce((i,a)=>([a.markerStart,a.markerEnd].forEach(o=>{if(o&&typeof o=="object"){const s=Ru(o,t);n.includes(s)||(i.push({id:s,color:o.color||e,...o}),n.push(s))}}),i),[]).sort((i,a)=>i.id.localeCompare(a.id))},qg=({defaultColor:e,rfId:t})=>{const r=ne(k.useCallback(a1({defaultColor:e,rfId:t}),[e,t]),(n,i)=>!(n.length!==i.length||n.some((a,o)=>a.id!==i[o].id)));return L.createElement("defs",null,r.map(n=>L.createElement(i1,{id:n.id,key:n.id,type:n.type,color:n.color,width:n.width,height:n.height,markerUnits:n.markerUnits,strokeWidth:n.strokeWidth,orient:n.orient})))};qg.displayName="MarkerDefinitions";var o1=k.memo(qg);const s1=e=>({nodesConnectable:e.nodesConnectable,edgesFocusable:e.edgesFocusable,edgesUpdatable:e.edgesUpdatable,elementsSelectable:e.elementsSelectable,width:e.width,height:e.height,connectionMode:e.connectionMode,nodeInternals:e.nodeInternals,onError:e.onError}),Rg=({defaultMarkerColor:e,onlyRenderVisibleElements:t,elevateEdgesOnSelect:r,rfId:n,edgeTypes:i,noPanClassName:a,onEdgeContextMenu:o,onEdgeMouseEnter:s,onEdgeMouseMove:u,onEdgeMouseLeave:l,onEdgeClick:c,onEdgeDoubleClick:f,onReconnect:d,onReconnectStart:h,onReconnectEnd:_,reconnectRadius:g,children:v,disableKeyboardA11y:p})=>{const{edgesFocusable:y,edgesUpdatable:b,elementsSelectable:m,width:E,height:x,connectionMode:S,nodeInternals:N,onError:q}=ne(s1,he),A=e1(t,N,r);return E?L.createElement(L.Fragment,null,A.map(({level:I,edges:D,isMaxLevel:O})=>L.createElement("svg",{key:I,style:{zIndex:I},width:E,height:x,className:"react-flow__edges react-flow__container"},O&&L.createElement(o1,{defaultColor:e,rfId:n}),L.createElement("g",null,D.map(w=>{const[T,C,z]=al(N.get(w.source)),[H,M,B]=al(N.get(w.target));if(!z||!B)return null;let G=w.type||"default";i[G]||(q?.("011",Ue.error011(G)),G="default");const V=i[G]||i.default,U=S===ot.Strict?M.target:(M.target??[]).concat(M.source??[]),R=il(C.source,w.sourceHandle),P=il(U,w.targetHandle),F=R?.position||J.Bottom,$=P?.position||J.Top,j=!!(w.focusable||y&&typeof w.focusable>"u"),W=w.reconnectable||w.updatable,Z=typeof d<"u"&&(W||b&&typeof W>"u");if(!R||!P)return q?.("008",Ue.error008(R,w)),null;const{sourceX:te,sourceY:ie,targetX:re,targetY:ee}=Zw(T,R,F,H,P,$);return L.createElement(V,{key:w.id,id:w.id,className:pe([w.className,a]),type:G,data:w.data,selected:!!w.selected,animated:!!w.animated,hidden:!!w.hidden,label:w.label,labelStyle:w.labelStyle,labelShowBg:w.labelShowBg,labelBgStyle:w.labelBgStyle,labelBgPadding:w.labelBgPadding,labelBgBorderRadius:w.labelBgBorderRadius,style:w.style,source:w.source,target:w.target,sourceHandleId:w.sourceHandle,targetHandleId:w.targetHandle,markerEnd:w.markerEnd,markerStart:w.markerStart,sourceX:te,sourceY:ie,targetX:re,targetY:ee,sourcePosition:F,targetPosition:$,elementsSelectable:m,onContextMenu:o,onMouseEnter:s,onMouseMove:u,onMouseLeave:l,onClick:c,onEdgeDoubleClick:f,onReconnect:d,onReconnectStart:h,onReconnectEnd:_,reconnectRadius:g,rfId:n,ariaLabel:w.ariaLabel,isFocusable:j,isReconnectable:Z,pathOptions:"pathOptions"in w?w.pathOptions:void 0,interactionWidth:w.interactionWidth,disableKeyboardA11y:p})})))),v):null};Rg.displayName="EdgeRenderer";var u1=k.memo(Rg);const c1=e=>`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]})`;function l1({children:e}){const t=ne(c1);return L.createElement("div",{className:"react-flow__viewport react-flow__container",style:{transform:t}},e)}function f1(e){const t=Uu(),r=k.useRef(!1);k.useEffect(()=>{!r.current&&t.viewportInitialized&&e&&(setTimeout(()=>e(t),1),r.current=!0)},[e,t.viewportInitialized])}const d1={[J.Left]:J.Right,[J.Right]:J.Left,[J.Top]:J.Bottom,[J.Bottom]:J.Top},Cg=({nodeId:e,handleType:t,style:r,type:n=Xe.Bezier,CustomComponent:i,connectionStatus:a})=>{const{fromNode:o,handleId:s,toX:u,toY:l,connectionMode:c}=ne(k.useCallback(x=>({fromNode:x.nodeInternals.get(e),handleId:x.connectionHandleId,toX:(x.connectionPosition.x-x.transform[0])/x.transform[2],toY:(x.connectionPosition.y-x.transform[1])/x.transform[2],connectionMode:x.connectionMode}),[e]),he),f=o?.[se]?.handleBounds;let d=f?.[t];if(c===ot.Loose&&(d=d||f?.[t==="source"?"target":"source"]),!o||!d)return null;const h=s?d.find(x=>x.id===s):d[0],_=h?h.x+h.width/2:(o.width??0)/2,g=h?h.y+h.height/2:o.height??0,v=(o.positionAbsolute?.x??0)+_,p=(o.positionAbsolute?.y??0)+g,y=h?.position,b=y?d1[y]:null;if(!y||!b)return null;if(i)return L.createElement(i,{connectionLineType:n,connectionLineStyle:r,fromNode:o,fromHandle:h,fromX:v,fromY:p,toX:u,toY:l,fromPosition:y,toPosition:b,connectionStatus:a});let m="";const E={sourceX:v,sourceY:p,sourcePosition:y,targetX:u,targetY:l,targetPosition:b};return n===Xe.Bezier?[m]=Zv(E):n===Xe.Step?[m]=qu({...E,borderRadius:0}):n===Xe.SmoothStep?[m]=qu(E):n===Xe.SimpleBezier?[m]=Wv(E):m=`M${v},${p} ${u},${l}`,L.createElement("path",{d:m,fill:"none",className:"react-flow__connection-path",style:r})};Cg.displayName="ConnectionLine";const h1=e=>({nodeId:e.connectionNodeId,handleType:e.connectionHandleType,nodesConnectable:e.nodesConnectable,connectionStatus:e.connectionStatus,width:e.width,height:e.height});function p1({containerStyle:e,style:t,type:r,component:n}){const{nodeId:i,handleType:a,nodesConnectable:o,width:s,height:u,connectionStatus:l}=ne(h1,he);return!(i&&a&&s&&o)?null:L.createElement("svg",{style:e,width:s,height:u,className:"react-flow__edges react-flow__connectionline react-flow__container"},L.createElement("g",{className:pe(["react-flow__connection",l])},L.createElement(Cg,{nodeId:i,handleType:a,style:t,type:r,CustomComponent:n,connectionStatus:l})))}function sl(e,t){return k.useRef(null),fe(),k.useMemo(()=>t(e),[e])}const Ag=({nodeTypes:e,edgeTypes:t,onMove:r,onMoveStart:n,onMoveEnd:i,onInit:a,onNodeClick:o,onEdgeClick:s,onNodeDoubleClick:u,onEdgeDoubleClick:l,onNodeMouseEnter:c,onNodeMouseMove:f,onNodeMouseLeave:d,onNodeContextMenu:h,onSelectionContextMenu:_,onSelectionStart:g,onSelectionEnd:v,connectionLineType:p,connectionLineStyle:y,connectionLineComponent:b,connectionLineContainerStyle:m,selectionKeyCode:E,selectionOnDrag:x,selectionMode:S,multiSelectionKeyCode:N,panActivationKeyCode:q,zoomActivationKeyCode:A,deleteKeyCode:I,onlyRenderVisibleElements:D,elementsSelectable:O,selectNodesOnDrag:w,defaultViewport:T,translateExtent:C,minZoom:z,maxZoom:H,preventScrolling:M,defaultMarkerColor:B,zoomOnScroll:G,zoomOnPinch:V,panOnScroll:U,panOnScrollSpeed:R,panOnScrollMode:P,zoomOnDoubleClick:F,panOnDrag:$,onPaneClick:j,onPaneMouseEnter:W,onPaneMouseMove:Z,onPaneMouseLeave:te,onPaneScroll:ie,onPaneContextMenu:re,onEdgeContextMenu:ee,onEdgeMouseEnter:X,onEdgeMouseMove:ue,onEdgeMouseLeave:K,onReconnect:Y,onReconnectStart:oe,onReconnectEnd:Ce,reconnectRadius:Oe,noDragClassName:ge,noWheelClassName:ce,noPanClassName:me,elevateEdgesOnSelect:Ae,disableKeyboardA11y:ze,nodeOrigin:ke,nodeExtent:be,rfId:Be})=>{const Ye=sl(e,$w),de=sl(t,Ww);return f1(a),L.createElement(Bw,{onPaneClick:j,onPaneMouseEnter:W,onPaneMouseMove:Z,onPaneMouseLeave:te,onPaneContextMenu:re,onPaneScroll:ie,deleteKeyCode:I,selectionKeyCode:E,selectionOnDrag:x,selectionMode:S,onSelectionStart:g,onSelectionEnd:v,multiSelectionKeyCode:N,panActivationKeyCode:q,zoomActivationKeyCode:A,elementsSelectable:O,onMove:r,onMoveStart:n,onMoveEnd:i,zoomOnScroll:G,zoomOnPinch:V,zoomOnDoubleClick:F,panOnScroll:U,panOnScrollSpeed:R,panOnScrollMode:P,panOnDrag:$,defaultViewport:T,translateExtent:C,minZoom:z,maxZoom:H,onSelectionContextMenu:_,preventScrolling:M,noDragClassName:ge,noWheelClassName:ce,noPanClassName:me,disableKeyboardA11y:ze},L.createElement(l1,null,L.createElement(u1,{edgeTypes:de,onEdgeClick:s,onEdgeDoubleClick:l,onlyRenderVisibleElements:D,onEdgeContextMenu:ee,onEdgeMouseEnter:X,onEdgeMouseMove:ue,onEdgeMouseLeave:K,onReconnect:Y,onReconnectStart:oe,onReconnectEnd:Ce,reconnectRadius:Oe,defaultMarkerColor:B,noPanClassName:me,elevateEdgesOnSelect:!!Ae,disableKeyboardA11y:ze,rfId:Be},L.createElement(p1,{style:y,type:p,component:b,containerStyle:m})),L.createElement("div",{className:"react-flow__edgelabel-renderer"}),L.createElement(Uw,{nodeTypes:Ye,onNodeClick:o,onNodeDoubleClick:u,onNodeMouseEnter:c,onNodeMouseMove:f,onNodeMouseLeave:d,onNodeContextMenu:h,selectNodesOnDrag:w,onlyRenderVisibleElements:D,noPanClassName:me,noDragClassName:ge,disableKeyboardA11y:ze,nodeOrigin:ke,nodeExtent:be,rfId:Be})))};Ag.displayName="GraphView";var v1=k.memo(Ag);const Iu=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],We={rfId:"1",width:0,height:0,transform:[0,0,1],nodeInternals:new Map,edges:[],onNodesChange:null,onEdgesChange:null,hasDefaultNodes:!1,hasDefaultEdges:!1,d3Zoom:null,d3Selection:null,d3ZoomHandler:void 0,minZoom:.5,maxZoom:2,translateExtent:Iu,nodeExtent:Iu,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionNodeId:null,connectionHandleId:null,connectionHandleType:"source",connectionPosition:{x:0,y:0},connectionStatus:null,connectionMode:ot.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:[0,0],nodeDragThreshold:0,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesUpdatable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,fitViewOnInit:!1,fitViewOnInitDone:!1,fitViewOnInitOptions:void 0,onSelectionChange:[],multiSelectionActive:!1,connectionStartHandle:null,connectionEndHandle:null,connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,connectionRadius:20,onError:G0,isValidConnection:void 0},g1=()=>Im((e,t)=>({...We,setNodes:r=>{const{nodeInternals:n,nodeOrigin:i,elevateNodesOnSelect:a}=t();e({nodeInternals:un(r,n,i,a)})},getNodes:()=>Array.from(t().nodeInternals.values()),setEdges:r=>{const{defaultEdgeOptions:n={}}=t();e({edges:r.map(i=>({...n,...i}))})},setDefaultNodesAndEdges:(r,n)=>{const i=typeof r<"u",a=typeof n<"u",o=i?un(r,new Map,t().nodeOrigin,t().elevateNodesOnSelect):new Map;e({nodeInternals:o,edges:a?n:[],hasDefaultNodes:i,hasDefaultEdges:a})},updateNodeDimensions:r=>{const{onNodesChange:n,nodeInternals:i,fitViewOnInit:a,fitViewOnInitDone:o,fitViewOnInitOptions:s,domNode:u,nodeOrigin:l}=t(),c=u?.querySelector(".react-flow__viewport");if(!c)return;const f=window.getComputedStyle(c),{m22:d}=new window.DOMMatrixReadOnly(f.transform),h=r.reduce((g,v)=>{const p=i.get(v.id);if(p?.hidden)i.set(p.id,{...p,[se]:{...p[se],handleBounds:void 0}});else if(p){const y=Lu(v.nodeElement);!!(y.width&&y.height&&(p.width!==y.width||p.height!==y.height||v.forceUpdate))&&(i.set(p.id,{...p,[se]:{...p[se],handleBounds:{source:el(".source",v.nodeElement,d,l),target:el(".target",v.nodeElement,d,l)}},...y}),g.push({id:p.id,type:"dimensions",dimensions:y}))}return g},[]);pg(i,l);const _=o||a&&!o&&vg(t,{initial:!0,...s});e({nodeInternals:new Map(i),fitViewOnInitDone:_}),h?.length>0&&n?.(h)},updateNodePositions:(r,n=!0,i=!1)=>{const{triggerNodeChanges:a}=t(),o=r.map(s=>{const u={id:s.id,type:"position",dragging:i};return n&&(u.positionAbsolute=s.positionAbsolute,u.position=s.position),u});a(o)},triggerNodeChanges:r=>{const{onNodesChange:n,nodeInternals:i,hasDefaultNodes:a,nodeOrigin:o,getNodes:s,elevateNodesOnSelect:u}=t();if(r?.length){if(a){const l=yg(r,s()),c=un(l,i,o,u);e({nodeInternals:c})}n?.(r)}},addSelectedNodes:r=>{const{multiSelectionActive:n,edges:i,getNodes:a}=t();let o,s=null;n?o=r.map(u=>Ze(u,!0)):(o=gt(a(),r),s=gt(i,[])),rr({changedNodes:o,changedEdges:s,get:t,set:e})},addSelectedEdges:r=>{const{multiSelectionActive:n,edges:i,getNodes:a}=t();let o,s=null;n?o=r.map(u=>Ze(u,!0)):(o=gt(i,r),s=gt(a(),[])),rr({changedNodes:s,changedEdges:o,get:t,set:e})},unselectNodesAndEdges:({nodes:r,edges:n}={})=>{const{edges:i,getNodes:a}=t(),o=r||a(),s=n||i,u=o.map(c=>(c.selected=!1,Ze(c.id,!1))),l=s.map(c=>Ze(c.id,!1));rr({changedNodes:u,changedEdges:l,get:t,set:e})},setMinZoom:r=>{const{d3Zoom:n,maxZoom:i}=t();n?.scaleExtent([r,i]),e({minZoom:r})},setMaxZoom:r=>{const{d3Zoom:n,minZoom:i}=t();n?.scaleExtent([i,r]),e({maxZoom:r})},setTranslateExtent:r=>{t().d3Zoom?.translateExtent(r),e({translateExtent:r})},resetSelectedElements:()=>{const{edges:r,getNodes:n}=t(),a=n().filter(s=>s.selected).map(s=>Ze(s.id,!1)),o=r.filter(s=>s.selected).map(s=>Ze(s.id,!1));rr({changedNodes:a,changedEdges:o,get:t,set:e})},setNodeExtent:r=>{const{nodeInternals:n}=t();n.forEach(i=>{i.positionAbsolute=Fu(i.position,r)}),e({nodeExtent:r,nodeInternals:new Map(n)})},panBy:r=>{const{transform:n,width:i,height:a,d3Zoom:o,d3Selection:s,translateExtent:u}=t();if(!o||!s||!r.x&&!r.y)return!1;const l=Ge.translate(n[0]+r.x,n[1]+r.y).scale(n[2]),c=[[0,0],[i,a]],f=o?.constrain()(l,c,u);return o.transform(s,f),n[0]!==f.x||n[1]!==f.y||n[2]!==f.k},cancelConnection:()=>e({connectionNodeId:We.connectionNodeId,connectionHandleId:We.connectionHandleId,connectionHandleType:We.connectionHandleType,connectionStatus:We.connectionStatus,connectionStartHandle:We.connectionStartHandle,connectionEndHandle:We.connectionEndHandle}),reset:()=>e({...We})}),Object.is),Ng=({children:e})=>{const t=k.useRef(null);return t.current||(t.current=g1()),L.createElement(D0,{value:t.current},e)};Ng.displayName="ReactFlowProvider";const Ig=({children:e})=>k.useContext(wr)?L.createElement(L.Fragment,null,e):L.createElement(Ng,null,e);Ig.displayName="ReactFlowWrapper";const y1={input:sg,default:Au,output:cg,group:Vu},m1={default:pr,straight:Hu,step:Bu,smoothstep:Er,simplebezier:zu},_1=[0,0],b1=[15,15],w1={x:0,y:0,zoom:1},E1={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},x1=k.forwardRef(({nodes:e,edges:t,defaultNodes:r,defaultEdges:n,className:i,nodeTypes:a=y1,edgeTypes:o=m1,onNodeClick:s,onEdgeClick:u,onInit:l,onMove:c,onMoveStart:f,onMoveEnd:d,onConnect:h,onConnectStart:_,onConnectEnd:g,onClickConnectStart:v,onClickConnectEnd:p,onNodeMouseEnter:y,onNodeMouseMove:b,onNodeMouseLeave:m,onNodeContextMenu:E,onNodeDoubleClick:x,onNodeDragStart:S,onNodeDrag:N,onNodeDragStop:q,onNodesDelete:A,onEdgesDelete:I,onSelectionChange:D,onSelectionDragStart:O,onSelectionDrag:w,onSelectionDragStop:T,onSelectionContextMenu:C,onSelectionStart:z,onSelectionEnd:H,connectionMode:M=ot.Strict,connectionLineType:B=Xe.Bezier,connectionLineStyle:G,connectionLineComponent:V,connectionLineContainerStyle:U,deleteKeyCode:R="Backspace",selectionKeyCode:P="Shift",selectionOnDrag:F=!1,selectionMode:$=$t.Full,panActivationKeyCode:j="Space",multiSelectionKeyCode:W=dr()?"Meta":"Control",zoomActivationKeyCode:Z=dr()?"Meta":"Control",snapToGrid:te=!1,snapGrid:ie=b1,onlyRenderVisibleElements:re=!1,selectNodesOnDrag:ee=!0,nodesDraggable:X,nodesConnectable:ue,nodesFocusable:K,nodeOrigin:Y=_1,edgesFocusable:oe,edgesUpdatable:Ce,elementsSelectable:Oe,defaultViewport:ge=w1,minZoom:ce=.5,maxZoom:me=2,translateExtent:Ae=Iu,preventScrolling:ze=!0,nodeExtent:ke,defaultMarkerColor:be="#b1b1b7",zoomOnScroll:Be=!0,zoomOnPinch:Ye=!0,panOnScroll:de=!1,panOnScrollSpeed:we=.5,panOnScrollMode:ve=nt.Free,zoomOnDoubleClick:ye=!0,panOnDrag:ft=!0,onPaneClick:De,onPaneMouseEnter:et,onPaneMouseMove:Hr,onPaneMouseLeave:$r,onPaneScroll:Ct,onPaneContextMenu:Gr,children:fc,onEdgeContextMenu:tt,onEdgeDoubleClick:Oy,onEdgeMouseEnter:ky,onEdgeMouseMove:Dy,onEdgeMouseLeave:Ly,onEdgeUpdate:Fy,onEdgeUpdateStart:zy,onEdgeUpdateEnd:By,onReconnect:Hy,onReconnectStart:$y,onReconnectEnd:Gy,reconnectRadius:Vy=10,edgeUpdaterRadius:Uy=10,onNodesChange:jy,onEdgesChange:Ky,noDragClassName:Yy="nodrag",noWheelClassName:Wy="nowheel",noPanClassName:dc="nopan",fitView:Zy=!1,fitViewOptions:Xy,connectOnClick:Jy=!0,attributionPosition:Qy,proOptions:em,defaultEdgeOptions:tm,elevateNodesOnSelect:rm=!0,elevateEdgesOnSelect:nm=!1,disableKeyboardA11y:hc=!1,autoPanOnConnect:im=!0,autoPanOnNodeDrag:am=!0,connectionRadius:om=20,isValidConnection:sm,onError:um,style:cm,id:pc,nodeDragThreshold:lm,...fm},dm)=>{const Vr=pc||"1";return L.createElement("div",{...fm,style:{...cm,...E1},ref:dm,className:pe(["react-flow",i]),"data-testid":"rf__wrapper",id:pc},L.createElement(Ig,null,L.createElement(v1,{onInit:l,onMove:c,onMoveStart:f,onMoveEnd:d,onNodeClick:s,onEdgeClick:u,onNodeMouseEnter:y,onNodeMouseMove:b,onNodeMouseLeave:m,onNodeContextMenu:E,onNodeDoubleClick:x,nodeTypes:a,edgeTypes:o,connectionLineType:B,connectionLineStyle:G,connectionLineComponent:V,connectionLineContainerStyle:U,selectionKeyCode:P,selectionOnDrag:F,selectionMode:$,deleteKeyCode:R,multiSelectionKeyCode:W,panActivationKeyCode:j,zoomActivationKeyCode:Z,onlyRenderVisibleElements:re,selectNodesOnDrag:ee,defaultViewport:ge,translateExtent:Ae,minZoom:ce,maxZoom:me,preventScrolling:ze,zoomOnScroll:Be,zoomOnPinch:Ye,zoomOnDoubleClick:ye,panOnScroll:de,panOnScrollSpeed:we,panOnScrollMode:ve,panOnDrag:ft,onPaneClick:De,onPaneMouseEnter:et,onPaneMouseMove:Hr,onPaneMouseLeave:$r,onPaneScroll:Ct,onPaneContextMenu:Gr,onSelectionContextMenu:C,onSelectionStart:z,onSelectionEnd:H,onEdgeContextMenu:tt,onEdgeDoubleClick:Oy,onEdgeMouseEnter:ky,onEdgeMouseMove:Dy,onEdgeMouseLeave:Ly,onReconnect:Hy??Fy,onReconnectStart:$y??zy,onReconnectEnd:Gy??By,reconnectRadius:Vy??Uy,defaultMarkerColor:be,noDragClassName:Yy,noWheelClassName:Wy,noPanClassName:dc,elevateEdgesOnSelect:nm,rfId:Vr,disableKeyboardA11y:hc,nodeOrigin:Y,nodeExtent:ke}),L.createElement(dw,{nodes:e,edges:t,defaultNodes:r,defaultEdges:n,onConnect:h,onConnectStart:_,onConnectEnd:g,onClickConnectStart:v,onClickConnectEnd:p,nodesDraggable:X,nodesConnectable:ue,nodesFocusable:K,edgesFocusable:oe,edgesUpdatable:Ce,elementsSelectable:Oe,elevateNodesOnSelect:rm,minZoom:ce,maxZoom:me,nodeExtent:ke,onNodesChange:jy,onEdgesChange:Ky,snapToGrid:te,snapGrid:ie,connectionMode:M,translateExtent:Ae,connectOnClick:Jy,defaultEdgeOptions:tm,fitView:Zy,fitViewOptions:Xy,onNodesDelete:A,onEdgesDelete:I,onNodeDragStart:S,onNodeDrag:N,onNodeDragStop:q,onSelectionDrag:w,onSelectionDragStart:O,onSelectionDragStop:T,noPanClassName:dc,nodeOrigin:Y,rfId:Vr,autoPanOnConnect:im,autoPanOnNodeDrag:am,onError:um,connectionRadius:om,isValidConnection:sm,nodeDragThreshold:lm}),L.createElement(lw,{onSelectionChange:D}),fc,L.createElement(F0,{proOptions:em,position:Qy}),L.createElement(yw,{rfId:Vr,disableKeyboardA11y:hc})))});x1.displayName="ReactFlow";function Tg(e){return t=>{const[r,n]=k.useState(t),i=k.useCallback(a=>n(o=>e(a,o)),[]);return[r,n,i]}}const tq=Tg(yg),rq=Tg(Tw),Mg=({id:e,x:t,y:r,width:n,height:i,style:a,color:o,strokeColor:s,strokeWidth:u,className:l,borderRadius:c,shapeRendering:f,onClick:d,selected:h})=>{const{background:_,backgroundColor:g}=a||{},v=o||_||g;return L.createElement("rect",{className:pe(["react-flow__minimap-node",{selected:h},l]),x:t,y:r,rx:c,ry:c,width:n,height:i,fill:v,stroke:s,strokeWidth:u,shapeRendering:f,onClick:d?p=>d(p,e):void 0})};Mg.displayName="MiniMapNode";var S1=k.memo(Mg);const q1=e=>e.nodeOrigin,R1=e=>e.getNodes().filter(t=>!t.hidden&&t.width&&t.height),dn=e=>e instanceof Function?e:()=>e;function C1({nodeStrokeColor:e="transparent",nodeColor:t="#e2e2e2",nodeClassName:r="",nodeBorderRadius:n=5,nodeStrokeWidth:i=2,nodeComponent:a=S1,onClick:o}){const s=ne(R1,he),u=ne(q1),l=dn(t),c=dn(e),f=dn(r),d=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return L.createElement(L.Fragment,null,s.map(h=>{const{x:_,y:g}=it(h,u).positionAbsolute;return L.createElement(a,{key:h.id,x:_,y:g,width:h.width,height:h.height,style:h.style,selected:h.selected,className:f(h),color:l(h),borderRadius:n,strokeColor:c(h),strokeWidth:i,shapeRendering:d,onClick:o,id:h.id})}))}var A1=k.memo(C1);const N1=200,I1=150,T1=e=>{const t=e.getNodes(),r={x:-e.transform[0]/e.transform[2],y:-e.transform[1]/e.transform[2],width:e.width/e.transform[2],height:e.height/e.transform[2]};return{viewBB:r,boundingRect:t.length>0?H0(xr(t,e.nodeOrigin),r):r,rfId:e.rfId}},M1="react-flow__minimap-desc";function Pg({style:e,className:t,nodeStrokeColor:r="transparent",nodeColor:n="#e2e2e2",nodeClassName:i="",nodeBorderRadius:a=5,nodeStrokeWidth:o=2,nodeComponent:s,maskColor:u="rgb(240, 240, 240, 0.6)",maskStrokeColor:l="none",maskStrokeWidth:c=1,position:f="bottom-right",onClick:d,onNodeClick:h,pannable:_=!1,zoomable:g=!1,ariaLabel:v="React Flow mini map",inversePan:p=!1,zoomStep:y=10,offsetScale:b=5}){const m=fe(),E=k.useRef(null),{boundingRect:x,viewBB:S,rfId:N}=ne(T1,he),q=e?.width??N1,A=e?.height??I1,I=x.width/q,D=x.height/A,O=Math.max(I,D),w=O*q,T=O*A,C=b*O,z=x.x-(w-x.width)/2-C,H=x.y-(T-x.height)/2-C,M=w+C*2,B=T+C*2,G=`${M1}-${N}`,V=k.useRef(0);V.current=O,k.useEffect(()=>{if(E.current){const P=xe(E.current),F=W=>{const{transform:Z,d3Selection:te,d3Zoom:ie}=m.getState();if(W.sourceEvent.type!=="wheel"||!te||!ie)return;const re=-W.sourceEvent.deltaY*(W.sourceEvent.deltaMode===1?.05:W.sourceEvent.deltaMode?1:.002)*y,ee=Z[2]*Math.pow(2,re);ie.scaleTo(te,ee)},$=W=>{const{transform:Z,d3Selection:te,d3Zoom:ie,translateExtent:re,width:ee,height:X}=m.getState();if(W.sourceEvent.type!=="mousemove"||!te||!ie)return;const ue=V.current*Math.max(1,Z[2])*(p?-1:1),K={x:Z[0]-W.sourceEvent.movementX*ue,y:Z[1]-W.sourceEvent.movementY*ue},Y=[[0,0],[ee,X]],oe=Ge.translate(K.x,K.y).scale(Z[2]),Ce=ie.constrain()(oe,Y,re);ie.transform(te,Ce)},j=zv().on("zoom",_?$:null).on("zoom.wheel",g?F:null);return P.call(j),()=>{P.on("zoom",null)}}},[_,g,p,y]);const U=d?P=>{const F=Ne(P);d(P,{x:F[0],y:F[1]})}:void 0,R=h?(P,F)=>{const $=m.getState().nodeInternals.get(F);h(P,$)}:void 0;return L.createElement(Du,{position:f,style:e,className:pe(["react-flow__minimap",t]),"data-testid":"rf__minimap"},L.createElement("svg",{width:q,height:A,viewBox:`${z} ${H} ${M} ${B}`,role:"img","aria-labelledby":G,ref:E,onClick:U},v&&L.createElement("title",{id:G},v),L.createElement(A1,{onClick:R,nodeColor:n,nodeStrokeColor:r,nodeBorderRadius:a,nodeClassName:i,nodeStrokeWidth:o,nodeComponent:s}),L.createElement("path",{className:"react-flow__minimap-mask",d:`M${z-C},${H-C}h${M+C*2}v${B+C*2}h${-M-C*2}z + M${S.x},${S.y}h${S.width}v${S.height}h${-S.width}z`,fill:u,fillRule:"evenodd",stroke:l,strokeWidth:c,pointerEvents:"none"})))}Pg.displayName="MiniMap";var nq=k.memo(Pg);function P1(){return L.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32"},L.createElement("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"}))}function O1(){return L.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5"},L.createElement("path",{d:"M0 0h32v4.2H0z"}))}function k1(){return L.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30"},L.createElement("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"}))}function D1(){return L.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32"},L.createElement("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"}))}function L1(){return L.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32"},L.createElement("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"}))}const kt=({children:e,className:t,...r})=>L.createElement("button",{type:"button",className:pe(["react-flow__controls-button",t]),...r},e);kt.displayName="ControlButton";const F1=e=>({isInteractive:e.nodesDraggable||e.nodesConnectable||e.elementsSelectable,minZoomReached:e.transform[2]<=e.minZoom,maxZoomReached:e.transform[2]>=e.maxZoom}),Og=({style:e,showZoom:t=!0,showFitView:r=!0,showInteractive:n=!0,fitViewOptions:i,onZoomIn:a,onZoomOut:o,onFitView:s,onInteractiveChange:u,className:l,children:c,position:f="bottom-left"})=>{const d=fe(),[h,_]=k.useState(!1),{isInteractive:g,minZoomReached:v,maxZoomReached:p}=ne(F1,he),{zoomIn:y,zoomOut:b,fitView:m}=Uu();if(k.useEffect(()=>{_(!0)},[]),!h)return null;const E=()=>{y(),a?.()},x=()=>{b(),o?.()},S=()=>{m(i),s?.()},N=()=>{d.setState({nodesDraggable:!g,nodesConnectable:!g,elementsSelectable:!g}),u?.(!g)};return L.createElement(Du,{className:pe(["react-flow__controls",l]),position:f,style:e,"data-testid":"rf__controls"},t&&L.createElement(L.Fragment,null,L.createElement(kt,{onClick:E,className:"react-flow__controls-zoomin",title:"zoom in","aria-label":"zoom in",disabled:p},L.createElement(P1,null)),L.createElement(kt,{onClick:x,className:"react-flow__controls-zoomout",title:"zoom out","aria-label":"zoom out",disabled:v},L.createElement(O1,null))),r&&L.createElement(kt,{className:"react-flow__controls-fitview",onClick:S,title:"fit view","aria-label":"fit view"},L.createElement(k1,null)),n&&L.createElement(kt,{className:"react-flow__controls-interactive",onClick:N,title:"toggle interactivity","aria-label":"toggle interactivity"},g?L.createElement(L1,null):L.createElement(D1,null)),c)};Og.displayName="Controls";var iq=k.memo(Og),Ie;(function(e){e.Lines="lines",e.Dots="dots",e.Cross="cross"})(Ie||(Ie={}));function z1({color:e,dimensions:t,lineWidth:r}){return L.createElement("path",{stroke:e,strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`})}function B1({color:e,radius:t}){return L.createElement("circle",{cx:t,cy:t,r:t,fill:e})}const H1={[Ie.Dots]:"#91919a",[Ie.Lines]:"#eee",[Ie.Cross]:"#e2e2e2"},$1={[Ie.Dots]:1,[Ie.Lines]:1,[Ie.Cross]:6},G1=e=>({transform:e.transform,patternId:`pattern-${e.rfId}`});function kg({id:e,variant:t=Ie.Dots,gap:r=20,size:n,lineWidth:i=1,offset:a=2,color:o,style:s,className:u}){const l=k.useRef(null),{transform:c,patternId:f}=ne(G1,he),d=o||H1[t],h=n||$1[t],_=t===Ie.Dots,g=t===Ie.Cross,v=Array.isArray(r)?r:[r,r],p=[v[0]*c[2]||1,v[1]*c[2]||1],y=h*c[2],b=g?[y,y]:p,m=_?[y/a,y/a]:[b[0]/a,b[1]/a];return L.createElement("svg",{className:pe(["react-flow__background",u]),style:{...s,position:"absolute",width:"100%",height:"100%",top:0,left:0},ref:l,"data-testid":"rf__background"},L.createElement("pattern",{id:f+e,x:c[0]%p[0],y:c[1]%p[1],width:p[0],height:p[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${m[0]},-${m[1]})`},_?L.createElement(B1,{color:d,radius:y/a}):L.createElement(z1,{dimensions:b,color:d,lineWidth:i})),L.createElement("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${f+e})`}))}kg.displayName="Background";var aq=k.memo(kg);function Ku(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var hn,ul;function V1(){if(ul)return hn;ul=1;function e(){this.__data__=[],this.size=0}return hn=e,hn}var pn,cl;function St(){if(cl)return pn;cl=1;function e(t,r){return t===r||t!==t&&r!==r}return pn=e,pn}var vn,ll;function Sr(){if(ll)return vn;ll=1;var e=St();function t(r,n){for(var i=r.length;i--;)if(e(r[i][0],n))return i;return-1}return vn=t,vn}var gn,fl;function U1(){if(fl)return gn;fl=1;var e=Sr(),t=Array.prototype,r=t.splice;function n(i){var a=this.__data__,o=e(a,i);if(o<0)return!1;var s=a.length-1;return o==s?a.pop():r.call(a,o,1),--this.size,!0}return gn=n,gn}var yn,dl;function j1(){if(dl)return yn;dl=1;var e=Sr();function t(r){var n=this.__data__,i=e(n,r);return i<0?void 0:n[i][1]}return yn=t,yn}var mn,hl;function K1(){if(hl)return mn;hl=1;var e=Sr();function t(r){return e(this.__data__,r)>-1}return mn=t,mn}var _n,pl;function Y1(){if(pl)return _n;pl=1;var e=Sr();function t(r,n){var i=this.__data__,a=e(i,r);return a<0?(++this.size,i.push([r,n])):i[a][1]=n,this}return _n=t,_n}var bn,vl;function qr(){if(vl)return bn;vl=1;var e=V1(),t=U1(),r=j1(),n=K1(),i=Y1();function a(o){var s=-1,u=o==null?0:o.length;for(this.clear();++s-1&&n%1==0&&n-1&&r%1==0&&r<=e}return si=t,si}var ui,af;function _E(){if(af)return ui;af=1;var e=st(),t=Xu(),r=Le(),n="[object Arguments]",i="[object Array]",a="[object Boolean]",o="[object Date]",s="[object Error]",u="[object Function]",l="[object Map]",c="[object Number]",f="[object Object]",d="[object RegExp]",h="[object Set]",_="[object String]",g="[object WeakMap]",v="[object ArrayBuffer]",p="[object DataView]",y="[object Float32Array]",b="[object Float64Array]",m="[object Int8Array]",E="[object Int16Array]",x="[object Int32Array]",S="[object Uint8Array]",N="[object Uint8ClampedArray]",q="[object Uint16Array]",A="[object Uint32Array]",I={};I[y]=I[b]=I[m]=I[E]=I[x]=I[S]=I[N]=I[q]=I[A]=!0,I[n]=I[i]=I[v]=I[a]=I[p]=I[o]=I[s]=I[u]=I[l]=I[c]=I[f]=I[d]=I[h]=I[_]=I[g]=!1;function D(O){return r(O)&&t(O.length)&&!!I[e(O)]}return ui=D,ui}var ci,of;function Mr(){if(of)return ci;of=1;function e(t){return function(r){return t(r)}}return ci=e,ci}var Lt={exports:{}};Lt.exports;var sf;function Ju(){return sf||(sf=1,(function(e,t){var r=gv(),n=t&&!t.nodeType&&t,i=n&&!0&&e&&!e.nodeType&&e,a=i&&i.exports===n,o=a&&r.process,s=(function(){try{var u=i&&i.require&&i.require("util").types;return u||o&&o.binding&&o.binding("util")}catch{}})();e.exports=s})(Lt,Lt.exports)),Lt.exports}var li,uf;function Wt(){if(uf)return li;uf=1;var e=_E(),t=Mr(),r=Ju(),n=r&&r.isTypedArray,i=n?t(n):e;return li=i,li}var fi,cf;function Fg(){if(cf)return fi;cf=1;var e=gE(),t=Yt(),r=le(),n=qt(),i=Tr(),a=Wt(),o=Object.prototype,s=o.hasOwnProperty;function u(l,c){var f=r(l),d=!f&&t(l),h=!f&&!d&&n(l),_=!f&&!d&&!h&&a(l),g=f||d||h||_,v=g?e(l.length,String):[],p=v.length;for(var y in l)(c||s.call(l,y))&&!(g&&(y=="length"||h&&(y=="offset"||y=="parent")||_&&(y=="buffer"||y=="byteLength"||y=="byteOffset")||i(y,p)))&&v.push(y);return v}return fi=u,fi}var di,lf;function Pr(){if(lf)return di;lf=1;var e=Object.prototype;function t(r){var n=r&&r.constructor,i=typeof n=="function"&&n.prototype||e;return r===i}return di=t,di}var hi,ff;function zg(){if(ff)return hi;ff=1;function e(t,r){return function(n){return t(r(n))}}return hi=e,hi}var pi,df;function bE(){if(df)return pi;df=1;var e=zg(),t=e(Object.keys,Object);return pi=t,pi}var vi,hf;function Qu(){if(hf)return vi;hf=1;var e=Pr(),t=bE(),r=Object.prototype,n=r.hasOwnProperty;function i(a){if(!e(a))return t(a);var o=[];for(var s in Object(a))n.call(a,s)&&s!="constructor"&&o.push(s);return o}return vi=i,vi}var gi,pf;function je(){if(pf)return gi;pf=1;var e=jt(),t=Xu();function r(n){return n!=null&&t(n.length)&&!e(n)}return gi=r,gi}var yi,vf;function Qe(){if(vf)return yi;vf=1;var e=Fg(),t=Qu(),r=je();function n(i){return r(i)?e(i):t(i)}return yi=n,yi}var mi,gf;function wE(){if(gf)return mi;gf=1;var e=Kt(),t=Qe();function r(n,i){return n&&e(i,t(i),n)}return mi=r,mi}var _i,yf;function EE(){if(yf)return _i;yf=1;function e(t){var r=[];if(t!=null)for(var n in Object(t))r.push(n);return r}return _i=e,_i}var bi,mf;function xE(){if(mf)return bi;mf=1;var e=qe(),t=Pr(),r=EE(),n=Object.prototype,i=n.hasOwnProperty;function a(o){if(!e(o))return r(o);var s=t(o),u=[];for(var l in o)l=="constructor"&&(s||!i.call(o,l))||u.push(l);return u}return bi=a,bi}var wi,_f;function ct(){if(_f)return wi;_f=1;var e=Fg(),t=xE(),r=je();function n(i){return r(i)?e(i,!0):t(i)}return wi=n,wi}var Ei,bf;function SE(){if(bf)return Ei;bf=1;var e=Kt(),t=ct();function r(n,i){return n&&e(i,t(i),n)}return Ei=r,Ei}var Ft={exports:{}};Ft.exports;var wf;function Bg(){return wf||(wf=1,(function(e,t){var r=Me(),n=t&&!t.nodeType&&t,i=n&&!0&&e&&!e.nodeType&&e,a=i&&i.exports===n,o=a?r.Buffer:void 0,s=o?o.allocUnsafe:void 0;function u(l,c){if(c)return l.slice();var f=l.length,d=s?s(f):new l.constructor(f);return l.copy(d),d}e.exports=u})(Ft,Ft.exports)),Ft.exports}var xi,Ef;function Hg(){if(Ef)return xi;Ef=1;function e(t,r){var n=-1,i=t.length;for(r||(r=Array(i));++nh))return!1;var g=f.get(o),v=f.get(s);if(g&&v)return g==s&&v==o;var p=-1,y=!0,b=u&i?new e:void 0;for(f.set(o,s),f.set(s,o);++p0&&a(c)?i>1?r(c,i-1,a,o,s):e(s,c):o||(s[s.length]=c)}return s}return po=r,po}var vo,hh;function wx(){if(hh)return vo;hh=1;function e(t,r,n){switch(n.length){case 0:return t.call(r);case 1:return t.call(r,n[0]);case 2:return t.call(r,n[0],n[1]);case 3:return t.call(r,n[0],n[1],n[2])}return t.apply(r,n)}return vo=e,vo}var go,ph;function my(){if(ph)return go;ph=1;var e=wx(),t=Math.max;function r(n,i,a){return i=t(i===void 0?n.length-1:i,0),function(){for(var o=arguments,s=-1,u=t(o.length-i,0),l=Array(u);++s0){if(++a>=e)return arguments[0]}else a=0;return i.apply(void 0,arguments)}}return mo=n,mo}var _o,yh;function _y(){if(yh)return _o;yh=1;var e=Ex(),t=xx(),r=t(e);return _o=r,_o}var bo,mh;function zr(){if(mh)return bo;mh=1;var e=lt(),t=my(),r=_y();function n(i,a){return r(t(i,a,e),i+"")}return bo=n,bo}var wo,_h;function by(){if(_h)return wo;_h=1;function e(t,r,n,i){for(var a=t.length,o=n+(i?1:-1);i?o--:++o-1}return qo=t,qo}var Ro,Sh;function Ax(){if(Sh)return Ro;Sh=1;function e(t,r,n){for(var i=-1,a=t==null?0:t.length;++i=o){var p=l?null:i(u);if(p)return a(p);_=!1,d=n,v=new e}else v=l?[]:g;e:for(;++f1?h.setNode(_,f):h.setNode(_)}),this},i.prototype.setNode=function(c,f){return e.has(this._nodes,c)?(arguments.length>1&&(this._nodes[c]=f),this):(this._nodes[c]=arguments.length>1?f:this._defaultNodeLabelFn(c),this._isCompound&&(this._parent[c]=r,this._children[c]={},this._children[r][c]=!0),this._in[c]={},this._preds[c]={},this._out[c]={},this._sucs[c]={},++this._nodeCount,this)},i.prototype.node=function(c){return this._nodes[c]},i.prototype.hasNode=function(c){return e.has(this._nodes,c)},i.prototype.removeNode=function(c){var f=this;if(e.has(this._nodes,c)){var d=function(h){f.removeEdge(f._edgeObjs[h])};delete this._nodes[c],this._isCompound&&(this._removeFromParentsChildList(c),delete this._parent[c],e.each(this.children(c),function(h){f.setParent(h)}),delete this._children[c]),e.each(e.keys(this._in[c]),d),delete this._in[c],delete this._preds[c],e.each(e.keys(this._out[c]),d),delete this._out[c],delete this._sucs[c],--this._nodeCount}return this},i.prototype.setParent=function(c,f){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(e.isUndefined(f))f=r;else{f+="";for(var d=f;!e.isUndefined(d);d=this.parent(d))if(d===c)throw new Error("Setting "+f+" as parent of "+c+" would create a cycle");this.setNode(f)}return this.setNode(c),this._removeFromParentsChildList(c),this._parent[c]=f,this._children[f][c]=!0,this},i.prototype._removeFromParentsChildList=function(c){delete this._children[this._parent[c]][c]},i.prototype.parent=function(c){if(this._isCompound){var f=this._parent[c];if(f!==r)return f}},i.prototype.children=function(c){if(e.isUndefined(c)&&(c=r),this._isCompound){var f=this._children[c];if(f)return e.keys(f)}else{if(c===r)return this.nodes();if(this.hasNode(c))return[]}},i.prototype.predecessors=function(c){var f=this._preds[c];if(f)return e.keys(f)},i.prototype.successors=function(c){var f=this._sucs[c];if(f)return e.keys(f)},i.prototype.neighbors=function(c){var f=this.predecessors(c);if(f)return e.union(f,this.successors(c))},i.prototype.isLeaf=function(c){var f;return this.isDirected()?f=this.successors(c):f=this.neighbors(c),f.length===0},i.prototype.filterNodes=function(c){var f=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});f.setGraph(this.graph());var d=this;e.each(this._nodes,function(g,v){c(v)&&f.setNode(v,g)}),e.each(this._edgeObjs,function(g){f.hasNode(g.v)&&f.hasNode(g.w)&&f.setEdge(g,d.edge(g))});var h={};function _(g){var v=d.parent(g);return v===void 0||f.hasNode(v)?(h[g]=v,v):v in h?h[v]:_(v)}return this._isCompound&&e.each(f.nodes(),function(g){f.setParent(g,_(g))}),f},i.prototype.setDefaultEdgeLabel=function(c){return e.isFunction(c)||(c=e.constant(c)),this._defaultEdgeLabelFn=c,this},i.prototype.edgeCount=function(){return this._edgeCount},i.prototype.edges=function(){return e.values(this._edgeObjs)},i.prototype.setPath=function(c,f){var d=this,h=arguments;return e.reduce(c,function(_,g){return h.length>1?d.setEdge(_,g,f):d.setEdge(_,g),g}),this},i.prototype.setEdge=function(){var c,f,d,h,_=!1,g=arguments[0];typeof g=="object"&&g!==null&&"v"in g?(c=g.v,f=g.w,d=g.name,arguments.length===2&&(h=arguments[1],_=!0)):(c=g,f=arguments[1],d=arguments[3],arguments.length>2&&(h=arguments[2],_=!0)),c=""+c,f=""+f,e.isUndefined(d)||(d=""+d);var v=s(this._isDirected,c,f,d);if(e.has(this._edgeLabels,v))return _&&(this._edgeLabels[v]=h),this;if(!e.isUndefined(d)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(c),this.setNode(f),this._edgeLabels[v]=_?h:this._defaultEdgeLabelFn(c,f,d);var p=u(this._isDirected,c,f,d);return c=p.v,f=p.w,Object.freeze(p),this._edgeObjs[v]=p,a(this._preds[f],c),a(this._sucs[c],f),this._in[f][v]=p,this._out[c][v]=p,this._edgeCount++,this},i.prototype.edge=function(c,f,d){var h=arguments.length===1?l(this._isDirected,arguments[0]):s(this._isDirected,c,f,d);return this._edgeLabels[h]},i.prototype.hasEdge=function(c,f,d){var h=arguments.length===1?l(this._isDirected,arguments[0]):s(this._isDirected,c,f,d);return e.has(this._edgeLabels,h)},i.prototype.removeEdge=function(c,f,d){var h=arguments.length===1?l(this._isDirected,arguments[0]):s(this._isDirected,c,f,d),_=this._edgeObjs[h];return _&&(c=_.v,f=_.w,delete this._edgeLabels[h],delete this._edgeObjs[h],o(this._preds[f],c),o(this._sucs[c],f),delete this._in[f][h],delete this._out[c][h],this._edgeCount--),this},i.prototype.inEdges=function(c,f){var d=this._in[c];if(d){var h=e.values(d);return f?e.filter(h,function(_){return _.v===f}):h}},i.prototype.outEdges=function(c,f){var d=this._out[c];if(d){var h=e.values(d);return f?e.filter(h,function(_){return _.w===f}):h}},i.prototype.nodeEdges=function(c,f){var d=this.inEdges(c,f);if(d)return d.concat(this.outEdges(c,f))};function a(c,f){c[f]?c[f]++:c[f]=1}function o(c,f){--c[f]||delete c[f]}function s(c,f,d,h){var _=""+f,g=""+d;if(!c&&_>g){var v=_;_=g,g=v}return _+n+g+n+(e.isUndefined(h)?t:h)}function u(c,f,d,h){var _=""+f,g=""+d;if(!c&&_>g){var v=_;_=g,g=v}var p={v:_,w:g};return h&&(p.name=h),p}function l(c,f){return s(c,f.v,f.w,f.name)}return ko}var Do,Oh;function Ox(){return Oh||(Oh=1,Do="2.1.8"),Do}var Lo,kh;function kx(){return kh||(kh=1,Lo={Graph:cc(),version:Ox()}),Lo}var Fo,Dh;function Dx(){if(Dh)return Fo;Dh=1;var e=Re(),t=cc();Fo={write:r,read:a};function r(o){var s={options:{directed:o.isDirected(),multigraph:o.isMultigraph(),compound:o.isCompound()},nodes:n(o),edges:i(o)};return e.isUndefined(o.graph())||(s.value=e.clone(o.graph())),s}function n(o){return e.map(o.nodes(),function(s){var u=o.node(s),l=o.parent(s),c={v:s};return e.isUndefined(u)||(c.value=u),e.isUndefined(l)||(c.parent=l),c})}function i(o){return e.map(o.edges(),function(s){var u=o.edge(s),l={v:s.v,w:s.w};return e.isUndefined(s.name)||(l.name=s.name),e.isUndefined(u)||(l.value=u),l})}function a(o){var s=new t(o.options).setGraph(o.value);return e.each(o.nodes,function(u){s.setNode(u.v,u.value),u.parent&&s.setParent(u.v,u.parent)}),e.each(o.edges,function(u){s.setEdge({v:u.v,w:u.w,name:u.name},u.value)}),s}return Fo}var zo,Lh;function Lx(){if(Lh)return zo;Lh=1;var e=Re();zo=t;function t(r){var n={},i=[],a;function o(s){e.has(n,s)||(n[s]=!0,a.push(s),e.each(r.successors(s),o),e.each(r.predecessors(s),o))}return e.each(r.nodes(),function(s){a=[],o(s),a.length&&i.push(a)}),i}return zo}var Bo,Fh;function xy(){if(Fh)return Bo;Fh=1;var e=Re();Bo=t;function t(){this._arr=[],this._keyIndices={}}return t.prototype.size=function(){return this._arr.length},t.prototype.keys=function(){return this._arr.map(function(r){return r.key})},t.prototype.has=function(r){return e.has(this._keyIndices,r)},t.prototype.priority=function(r){var n=this._keyIndices[r];if(n!==void 0)return this._arr[n].priority},t.prototype.min=function(){if(this.size()===0)throw new Error("Queue underflow");return this._arr[0].key},t.prototype.add=function(r,n){var i=this._keyIndices;if(r=String(r),!e.has(i,r)){var a=this._arr,o=a.length;return i[r]=o,a.push({key:r,priority:n}),this._decrease(o),!0}return!1},t.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var r=this._arr.pop();return delete this._keyIndices[r.key],this._heapify(0),r.key},t.prototype.decrease=function(r,n){var i=this._keyIndices[r];if(n>this._arr[i].priority)throw new Error("New priority is greater than current priority. Key: "+r+" Old: "+this._arr[i].priority+" New: "+n);this._arr[i].priority=n,this._decrease(i)},t.prototype._heapify=function(r){var n=this._arr,i=2*r,a=i+1,o=r;i>1,!(n[a].priority0&&(f=c.removeMin(),d=l[f],d.distance!==Number.POSITIVE_INFINITY);)u(f).forEach(h);return l}return Ho}var $o,Bh;function Fx(){if(Bh)return $o;Bh=1;var e=Sy(),t=Re();$o=r;function r(n,i,a){return t.transform(n.nodes(),function(o,s){o[s]=e(n,s,i,a)},{})}return $o}var Go,Hh;function qy(){if(Hh)return Go;Hh=1;var e=Re();Go=t;function t(r){var n=0,i=[],a={},o=[];function s(u){var l=a[u]={onStack:!0,lowlink:n,index:n++};if(i.push(u),r.successors(u).forEach(function(d){e.has(a,d)?a[d].onStack&&(l.lowlink=Math.min(l.lowlink,a[d].index)):(s(d),l.lowlink=Math.min(l.lowlink,a[d].lowlink))}),l.lowlink===l.index){var c=[],f;do f=i.pop(),a[f].onStack=!1,c.push(f);while(u!==f);o.push(c)}}return r.nodes().forEach(function(u){e.has(a,u)||s(u)}),o}return Go}var Vo,$h;function zx(){if($h)return Vo;$h=1;var e=Re(),t=qy();Vo=r;function r(n){return e.filter(t(n),function(i){return i.length>1||i.length===1&&n.hasEdge(i[0],i[0])})}return Vo}var Uo,Gh;function Bx(){if(Gh)return Uo;Gh=1;var e=Re();Uo=r;var t=e.constant(1);function r(i,a,o){return n(i,a||t,o||function(s){return i.outEdges(s)})}function n(i,a,o){var s={},u=i.nodes();return u.forEach(function(l){s[l]={},s[l][l]={distance:0},u.forEach(function(c){l!==c&&(s[l][c]={distance:Number.POSITIVE_INFINITY})}),o(l).forEach(function(c){var f=c.v===l?c.w:c.v,d=a(c);s[l][f]={distance:d,predecessor:l}})}),u.forEach(function(l){var c=s[l];u.forEach(function(f){var d=s[f];u.forEach(function(h){var _=d[l],g=c[h],v=d[h],p=_.distance+g.distance;p0;){if(l=u.removeMin(),e.has(s,l))o.setEdge(l,s[l]);else{if(f)throw new Error("Input graph is not connected: "+i);f=!0}i.nodeEdges(l).forEach(c)}return o}return Xo}var Jo,Zh;function Ux(){return Zh||(Zh=1,Jo={components:Lx(),dijkstra:Sy(),dijkstraAll:Fx(),findCycles:zx(),floydWarshall:Bx(),isAcyclic:Hx(),postorder:$x(),preorder:Gx(),prim:Vx(),tarjan:qy(),topsort:Ry()}),Jo}var Qo,Xh;function jx(){if(Xh)return Qo;Xh=1;var e=kx();return Qo={Graph:e.Graph,json:Dx(),alg:Ux(),version:e.version},Qo}var es,Jh;function Te(){if(Jh)return es;Jh=1;var e;if(typeof Ku=="function")try{e=jx()}catch{}return e||(e=window.graphlib),es=e,es}var ts,Qh;function Kx(){if(Qh)return ts;Qh=1;var e=Jg(),t=1,r=4;function n(i){return e(i,t|r)}return ts=n,ts}var rs,ep;function Br(){if(ep)return rs;ep=1;var e=St(),t=je(),r=Tr(),n=qe();function i(a,o,s){if(!n(s))return!1;var u=typeof o;return(u=="number"?t(s)&&r(o,s.length):u=="string"&&o in s)?e(s[o],a):!1}return rs=i,rs}var ns,tp;function Yx(){if(tp)return ns;tp=1;var e=zr(),t=St(),r=Br(),n=ct(),i=Object.prototype,a=i.hasOwnProperty,o=e(function(s,u){s=Object(s);var l=-1,c=u.length,f=c>2?u[2]:void 0;for(f&&r(u[0],u[1],f)&&(c=1);++l-1?u[l?a[c]:c]:void 0}}return is=n,is}var as,np;function Ay(){if(np)return as;np=1;var e=Sm(),t=1/0,r=17976931348623157e292;function n(i){if(!i)return i===0?i:0;if(i=e(i),i===t||i===-t){var a=i<0?-1:1;return a*r}return i===i?i:0}return as=n,as}var os,ip;function Zx(){if(ip)return os;ip=1;var e=Ay();function t(r){var n=e(r),i=n%1;return n===n?i?n-i:n:0}return os=t,os}var ss,ap;function Xx(){if(ap)return ss;ap=1;var e=by(),t=Ke(),r=Zx(),n=Math.max;function i(a,o,s){var u=a==null?0:a.length;if(!u)return-1;var l=s==null?0:r(s);return l<0&&(l=n(u+l,0)),e(a,t(o,3),l)}return ss=i,ss}var us,op;function Jx(){if(op)return us;op=1;var e=Wx(),t=Xx(),r=e(t);return us=r,us}var cs,sp;function Ny(){if(sp)return cs;sp=1;var e=uc();function t(r){var n=r==null?0:r.length;return n?e(r,1):[]}return cs=t,cs}var ls,up;function Qx(){if(up)return ls;up=1;var e=ic(),t=Qg(),r=ct();function n(i,a){return i==null?i:e(i,t(a),r)}return ls=n,ls}var fs,cp;function eS(){if(cp)return fs;cp=1;function e(t){var r=t==null?0:t.length;return r?t[r-1]:void 0}return fs=e,fs}var ds,lp;function tS(){if(lp)return ds;lp=1;var e=Nr(),t=ac(),r=Ke();function n(i,a){var o={};return a=r(a,3),t(i,function(s,u,l){e(o,u,a(s,u,l))}),o}return ds=n,ds}var hs,fp;function lc(){if(fp)return hs;fp=1;var e=xt();function t(r,n,i){for(var a=-1,o=r.length;++ar}return ps=e,ps}var vs,hp;function nS(){if(hp)return vs;hp=1;var e=lc(),t=rS(),r=lt();function n(i){return i&&i.length?e(i,r,t):void 0}return vs=n,vs}var gs,pp;function Iy(){if(pp)return gs;pp=1;var e=Nr(),t=St();function r(n,i,a){(a!==void 0&&!t(n[i],a)||a===void 0&&!(i in n))&&e(n,i,a)}return gs=r,gs}var ys,vp;function iS(){if(vp)return ys;vp=1;var e=st(),t=Or(),r=Le(),n="[object Object]",i=Function.prototype,a=Object.prototype,o=i.toString,s=a.hasOwnProperty,u=o.call(Object);function l(c){if(!r(c)||e(c)!=n)return!1;var f=t(c);if(f===null)return!0;var d=s.call(f,"constructor")&&f.constructor;return typeof d=="function"&&d instanceof d&&o.call(d)==u}return ys=l,ys}var ms,gp;function Ty(){if(gp)return ms;gp=1;function e(t,r){if(!(r==="constructor"&&typeof t[r]=="function")&&r!="__proto__")return t[r]}return ms=e,ms}var _s,yp;function aS(){if(yp)return _s;yp=1;var e=Kt(),t=ct();function r(n){return e(n,t(n))}return _s=r,_s}var bs,mp;function oS(){if(mp)return bs;mp=1;var e=Iy(),t=Bg(),r=Wg(),n=Hg(),i=Xg(),a=Yt(),o=le(),s=wy(),u=qt(),l=jt(),c=qe(),f=iS(),d=Wt(),h=Ty(),_=aS();function g(v,p,y,b,m,E,x){var S=h(v,y),N=h(p,y),q=x.get(N);if(q){e(v,y,q);return}var A=E?E(S,N,y+"",v,p,x):void 0,I=A===void 0;if(I){var D=o(N),O=!D&&u(N),w=!D&&!O&&d(N);A=N,D||O||w?o(S)?A=S:s(S)?A=n(S):O?(I=!1,A=t(N,!0)):w?(I=!1,A=r(N,!0)):A=[]:f(N)||a(N)?(A=S,a(S)?A=_(S):(!c(S)||l(S))&&(A=i(N))):I=!1}I&&(x.set(N,A),m(A,N,b,E,x),x.delete(N)),e(v,y,A)}return bs=g,bs}var ws,_p;function sS(){if(_p)return ws;_p=1;var e=Ar(),t=Iy(),r=ic(),n=oS(),i=qe(),a=ct(),o=Ty();function s(u,l,c,f,d){u!==l&&r(l,function(h,_){if(d||(d=new e),i(h))n(u,l,_,c,s,f,d);else{var g=f?f(o(u,_),h,_+"",u,l,d):void 0;g===void 0&&(g=h),t(u,_,g)}},a)}return ws=s,ws}var Es,bp;function uS(){if(bp)return Es;bp=1;var e=zr(),t=Br();function r(n){return e(function(i,a){var o=-1,s=a.length,u=s>1?a[s-1]:void 0,l=s>2?a[2]:void 0;for(u=n.length>3&&typeof u=="function"?(s--,u):void 0,l&&t(a[0],a[1],l)&&(u=s<3?void 0:u,s=1),i=Object(i);++on||s&&u&&c&&!l&&!f||a&&u&&c||!i&&c||!o)return 1;if(!a&&!s&&!f&&r=l)return c;var f=i[a];return c*(f=="desc"?-1:1)}}return r.index-n.index}return Ls=t,Ls}var Fs,Dp;function xS(){if(Dp)return Fs;Dp=1;var e=Dr(),t=Fr(),r=Ke(),n=vy(),i=bS(),a=Mr(),o=ES(),s=lt(),u=le();function l(c,f,d){f.length?f=e(f,function(g){return u(g)?function(v){return t(v,g.length===1?g[0]:g)}:g}):f=[s];var h=-1;f=e(f,a(r));var _=n(c,function(g,v,p){var y=e(f,function(b){return b(g)});return{criteria:y,index:++h,value:g}});return i(_,function(g,v){return o(g,v,d)})}return Fs=l,Fs}var zs,Lp;function SS(){if(Lp)return zs;Lp=1;var e=uc(),t=xS(),r=zr(),n=Br(),i=r(function(a,o){if(a==null)return[];var s=o.length;return s>1&&n(a,o[0],o[1])?o=[]:s>2&&n(o[0],o[1],o[2])&&(o=[o[0]]),t(a,e(o,1),[])});return zs=i,zs}var Bs,Fp;function qS(){if(Fp)return Bs;Fp=1;var e=uy(),t=0;function r(n){var i=++t;return e(n)+i}return Bs=r,Bs}var Hs,zp;function RS(){if(zp)return Hs;zp=1;function e(t,r,n){for(var i=-1,a=t.length,o=r.length,s={};++i0;--v)if(g=c[v].dequeue(),g){d=d.concat(o(l,c,f,g,!0));break}}}return d}function o(l,c,f,d,h){var _=h?[]:void 0;return e.forEach(l.inEdges(d.v),function(g){var v=l.edge(g),p=l.node(g.v);h&&_.push({v:g.v,w:g.w}),p.out-=v,u(c,f,p)}),e.forEach(l.outEdges(d.v),function(g){var v=l.edge(g),p=g.w,y=l.node(p);y.in-=v,u(c,f,y)}),l.removeNode(d.v),_}function s(l,c){var f=new t,d=0,h=0;e.forEach(l.nodes(),function(v){f.setNode(v,{v,in:0,out:0})}),e.forEach(l.edges(),function(v){var p=f.edge(v.v,v.w)||0,y=c(v),b=p+y;f.setEdge(v.v,v.w,b),h=Math.max(h,f.node(v.v).out+=y),d=Math.max(d,f.node(v.w).in+=y)});var _=e.range(h+d+3).map(function(){return new r}),g=d+1;return e.forEach(f.nodes(),function(v){u(_,g,f.node(v))}),{graph:f,buckets:_,zeroIdx:g}}function u(l,c,f){f.out?f.in?l[f.out-f.in+c].enqueue(f):l[l.length-1].enqueue(f):l[0].enqueue(f)}return Us}var js,Vp;function IS(){if(Vp)return js;Vp=1;var e=ae(),t=NS();js={run:r,undo:i};function r(a){var o=a.graph().acyclicer==="greedy"?t(a,s(a)):n(a);e.forEach(o,function(u){var l=a.edge(u);a.removeEdge(u),l.forwardName=u.name,l.reversed=!0,a.setEdge(u.w,u.v,l,e.uniqueId("rev"))});function s(u){return function(l){return u.edge(l).weight}}}function n(a){var o=[],s={},u={};function l(c){e.has(u,c)||(u[c]=!0,s[c]=!0,e.forEach(a.outEdges(c),function(f){e.has(s,f.w)?o.push(f):l(f.w)}),delete s[c])}return e.forEach(a.nodes(),l),o}function i(a){e.forEach(a.edges(),function(o){var s=a.edge(o);if(s.reversed){a.removeEdge(o);var u=s.forwardName;delete s.reversed,delete s.forwardName,a.setEdge(o.w,o.v,s,u)}})}return js}var Ks,Up;function _e(){if(Up)return Ks;Up=1;var e=ae(),t=Te().Graph;Ks={addDummyNode:r,simplify:n,asNonCompoundGraph:i,successorWeights:a,predecessorWeights:o,intersectRect:s,buildLayerMatrix:u,normalizeRanks:l,removeEmptyRanks:c,addBorderNode:f,maxRank:d,partition:h,time:_,notime:g};function r(v,p,y,b){var m;do m=e.uniqueId(b);while(v.hasNode(m));return y.dummy=p,v.setNode(m,y),m}function n(v){var p=new t().setGraph(v.graph());return e.forEach(v.nodes(),function(y){p.setNode(y,v.node(y))}),e.forEach(v.edges(),function(y){var b=p.edge(y.v,y.w)||{weight:0,minlen:1},m=v.edge(y);p.setEdge(y.v,y.w,{weight:b.weight+m.weight,minlen:Math.max(b.minlen,m.minlen)})}),p}function i(v){var p=new t({multigraph:v.isMultigraph()}).setGraph(v.graph());return e.forEach(v.nodes(),function(y){v.children(y).length||p.setNode(y,v.node(y))}),e.forEach(v.edges(),function(y){p.setEdge(y,v.edge(y))}),p}function a(v){var p=e.map(v.nodes(),function(y){var b={};return e.forEach(v.outEdges(y),function(m){b[m.w]=(b[m.w]||0)+v.edge(m).weight}),b});return e.zipObject(v.nodes(),p)}function o(v){var p=e.map(v.nodes(),function(y){var b={};return e.forEach(v.inEdges(y),function(m){b[m.v]=(b[m.v]||0)+v.edge(m).weight}),b});return e.zipObject(v.nodes(),p)}function s(v,p){var y=v.x,b=v.y,m=p.x-y,E=p.y-b,x=v.width/2,S=v.height/2;if(!m&&!E)throw new Error("Not possible to find intersection inside of the rectangle");var N,q;return Math.abs(E)*x>Math.abs(m)*S?(E<0&&(S=-S),N=S*m/E,q=S):(m<0&&(x=-x),N=x,q=x*E/m),{x:y+N,y:b+q}}function u(v){var p=e.map(e.range(d(v)+1),function(){return[]});return e.forEach(v.nodes(),function(y){var b=v.node(y),m=b.rank;e.isUndefined(m)||(p[m][b.order]=y)}),p}function l(v){var p=e.min(e.map(v.nodes(),function(y){return v.node(y).rank}));e.forEach(v.nodes(),function(y){var b=v.node(y);e.has(b,"rank")&&(b.rank-=p)})}function c(v){var p=e.min(e.map(v.nodes(),function(E){return v.node(E).rank})),y=[];e.forEach(v.nodes(),function(E){var x=v.node(E).rank-p;y[x]||(y[x]=[]),y[x].push(E)});var b=0,m=v.graph().nodeRankFactor;e.forEach(y,function(E,x){e.isUndefined(E)&&x%m!==0?--b:b&&e.forEach(E,function(S){v.node(S).rank+=b})})}function f(v,p,y,b){var m={width:0,height:0};return arguments.length>=4&&(m.rank=y,m.order=b),r(v,"border",m,p)}function d(v){return e.max(e.map(v.nodes(),function(p){var y=v.node(p).rank;if(!e.isUndefined(y))return y}))}function h(v,p){var y={lhs:[],rhs:[]};return e.forEach(v,function(b){p(b)?y.lhs.push(b):y.rhs.push(b)}),y}function _(v,p){var y=e.now();try{return p()}finally{console.log(v+" time: "+(e.now()-y)+"ms")}}function g(v,p){return p()}return Ks}var Ys,jp;function TS(){if(jp)return Ys;jp=1;var e=ae(),t=_e();Ys={run:r,undo:i};function r(a){a.graph().dummyChains=[],e.forEach(a.edges(),function(o){n(a,o)})}function n(a,o){var s=o.v,u=a.node(s).rank,l=o.w,c=a.node(l).rank,f=o.name,d=a.edge(o),h=d.labelRank;if(c!==u+1){a.removeEdge(o);var _,g,v;for(v=0,++u;uq.lim&&(A=q,I=!0);var D=e.filter(m.edges(),function(O){return I===y(b,b.node(O.v),A)&&I!==y(b,b.node(O.w),A)});return e.minBy(D,function(O){return r(m,O)})}function g(b,m,E,x){var S=E.v,N=E.w;b.removeEdge(S,N),b.setEdge(x.v,x.w,{}),f(b),u(b,m),v(b,m)}function v(b,m){var E=e.find(b.nodes(),function(S){return!m.node(S).parent}),x=i(b,E);x=x.slice(1),e.forEach(x,function(S){var N=b.node(S).parent,q=m.edge(S,N),A=!1;q||(q=m.edge(N,S),A=!0),m.node(S).rank=m.node(N).rank+(A?q.minlen:-q.minlen)})}function p(b,m,E){return b.hasEdge(m,E)}function y(b,m,E){return E.low<=m.lim&&m.lim<=E.lim}return Xs}var Js,Zp;function PS(){if(Zp)return Js;Zp=1;var e=gr(),t=e.longestPath,r=Py(),n=MS();Js=i;function i(u){switch(u.graph().ranker){case"network-simplex":s(u);break;case"tight-tree":o(u);break;case"longest-path":a(u);break;default:s(u)}}var a=t;function o(u){t(u),r(u)}function s(u){n(u)}return Js}var Qs,Xp;function OS(){if(Xp)return Qs;Xp=1;var e=ae();Qs=t;function t(i){var a=n(i);e.forEach(i.graph().dummyChains,function(o){for(var s=i.node(o),u=s.edgeObj,l=r(i,a,u.v,u.w),c=l.path,f=l.lca,d=0,h=c[d],_=!0;o!==u.w;){if(s=i.node(o),_){for(;(h=c[d])!==f&&i.node(h).maxRankc||f>a[d].lim));for(h=d,d=s;(d=i.parent(d))!==h;)l.push(d);return{path:u.concat(l.reverse()),lca:h}}function n(i){var a={},o=0;function s(u){var l=o;e.forEach(i.children(u),s),a[u]={low:l,lim:o++}}return e.forEach(i.children(),s),a}return Qs}var eu,Jp;function kS(){if(Jp)return eu;Jp=1;var e=ae(),t=_e();eu={run:r,cleanup:o};function r(s){var u=t.addDummyNode(s,"root",{},"_root"),l=i(s),c=e.max(e.values(l))-1,f=2*c+1;s.graph().nestingRoot=u,e.forEach(s.edges(),function(h){s.edge(h).minlen*=f});var d=a(s)+1;e.forEach(s.children(),function(h){n(s,u,f,d,c,l,h)}),s.graph().nodeRankFactor=f}function n(s,u,l,c,f,d,h){var _=s.children(h);if(!_.length){h!==u&&s.setEdge(u,h,{weight:0,minlen:l});return}var g=t.addBorderNode(s,"_bt"),v=t.addBorderNode(s,"_bb"),p=s.node(h);s.setParent(g,h),p.borderTop=g,s.setParent(v,h),p.borderBottom=v,e.forEach(_,function(y){n(s,u,l,c,f,d,y);var b=s.node(y),m=b.borderTop?b.borderTop:y,E=b.borderBottom?b.borderBottom:y,x=b.borderTop?c:2*c,S=m!==E?1:f-d[h]+1;s.setEdge(g,m,{weight:x,minlen:S,nestingEdge:!0}),s.setEdge(E,v,{weight:x,minlen:S,nestingEdge:!0})}),s.parent(h)||s.setEdge(u,g,{weight:0,minlen:f+d[h]})}function i(s){var u={};function l(c,f){var d=s.children(c);d&&d.length&&e.forEach(d,function(h){l(h,f+1)}),u[c]=f}return e.forEach(s.children(),function(c){l(c,1)}),u}function a(s){return e.reduce(s.edges(),function(u,l){return u+s.edge(l).weight},0)}function o(s){var u=s.graph();s.removeNode(u.nestingRoot),delete u.nestingRoot,e.forEach(s.edges(),function(l){var c=s.edge(l);c.nestingEdge&&s.removeEdge(l)})}return eu}var tu,Qp;function DS(){if(Qp)return tu;Qp=1;var e=ae(),t=_e();tu=r;function r(i){function a(o){var s=i.children(o),u=i.node(o);if(s.length&&e.forEach(s,a),e.has(u,"minRank")){u.borderLeft=[],u.borderRight=[];for(var l=u.minRank,c=u.maxRank+1;l0;)h%2&&(_+=c[h+1]),h=h-1>>1,c[h]+=d.weight;f+=d.weight*_})),f}return iu}var au,nv;function BS(){if(nv)return au;nv=1;var e=ae();au=t;function t(r,n){return e.map(n,function(i){var a=r.inEdges(i);if(a.length){var o=e.reduce(a,function(s,u){var l=r.edge(u),c=r.node(u.v);return{sum:s.sum+l.weight*c.order,weight:s.weight+l.weight}},{sum:0,weight:0});return{v:i,barycenter:o.sum/o.weight,weight:o.weight}}else return{v:i}})}return au}var ou,iv;function HS(){if(iv)return ou;iv=1;var e=ae();ou=t;function t(i,a){var o={};e.forEach(i,function(u,l){var c=o[u.v]={indegree:0,in:[],out:[],vs:[u.v],i:l};e.isUndefined(u.barycenter)||(c.barycenter=u.barycenter,c.weight=u.weight)}),e.forEach(a.edges(),function(u){var l=o[u.v],c=o[u.w];!e.isUndefined(l)&&!e.isUndefined(c)&&(c.indegree++,l.out.push(o[u.w]))});var s=e.filter(o,function(u){return!u.indegree});return r(s)}function r(i){var a=[];function o(l){return function(c){c.merged||(e.isUndefined(c.barycenter)||e.isUndefined(l.barycenter)||c.barycenter>=l.barycenter)&&n(l,c)}}function s(l){return function(c){c.in.push(l),--c.indegree===0&&i.push(c)}}for(;i.length;){var u=i.pop();a.push(u),e.forEach(u.in.reverse(),o(u)),e.forEach(u.out,s(u))}return e.map(e.filter(a,function(l){return!l.merged}),function(l){return e.pick(l,["vs","i","barycenter","weight"])})}function n(i,a){var o=0,s=0;i.weight&&(o+=i.barycenter*i.weight,s+=i.weight),a.weight&&(o+=a.barycenter*a.weight,s+=a.weight),i.vs=a.vs.concat(i.vs),i.barycenter=o/s,i.weight=s,i.i=Math.min(a.i,i.i),a.merged=!0}return ou}var su,av;function $S(){if(av)return su;av=1;var e=ae(),t=_e();su=r;function r(a,o){var s=t.partition(a,function(g){return e.has(g,"barycenter")}),u=s.lhs,l=e.sortBy(s.rhs,function(g){return-g.i}),c=[],f=0,d=0,h=0;u.sort(i(!!o)),h=n(c,l,h),e.forEach(u,function(g){h+=g.vs.length,c.push(g.vs),f+=g.barycenter*g.weight,d+=g.weight,h=n(c,l,h)});var _={vs:e.flatten(c,!0)};return d&&(_.barycenter=f/d,_.weight=d),_}function n(a,o,s){for(var u;o.length&&(u=e.last(o)).i<=s;)o.pop(),a.push(u.vs),s++;return s}function i(a){return function(o,s){return o.barycenters.barycenter?1:a?s.i-o.i:o.i-s.i}}return su}var uu,ov;function GS(){if(ov)return uu;ov=1;var e=ae(),t=BS(),r=HS(),n=$S();uu=i;function i(s,u,l,c){var f=s.children(u),d=s.node(u),h=d?d.borderLeft:void 0,_=d?d.borderRight:void 0,g={};h&&(f=e.filter(f,function(E){return E!==h&&E!==_}));var v=t(s,f);e.forEach(v,function(E){if(s.children(E.v).length){var x=i(s,E.v,l,c);g[E.v]=x,e.has(x,"barycenter")&&o(E,x)}});var p=r(v,l);a(p,g);var y=n(p,c);if(h&&(y.vs=e.flatten([h,y.vs,_],!0),s.predecessors(h).length)){var b=s.node(s.predecessors(h)[0]),m=s.node(s.predecessors(_)[0]);e.has(y,"barycenter")||(y.barycenter=0,y.weight=0),y.barycenter=(y.barycenter*y.weight+b.order+m.order)/(y.weight+2),y.weight+=2}return y}function a(s,u){e.forEach(s,function(l){l.vs=e.flatten(l.vs.map(function(c){return u[c]?u[c].vs:c}),!0)})}function o(s,u){e.isUndefined(s.barycenter)?(s.barycenter=u.barycenter,s.weight=u.weight):(s.barycenter=(s.barycenter*s.weight+u.barycenter*u.weight)/(s.weight+u.weight),s.weight+=u.weight)}return uu}var cu,sv;function VS(){if(sv)return cu;sv=1;var e=ae(),t=Te().Graph;cu=r;function r(i,a,o){var s=n(i),u=new t({compound:!0}).setGraph({root:s}).setDefaultNodeLabel(function(l){return i.node(l)});return e.forEach(i.nodes(),function(l){var c=i.node(l),f=i.parent(l);(c.rank===a||c.minRank<=a&&a<=c.maxRank)&&(u.setNode(l),u.setParent(l,f||s),e.forEach(i[o](l),function(d){var h=d.v===l?d.w:d.v,_=u.edge(h,l),g=e.isUndefined(_)?0:_.weight;u.setEdge(h,l,{weight:i.edge(d).weight+g})}),e.has(c,"minRank")&&u.setNode(l,{borderLeft:c.borderLeft[a],borderRight:c.borderRight[a]}))}),u}function n(i){for(var a;i.hasNode(a=e.uniqueId("_root")););return a}return cu}var lu,uv;function US(){if(uv)return lu;uv=1;var e=ae();lu=t;function t(r,n,i){var a={},o;e.forEach(i,function(s){for(var u=r.parent(s),l,c;u;){if(l=r.parent(u),l?(c=a[l],a[l]=u):(c=o,o=u),c&&c!==u){n.setEdge(c,u);return}u=l}})}return lu}var fu,cv;function jS(){if(cv)return fu;cv=1;var e=ae(),t=FS(),r=zS(),n=GS(),i=VS(),a=US(),o=Te().Graph,s=_e();fu=u;function u(d){var h=s.maxRank(d),_=l(d,e.range(1,h+1),"inEdges"),g=l(d,e.range(h-1,-1,-1),"outEdges"),v=t(d);f(d,v);for(var p=Number.POSITIVE_INFINITY,y,b=0,m=0;m<4;++b,++m){c(b%2?_:g,b%4>=2),v=s.buildLayerMatrix(d);var E=r(d,v);EA)&&o(b,O,I)})})}function E(x,S){var N=-1,q,A=0;return e.forEach(S,function(I,D){if(p.node(I).dummy==="border"){var O=p.predecessors(I);O.length&&(q=p.node(O[0]).order,m(S,A,D,N,q),A=D,N=q)}m(S,A,S.length,q,x.length)}),S}return e.reduce(y,E),b}function a(p,y){if(p.node(y).dummy)return e.find(p.predecessors(y),function(b){return p.node(b).dummy})}function o(p,y,b){if(y>b){var m=y;y=b,b=m}var E=p[y];E||(p[y]=E={}),E[b]=!0}function s(p,y,b){if(y>b){var m=y;y=b,b=m}return e.has(p[y],b)}function u(p,y,b,m){var E={},x={},S={};return e.forEach(y,function(N){e.forEach(N,function(q,A){E[q]=q,x[q]=q,S[q]=A})}),e.forEach(y,function(N){var q=-1;e.forEach(N,function(A){var I=m(A);if(I.length){I=e.sortBy(I,function(C){return S[C]});for(var D=(I.length-1)/2,O=Math.floor(D),w=Math.ceil(D);O<=w;++O){var T=I[O];x[A]===A&&qn[o]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var P=Cs(),b=le();const at=ue(b),Co=Ms({__proto__:null,default:at},[b]),re=new WeakMap,Is=new WeakMap,Tt={current:[]};let qt=!1,mt=0;const pt=new Set,Pt=new Map;function Qe(t){for(const s of t){if(Tt.current.includes(s))continue;Tt.current.push(s),s.recompute();const e=Is.get(s);if(e)for(const n of e){const o=re.get(n);o?.length&&Qe(o)}}}function Es(t){const s={prevVal:t.prevState,currentVal:t.state};for(const e of t.listeners)e(s)}function ks(t){const s={prevVal:t.prevState,currentVal:t.state};for(const e of t.listeners)e(s)}function ts(t){if(mt>0&&!Pt.has(t)&&Pt.set(t,t.prevState),pt.add(t),!(mt>0)&&!qt)try{for(qt=!0;pt.size>0;){const s=Array.from(pt);pt.clear();for(const e of s){const n=Pt.get(e)??e.prevState;e.prevState=n,Es(e)}for(const e of s){const n=re.get(e);n&&(Tt.current.push(e),Qe(n))}for(const e of s){const n=re.get(e);if(n)for(const o of n)ks(o)}}}finally{qt=!1,Tt.current=[],Pt.clear()}}function gt(t){mt++;try{t()}finally{if(mt--,mt===0){const s=pt.values().next().value;s&&ts(s)}}}function Ts(t){return typeof t=="function"}class Os{constructor(s,e){this.listeners=new Set,this.subscribe=n=>{var o,i;this.listeners.add(n);const r=(i=(o=this.options)==null?void 0:o.onSubscribe)==null?void 0:i.call(o,n,this);return()=>{this.listeners.delete(n),r?.()}},this.prevState=s,this.state=s,this.options=e}setState(s){var e,n,o;this.prevState=this.state,(e=this.options)!=null&&e.updateFn?this.state=this.options.updateFn(this.prevState)(s):Ts(s)?this.state=s(this.prevState):this.state=s,(o=(n=this.options)==null?void 0:n.onUpdate)==null||o.call(n),ts(this)}}const G="__TSR_index",Me="popstate",Ie="beforeunload";function Fs(t){let s=t.getLocation();const e=new Set,n=r=>{s=t.getLocation(),e.forEach(a=>a({location:s,action:r}))},o=r=>{t.notifyOnIndexChange??!0?n(r):s=t.getLocation()},i=async({task:r,navigateOpts:a,...c})=>{if(a?.ignoreBlocker??!1){r();return}const d=t.getBlockers?.()??[],l=c.type==="PUSH"||c.type==="REPLACE";if(typeof document<"u"&&d.length&&l)for(const u of d){const f=Ot(c.path,c.state);if(await u.blockerFn({currentLocation:s,nextLocation:f,action:c.type})){t.onBlocked?.();return}}r()};return{get location(){return s},get length(){return t.getLength()},subscribers:e,subscribe:r=>(e.add(r),()=>{e.delete(r)}),push:(r,a,c)=>{const h=s.state[G];a=Ee(h+1,a),i({task:()=>{t.pushState(r,a),n({type:"PUSH"})},navigateOpts:c,type:"PUSH",path:r,state:a})},replace:(r,a,c)=>{const h=s.state[G];a=Ee(h,a),i({task:()=>{t.replaceState(r,a),n({type:"REPLACE"})},navigateOpts:c,type:"REPLACE",path:r,state:a})},go:(r,a)=>{i({task:()=>{t.go(r),o({type:"GO",index:r})},navigateOpts:a,type:"GO"})},back:r=>{i({task:()=>{t.back(r?.ignoreBlocker??!1),o({type:"BACK"})},navigateOpts:r,type:"BACK"})},forward:r=>{i({task:()=>{t.forward(r?.ignoreBlocker??!1),o({type:"FORWARD"})},navigateOpts:r,type:"FORWARD"})},canGoBack:()=>s.state[G]!==0,createHref:r=>t.createHref(r),block:r=>{if(!t.setBlockers)return()=>{};const a=t.getBlockers?.()??[];return t.setBlockers([...a,r]),()=>{const c=t.getBlockers?.()??[];t.setBlockers?.(c.filter(h=>h!==r))}},flush:()=>t.flush?.(),destroy:()=>t.destroy?.(),notify:n}}function Ee(t,s){s||(s={});const e=he();return{...s,key:e,__TSR_key:e,[G]:t}}function As(t){const s=typeof document<"u"?window:void 0,e=s.history.pushState,n=s.history.replaceState;let o=[];const i=()=>o,r=w=>o=w,a=(w=>w),c=(()=>Ot(`${s.location.pathname}${s.location.search}${s.location.hash}`,s.history.state));if(!s.history.state?.__TSR_key&&!s.history.state?.key){const w=he();s.history.replaceState({[G]:0,key:w,__TSR_key:w},"")}let h=c(),d,l=!1,u=!1,f=!1,p=!1;const g=()=>h;let m,y;const v=()=>{m&&(R._ignoreSubscribers=!0,(m.isPush?s.history.pushState:s.history.replaceState)(m.state,"",m.href),R._ignoreSubscribers=!1,m=void 0,y=void 0,d=void 0)},S=(w,C,M)=>{const I=a(C);y||(d=h),h=Ot(C,M),m={href:I,state:M,isPush:m?.isPush||w==="push"},y||(y=Promise.resolve().then(()=>v()))},x=w=>{h=c(),R.notify({type:w})},L=async()=>{if(u){u=!1;return}const w=c(),C=w.state[G]-h.state[G],M=C===1,I=C===-1,F=!M&&!I||l;l=!1;const A=F?"GO":I?"BACK":"FORWARD",j=F?{type:"GO",index:C}:{type:I?"BACK":"FORWARD"};if(f)f=!1;else{const N=i();if(typeof document<"u"&&N.length){for(const nt of N)if(await nt.blockerFn({currentLocation:h,nextLocation:w,action:A})){u=!0,s.history.go(1),R.notify(j);return}}}h=c(),R.notify(j)},_=w=>{if(p){p=!1;return}let C=!1;const M=i();if(typeof document<"u"&&M.length)for(const I of M){const F=I.enableBeforeUnload??!0;if(F===!0){C=!0;break}if(typeof F=="function"&&F()===!0){C=!0;break}}if(C)return w.preventDefault(),w.returnValue=""},R=Fs({getLocation:g,getLength:()=>s.history.length,pushState:(w,C)=>S("push",w,C),replaceState:(w,C)=>S("replace",w,C),back:w=>(w&&(f=!0),p=!0,s.history.back()),forward:w=>{w&&(f=!0),p=!0,s.history.forward()},go:w=>{l=!0,s.history.go(w)},createHref:w=>a(w),flush:v,destroy:()=>{s.history.pushState=e,s.history.replaceState=n,s.removeEventListener(Ie,_,{capture:!0}),s.removeEventListener(Me,L)},onBlocked:()=>{d&&h!==d&&(h=d)},getBlockers:i,setBlockers:r,notifyOnIndexChange:!1});return s.addEventListener(Ie,_,{capture:!0}),s.addEventListener(Me,L),s.history.pushState=function(...w){const C=e.apply(s.history,w);return R._ignoreSubscribers||x("PUSH"),C},s.history.replaceState=function(...w){const C=n.apply(s.history,w);return R._ignoreSubscribers||x("REPLACE"),C},R}function Ot(t,s){const e=t.indexOf("#"),n=t.indexOf("?"),o=he();return{href:t,pathname:t.substring(0,e>0?n>0?Math.min(e,n):e:n>0?n:t.length),hash:e>-1?t.substring(e):"",search:n>-1?t.slice(n,e===-1?void 0:e):"",state:s||{[G]:0,key:o,__TSR_key:o}}}function he(){return(Math.random()+1).toString(36).substring(7)}function Ft(t){return t[t.length-1]}function Bs(t){return typeof t=="function"}function H(t,s){return Bs(t)?t(s):t}const zs=Object.prototype.hasOwnProperty;function z(t,s){if(t===s)return t;const e=s,n=Oe(t)&&Oe(e);if(!n&&!(At(t)&&At(e)))return e;const o=n?t:ke(t);if(!o)return e;const i=n?e:ke(e);if(!i)return e;const r=o.length,a=i.length,c=n?new Array(a):{};let h=0;for(let d=0;d"u")return!0;const e=s.prototype;return!(!Te(e)||!e.hasOwnProperty("isPrototypeOf"))}function Te(t){return Object.prototype.toString.call(t)==="[object Object]"}function Oe(t){return Array.isArray(t)&&t.length===Object.keys(t).length}function Z(t,s,e){if(t===s)return!0;if(typeof t!=typeof s)return!1;if(Array.isArray(t)&&Array.isArray(s)){if(t.length!==s.length)return!1;for(let n=0,o=t.length;no||!Z(t[r],s[r],e)))return!1;return o===i}return!1}function ct(t){let s,e;const n=new Promise((o,i)=>{s=o,e=i});return n.status="pending",n.resolve=o=>{n.status="resolved",n.value=o,s(o),t?.(o)},n.reject=o=>{n.status="rejected",e(o)},n}function J(t){return!!(t&&typeof t=="object"&&typeof t.then=="function")}function Fe(t){try{return decodeURI(t)}catch{return t.replaceAll(/%[0-9A-F]{2}/gi,s=>{try{return decodeURI(s)}catch{return s}})}}function Ae(t,s){if(!t)return t;const e=/%25|%5C/gi;let n=0,o="",i;for(;(i=e.exec(t))!==null;)o+=Fe(t.slice(n,i.index))+i[0],n=e.lastIndex;return o+Fe(n?t.slice(n):t)}var Ds="Invariant failed";function K(t,s){if(!t)throw new Error(Ds)}function Bt(t){const s=new Map;let e,n;const o=i=>{i.next&&(i.prev?(i.prev.next=i.next,i.next.prev=i.prev,i.next=void 0,n&&(n.next=i,i.prev=n)):(i.next.prev=void 0,e=i.next,i.next=void 0,n&&(i.prev=n,n.next=i)),n=i)};return{get(i){const r=s.get(i);if(r)return o(r),r.value},set(i,r){if(s.size>=t&&e){const c=e;s.delete(c.key),c.next&&(e=c.next,c.next.prev=void 0),c===n&&(n=void 0)}const a=s.get(i);if(a)a.value=r,o(a);else{const c={key:i,value:r,prev:n};n&&(n.next=c),n=c,e||(e=c),s.set(i,c)}},clear(){s.clear(),e=void 0,n=void 0}}}const lt=0,et=1,st=2,vt=3,js=/^([^{]*)\{\$([a-zA-Z_$][a-zA-Z0-9_$]*)\}([^}]*)$/,Ns=/^([^{]*)\{-\$([a-zA-Z_$][a-zA-Z0-9_$]*)\}([^}]*)$/,Ws=/^([^{]*)\{\$\}([^}]*)$/;function de(t,s,e=new Uint16Array(6)){const n=t.indexOf("/",s),o=n===-1?t.length:n,i=t.substring(s,o);if(!i||!i.includes("$"))return e[0]=lt,e[1]=s,e[2]=s,e[3]=o,e[4]=o,e[5]=o,e;if(i==="$"){const h=t.length;return e[0]=st,e[1]=s,e[2]=s,e[3]=h,e[4]=h,e[5]=h,e}if(i.charCodeAt(0)===36)return e[0]=et,e[1]=s,e[2]=s+1,e[3]=o,e[4]=o,e[5]=o,e;const r=i.match(Ws);if(r){const d=r[1].length;return e[0]=st,e[1]=s+d,e[2]=s+d+1,e[3]=s+d+2,e[4]=s+d+3,e[5]=t.length,e}const a=i.match(Ns);if(a){const h=a[1],d=a[2],l=a[3],u=h.length;return e[0]=vt,e[1]=s+u,e[2]=s+u+3,e[3]=s+u+3+d.length,e[4]=o-l.length,e[5]=o,e}const c=i.match(js);if(c){const h=c[1],d=c[2],l=c[3],u=h.length;return e[0]=et,e[1]=s+u,e[2]=s+u+2,e[3]=s+u+2+d.length,e[4]=o-l.length,e[5]=o,e}return e[0]=lt,e[1]=s,e[2]=s,e[3]=o,e[4]=o,e[5]=o,e}function Wt(t,s,e,n,o,i,r){r?.(e);let a=n;{const c=e.fullPath??e.from,h=c.length,d=e.options?.caseSensitive??t;for(;a_.caseSensitive===v&&_.prefix===S&&_.suffix===x);if(L)u=L;else{const _=Jt(et,e.fullPath??e.from,v,S,x);u=_,_.depth=i,_.parent=o,o.dynamic??=[],o.dynamic.push(_)}break}case vt:{const m=c.substring(f,l[1]),y=c.substring(l[4],p),v=d&&!!(m||y),S=m?v?m:m.toLowerCase():void 0,x=y?v?y:y.toLowerCase():void 0,L=o.optional?.find(_=>_.caseSensitive===v&&_.prefix===S&&_.suffix===x);if(L)u=L;else{const _=Jt(vt,e.fullPath??e.from,v,S,x);u=_,_.parent=o,_.depth=i,o.optional??=[],o.optional.push(_)}break}case st:{const m=c.substring(f,l[1]),y=c.substring(l[4],p),v=d&&!!(m||y),S=m?v?m:m.toLowerCase():void 0,x=y?v?y:y.toLowerCase():void 0,L=Jt(st,e.fullPath??e.from,v,S,x);u=L,L.parent=o,L.depth=i,o.wildcard??=[],o.wildcard.push(L)}}o=u}if((e.path||!e.children)&&!e.isRoot){const l=c.endsWith("/");l||(o.notFound=e),(!o.route||!o.isIndex&&l)&&(o.route=e,o.fullPath=e.fullPath??e.from),o.isIndex||=l}}if(e.children)for(const c of e.children)Wt(t,s,c,a,o,i,r)}function Gt(t,s){if(t.prefix&&s.prefix&&t.prefix!==s.prefix){if(t.prefix.startsWith(s.prefix))return-1;if(s.prefix.startsWith(t.prefix))return 1}if(t.suffix&&s.suffix&&t.suffix!==s.suffix){if(t.suffix.endsWith(s.suffix))return-1;if(s.suffix.endsWith(t.suffix))return 1}return t.prefix&&!s.prefix?-1:!t.prefix&&s.prefix?1:t.suffix&&!s.suffix?-1:!t.suffix&&s.suffix?1:t.caseSensitive&&!s.caseSensitive?-1:!t.caseSensitive&&s.caseSensitive?1:0}function X(t){if(t.static)for(const s of t.static.values())X(s);if(t.staticInsensitive)for(const s of t.staticInsensitive.values())X(s);if(t.dynamic?.length){t.dynamic.sort(Gt);for(const s of t.dynamic)X(s)}if(t.optional?.length){t.optional.sort(Gt);for(const s of t.optional)X(s)}if(t.wildcard?.length){t.wildcard.sort(Gt);for(const s of t.wildcard)X(s)}}function St(t){return{kind:lt,depth:0,static:null,staticInsensitive:null,dynamic:null,optional:null,wildcard:null,route:null,fullPath:t,parent:null,isIndex:!1,notFound:null}}function Jt(t,s,e,n,o){return{kind:t,depth:0,static:null,staticInsensitive:null,dynamic:null,optional:null,wildcard:null,route:null,fullPath:s,parent:null,isIndex:!1,notFound:null,caseSensitive:e,prefix:n,suffix:o}}function $s(t,s){const e=St("/"),n=new Uint16Array(6);for(const o of t)Wt(!1,n,o,1,e,0);X(e),s.masksTree=e,s.flatCache=Bt(1e3)}function Us(t,s){t||="/";const e=s.flatCache.get(t);if(e)return e;const n=fe(t,s.masksTree);return s.flatCache.set(t,n),n}function Vs(t,s,e,n,o){t||="/",n||="/";const i=s?`case\0${t}`:t;let r=o.singleCache.get(i);if(!r){r=St("/");const a=new Uint16Array(6);Wt(s,a,{from:t},1,r,0),o.singleCache.set(i,r)}return fe(n,r,e)}function Ks(t,s,e=!1){const n=e?t:`nofuzz\0${t}`,o=s.matchCache.get(n);if(o!==void 0)return o;t||="/";const i=fe(t,s.segmentTree,e);return i&&(i.branch=Js(i.route)),s.matchCache.set(n,i),i}function Hs(t){return t==="/"?t:t.replace(/\/{1,}$/,"")}function qs(t,s=!1,e){const n=St(t.fullPath),o=new Uint16Array(6),i={},r={};let a=0;return Wt(s,o,t,1,n,0,h=>{if(e?.(h,a),K(!(h.id in i),`Duplicate routes found with id: ${String(h.id)}`),i[h.id]=h,a!==0&&h.path){const d=Hs(h.fullPath);(!r[d]||h.fullPath.endsWith("/"))&&(r[d]=h)}a++}),X(n),{processedTree:{segmentTree:n,singleCache:Bt(1e3),matchCache:Bt(1e3),flatCache:null,masksTree:null},routesById:i,routesByPath:r}}function fe(t,s,e=!1){const n=t.split("/"),o=Xs(t,n,s,e);if(!o)return null;const i=Gs(t,n,o),r="**"in o;return r&&(i["**"]=o["**"]),{route:r?o.node.notFound??o.node.route:o.node.route,params:i}}function Gs(t,s,e){const n=Ys(e.node);let o=null;const i={};for(let r=0,a=0,c=0;a=0;w--){const C=u.optional[w];a.push({node:C,index:f,skipped:_,depth:R,statics:m,dynamics:y,optionals:v})}if(!S)for(let w=u.optional.length-1;w>=0;w--){const C=u.optional[w],{prefix:M,suffix:I}=C;if(M||I){const F=C.caseSensitive?x:L??=x.toLowerCase();if(M&&!F.startsWith(M)||I&&!F.endsWith(I))continue}a.push({node:C,index:f+1,skipped:p,depth:R,statics:m,dynamics:y,optionals:v+1})}}if(!S&&u.dynamic&&x)for(let _=u.dynamic.length-1;_>=0;_--){const R=u.dynamic[_],{prefix:w,suffix:C}=R;if(w||C){const M=R.caseSensitive?x:L??=x.toLowerCase();if(w&&!M.startsWith(w)||C&&!M.endsWith(C))continue}a.push({node:R,index:f+1,skipped:p,depth:g+1,statics:m,dynamics:y+1,optionals:v})}if(!S&&u.staticInsensitive){const _=u.staticInsensitive.get(L??=x.toLowerCase());_&&a.push({node:_,index:f+1,skipped:p,depth:g+1,statics:m+1,dynamics:y,optionals:v})}if(!S&&u.static){const _=u.static.get(x);_&&a.push({node:_,index:f+1,skipped:p,depth:g+1,statics:m+1,dynamics:y,optionals:v})}}if(d&&c)return bt(c,d)?d:c;if(d)return d;if(c)return c;if(n&&h){let l=h.index;for(let f=0;ft.statics||s.statics===t.statics&&(s.dynamics>t.dynamics||s.dynamics===t.dynamics&&(s.optionals>t.optionals||s.optionals===t.optionals&&(s.node.isIndex>t.node.isIndex||s.node.isIndex===t.node.isIndex&&s.depth>t.depth))):!0}function It(t){return pe(t.filter(s=>s!==void 0).join("/"))}function pe(t){return t.replace(/\/{2,}/g,"/")}function es(t){return t==="/"?t:t.replace(/^\/{1,}/,"")}function Q(t){const s=t.length;return s>1&&t[s-1]==="/"?t.replace(/\/{1,}$/,""):t}function Et(t){return Q(es(t))}function zt(t,s){return t?.endsWith("/")&&t!=="/"&&t!==`${s}/`?t.slice(0,-1):t}function Zs(t,s,e){return zt(t,e)===zt(s,e)}function Qs({base:t,to:s,trailingSlash:e="never",cache:n}){const o=s.startsWith("/"),i=!o&&s===".";let r;if(n){r=o?s:i?t:t+"\0"+s;const l=n.get(r);if(l)return l}let a;if(i)a=t.split("/");else if(o)a=s.split("/");else{for(a=t.split("/");a.length>1&&Ft(a)==="";)a.pop();const l=s.split("/");for(let u=0,f=l.length;u1&&(Ft(a)===""?e==="never"&&a.pop():e==="always"&&a.push(""));let c,h="";for(let l=0;l0&&(h+="/");const u=a[l];if(!u)continue;c=de(u,0,c);const f=c[0];if(f===lt){h+=u;continue}const p=c[5],g=u.substring(0,c[1]),m=u.substring(c[4],p),y=u.substring(c[2],c[3]);f===et?h+=g||m?`${g}{$${y}}${m}`:`$${y}`:f===st?h+=g||m?`${g}{$}${m}`:"$":h+=`${g}{-$${y}}${m}`}h=pe(h);const d=h||"/";return r&&n&&n.set(r,d),d}function Yt(t,s,e){const n=s[t];return typeof n!="string"?n:t==="_splat"?encodeURI(n):tn(n,e)}function Xt({path:t,params:s,decodeCharMap:e}){let n=!1;const o={};if(!t||t==="/")return{interpolatedPath:"/",usedParams:o,isMissingParams:n};if(!t.includes("$"))return{interpolatedPath:t,usedParams:o,isMissingParams:n};const i=t.length;let r=0,a,c="";for(;r{let e;return(...n)=>{e||(e=setTimeout(()=>{t(...n),e=null},s))}};function nn(){const t=en();if(!t)return null;const s=t.getItem(Dt);let e=s?JSON.parse(s):{};return{state:e,set:n=>(e=H(n,e)||e,t.setItem(Dt,JSON.stringify(e)))}}const Ct=nn(),ae=t=>t.state.__TSR_key||t.href;function on(t){const s=[];let e;for(;e=t.parentNode;)s.push(`${t.tagName}:nth-child(${Array.prototype.indexOf.call(e.children,t)+1})`),t=e;return`${s.reverse().join(" > ")}`.toLowerCase()}let jt=!1;function ss({storageKey:t,key:s,behavior:e,shouldScrollRestoration:n,scrollToTopSelectors:o,location:i}){let r;try{r=JSON.parse(sessionStorage.getItem(t)||"{}")}catch(h){console.error(h);return}const a=s||window.history.state?.__TSR_key,c=r[a];jt=!0;t:{if(n&&c&&Object.keys(c).length>0){for(const l in c){const u=c[l];if(l==="window")window.scrollTo({top:u.scrollY,left:u.scrollX,behavior:e});else if(l){const f=document.querySelector(l);f&&(f.scrollLeft=u.scrollX,f.scrollTop=u.scrollY)}}break t}const h=(i??window.location).hash.split("#",2)[1];if(h){const l=window.history.state?.__hashScrollIntoViewOptions??!0;if(l){const u=document.getElementById(h);u&&u.scrollIntoView(l)}break t}const d={top:0,left:0,behavior:e};if(window.scrollTo(d),o)for(const l of o){if(l==="window")continue;const u=typeof l=="function"?l():document.querySelector(l);u&&u.scrollTo(d)}}jt=!1}function rn(t,s){if(!Ct&&!t.isServer||((t.options.scrollRestoration??!1)&&(t.isScrollRestoring=!0),t.isServer||t.isScrollRestorationSetup||!Ct))return;t.isScrollRestorationSetup=!0,jt=!1;const n=t.options.getScrollRestorationKey||ae;window.history.scrollRestoration="manual";const o=i=>{if(jt||!t.isScrollRestoring)return;let r="";if(i.target===document||i.target===window)r="window";else{const c=i.target.getAttribute("data-scroll-restoration-id");c?r=`[data-scroll-restoration-id="${c}"]`:r=on(i.target)}const a=n(t.state.location);Ct.set(c=>{const h=c[a]||={},d=h[r]||={};if(r==="window")d.scrollX=window.scrollX||0,d.scrollY=window.scrollY||0;else if(r){const l=document.querySelector(r);l&&(d.scrollX=l.scrollLeft||0,d.scrollY=l.scrollTop||0)}return c})};typeof document<"u"&&document.addEventListener("scroll",sn(o,100),!0),t.subscribe("onRendered",i=>{const r=n(i.toLocation);if(!t.resetNextScroll){t.resetNextScroll=!0;return}typeof t.options.scrollRestoration=="function"&&!t.options.scrollRestoration({location:t.latestLocation})||(ss({storageKey:Dt,key:r,behavior:t.options.scrollRestorationBehavior,shouldScrollRestoration:t.isScrollRestoring,scrollToTopSelectors:t.options.scrollToTopSelectors,location:t.history.location}),t.isScrollRestoring&&Ct.set(a=>(a[r]||={},a)))})}function an(t){if(typeof document<"u"&&document.querySelector){const s=t.state.location.state.__hashScrollIntoViewOptions??!0;if(s&&t.state.location.hash!==""){const e=document.getElementById(t.state.location.hash);e&&e.scrollIntoView(s)}}}function cn(t,s=String){const e=new URLSearchParams;for(const n in t){const o=t[n];o!==void 0&&e.set(n,s(o))}return e.toString()}function Zt(t){return t?t==="false"?!1:t==="true"?!0:+t*0===0&&+t+""===t?+t:t:""}function ln(t){const s=new URLSearchParams(t),e={};for(const[n,o]of s.entries()){const i=e[n];i==null?e[n]=Zt(o):Array.isArray(i)?i.push(Zt(o)):e[n]=[i,Zt(o)]}return e}const un=dn(JSON.parse),hn=fn(JSON.stringify,JSON.parse);function dn(t){return s=>{s[0]==="?"&&(s=s.substring(1));const e=ln(s);for(const n in e){const o=e[n];if(typeof o=="string")try{e[n]=t(o)}catch{}}return e}}function fn(t,s){const e=typeof s=="function";function n(o){if(typeof o=="object"&&o!==null)try{return t(o)}catch{}else if(e&&typeof o=="string")try{return s(o),t(o)}catch{}return o}return o=>{const i=cn(o,n);return i?`?${i}`:""}}const B="__root__";function pn(t){if(t.statusCode=t.statusCode||t.code||307,!t.reloadDocument&&typeof t.href=="string")try{new URL(t.href),t.reloadDocument=!0}catch{}const s=new Headers(t.headers);t.href&&s.get("Location")===null&&s.set("Location",t.href);const e=new Response(null,{status:t.statusCode,headers:s});if(e.options=t,t.throw)throw e;return e}function $(t){return t instanceof Response&&!!t.options}const kt=t=>{if(!t.rendered)return t.rendered=!0,t.onReady?.()},$t=(t,s)=>!!(t.preload&&!t.router.state.matches.some(e=>e.id===s)),ns=(t,s)=>{const e=t.router.routesById[s.routeId??""]??t.router.routeTree;!e.options.notFoundComponent&&t.router.options?.defaultNotFoundComponent&&(e.options.notFoundComponent=t.router.options.defaultNotFoundComponent),K(e.options.notFoundComponent);const n=t.matches.find(o=>o.routeId===e.id);K(n,"Could not find match for route: "+e.id),t.updateMatch(n.id,o=>({...o,status:"notFound",error:s,isFetching:!1})),s.routerCode==="BEFORE_LOAD"&&e.parentRoute&&(s.routeId=e.parentRoute.id,ns(t,s))},q=(t,s,e)=>{if(!(!$(e)&&!D(e))){if($(e)&&e.redirectHandled&&!e.options.reloadDocument)throw e;if(s){s._nonReactive.beforeLoadPromise?.resolve(),s._nonReactive.loaderPromise?.resolve(),s._nonReactive.beforeLoadPromise=void 0,s._nonReactive.loaderPromise=void 0;const n=$(e)?"redirected":"notFound";s._nonReactive.error=e,t.updateMatch(s.id,o=>({...o,status:n,isFetching:!1,error:e})),D(e)&&!e.routeId&&(e.routeId=s.routeId),s._nonReactive.loadPromise?.resolve()}throw $(e)?(t.rendered=!0,e.options._fromLocation=t.location,e.redirectHandled=!0,e=t.router.resolveRedirect(e),e):(ns(t,e),e)}},os=(t,s)=>{const e=t.router.getMatch(s);return!!(!t.router.isServer&&e._nonReactive.dehydrated||t.router.isServer&&e.ssr===!1)},ht=(t,s,e,n)=>{const{id:o,routeId:i}=t.matches[s],r=t.router.looseRoutesById[i];if(e instanceof Promise)throw e;e.routerCode=n,t.firstBadMatchIndex??=s,q(t,t.router.getMatch(o),e);try{r.options.onError?.(e)}catch(a){e=a,q(t,t.router.getMatch(o),e)}t.updateMatch(o,a=>(a._nonReactive.beforeLoadPromise?.resolve(),a._nonReactive.beforeLoadPromise=void 0,a._nonReactive.loadPromise?.resolve(),{...a,error:e,status:"error",isFetching:!1,updatedAt:Date.now(),abortController:new AbortController}))},mn=(t,s,e,n)=>{const o=t.router.getMatch(s),i=t.matches[e-1]?.id,r=i?t.router.getMatch(i):void 0;if(t.router.isShell()){o.ssr=n.id===B;return}if(r?.ssr===!1){o.ssr=!1;return}const a=f=>f===!0&&r?.ssr==="data-only"?"data-only":f,c=t.router.options.defaultSsr??!0;if(n.options.ssr===void 0){o.ssr=a(c);return}if(typeof n.options.ssr!="function"){o.ssr=a(n.options.ssr);return}const{search:h,params:d}=o,l={search:Lt(h,o.searchError),params:Lt(d,o.paramsError),location:t.location,matches:t.matches.map(f=>({index:f.index,pathname:f.pathname,fullPath:f.fullPath,staticData:f.staticData,id:f.id,routeId:f.routeId,search:Lt(f.search,f.searchError),params:Lt(f.params,f.paramsError),ssr:f.ssr}))},u=n.options.ssr(l);if(J(u))return u.then(f=>{o.ssr=a(f??c)});o.ssr=a(u??c)},is=(t,s,e,n)=>{if(n._nonReactive.pendingTimeout!==void 0)return;const o=e.options.pendingMs??t.router.options.defaultPendingMs;if(!!(t.onReady&&!t.router.isServer&&!$t(t,s)&&(e.options.loader||e.options.beforeLoad||cs(e))&&typeof o=="number"&&o!==1/0&&(e.options.pendingComponent??t.router.options?.defaultPendingComponent))){const r=setTimeout(()=>{kt(t)},o);n._nonReactive.pendingTimeout=r}},gn=(t,s,e)=>{const n=t.router.getMatch(s);if(!n._nonReactive.beforeLoadPromise&&!n._nonReactive.loaderPromise)return;is(t,s,e,n);const o=()=>{const i=t.router.getMatch(s);i.preload&&(i.status==="redirected"||i.status==="notFound")&&q(t,i,i.error)};return n._nonReactive.beforeLoadPromise?n._nonReactive.beforeLoadPromise.then(o):o()},yn=(t,s,e,n)=>{const o=t.router.getMatch(s),i=o._nonReactive.loadPromise;o._nonReactive.loadPromise=ct(()=>{i?.resolve()});const{paramsError:r,searchError:a}=o;r&&ht(t,e,r,"PARSE_PARAMS"),a&&ht(t,e,a,"VALIDATE_SEARCH"),is(t,s,n,o);const c=new AbortController,h=t.matches[e-1]?.id,u={...(h?t.router.getMatch(h):void 0)?.context??t.router.options.context??void 0,...o.__routeContext};let f=!1;const p=()=>{f||(f=!0,t.updateMatch(s,R=>({...R,isFetching:"beforeLoad",fetchCount:R.fetchCount+1,abortController:c,context:u})))},g=()=>{o._nonReactive.beforeLoadPromise?.resolve(),o._nonReactive.beforeLoadPromise=void 0,t.updateMatch(s,R=>({...R,isFetching:!1}))};if(!n.options.beforeLoad){gt(()=>{p(),g()});return}o._nonReactive.beforeLoadPromise=ct();const{search:m,params:y,cause:v}=o,S=$t(t,s),x={search:m,abortController:c,params:y,preload:S,context:u,location:t.location,navigate:R=>t.router.navigate({...R,_fromLocation:t.location}),buildLocation:t.router.buildLocation,cause:S?"preload":v,matches:t.matches,...t.router.options.additionalContext},L=R=>{if(R===void 0){gt(()=>{p(),g()});return}($(R)||D(R))&&(p(),ht(t,e,R,"BEFORE_LOAD")),gt(()=>{p(),t.updateMatch(s,w=>({...w,__beforeLoadContext:R,context:{...w.context,...R}})),g()})};let _;try{if(_=n.options.beforeLoad(x),J(_))return p(),_.catch(R=>{ht(t,e,R,"BEFORE_LOAD")}).then(L)}catch(R){p(),ht(t,e,R,"BEFORE_LOAD")}L(_)},vn=(t,s)=>{const{id:e,routeId:n}=t.matches[s],o=t.router.looseRoutesById[n],i=()=>{if(t.router.isServer){const c=mn(t,e,s,o);if(J(c))return c.then(a)}return a()},r=()=>yn(t,e,s,o),a=()=>{if(os(t,e))return;const c=gn(t,e,o);return J(c)?c.then(r):r()};return i()},yt=(t,s,e)=>{const n=t.router.getMatch(s);if(!n||!e.options.head&&!e.options.scripts&&!e.options.headers)return;const o={matches:t.matches,match:n,params:n.params,loaderData:n.loaderData};return Promise.all([e.options.head?.(o),e.options.scripts?.(o),e.options.headers?.(o)]).then(([i,r,a])=>{const c=i?.meta,h=i?.links,d=i?.scripts,l=i?.styles;return{meta:c,links:h,headScripts:d,headers:a,scripts:r,styles:l}})},rs=(t,s,e,n)=>{const o=t.matchPromises[e-1],{params:i,loaderDeps:r,abortController:a,cause:c}=t.router.getMatch(s);let h=t.router.options.context??{};for(let l=0;l<=e;l++){const u=t.matches[l];if(!u)continue;const f=t.router.getMatch(u.id);f&&(h={...h,...f.__routeContext??{},...f.__beforeLoadContext??{}})}const d=$t(t,s);return{params:i,deps:r,preload:!!d,parentMatchPromise:o,abortController:a,context:h,location:t.location,navigate:l=>t.router.navigate({...l,_fromLocation:t.location}),cause:d?"preload":c,route:n,...t.router.options.additionalContext}},Be=async(t,s,e,n)=>{try{const o=t.router.getMatch(s);try{(!t.router.isServer||o.ssr===!0)&&as(n);const i=n.options.loader?.(rs(t,s,e,n)),r=n.options.loader&&J(i);if(!!(r||n._lazyPromise||n._componentsPromise||n.options.head||n.options.scripts||n.options.headers||o._nonReactive.minPendingPromise)&&t.updateMatch(s,l=>({...l,isFetching:"loader"})),n.options.loader){const l=r?await i:i;q(t,t.router.getMatch(s),l),l!==void 0&&t.updateMatch(s,u=>({...u,loaderData:l}))}n._lazyPromise&&await n._lazyPromise;const c=yt(t,s,n),h=c?await c:void 0,d=o._nonReactive.minPendingPromise;d&&await d,n._componentsPromise&&await n._componentsPromise,t.updateMatch(s,l=>({...l,error:void 0,status:"success",isFetching:!1,updatedAt:Date.now(),...h}))}catch(i){let r=i;const a=o._nonReactive.minPendingPromise;a&&await a,D(i)&&await n.options.notFoundComponent?.preload?.(),q(t,t.router.getMatch(s),i);try{n.options.onError?.(i)}catch(d){r=d,q(t,t.router.getMatch(s),d)}const c=yt(t,s,n),h=c?await c:void 0;t.updateMatch(s,d=>({...d,error:r,status:"error",isFetching:!1,...h}))}}catch(o){const i=t.router.getMatch(s);if(i){const r=yt(t,s,n);if(r){const a=await r;t.updateMatch(s,c=>({...c,...a}))}i._nonReactive.loaderPromise=void 0}q(t,i,o)}},Sn=async(t,s)=>{const{id:e,routeId:n}=t.matches[s];let o=!1,i=!1;const r=t.router.looseRoutesById[n];if(os(t,e)){if(t.router.isServer){const h=yt(t,e,r);if(h){const d=await h;t.updateMatch(e,l=>({...l,...d}))}return t.router.getMatch(e)}}else{const h=t.router.getMatch(e);if(h._nonReactive.loaderPromise){if(h.status==="success"&&!t.sync&&!h.preload)return h;await h._nonReactive.loaderPromise;const d=t.router.getMatch(e),l=d._nonReactive.error||d.error;l&&q(t,d,l)}else{const d=Date.now()-h.updatedAt,l=$t(t,e),u=l?r.options.preloadStaleTime??t.router.options.defaultPreloadStaleTime??3e4:r.options.staleTime??t.router.options.defaultStaleTime??0,f=r.options.shouldReload,p=typeof f=="function"?f(rs(t,e,s,r)):f,g=!!l&&!t.router.state.matches.some(S=>S.id===e),m=t.router.getMatch(e);m._nonReactive.loaderPromise=ct(),g!==m.preload&&t.updateMatch(e,S=>({...S,preload:g}));const{status:y,invalid:v}=m;if(o=y==="success"&&(v||(p??d>u)),!(l&&r.options.preload===!1))if(o&&!t.sync)i=!0,(async()=>{try{await Be(t,e,s,r);const S=t.router.getMatch(e);S._nonReactive.loaderPromise?.resolve(),S._nonReactive.loadPromise?.resolve(),S._nonReactive.loaderPromise=void 0}catch(S){$(S)&&await t.router.navigate(S.options)}})();else if(y!=="success"||o&&t.sync)await Be(t,e,s,r);else{const S=yt(t,e,r);if(S){const x=await S;t.updateMatch(e,L=>({...L,...x}))}}}}const a=t.router.getMatch(e);i||(a._nonReactive.loaderPromise?.resolve(),a._nonReactive.loadPromise?.resolve()),clearTimeout(a._nonReactive.pendingTimeout),a._nonReactive.pendingTimeout=void 0,i||(a._nonReactive.loaderPromise=void 0),a._nonReactive.dehydrated=void 0;const c=i?a.isFetching:!1;return c!==a.isFetching||a.invalid!==!1?(t.updateMatch(e,h=>({...h,isFetching:c,invalid:!1})),t.router.getMatch(e)):a};async function ze(t){const s=Object.assign(t,{matchPromises:[]});!s.router.isServer&&s.router.state.matches.some(e=>e._forcePending)&&kt(s);try{for(let o=0;o{const{id:e,...n}=s.options;Object.assign(t.options,n),t._lazyLoaded=!0,t._lazyPromise=void 0}):t._lazyLoaded=!0),!t._componentsLoaded&&t._componentsPromise===void 0){const s=()=>{const e=[];for(const n of ls){const o=t.options[n]?.preload;o&&e.push(o())}if(e.length)return Promise.all(e).then(()=>{t._componentsLoaded=!0,t._componentsPromise=void 0});t._componentsLoaded=!0,t._componentsPromise=void 0};t._componentsPromise=t._lazyPromise?t._lazyPromise.then(s):s()}return t._componentsPromise}function Lt(t,s){return s?{status:"error",error:s}:{status:"success",value:t}}function cs(t){for(const s of ls)if(t.options[s]?.preload)return!0;return!1}const ls=["component","errorComponent","pendingComponent","notFoundComponent"];function _n(t){return{input:({url:s})=>{for(const e of t)s=us(e,s);return s},output:({url:s})=>{for(let e=t.length-1;e>=0;e--)s=hs(t[e],s);return s}}}function wn(t){const s=Et(t.basepath),e=`/${s}`,n=`${e}/`,o=t.caseSensitive?e:e.toLowerCase(),i=t.caseSensitive?n:n.toLowerCase();return{input:({url:r})=>{const a=t.caseSensitive?r.pathname:r.pathname.toLowerCase();return a===o?r.pathname="/":a.startsWith(i)&&(r.pathname=r.pathname.slice(e.length)),r},output:({url:r})=>(r.pathname=It(["/",s,r.pathname]),r)}}function us(t,s){const e=t?.input?.({url:s});if(e){if(typeof e=="string")return new URL(e);if(e instanceof URL)return e}return s}function hs(t,s){const e=t?.output?.({url:s});if(e){if(typeof e=="string")return new URL(e);if(e instanceof URL)return e}return s}function tt(t){const s=t.resolvedLocation,e=t.location,n=s?.pathname!==e.pathname,o=s?.href!==e.href,i=s?.hash!==e.hash;return{fromLocation:s,toLocation:e,pathChanged:n,hrefChanged:o,hashChanged:i}}class Rn{constructor(s){this.tempLocationKey=`${Math.round(Math.random()*1e7)}`,this.resetNextScroll=!0,this.shouldViewTransition=void 0,this.isViewTransitionTypesSupported=void 0,this.subscribers=new Set,this.isScrollRestoring=!1,this.isScrollRestorationSetup=!1,this.startTransition=e=>e(),this.update=e=>{e.notFoundRoute&&console.warn("The notFoundRoute API is deprecated and will be removed in the next major version. See https://tanstack.com/router/v1/docs/framework/react/guide/not-found-errors#migrating-from-notfoundroute for more info.");const n=this.options,o=this.basepath??n?.basepath??"/",i=this.basepath===void 0,r=n?.rewrite;this.options={...n,...e},this.isServer=this.options.isServer??typeof document>"u",this.pathParamsDecodeCharMap=this.options.pathParamsAllowedCharacters?new Map(this.options.pathParamsAllowedCharacters.map(u=>[encodeURIComponent(u),u])):void 0,(!this.history||this.options.history&&this.options.history!==this.history)&&(this.options.history?this.history=this.options.history:this.isServer||(this.history=As())),this.origin=this.options.origin,this.origin||(!this.isServer&&window?.origin&&window.origin!=="null"?this.origin=window.origin:this.origin="http://localhost"),this.history&&this.updateLatestLocation(),this.options.routeTree!==this.routeTree&&(this.routeTree=this.options.routeTree,this.buildRouteTree()),!this.__store&&this.latestLocation&&(this.__store=new Os(Pn(this.latestLocation),{onUpdate:()=>{this.__store.state={...this.state,cachedMatches:this.state.cachedMatches.filter(u=>!["redirected"].includes(u.status))}}}),rn(this));let a=!1;const c=this.options.basepath??"/",h=this.options.rewrite;if(i||o!==c||r!==h){this.basepath=c;const u=[];Et(c)!==""&&u.push(wn({basepath:c})),h&&u.push(h),this.rewrite=u.length===0?void 0:u.length===1?u[0]:_n(u),this.history&&this.updateLatestLocation(),a=!0}a&&this.__store&&(this.__store.state={...this.state,location:this.latestLocation}),typeof window<"u"&&"CSS"in window&&typeof window.CSS?.supports=="function"&&(this.isViewTransitionTypesSupported=window.CSS.supports("selector(:active-view-transition-type(a)"))},this.updateLatestLocation=()=>{this.latestLocation=this.parseLocation(this.history.location,this.latestLocation)},this.buildRouteTree=()=>{const{routesById:e,routesByPath:n,processedTree:o}=qs(this.routeTree,this.options.caseSensitive,(r,a)=>{r.init({originalIndex:a})});this.options.routeMasks&&$s(this.options.routeMasks,o),this.routesById=e,this.routesByPath=n,this.processedTree=o;const i=this.options.notFoundRoute;i&&(i.init({originalIndex:99999999999}),this.routesById[i.id]=i)},this.subscribe=(e,n)=>{const o={eventType:e,fn:n};return this.subscribers.add(o),()=>{this.subscribers.delete(o)}},this.emit=e=>{this.subscribers.forEach(n=>{n.eventType===e.type&&n.fn(e)})},this.parseLocation=(e,n)=>{const o=({href:c,state:h})=>{const d=new URL(c,this.origin),l=us(this.rewrite,d),u=this.options.parseSearch(l.search),f=this.options.stringifySearch(u);l.search=f;const p=l.href.replace(l.origin,""),{pathname:g,hash:m}=l;return{href:p,publicHref:c,url:l.href,pathname:Ae(g),searchStr:f,search:z(n?.search,u),hash:m.split("#").reverse()[0]??"",state:z(n?.state,h)}},i=o(e),{__tempLocation:r,__tempKey:a}=i.state;if(r&&(!a||a===this.tempLocationKey)){const c=o(r);return c.state.key=i.state.key,c.state.__TSR_key=i.state.__TSR_key,delete c.state.__tempLocation,{...c,maskedLocation:i}}return i},this.resolvePathCache=Bt(1e3),this.resolvePathWithBase=(e,n)=>Qs({base:e,to:pe(n),trailingSlash:this.options.trailingSlash,cache:this.resolvePathCache}),this.matchRoutes=(e,n,o)=>typeof e=="string"?this.matchRoutesInternal({pathname:e,search:n},o):this.matchRoutesInternal(e,n),this.getMatchedRoutes=e=>bn({pathname:e,routesById:this.routesById,processedTree:this.processedTree}),this.cancelMatch=e=>{const n=this.getMatch(e);n&&(n.abortController.abort(),clearTimeout(n._nonReactive.pendingTimeout),n._nonReactive.pendingTimeout=void 0)},this.cancelMatches=()=>{const e=this.state.matches.filter(i=>i.status==="pending"),n=this.state.matches.filter(i=>i.isFetching==="loader");new Set([...this.state.pendingMatches??[],...e,...n]).forEach(i=>{this.cancelMatch(i.id)})},this.buildLocation=e=>{const n=(i={})=>{const r=i._fromLocation||this.pendingBuiltLocation||this.latestLocation,a=this.matchRoutes(r,{_buildLocation:!0}),c=Ft(a);i.from;const h=i.unsafeRelative==="path"?r.pathname:i.from??c.fullPath,d=this.resolvePathWithBase(h,"."),l=c.search,u={...c.params},f=i.to?this.resolvePathWithBase(d,`${i.to}`):this.resolvePathWithBase(d,"."),p=i.params===!1||i.params===null?{}:(i.params??!0)===!0?u:Object.assign(u,H(i.params,u)),g=Xt({path:f,params:p}).interpolatedPath,m=this.matchRoutes(g,void 0,{_buildLocation:!0}).map(M=>this.looseRoutesById[M.routeId]);if(Object.keys(p).length>0)for(const M of m){const I=M.options.params?.stringify??M.options.stringifyParams;I&&Object.assign(p,I(p))}const y=e.leaveParams?f:Ae(Xt({path:f,params:p,decodeCharMap:this.pathParamsDecodeCharMap}).interpolatedPath);let v=l;if(e._includeValidateSearch&&this.options.search?.strict){const M={};m.forEach(I=>{if(I.options.validateSearch)try{Object.assign(M,ce(I.options.validateSearch,{...M,...v}))}catch{}}),v=M}v=Cn({search:v,dest:i,destRoutes:m,_includeValidateSearch:e._includeValidateSearch}),v=z(l,v);const S=this.options.stringifySearch(v),x=i.hash===!0?r.hash:i.hash?H(i.hash,r.hash):void 0,L=x?`#${x}`:"";let _=i.state===!0?r.state:i.state?H(i.state,r.state):{};_=z(r.state,_);const R=`${y}${S}${L}`,w=new URL(R,this.origin),C=hs(this.rewrite,w);return{publicHref:C.pathname+C.search+C.hash,href:R,url:C.href,pathname:y,search:v,searchStr:S,state:_,hash:x??"",unmaskOnReload:i.unmaskOnReload}},o=(i={},r)=>{const a=n(i);let c=r?n(r):void 0;if(!c){const h={};if(this.options.routeMasks){const d=Us(a.pathname,this.processedTree);if(d){Object.assign(h,d.params);const{from:l,params:u,...f}=d.route,p=u===!1||u===null?{}:(u??!0)===!0?h:Object.assign(h,H(u,h));r={from:e.from,...f,params:p},c=n(r)}}}return c&&(a.maskedLocation=c),a};return e.mask?o(e,{from:e.from,...e.mask}):o(e)},this.commitLocation=({viewTransition:e,ignoreBlocker:n,...o})=>{const i=()=>{const c=["key","__TSR_key","__TSR_index","__hashScrollIntoViewOptions"];c.forEach(d=>{o.state[d]=this.latestLocation.state[d]});const h=Z(o.state,this.latestLocation.state);return c.forEach(d=>{delete o.state[d]}),h},r=Q(this.latestLocation.href)===Q(o.href),a=this.commitLocationPromise;if(this.commitLocationPromise=ct(()=>{a?.resolve()}),r&&i())this.load();else{let{maskedLocation:c,hashScrollIntoView:h,...d}=o;c&&(d={...c,state:{...c.state,__tempKey:void 0,__tempLocation:{...d,search:d.searchStr,state:{...d.state,__tempKey:void 0,__tempLocation:void 0,__TSR_key:void 0,key:void 0}}}},(d.unmaskOnReload??this.options.unmaskOnReload??!1)&&(d.state.__tempKey=this.tempLocationKey)),d.state.__hashScrollIntoViewOptions=h??this.options.defaultHashScrollIntoView??!0,this.shouldViewTransition=e,this.history[o.replace?"replace":"push"](d.publicHref,d.state,{ignoreBlocker:n})}return this.resetNextScroll=o.resetScroll??!0,this.history.subscribers.size||this.load(),this.commitLocationPromise},this.buildAndCommitLocation=({replace:e,resetScroll:n,hashScrollIntoView:o,viewTransition:i,ignoreBlocker:r,href:a,...c}={})=>{if(a){const l=this.history.location.state.__TSR_index,u=Ot(a,{__TSR_index:e?l:l+1});c.to=u.pathname,c.search=this.options.parseSearch(u.search),c.hash=u.hash.slice(1)}const h=this.buildLocation({...c,_includeValidateSearch:!0});this.pendingBuiltLocation=h;const d=this.commitLocation({...h,viewTransition:i,replace:e,resetScroll:n,hashScrollIntoView:o,ignoreBlocker:r});return Promise.resolve().then(()=>{this.pendingBuiltLocation===h&&(this.pendingBuiltLocation=void 0)}),d},this.navigate=async({to:e,reloadDocument:n,href:o,...i})=>{if(!n&&o)try{new URL(`${o}`),n=!0}catch{}if(n){if(o||(o=this.buildLocation({to:e,...i}).url),!i.ignoreBlocker){const a=this.history.getBlockers?.()??[];for(const c of a)if(c?.blockerFn&&await c.blockerFn({currentLocation:this.latestLocation,nextLocation:this.latestLocation,action:"PUSH"}))return Promise.resolve()}return i.replace?window.location.replace(o):window.location.href=o,Promise.resolve()}return this.buildAndCommitLocation({...i,href:o,to:e,_isNavigate:!0})},this.beforeLoad=()=>{if(this.cancelMatches(),this.updateLatestLocation(),this.isServer){const n=this.buildLocation({to:this.latestLocation.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0}),o=i=>{try{return encodeURI(decodeURI(i))}catch{return i}};if(Et(o(this.latestLocation.href))!==Et(o(n.href))){let i=n.url;throw this.origin&&i.startsWith(this.origin)&&(i=i.replace(this.origin,"")||"/"),pn({href:i})}}const e=this.matchRoutes(this.latestLocation);this.__store.setState(n=>({...n,status:"pending",statusCode:200,isLoading:!0,location:this.latestLocation,pendingMatches:e,cachedMatches:n.cachedMatches.filter(o=>!e.some(i=>i.id===o.id))}))},this.load=async e=>{let n,o,i;for(i=new Promise(a=>{this.startTransition(async()=>{try{this.beforeLoad();const c=this.latestLocation,h=this.state.resolvedLocation;this.state.redirect||this.emit({type:"onBeforeNavigate",...tt({resolvedLocation:h,location:c})}),this.emit({type:"onBeforeLoad",...tt({resolvedLocation:h,location:c})}),await ze({router:this,sync:e?.sync,matches:this.state.pendingMatches,location:c,updateMatch:this.updateMatch,onReady:async()=>{this.startTransition(()=>{this.startViewTransition(async()=>{let d=[],l=[],u=[];gt(()=>{this.__store.setState(f=>{const p=f.matches,g=f.pendingMatches||f.matches;return d=p.filter(m=>!g.some(y=>y.id===m.id)),l=g.filter(m=>!p.some(y=>y.id===m.id)),u=g.filter(m=>p.some(y=>y.id===m.id)),{...f,isLoading:!1,loadedAt:Date.now(),matches:g,pendingMatches:void 0,cachedMatches:[...f.cachedMatches,...d.filter(m=>m.status!=="error"&&m.status!=="notFound")]}}),this.clearExpiredCache()}),[[d,"onLeave"],[l,"onEnter"],[u,"onStay"]].forEach(([f,p])=>{f.forEach(g=>{this.looseRoutesById[g.routeId].options[p]?.(g)})})})})}})}catch(c){$(c)?(n=c,this.isServer||this.navigate({...n.options,replace:!0,ignoreBlocker:!0})):D(c)&&(o=c),this.__store.setState(h=>({...h,statusCode:n?n.status:o?404:h.matches.some(d=>d.status==="error")?500:200,redirect:n}))}this.latestLoadPromise===i&&(this.commitLocationPromise?.resolve(),this.latestLoadPromise=void 0,this.commitLocationPromise=void 0),a()})}),this.latestLoadPromise=i,await i;this.latestLoadPromise&&i!==this.latestLoadPromise;)await this.latestLoadPromise;let r;this.hasNotFoundMatch()?r=404:this.__store.state.matches.some(a=>a.status==="error")&&(r=500),r!==void 0&&this.__store.setState(a=>({...a,statusCode:r}))},this.startViewTransition=e=>{const n=this.shouldViewTransition??this.options.defaultViewTransition;if(delete this.shouldViewTransition,n&&typeof document<"u"&&"startViewTransition"in document&&typeof document.startViewTransition=="function"){let o;if(typeof n=="object"&&this.isViewTransitionTypesSupported){const i=this.latestLocation,r=this.state.resolvedLocation,a=typeof n.types=="function"?n.types(tt({resolvedLocation:r,location:i})):n.types;if(a===!1){e();return}o={update:e,types:a}}else o=e;document.startViewTransition(o)}else e()},this.updateMatch=(e,n)=>{this.startTransition(()=>{const o=this.state.pendingMatches?.some(i=>i.id===e)?"pendingMatches":this.state.matches.some(i=>i.id===e)?"matches":this.state.cachedMatches.some(i=>i.id===e)?"cachedMatches":"";o&&this.__store.setState(i=>({...i,[o]:i[o]?.map(r=>r.id===e?n(r):r)}))})},this.getMatch=e=>{const n=o=>o.id===e;return this.state.cachedMatches.find(n)??this.state.pendingMatches?.find(n)??this.state.matches.find(n)},this.invalidate=e=>{const n=o=>e?.filter?.(o)??!0?{...o,invalid:!0,...e?.forcePending||o.status==="error"||o.status==="notFound"?{status:"pending",error:void 0}:void 0}:o;return this.__store.setState(o=>({...o,matches:o.matches.map(n),cachedMatches:o.cachedMatches.map(n),pendingMatches:o.pendingMatches?.map(n)})),this.shouldViewTransition=!1,this.load({sync:e?.sync})},this.resolveRedirect=e=>{if(!e.options.href){const n=this.buildLocation(e.options);let o=n.url;this.origin&&o.startsWith(this.origin)&&(o=o.replace(this.origin,"")||"/"),e.options.href=n.href,e.headers.set("Location",o)}return e.headers.get("Location")||e.headers.set("Location",e.options.href),e},this.clearCache=e=>{const n=e?.filter;n!==void 0?this.__store.setState(o=>({...o,cachedMatches:o.cachedMatches.filter(i=>!n(i))})):this.__store.setState(o=>({...o,cachedMatches:[]}))},this.clearExpiredCache=()=>{const e=n=>{const o=this.looseRoutesById[n.routeId];if(!o.options.loader)return!0;const i=(n.preload?o.options.preloadGcTime??this.options.defaultPreloadGcTime:o.options.gcTime??this.options.defaultGcTime)??300*1e3;return n.status==="error"?!0:Date.now()-n.updatedAt>=i};this.clearCache({filter:e})},this.loadRouteChunk=as,this.preloadRoute=async e=>{const n=this.buildLocation(e);let o=this.matchRoutes(n,{throwOnError:!0,preload:!0,dest:e});const i=new Set([...this.state.matches,...this.state.pendingMatches??[]].map(a=>a.id)),r=new Set([...i,...this.state.cachedMatches.map(a=>a.id)]);gt(()=>{o.forEach(a=>{r.has(a.id)||this.__store.setState(c=>({...c,cachedMatches:[...c.cachedMatches,a]}))})});try{return o=await ze({router:this,matches:o,location:n,preload:!0,updateMatch:(a,c)=>{i.has(a)?o=o.map(h=>h.id===a?c(h):h):this.updateMatch(a,c)}}),o}catch(a){if($(a))return a.options.reloadDocument?void 0:await this.preloadRoute({...a.options,_fromLocation:n});D(a)||console.error(a);return}},this.matchRoute=(e,n)=>{const o={...e,to:e.to?this.resolvePathWithBase(e.from||"",e.to):void 0,params:e.params||{},leaveParams:!0},i=this.buildLocation(o);if(n?.pending&&this.state.status!=="pending")return!1;const a=(n?.pending===void 0?!this.state.isLoading:n.pending)?this.latestLocation:this.state.resolvedLocation||this.state.location,c=Vs(i.pathname,n?.caseSensitive??!1,n?.fuzzy??!1,a.pathname,this.processedTree);return!c||e.params&&!Z(c.params,e.params,{partial:!0})?!1:n?.includeSearch??!0?Z(a.search,i.search,{partial:!0})?c.params:!1:c.params},this.hasNotFoundMatch=()=>this.__store.state.matches.some(e=>e.status==="notFound"||e.globalNotFound),this.update({defaultPreloadDelay:50,defaultPendingMs:1e3,defaultPendingMinMs:500,context:void 0,...s,caseSensitive:s.caseSensitive??!1,notFoundMode:s.notFoundMode??"fuzzy",stringifySearch:s.stringifySearch??hn,parseSearch:s.parseSearch??un}),typeof document<"u"&&(self.__TSR_ROUTER__=this)}isShell(){return!!this.options.isShell}isPrerendering(){return!!this.options.isPrerendering}get state(){return this.__store.state}get looseRoutesById(){return this.routesById}matchRoutesInternal(s,e){const n=this.getMatchedRoutes(s.pathname),{foundRoute:o,routeParams:i}=n;let{matchedRoutes:r}=n,a=!1;(o?o.path!=="/"&&i["**"]:Q(s.pathname))&&(this.options.notFoundRoute?r=[...r,this.options.notFoundRoute]:a=!0);const c=(()=>{if(a){if(this.options.notFoundMode!=="root")for(let l=r.length-1;l>=0;l--){const u=r[l];if(u.children)return u.id}return B}})(),h=[],d=l=>l?.id?l.context??this.options.context??void 0:this.options.context??void 0;return r.forEach((l,u)=>{const f=h[u-1],[p,g,m]=(()=>{const A=f?.search??s.search,j=f?._strictSearch??void 0;try{const N=ce(l.options.validateSearch,{...A})??void 0;return[{...A,...N},{...j,...N},void 0]}catch(N){let nt=N;if(N instanceof Nt||(nt=new Nt(N.message,{cause:N})),e?.throwOnError)throw nt;return[A,{},nt]}})(),y=l.options.loaderDeps?.({search:p})??"",v=y?JSON.stringify(y):"",{interpolatedPath:S,usedParams:x}=Xt({path:l.fullPath,params:i,decodeCharMap:this.pathParamsDecodeCharMap}),L=l.id+S+v,_=this.getMatch(L),R=this.state.matches.find(A=>A.routeId===l.id),w=_?._strictParams??x;let C;if(!_){const A=l.options.params?.parse??l.options.parseParams;if(A)try{Object.assign(w,A(w))}catch(j){if(D(j)||$(j)?C=j:C=new xn(j.message,{cause:j}),e?.throwOnError)throw C}}Object.assign(i,w);const M=R?"stay":"enter";let I;if(_)I={..._,cause:M,params:R?z(R.params,i):i,_strictParams:w,search:z(R?R.search:_.search,p),_strictSearch:g};else{const A=l.options.loader||l.options.beforeLoad||l.lazyFn||cs(l)?"pending":"success";I={id:L,ssr:this.isServer?void 0:l.options.ssr,index:u,routeId:l.id,params:R?z(R.params,i):i,_strictParams:w,pathname:S,updatedAt:Date.now(),search:R?z(R.search,p):p,_strictSearch:g,searchError:void 0,status:A,isFetching:!1,error:void 0,paramsError:C,__routeContext:void 0,_nonReactive:{loadPromise:ct()},__beforeLoadContext:void 0,context:{},abortController:new AbortController,fetchCount:0,cause:M,loaderDeps:R?z(R.loaderDeps,y):y,invalid:!1,preload:!1,links:void 0,scripts:void 0,headScripts:void 0,meta:void 0,staticData:l.options.staticData||{},fullPath:l.fullPath}}e?.preload||(I.globalNotFound=c===l.id),I.searchError=m;const F=d(f);I.context={...F,...I.__routeContext,...I.__beforeLoadContext},h.push(I)}),h.forEach((l,u)=>{const f=this.looseRoutesById[l.routeId];if(!this.getMatch(l.id)&&e?._buildLocation!==!0){const g=h[u-1],m=d(g);if(f.options.context){const y={deps:l.loaderDeps,params:l.params,context:m??{},location:s,navigate:v=>this.navigate({...v,_fromLocation:s}),buildLocation:this.buildLocation,cause:l.cause,abortController:l.abortController,preload:!!l.preload,matches:h};l.__routeContext=f.options.context(y)??void 0}l.context={...m,...l.__routeContext,...l.__beforeLoadContext}}}),h}}class Nt extends Error{}class xn extends Error{}function Pn(t){return{loadedAt:0,isLoading:!1,isTransitioning:!1,status:"idle",resolvedLocation:void 0,location:t,matches:[],pendingMatches:[],cachedMatches:[],statusCode:200}}function ce(t,s){if(t==null)return{};if("~standard"in t){const e=t["~standard"].validate(s);if(e instanceof Promise)throw new Nt("Async validation not supported");if(e.issues)throw new Nt(JSON.stringify(e.issues,void 0,2),{cause:e});return e.value}return"parse"in t?t.parse(s):typeof t=="function"?t(s):{}}function bn({pathname:t,routesById:s,processedTree:e}){const n={},o=Q(t);let i;const r=Ks(o,e,!0);return r&&(i=r.route,Object.assign(n,r.params)),{matchedRoutes:r?.branch||[s[B]],routeParams:n,foundRoute:i}}function Cn({search:t,dest:s,destRoutes:e,_includeValidateSearch:n}){const o=e.reduce((a,c)=>{const h=[];if("search"in c.options)c.options.search?.middlewares&&h.push(...c.options.search.middlewares);else if(c.options.preSearchFilters||c.options.postSearchFilters){const d=({search:l,next:u})=>{let f=l;"preSearchFilters"in c.options&&c.options.preSearchFilters&&(f=c.options.preSearchFilters.reduce((g,m)=>m(g),l));const p=u(f);return"postSearchFilters"in c.options&&c.options.postSearchFilters?c.options.postSearchFilters.reduce((g,m)=>m(g),p):p};h.push(d)}if(n&&c.options.validateSearch){const d=({search:l,next:u})=>{const f=u(l);try{return{...f,...ce(c.options.validateSearch,f)??void 0}}catch{return f}};h.push(d)}return a.concat(h)},[])??[],i=({search:a})=>s.search?s.search===!0?a:H(s.search,a):{};o.push(i);const r=(a,c)=>{if(a>=o.length)return c;const h=o[a];return h({search:c,next:l=>r(a+1,l)})};return r(0,t)}const Ln="Error preloading route! ☝️";class ds{constructor(s){if(this.init=e=>{this.originalIndex=e.originalIndex;const n=this.options,o=!n?.path&&!n?.id;this.parentRoute=this.options.getParentRoute?.(),o?this._path=B:this.parentRoute||K(!1);let i=o?B:n?.path;i&&i!=="/"&&(i=es(i));const r=n?.id||i;let a=o?B:It([this.parentRoute.id===B?"":this.parentRoute.id,r]);i===B&&(i="/"),a!==B&&(a=It(["/",a]));const c=a===B?"/":It([this.parentRoute.fullPath,i]);this._path=i,this._id=a,this._fullPath=c,this._to=c},this.addChildren=e=>this._addFileChildren(e),this._addFileChildren=e=>(Array.isArray(e)&&(this.children=e),typeof e=="object"&&e!==null&&(this.children=Object.values(e)),this),this._addFileTypes=()=>this,this.updateLoader=e=>(Object.assign(this.options,e),this),this.update=e=>(Object.assign(this.options,e),this),this.lazy=e=>(this.lazyFn=e,this),this.options=s||{},this.isRoot=!s?.getParentRoute,s?.id&&s?.path)throw new Error("Route cannot have both an 'id' and a 'path' option.")}get to(){return this._to}get id(){return this._id}get path(){return this._path}get fullPath(){return this._fullPath}}class Mn extends ds{constructor(s){super(s)}}function me(t){const s=t.errorComponent??Ut;return P.jsx(In,{getResetKey:t.getResetKey,onCatch:t.onCatch,children:({error:e,reset:n})=>e?b.createElement(s,{error:e,reset:n}):t.children})}class In extends b.Component{constructor(){super(...arguments),this.state={error:null}}static getDerivedStateFromProps(s){return{resetKey:s.getResetKey()}}static getDerivedStateFromError(s){return{error:s}}reset(){this.setState({error:null})}componentDidUpdate(s,e){e.error&&e.resetKey!==this.state.resetKey&&this.reset()}componentDidCatch(s,e){this.props.onCatch&&this.props.onCatch(s,e)}render(){return this.props.children({error:this.state.resetKey!==this.props.getResetKey()?null:this.state.error,reset:()=>{this.reset()}})}}function Ut({error:t}){const[s,e]=b.useState(!1);return P.jsxs("div",{style:{padding:".5rem",maxWidth:"100%"},children:[P.jsxs("div",{style:{display:"flex",alignItems:"center",gap:".5rem"},children:[P.jsx("strong",{style:{fontSize:"1rem"},children:"Something went wrong!"}),P.jsx("button",{style:{appearance:"none",fontSize:".6em",border:"1px solid currentColor",padding:".1rem .2rem",fontWeight:"bold",borderRadius:".25rem"},onClick:()=>e(n=>!n),children:s?"Hide Error":"Show Error"})]}),P.jsx("div",{style:{height:".25rem"}}),s?P.jsx("div",{children:P.jsx("pre",{style:{fontSize:".7em",border:"1px solid red",borderRadius:".25rem",padding:".3rem",color:"red",overflow:"auto"},children:t.message?P.jsx("code",{children:t.message}):null})}):null]})}function En({children:t,fallback:s=null}){return kn()?P.jsx(at.Fragment,{children:t}):P.jsx(at.Fragment,{children:s})}function kn(){return at.useSyncExternalStore(Tn,()=>!0,()=>!1)}function Tn(){return()=>{}}var Qt={exports:{}},te={},ee={exports:{}},se={};var De;function On(){if(De)return se;De=1;var t=le();function s(l,u){return l===u&&(l!==0||1/l===1/u)||l!==l&&u!==u}var e=typeof Object.is=="function"?Object.is:s,n=t.useState,o=t.useEffect,i=t.useLayoutEffect,r=t.useDebugValue;function a(l,u){var f=u(),p=n({inst:{value:f,getSnapshot:u}}),g=p[0].inst,m=p[1];return i(function(){g.value=f,g.getSnapshot=u,c(g)&&m({inst:g})},[l,f,u]),o(function(){return c(g)&&m({inst:g}),l(function(){c(g)&&m({inst:g})})},[l]),r(f),f}function c(l){var u=l.getSnapshot;l=l.value;try{var f=u();return!e(l,f)}catch{return!0}}function h(l,u){return u()}var d=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?h:a;return se.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:d,se}var je;function Fn(){return je||(je=1,ee.exports=On()),ee.exports}var Ne;function An(){if(Ne)return te;Ne=1;var t=le(),s=Fn();function e(h,d){return h===d&&(h!==0||1/h===1/d)||h!==h&&d!==d}var n=typeof Object.is=="function"?Object.is:e,o=s.useSyncExternalStore,i=t.useRef,r=t.useEffect,a=t.useMemo,c=t.useDebugValue;return te.useSyncExternalStoreWithSelector=function(h,d,l,u,f){var p=i(null);if(p.current===null){var g={hasValue:!1,value:null};p.current=g}else g=p.current;p=a(function(){function y(_){if(!v){if(v=!0,S=_,_=u(_),f!==void 0&&g.hasValue){var R=g.value;if(f(R,_))return x=R}return x=_}if(R=x,n(S,_))return R;var w=u(_);return f!==void 0&&f(R,w)?(S=_,R):(S=_,x=w)}var v=!1,S,x,L=l===void 0?null:l;return[function(){return y(d())},L===null?void 0:function(){return y(L())}]},[d,l,u,f]);var m=o(h,p[0],p[1]);return r(function(){g.hasValue=!0,g.value=m},[m]),c(m),m},te}var We;function Bn(){return We||(We=1,Qt.exports=An()),Qt.exports}var fs=Bn();const Lo=ue(fs);function zn(t,s=n=>n,e={}){const n=e.equal??Dn;return fs.useSyncExternalStoreWithSelector(t.subscribe,()=>t.state,()=>t.state,s,n)}function Dn(t,s){if(Object.is(t,s))return!0;if(typeof t!="object"||t===null||typeof s!="object"||s===null)return!1;if(t instanceof Map&&s instanceof Map){if(t.size!==s.size)return!1;for(const[n,o]of t)if(!s.has(n)||!Object.is(o,s.get(n)))return!1;return!0}if(t instanceof Set&&s instanceof Set){if(t.size!==s.size)return!1;for(const n of t)if(!s.has(n))return!1;return!0}if(t instanceof Date&&s instanceof Date)return t.getTime()===s.getTime();const e=$e(t);if(e.length!==$e(s).length)return!1;for(let n=0;n"u"?ne:window.__TSR_ROUTER_CONTEXT__?window.__TSR_ROUTER_CONTEXT__:(window.__TSR_ROUTER_CONTEXT__=ne,ne)}function O(t){const s=b.useContext(ps());return t?.warn,s}function T(t){const s=O({warn:t?.router===void 0}),e=t?.router||s,n=b.useRef(void 0);return zn(e.__store,o=>{if(t?.select){if(t.structuralSharing??e.options.defaultStructuralSharing){const i=z(n.current,t.select(o));return n.current=i,i}return t.select(o)}return o})}const Vt=b.createContext(void 0),jn=b.createContext(void 0);function U(t){const s=b.useContext(t.from?jn:Vt);return T({select:n=>{const o=n.matches.find(i=>t.from?t.from===i.routeId:i.id===s);if(K(!((t.shouldThrow??!0)&&!o),`Could not find ${t.from?`an active match from "${t.from}"`:"a nearest match!"}`),o!==void 0)return t.select?t.select(o):o},structuralSharing:t.structuralSharing})}function ge(t){return U({from:t.from,strict:t.strict,structuralSharing:t.structuralSharing,select:s=>t.select?t.select(s.loaderData):s.loaderData})}function ye(t){const{select:s,...e}=t;return U({...e,select:n=>s?s(n.loaderDeps):n.loaderDeps})}function ve(t){return U({from:t.from,shouldThrow:t.shouldThrow,structuralSharing:t.structuralSharing,strict:t.strict,select:s=>{const e=t.strict===!1?s.params:s._strictParams;return t.select?t.select(e):e}})}function Se(t){return U({from:t.from,strict:t.strict,shouldThrow:t.shouldThrow,structuralSharing:t.structuralSharing,select:s=>t.select?t.select(s.search):s.search})}const Mt=typeof window<"u"?b.useLayoutEffect:b.useEffect;function oe(t){const s=b.useRef({value:t,prev:null}),e=s.current.value;return t!==e&&(s.current={value:t,prev:e}),s.current.prev}function Nn(t,s,e={},n={}){b.useEffect(()=>{if(!t.current||n.disabled||typeof IntersectionObserver!="function")return;const o=new IntersectionObserver(([i])=>{s(i)},e);return o.observe(t.current),()=>{o.disconnect()}},[s,e,n.disabled,t])}function Wn(t){const s=b.useRef(null);return b.useImperativeHandle(t,()=>s.current,[]),s}function _e(t){const s=O();return b.useCallback(e=>s.navigate({...e,from:e.from??t?.from}),[t?.from,s])}var we=Ls();const Mo=ue(we);function $n(t,s){const e=O(),[n,o]=b.useState(!1),i=b.useRef(!1),r=Wn(s),{activeProps:a,inactiveProps:c,activeOptions:h,to:d,preload:l,preloadDelay:u,hashScrollIntoView:f,replace:p,startTransition:g,resetScroll:m,viewTransition:y,children:v,target:S,disabled:x,style:L,className:_,onClick:R,onFocus:w,onMouseEnter:C,onMouseLeave:M,onTouchStart:I,ignoreBlocker:F,params:A,search:j,hash:N,state:nt,mask:Ss,reloadDocument:wo,unsafeRelative:Ro,from:xo,_fromLocation:Po,...Re}=t,_s=T({select:E=>E.location.search,structuralSharing:!0}),xe=t.from,ut=b.useMemo(()=>({...t,from:xe}),[e,_s,xe,t._fromLocation,t.hash,t.to,t.search,t.params,t.state,t.mask,t.unsafeRelative]),V=b.useMemo(()=>e.buildLocation({...ut}),[e,ut]),_t=b.useMemo(()=>{if(x)return;let E=V.maskedLocation?V.maskedLocation.url:V.url,k=!1;return e.origin&&(E.startsWith(e.origin)?E=e.history.createHref(E.replace(e.origin,""))||"/":k=!0),{href:E,external:k}},[x,V.maskedLocation,V.url,e.origin,e.history]),wt=b.useMemo(()=>{if(_t?.external)return _t.href;try{return new URL(d),d}catch{}},[d,_t]),ot=t.reloadDocument||wt?!1:l??e.options.defaultPreload,Kt=u??e.options.defaultPreloadDelay??0,Ht=T({select:E=>{if(wt)return!1;if(h?.exact){if(!Zs(E.location.pathname,V.pathname,e.basepath))return!1}else{const k=zt(E.location.pathname,e.basepath),W=zt(V.pathname,e.basepath);if(!(k.startsWith(W)&&(k.length===W.length||k[W.length]==="/")))return!1}return(h?.includeSearch??!0)&&!Z(E.location.search,V.search,{partial:!h?.exact,ignoreUndefined:!h?.explicitUndefined})?!1:h?.includeHash?E.location.hash===V.hash:!0}}),Y=b.useCallback(()=>{e.preloadRoute({...ut}).catch(E=>{console.warn(E),console.warn(Ln)})},[e,ut]),ws=b.useCallback(E=>{E?.isIntersecting&&Y()},[Y]);Nn(r,ws,qn,{disabled:!!x||ot!=="viewport"}),b.useEffect(()=>{i.current||!x&&ot==="render"&&(Y(),i.current=!0)},[x,Y,ot]);const Rs=E=>{const k=E.currentTarget.getAttribute("target"),W=S!==void 0?S:k;if(!x&&!Gn(E)&&!E.defaultPrevented&&(!W||W==="_self")&&E.button===0){E.preventDefault(),we.flushSync(()=>{o(!0)});const Le=e.subscribe("onResolved",()=>{Le(),o(!1)});e.navigate({...ut,replace:p,resetScroll:m,hashScrollIntoView:f,startTransition:g,viewTransition:y,ignoreBlocker:F})}};if(wt)return{...Re,ref:r,href:wt,...v&&{children:v},...S&&{target:S},...x&&{disabled:x},...L&&{style:L},..._&&{className:_},...R&&{onClick:R},...w&&{onFocus:w},...C&&{onMouseEnter:C},...M&&{onMouseLeave:M},...I&&{onTouchStart:I}};const Pe=E=>{x||ot&&Y()},xs=Pe,Ps=E=>{if(!(x||!ot))if(!Kt)Y();else{const k=E.target;if(dt.has(k))return;const W=setTimeout(()=>{dt.delete(k),Y()},Kt);dt.set(k,W)}},bs=E=>{if(x||!ot||!Kt)return;const k=E.target,W=dt.get(k);W&&(clearTimeout(W),dt.delete(k))},Rt=Ht?H(a,{})??Un:ie,xt=Ht?ie:H(c,{})??ie,be=[_,Rt.className,xt.className].filter(Boolean).join(" "),Ce=(L||Rt.style||xt.style)&&{...L,...Rt.style,...xt.style};return{...Re,...Rt,...xt,href:_t?.href,ref:r,onClick:ft([R,Rs]),onFocus:ft([w,Pe]),onMouseEnter:ft([C,Ps]),onMouseLeave:ft([M,bs]),onTouchStart:ft([I,xs]),disabled:!!x,target:S,...Ce&&{style:Ce},...be&&{className:be},...x&&Vn,...Ht&&Kn,...n&&Hn}}const ie={},Un={className:"active"},Vn={role:"link","aria-disabled":!0},Kn={"data-status":"active","aria-current":"page"},Hn={"data-transitioning":"transitioning"},dt=new WeakMap,qn={rootMargin:"100px"},ft=t=>s=>{for(const e of t)if(e){if(s.defaultPrevented)return;e(s)}},ms=b.forwardRef((t,s)=>{const{_asChild:e,...n}=t,{type:o,ref:i,...r}=$n(n,s),a=typeof n.children=="function"?n.children({isActive:r["data-status"]==="active"}):n.children;return e===void 0&&delete r.disabled,b.createElement(e||"a",{...r,ref:i},a)});function Gn(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}class Jn extends ds{constructor(s){super(s),this.useMatch=e=>U({select:e?.select,from:this.id,structuralSharing:e?.structuralSharing}),this.useRouteContext=e=>U({...e,from:this.id,select:n=>e?.select?e.select(n.context):n.context}),this.useSearch=e=>Se({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useParams=e=>ve({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useLoaderDeps=e=>ye({...e,from:this.id}),this.useLoaderData=e=>ge({...e,from:this.id}),this.useNavigate=()=>_e({from:this.fullPath}),this.Link=at.forwardRef((e,n)=>P.jsx(ms,{ref:n,from:this.fullPath,...e})),this.$$typeof=Symbol.for("react.memo")}}function Yn(t){return new Jn(t)}class Xn extends Mn{constructor(s){super(s),this.useMatch=e=>U({select:e?.select,from:this.id,structuralSharing:e?.structuralSharing}),this.useRouteContext=e=>U({...e,from:this.id,select:n=>e?.select?e.select(n.context):n.context}),this.useSearch=e=>Se({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useParams=e=>ve({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useLoaderDeps=e=>ye({...e,from:this.id}),this.useLoaderData=e=>ge({...e,from:this.id}),this.useNavigate=()=>_e({from:this.fullPath}),this.Link=at.forwardRef((e,n)=>P.jsx(ms,{ref:n,from:this.fullPath,...e})),this.$$typeof=Symbol.for("react.memo")}}function Io(t){return new Xn(t)}function Ue(t){return typeof t=="object"?new Ve(t,{silent:!0}).createRoute(t):new Ve(t,{silent:!0}).createRoute}class Ve{constructor(s,e){this.path=s,this.createRoute=n=>{this.silent;const o=Yn(n);return o.isRoot=!1,o},this.silent=e?.silent}}class Ke{constructor(s){this.useMatch=e=>U({select:e?.select,from:this.options.id,structuralSharing:e?.structuralSharing}),this.useRouteContext=e=>U({from:this.options.id,select:n=>e?.select?e.select(n.context):n.context}),this.useSearch=e=>Se({select:e?.select,structuralSharing:e?.structuralSharing,from:this.options.id}),this.useParams=e=>ve({select:e?.select,structuralSharing:e?.structuralSharing,from:this.options.id}),this.useLoaderDeps=e=>ye({...e,from:this.options.id}),this.useLoaderData=e=>ge({...e,from:this.options.id}),this.useNavigate=()=>{const e=O();return _e({from:e.routesById[this.options.id].fullPath})},this.options=s,this.$$typeof=Symbol.for("react.memo")}}function He(t){return typeof t=="object"?new Ke(t):s=>new Ke({id:t,...s})}function Zn(){const t=O(),s=b.useRef({router:t,mounted:!1}),[e,n]=b.useState(!1),{hasPendingMatches:o,isLoading:i}=T({select:l=>({isLoading:l.isLoading,hasPendingMatches:l.matches.some(u=>u.status==="pending")}),structuralSharing:!0}),r=oe(i),a=i||e||o,c=oe(a),h=i||o,d=oe(h);return t.startTransition=l=>{n(!0),b.startTransition(()=>{l(),n(!1)})},b.useEffect(()=>{const l=t.history.subscribe(t.load),u=t.buildLocation({to:t.latestLocation.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0});return Q(t.latestLocation.href)!==Q(u.href)&&t.commitLocation({...u,replace:!0}),()=>{l()}},[t,t.history]),Mt(()=>{if(typeof window<"u"&&t.ssr||s.current.router===t&&s.current.mounted)return;s.current={router:t,mounted:!0},(async()=>{try{await t.load()}catch(u){console.error(u)}})()},[t]),Mt(()=>{r&&!i&&t.emit({type:"onLoad",...tt(t.state)})},[r,t,i]),Mt(()=>{d&&!h&&t.emit({type:"onBeforeRouteMount",...tt(t.state)})},[h,d,t]),Mt(()=>{if(c&&!a){const l=tt(t.state);t.emit({type:"onResolved",...l}),t.__store.setState(u=>({...u,status:"idle",resolvedLocation:u.location})),l.hrefChanged&&an(t)}},[a,c,t]),null}function Qn(t){const s=T({select:e=>`not-found-${e.location.pathname}-${e.status}`});return P.jsx(me,{getResetKey:()=>s,onCatch:(e,n)=>{if(D(e))t.onCatch?.(e,n);else throw e},errorComponent:({error:e})=>{if(D(e))return t.fallback?.(e);throw e},children:t.children})}function to(){return P.jsx("p",{children:"Not Found"})}function rt(t){return P.jsx(P.Fragment,{children:t.children})}function gs(t,s,e){return s.options.notFoundComponent?P.jsx(s.options.notFoundComponent,{...e}):t.options.defaultNotFoundComponent?P.jsx(t.options.defaultNotFoundComponent,{...e}):P.jsx(to,{})}function eo({children:t}){const s=O();return s.isServer?P.jsx("script",{nonce:s.options.ssr?.nonce,className:"$tsr",dangerouslySetInnerHTML:{__html:t+';typeof $_TSR !== "undefined" && $_TSR.c()'}}):null}function so(){const t=O();if(!t.isScrollRestoring||!t.isServer||typeof t.options.scrollRestoration=="function"&&!t.options.scrollRestoration({location:t.latestLocation}))return null;const e=(t.options.getScrollRestorationKey||ae)(t.latestLocation),n=e!==ae(t.latestLocation)?e:void 0,o={storageKey:Dt,shouldScrollRestoration:!0};return n&&(o.key=n),P.jsx(eo,{children:`(${ss.toString()})(${JSON.stringify(o)})`})}const ys=b.memo(function({matchId:s}){const e=O(),n=T({select:y=>{const v=y.matches.find(S=>S.id===s);return K(v),{routeId:v.routeId,ssr:v.ssr,_displayPending:v._displayPending}},structuralSharing:!0}),o=e.routesById[n.routeId],i=o.options.pendingComponent??e.options.defaultPendingComponent,r=i?P.jsx(i,{}):null,a=o.options.errorComponent??e.options.defaultErrorComponent,c=o.options.onCatch??e.options.defaultOnCatch,h=o.isRoot?o.options.notFoundComponent??e.options.notFoundRoute?.options.component:o.options.notFoundComponent,d=n.ssr===!1||n.ssr==="data-only",l=(!o.isRoot||o.options.wrapInSuspense||d)&&(o.options.wrapInSuspense??i??(o.options.errorComponent?.preload||d))?b.Suspense:rt,u=a?me:rt,f=h?Qn:rt,p=T({select:y=>y.loadedAt}),g=T({select:y=>{const v=y.matches.findIndex(S=>S.id===s);return y.matches[v-1]?.routeId}}),m=o.isRoot?o.options.shellComponent??rt:rt;return P.jsxs(m,{children:[P.jsx(Vt.Provider,{value:s,children:P.jsx(l,{fallback:r,children:P.jsx(u,{getResetKey:()=>p,errorComponent:a||Ut,onCatch:(y,v)=>{if(D(y))throw y;c?.(y,v)},children:P.jsx(f,{fallback:y=>{if(!h||y.routeId&&y.routeId!==n.routeId||!y.routeId&&!o.isRoot)throw y;return b.createElement(h,y)},children:d||n._displayPending?P.jsx(En,{fallback:r,children:P.jsx(qe,{matchId:s})}):P.jsx(qe,{matchId:s})})})})}),g===B&&e.options.scrollRestoration?P.jsxs(P.Fragment,{children:[P.jsx(no,{}),P.jsx(so,{})]}):null]})});function no(){const t=O(),s=b.useRef(void 0);return P.jsx("script",{suppressHydrationWarning:!0,ref:e=>{e&&(s.current===void 0||s.current.href!==t.latestLocation.href)&&(t.emit({type:"onRendered",...tt(t.state)}),s.current=t.latestLocation)}},t.latestLocation.state.__TSR_key)}const qe=b.memo(function({matchId:s}){const e=O(),{match:n,key:o,routeId:i}=T({select:c=>{const h=c.matches.find(p=>p.id===s),d=h.routeId,u=(e.routesById[d].options.remountDeps??e.options.defaultRemountDeps)?.({routeId:d,loaderDeps:h.loaderDeps,params:h._strictParams,search:h._strictSearch});return{key:u?JSON.stringify(u):void 0,routeId:d,match:{id:h.id,status:h.status,error:h.error,_forcePending:h._forcePending,_displayPending:h._displayPending}}},structuralSharing:!0}),r=e.routesById[i],a=b.useMemo(()=>{const c=r.options.component??e.options.defaultComponent;return c?P.jsx(c,{},o):P.jsx(oo,{})},[o,r.options.component,e.options.defaultComponent]);if(n._displayPending)throw e.getMatch(n.id)?._nonReactive.displayPendingPromise;if(n._forcePending)throw e.getMatch(n.id)?._nonReactive.minPendingPromise;if(n.status==="pending"){const c=r.options.pendingMinMs??e.options.defaultPendingMinMs;if(c){const h=e.getMatch(n.id);if(h&&!h._nonReactive.minPendingPromise&&!e.isServer){const d=ct();h._nonReactive.minPendingPromise=d,setTimeout(()=>{d.resolve(),h._nonReactive.minPendingPromise=void 0},c)}}throw e.getMatch(n.id)?._nonReactive.loadPromise}if(n.status==="notFound")return K(D(n.error)),gs(e,r,n.error);if(n.status==="redirected")throw K($(n.error)),e.getMatch(n.id)?._nonReactive.loadPromise;if(n.status==="error"){if(e.isServer){const c=(r.options.errorComponent??e.options.defaultErrorComponent)||Ut;return P.jsx(c,{error:n.error,reset:void 0,info:{componentStack:""}})}throw n.error}return a}),oo=b.memo(function(){const s=O(),e=b.useContext(Vt),n=T({select:h=>h.matches.find(d=>d.id===e)?.routeId}),o=s.routesById[n],i=T({select:h=>{const l=h.matches.find(u=>u.id===e);return K(l),l.globalNotFound}}),r=T({select:h=>{const d=h.matches,l=d.findIndex(u=>u.id===e);return d[l+1]?.id}}),a=s.options.defaultPendingComponent?P.jsx(s.options.defaultPendingComponent,{}):null;if(i)return gs(s,o,void 0);if(!r)return null;const c=P.jsx(ys,{matchId:r});return n===B?P.jsx(b.Suspense,{fallback:a,children:c}):c});function io(){const t=O(),e=t.routesById[B].options.pendingComponent??t.options.defaultPendingComponent,n=e?P.jsx(e,{}):null,o=t.isServer||typeof document<"u"&&t.ssr?rt:b.Suspense,i=P.jsxs(o,{fallback:n,children:[!t.isServer&&P.jsx(Zn,{}),P.jsx(ro,{})]});return t.options.InnerWrap?P.jsx(t.options.InnerWrap,{children:i}):i}function ro(){const t=O(),s=T({select:o=>o.matches[0]?.id}),e=T({select:o=>o.loadedAt}),n=s?P.jsx(ys,{matchId:s}):null;return P.jsx(Vt.Provider,{value:s,children:t.options.disableGlobalCatchBoundary?n:P.jsx(me,{getResetKey:()=>e,errorComponent:Ut,onCatch:o=>{o.message||o.toString()},children:n})})}function Eo(){const t=O();return T({select:s=>[s.location.href,s.resolvedLocation?.href,s.status],structuralSharing:!0}),b.useCallback(s=>{const{pending:e,caseSensitive:n,fuzzy:o,includeSearch:i,...r}=s;return t.matchRoute(r,{pending:e,caseSensitive:n,fuzzy:o,includeSearch:i})},[t])}const ko=t=>new ao(t);class ao extends Rn{constructor(s){super(s)}}typeof globalThis<"u"?(globalThis.createFileRoute=Ue,globalThis.createLazyFileRoute=He):typeof window<"u"&&(window.createFileRoute=Ue,window.createLazyFileRoute=He);function co({router:t,children:s,...e}){Object.keys(e).length>0&&t.update({...t.options,...e,context:{...t.options.context,...e.context}});const n=ps(),o=P.jsx(n.Provider,{value:t,children:s});return t.options.Wrap?P.jsx(t.options.Wrap,{children:o}):o}function To({router:t,...s}){return P.jsx(co,{router:t,...s,children:P.jsx(io,{})})}function it(t,s,e){let n=e.initialDeps??[],o,i=!0;function r(){var a,c,h;let d;e.key&&((a=e.debug)!=null&&a.call(e))&&(d=Date.now());const l=t();if(!(l.length!==n.length||l.some((p,g)=>n[g]!==p)))return o;n=l;let f;if(e.key&&((c=e.debug)!=null&&c.call(e))&&(f=Date.now()),o=s(...l),e.key&&((h=e.debug)!=null&&h.call(e))){const p=Math.round((Date.now()-d)*100)/100,g=Math.round((Date.now()-f)*100)/100,m=g/16,y=(v,S)=>{for(v=String(v);v.length{n=a},r}function Ge(t,s){if(t===void 0)throw new Error("Unexpected undefined");return t}const lo=(t,s)=>Math.abs(t-s)<1.01,uo=(t,s,e)=>{let n;return function(...o){t.clearTimeout(n),n=t.setTimeout(()=>s.apply(this,o),e)}},Je=t=>{const{offsetWidth:s,offsetHeight:e}=t;return{width:s,height:e}},ho=t=>t,fo=t=>{const s=Math.max(t.startIndex-t.overscan,0),e=Math.min(t.endIndex+t.overscan,t.count-1),n=[];for(let o=s;o<=e;o++)n.push(o);return n},po=(t,s)=>{const e=t.scrollElement;if(!e)return;const n=t.targetWindow;if(!n)return;const o=r=>{const{width:a,height:c}=r;s({width:Math.round(a),height:Math.round(c)})};if(o(Je(e)),!n.ResizeObserver)return()=>{};const i=new n.ResizeObserver(r=>{const a=()=>{const c=r[0];if(c?.borderBoxSize){const h=c.borderBoxSize[0];if(h){o({width:h.inlineSize,height:h.blockSize});return}}o(Je(e))};t.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(a):a()});return i.observe(e,{box:"border-box"}),()=>{i.unobserve(e)}},Ye={passive:!0},Xe=typeof window>"u"?!0:"onscrollend"in window,mo=(t,s)=>{const e=t.scrollElement;if(!e)return;const n=t.targetWindow;if(!n)return;let o=0;const i=t.options.useScrollendEvent&&Xe?()=>{}:uo(n,()=>{s(o,!1)},t.options.isScrollingResetDelay),r=d=>()=>{const{horizontal:l,isRtl:u}=t.options;o=l?e.scrollLeft*(u&&-1||1):e.scrollTop,i(),s(o,d)},a=r(!0),c=r(!1);c(),e.addEventListener("scroll",a,Ye);const h=t.options.useScrollendEvent&&Xe;return h&&e.addEventListener("scrollend",c,Ye),()=>{e.removeEventListener("scroll",a),h&&e.removeEventListener("scrollend",c)}},go=(t,s,e)=>{if(s?.borderBoxSize){const n=s.borderBoxSize[0];if(n)return Math.round(n[e.options.horizontal?"inlineSize":"blockSize"])}return t[e.options.horizontal?"offsetWidth":"offsetHeight"]},yo=(t,{adjustments:s=0,behavior:e},n)=>{var o,i;const r=t+s;(i=(o=n.scrollElement)==null?void 0:o.scrollTo)==null||i.call(o,{[n.options.horizontal?"left":"top"]:r,behavior:e})};class vo{constructor(s){this.unsubs=[],this.scrollElement=null,this.targetWindow=null,this.isScrolling=!1,this.measurementsCache=[],this.itemSizeCache=new Map,this.laneAssignments=new Map,this.pendingMeasuredCacheIndexes=[],this.prevLanes=void 0,this.lanesChangedFlag=!1,this.lanesSettling=!1,this.scrollRect=null,this.scrollOffset=null,this.scrollDirection=null,this.scrollAdjustments=0,this.elementsCache=new Map,this.observer=(()=>{let e=null;const n=()=>e||(!this.targetWindow||!this.targetWindow.ResizeObserver?null:e=new this.targetWindow.ResizeObserver(o=>{o.forEach(i=>{const r=()=>{this._measureElement(i.target,i)};this.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(r):r()})}));return{disconnect:()=>{var o;(o=n())==null||o.disconnect(),e=null},observe:o=>{var i;return(i=n())==null?void 0:i.observe(o,{box:"border-box"})},unobserve:o=>{var i;return(i=n())==null?void 0:i.unobserve(o)}}})(),this.range=null,this.setOptions=e=>{Object.entries(e).forEach(([n,o])=>{typeof o>"u"&&delete e[n]}),this.options={debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:ho,rangeExtractor:fo,onChange:()=>{},measureElement:go,initialRect:{width:0,height:0},scrollMargin:0,gap:0,indexAttribute:"data-index",initialMeasurementsCache:[],lanes:1,isScrollingResetDelay:150,enabled:!0,isRtl:!1,useScrollendEvent:!1,useAnimationFrameWithResizeObserver:!1,...e}},this.notify=e=>{var n,o;(o=(n=this.options).onChange)==null||o.call(n,this,e)},this.maybeNotify=it(()=>(this.calculateRange(),[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]),e=>{this.notify(e)},{key:!1,debug:()=>this.options.debug,initialDeps:[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]}),this.cleanup=()=>{this.unsubs.filter(Boolean).forEach(e=>e()),this.unsubs=[],this.observer.disconnect(),this.scrollElement=null,this.targetWindow=null},this._didMount=()=>()=>{this.cleanup()},this._willUpdate=()=>{var e;const n=this.options.enabled?this.options.getScrollElement():null;if(this.scrollElement!==n){if(this.cleanup(),!n){this.maybeNotify();return}this.scrollElement=n,this.scrollElement&&"ownerDocument"in this.scrollElement?this.targetWindow=this.scrollElement.ownerDocument.defaultView:this.targetWindow=((e=this.scrollElement)==null?void 0:e.window)??null,this.elementsCache.forEach(o=>{this.observer.observe(o)}),this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0}),this.unsubs.push(this.options.observeElementRect(this,o=>{this.scrollRect=o,this.maybeNotify()})),this.unsubs.push(this.options.observeElementOffset(this,(o,i)=>{this.scrollAdjustments=0,this.scrollDirection=i?this.getScrollOffset()this.options.enabled?(this.scrollRect=this.scrollRect??this.options.initialRect,this.scrollRect[this.options.horizontal?"width":"height"]):(this.scrollRect=null,0),this.getScrollOffset=()=>this.options.enabled?(this.scrollOffset=this.scrollOffset??(typeof this.options.initialOffset=="function"?this.options.initialOffset():this.options.initialOffset),this.scrollOffset):(this.scrollOffset=null,0),this.getFurthestMeasurement=(e,n)=>{const o=new Map,i=new Map;for(let r=n-1;r>=0;r--){const a=e[r];if(o.has(a.lane))continue;const c=i.get(a.lane);if(c==null||a.end>c.end?i.set(a.lane,a):a.endr.end===a.end?r.index-a.index:r.end-a.end)[0]:void 0},this.getMeasurementOptions=it(()=>[this.options.count,this.options.paddingStart,this.options.scrollMargin,this.options.getItemKey,this.options.enabled,this.options.lanes],(e,n,o,i,r,a)=>(this.prevLanes!==void 0&&this.prevLanes!==a&&(this.lanesChangedFlag=!0),this.prevLanes=a,this.pendingMeasuredCacheIndexes=[],{count:e,paddingStart:n,scrollMargin:o,getItemKey:i,enabled:r,lanes:a}),{key:!1,skipInitialOnChange:!0,onChange:()=>{this.notify(this.isScrolling)}}),this.getMeasurements=it(()=>[this.getMeasurementOptions(),this.itemSizeCache],({count:e,paddingStart:n,scrollMargin:o,getItemKey:i,enabled:r,lanes:a},c)=>{if(!r)return this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),[];if(this.laneAssignments.size>e)for(const u of this.laneAssignments.keys())u>=e&&this.laneAssignments.delete(u);this.lanesChangedFlag&&(this.lanesChangedFlag=!1,this.lanesSettling=!0,this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),this.pendingMeasuredCacheIndexes=[]),this.measurementsCache.length===0&&(this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach(u=>{this.itemSizeCache.set(u.key,u.size)}));const h=this.lanesSettling?0:this.pendingMeasuredCacheIndexes.length>0?Math.min(...this.pendingMeasuredCacheIndexes):0;this.pendingMeasuredCacheIndexes=[],this.lanesSettling&&this.measurementsCache.length===e&&(this.lanesSettling=!1);const d=this.measurementsCache.slice(0,h),l=new Array(a).fill(void 0);for(let u=0;u1){g=p;const x=l[g],L=x!==void 0?d[x]:void 0;m=L?L.end+this.options.gap:n+o}else{const x=this.options.lanes===1?d[u-1]:this.getFurthestMeasurement(d,u);m=x?x.end+this.options.gap:n+o,g=x?x.lane:u%this.options.lanes,this.options.lanes>1&&this.laneAssignments.set(u,g)}const y=c.get(f),v=typeof y=="number"?y:this.options.estimateSize(u),S=m+v;d[u]={index:u,start:m,size:v,end:S,key:f,lane:g},l[g]=u}return this.measurementsCache=d,d},{key:!1,debug:()=>this.options.debug}),this.calculateRange=it(()=>[this.getMeasurements(),this.getSize(),this.getScrollOffset(),this.options.lanes],(e,n,o,i)=>this.range=e.length>0&&n>0?So({measurements:e,outerSize:n,scrollOffset:o,lanes:i}):null,{key:!1,debug:()=>this.options.debug}),this.getVirtualIndexes=it(()=>{let e=null,n=null;const o=this.calculateRange();return o&&(e=o.startIndex,n=o.endIndex),this.maybeNotify.updateDeps([this.isScrolling,e,n]),[this.options.rangeExtractor,this.options.overscan,this.options.count,e,n]},(e,n,o,i,r)=>i===null||r===null?[]:e({startIndex:i,endIndex:r,overscan:n,count:o}),{key:!1,debug:()=>this.options.debug}),this.indexFromElement=e=>{const n=this.options.indexAttribute,o=e.getAttribute(n);return o?parseInt(o,10):(console.warn(`Missing attribute name '${n}={index}' on measured element.`),-1)},this._measureElement=(e,n)=>{const o=this.indexFromElement(e),i=this.measurementsCache[o];if(!i)return;const r=i.key,a=this.elementsCache.get(r);a!==e&&(a&&this.observer.unobserve(a),this.observer.observe(e),this.elementsCache.set(r,e)),e.isConnected&&this.resizeItem(o,this.options.measureElement(e,n,this))},this.resizeItem=(e,n)=>{const o=this.measurementsCache[e];if(!o)return;const i=this.itemSizeCache.get(o.key)??o.size,r=n-i;r!==0&&((this.shouldAdjustScrollPositionOnItemSizeChange!==void 0?this.shouldAdjustScrollPositionOnItemSizeChange(o,r,this):o.start{if(!e){this.elementsCache.forEach((n,o)=>{n.isConnected||(this.observer.unobserve(n),this.elementsCache.delete(o))});return}this._measureElement(e,void 0)},this.getVirtualItems=it(()=>[this.getVirtualIndexes(),this.getMeasurements()],(e,n)=>{const o=[];for(let i=0,r=e.length;ithis.options.debug}),this.getVirtualItemForOffset=e=>{const n=this.getMeasurements();if(n.length!==0)return Ge(n[vs(0,n.length-1,o=>Ge(n[o]).start,e)])},this.getOffsetForAlignment=(e,n,o=0)=>{const i=this.getSize(),r=this.getScrollOffset();n==="auto"&&(n=e>=r+i?"end":"start"),n==="center"?e+=(o-i)/2:n==="end"&&(e-=i);const a=this.getTotalSize()+this.options.scrollMargin-i;return Math.max(Math.min(a,e),0)},this.getOffsetForIndex=(e,n="auto")=>{e=Math.max(0,Math.min(e,this.options.count-1));const o=this.measurementsCache[e];if(!o)return;const i=this.getSize(),r=this.getScrollOffset();if(n==="auto")if(o.end>=r+i-this.options.scrollPaddingEnd)n="end";else if(o.start<=r+this.options.scrollPaddingStart)n="start";else return[r,n];const a=n==="end"?o.end+this.options.scrollPaddingEnd:o.start-this.options.scrollPaddingStart;return[this.getOffsetForAlignment(a,n,o.size),n]},this.isDynamicMode=()=>this.elementsCache.size>0,this.scrollToOffset=(e,{align:n="start",behavior:o}={})=>{o==="smooth"&&this.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),this._scrollToOffset(this.getOffsetForAlignment(e,n),{adjustments:void 0,behavior:o})},this.scrollToIndex=(e,{align:n="auto",behavior:o}={})=>{o==="smooth"&&this.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),e=Math.max(0,Math.min(e,this.options.count-1));let i=0;const r=10,a=h=>{if(!this.targetWindow)return;const d=this.getOffsetForIndex(e,h);if(!d){console.warn("Failed to get offset for index:",e);return}const[l,u]=d;this._scrollToOffset(l,{adjustments:void 0,behavior:o}),this.targetWindow.requestAnimationFrame(()=>{const f=this.getScrollOffset(),p=this.getOffsetForIndex(e,u);if(!p){console.warn("Failed to get offset for index:",e);return}lo(p[0],f)||c(u)})},c=h=>{this.targetWindow&&(i++,ia(h)):console.warn(`Failed to scroll to index ${e} after ${r} attempts.`))};a(n)},this.scrollBy=(e,{behavior:n}={})=>{n==="smooth"&&this.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),this._scrollToOffset(this.getScrollOffset()+e,{adjustments:void 0,behavior:n})},this.getTotalSize=()=>{var e;const n=this.getMeasurements();let o;if(n.length===0)o=this.options.paddingStart;else if(this.options.lanes===1)o=((e=n[n.length-1])==null?void 0:e.end)??0;else{const i=Array(this.options.lanes).fill(null);let r=n.length-1;for(;r>=0&&i.some(a=>a===null);){const a=n[r];i[a.lane]===null&&(i[a.lane]=a.end),r--}o=Math.max(...i.filter(a=>a!==null))}return Math.max(o-this.options.scrollMargin+this.options.paddingEnd,0)},this._scrollToOffset=(e,{adjustments:n,behavior:o})=>{this.options.scrollToFn(e,{behavior:o,adjustments:n},this)},this.measure=()=>{this.itemSizeCache=new Map,this.laneAssignments=new Map,this.notify(!1)},this.setOptions(s)}}const vs=(t,s,e,n)=>{for(;t<=s;){const o=(t+s)/2|0,i=e(o);if(in)s=o-1;else return o}return t>0?t-1:0};function So({measurements:t,outerSize:s,scrollOffset:e,lanes:n}){const o=t.length-1,i=c=>t[c].start;if(t.length<=n)return{startIndex:0,endIndex:o};let r=vs(0,o,i,e),a=r;if(n===1)for(;a1){const c=Array(n).fill(0);for(;ad=0&&h.some(d=>d>=e);){const d=t[r];h[d.lane]=d.start,r--}r=Math.max(0,r-r%n),a=Math.min(o,a+(n-1-a%n))}return{startIndex:r,endIndex:a}}const Ze=typeof document<"u"?b.useLayoutEffect:b.useEffect;function _o(t){const s=b.useReducer(()=>({}),{})[1],e={...t,onChange:(o,i)=>{var r;i?we.flushSync(s):s(),(r=t.onChange)==null||r.call(t,o,i)}},[n]=b.useState(()=>new vo(e));return n.setOptions(e),Ze(()=>n._didMount(),[]),Ze(()=>n._willUpdate()),n}function Oo(t){return _o({observeElementRect:po,observeElementOffset:mo,scrollToFn:yo,...t})}export{ms as L,oo as O,at as R,Co as a,we as b,Mo as c,Fn as d,_e as e,Oo as f,Se as g,Eo as h,K as i,P as j,Io as k,Yn as l,ko as m,pn as n,To as o,b as r,Lo as u,fs as w}; diff --git a/webui/dist/assets/router-BWgTyY51.js b/webui/dist/assets/router-BWgTyY51.js deleted file mode 100644 index 78a82272..00000000 --- a/webui/dist/assets/router-BWgTyY51.js +++ /dev/null @@ -1,2 +0,0 @@ -import{r as fo,a as ee,g as Ne,b as po}from"./react-vendor-Dtc2IqVY.js";function mo(t,o){for(var e=0;es[n]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var g=fo(),R=ee();const rt=Ne(R),hn=mo({__proto__:null,default:rt},[R]),Yt=new WeakMap,go=new WeakMap,bt={current:[]};let Nt=!1,mt=0;const pt=new Set,Pt=new Map;function Ue(t){for(const o of t){if(bt.current.includes(o))continue;bt.current.push(o),o.recompute();const e=go.get(o);if(e)for(const s of e){const n=Yt.get(s);n?.length&&Ue(n)}}}function yo(t){const o={prevVal:t.prevState,currentVal:t.state};for(const e of t.listeners)e(o)}function vo(t){const o={prevVal:t.prevState,currentVal:t.state};for(const e of t.listeners)e(o)}function Ve(t){if(mt>0&&!Pt.has(t)&&Pt.set(t,t.prevState),pt.add(t),!(mt>0)&&!Nt)try{for(Nt=!0;pt.size>0;){const o=Array.from(pt);pt.clear();for(const e of o){const s=Pt.get(e)??e.prevState;e.prevState=s,yo(e)}for(const e of o){const s=Yt.get(e);s&&(bt.current.push(e),Ue(s))}for(const e of o){const s=Yt.get(e);if(s)for(const n of s)vo(n)}}}finally{Nt=!1,bt.current=[],Pt.clear()}}function gt(t){mt++;try{t()}finally{if(mt--,mt===0){const o=pt.values().next().value;o&&Ve(o)}}}function So(t){return typeof t=="function"}class _o{constructor(o,e){this.listeners=new Set,this.subscribe=s=>{var n,r;this.listeners.add(s);const i=(r=(n=this.options)==null?void 0:n.onSubscribe)==null?void 0:r.call(n,s,this);return()=>{this.listeners.delete(s),i?.()}},this.prevState=o,this.state=o,this.options=e}setState(o){var e,s,n;this.prevState=this.state,(e=this.options)!=null&&e.updateFn?this.state=this.options.updateFn(this.prevState)(o):So(o)?this.state=o(this.prevState):this.state=o,(n=(s=this.options)==null?void 0:s.onUpdate)==null||n.call(s),Ve(this)}}const G="__TSR_index",ve="popstate",Se="beforeunload";function Ro(t){let o=t.getLocation();const e=new Set,s=i=>{o=t.getLocation(),e.forEach(c=>c({location:o,action:i}))},n=i=>{t.notifyOnIndexChange??!0?s(i):o=t.getLocation()},r=async({task:i,navigateOpts:c,...a})=>{if(c?.ignoreBlocker??!1){i();return}const u=t.getBlockers?.()??[],h=a.type==="PUSH"||a.type==="REPLACE";if(typeof document<"u"&&u.length&&h)for(const f of u){const d=Et(a.path,a.state);if(await f.blockerFn({currentLocation:o,nextLocation:d,action:a.type})){t.onBlocked?.();return}}i()};return{get location(){return o},get length(){return t.getLength()},subscribers:e,subscribe:i=>(e.add(i),()=>{e.delete(i)}),push:(i,c,a)=>{const l=o.state[G];c=_e(l+1,c),r({task:()=>{t.pushState(i,c),s({type:"PUSH"})},navigateOpts:a,type:"PUSH",path:i,state:c})},replace:(i,c,a)=>{const l=o.state[G];c=_e(l,c),r({task:()=>{t.replaceState(i,c),s({type:"REPLACE"})},navigateOpts:a,type:"REPLACE",path:i,state:c})},go:(i,c)=>{r({task:()=>{t.go(i),n({type:"GO",index:i})},navigateOpts:c,type:"GO"})},back:i=>{r({task:()=>{t.back(i?.ignoreBlocker??!1),n({type:"BACK"})},navigateOpts:i,type:"BACK"})},forward:i=>{r({task:()=>{t.forward(i?.ignoreBlocker??!1),n({type:"FORWARD"})},navigateOpts:i,type:"FORWARD"})},canGoBack:()=>o.state[G]!==0,createHref:i=>t.createHref(i),block:i=>{if(!t.setBlockers)return()=>{};const c=t.getBlockers?.()??[];return t.setBlockers([...c,i]),()=>{const a=t.getBlockers?.()??[];t.setBlockers?.(a.filter(l=>l!==i))}},flush:()=>t.flush?.(),destroy:()=>t.destroy?.(),notify:s}}function _e(t,o){o||(o={});const e=oe();return{...o,key:e,__TSR_key:e,[G]:t}}function Po(t){const o=typeof document<"u"?window:void 0,e=o.history.pushState,s=o.history.replaceState;let n=[];const r=()=>n,i=v=>n=v,c=(v=>v),a=(()=>Et(`${o.location.pathname}${o.location.search}${o.location.hash}`,o.history.state));if(!o.history.state?.__TSR_key&&!o.history.state?.key){const v=oe();o.history.replaceState({[G]:0,key:v,__TSR_key:v},"")}let l=a(),u,h=!1,f=!1,d=!1,p=!1;const m=()=>l;let y,_;const x=()=>{y&&(S._ignoreSubscribers=!0,(y.isPush?o.history.pushState:o.history.replaceState)(y.state,"",y.href),S._ignoreSubscribers=!1,y=void 0,_=void 0,u=void 0)},P=(v,C,M)=>{const T=c(C);_||(u=l),l=Et(C,M),y={href:T,state:M,isPush:y?.isPush||v==="push"},_||(_=Promise.resolve().then(()=>x()))},L=v=>{l=a(),S.notify({type:v})},E=async()=>{if(f){f=!1;return}const v=a(),C=v.state[G]-l.state[G],M=C===1,T=C===-1,I=!M&&!T||h;h=!1;const Y=I?"GO":T?"BACK":"FORWARD",D=I?{type:"GO",index:C}:{type:T?"BACK":"FORWARD"};if(d)d=!1;else{const X=r();if(typeof document<"u"&&X.length){for(const he of X)if(await he.blockerFn({currentLocation:l,nextLocation:v,action:Y})){f=!0,o.history.go(1),S.notify(D);return}}}l=a(),S.notify(D)},w=v=>{if(p){p=!1;return}let C=!1;const M=r();if(typeof document<"u"&&M.length)for(const T of M){const I=T.enableBeforeUnload??!0;if(I===!0){C=!0;break}if(typeof I=="function"&&I()===!0){C=!0;break}}if(C)return v.preventDefault(),v.returnValue=""},S=Ro({getLocation:m,getLength:()=>o.history.length,pushState:(v,C)=>P("push",v,C),replaceState:(v,C)=>P("replace",v,C),back:v=>(v&&(d=!0),p=!0,o.history.back()),forward:v=>{v&&(d=!0),p=!0,o.history.forward()},go:v=>{h=!0,o.history.go(v)},createHref:v=>c(v),flush:x,destroy:()=>{o.history.pushState=e,o.history.replaceState=s,o.removeEventListener(Se,w,{capture:!0}),o.removeEventListener(ve,E)},onBlocked:()=>{u&&l!==u&&(l=u)},getBlockers:r,setBlockers:i,notifyOnIndexChange:!1});return o.addEventListener(Se,w,{capture:!0}),o.addEventListener(ve,E),o.history.pushState=function(...v){const C=e.apply(o.history,v);return S._ignoreSubscribers||L("PUSH"),C},o.history.replaceState=function(...v){const C=s.apply(o.history,v);return S._ignoreSubscribers||L("REPLACE"),C},S}function Et(t,o){const e=t.indexOf("#"),s=t.indexOf("?"),n=oe();return{href:t,pathname:t.substring(0,e>0?s>0?Math.min(e,s):e:s>0?s:t.length),hash:e>-1?t.substring(e):"",search:s>-1?t.slice(s,e===-1?void 0:e):"",state:o||{[G]:0,key:n,__TSR_key:n}}}function oe(){return(Math.random()+1).toString(36).substring(7)}function Xt(t){return t[t.length-1]}function wo(t){return typeof t=="function"}function Q(t,o){return wo(t)?t(o):t}const xo=Object.prototype.hasOwnProperty;function B(t,o){if(t===o)return t;const e=o,s=we(t)&&we(e);if(!s&&!(Tt(t)&&Tt(e)))return e;const n=s?t:Re(t);if(!n)return e;const r=s?e:Re(e);if(!r)return e;const i=n.length,c=r.length,a=s?new Array(c):{};let l=0;for(let u=0;u"u")return!0;const e=o.prototype;return!(!Pe(e)||!e.hasOwnProperty("isPrototypeOf"))}function Pe(t){return Object.prototype.toString.call(t)==="[object Object]"}function we(t){return Array.isArray(t)&&t.length===Object.keys(t).length}function tt(t,o,e){if(t===o)return!0;if(typeof t!=typeof o)return!1;if(Array.isArray(t)&&Array.isArray(o)){if(t.length!==o.length)return!1;for(let s=0,n=t.length;sn||!tt(t[i],o[i],e)))return!1;return n===r}return!1}function it(t){let o,e;const s=new Promise((n,r)=>{o=n,e=r});return s.status="pending",s.resolve=n=>{s.status="resolved",s.value=n,o(n),t?.(n)},s.reject=n=>{s.status="rejected",e(n)},s}function q(t){return!!(t&&typeof t=="object"&&typeof t.then=="function")}const Lo=Array.from(new Map([["%","%25"],["\\","%5C"]]).values());function xe(t,o=Lo){function e(n,r,i=0){for(let c=i;c{try{return decodeURI(c)}catch{return c}})}}if(t===""||!/%[0-9A-Fa-f]{2}/g.test(t))return t;const s=t.replaceAll(/%[0-9a-f]{2}/g,n=>n.toUpperCase());return e(s,o)}var Co="Invariant failed";function K(t,o){if(!t)throw new Error(Co)}const U=0,ot=1,at=2,ct=3;function z(t){return se(t.filter(o=>o!==void 0).join("/"))}function se(t){return t.replace(/\/{2,}/g,"/")}function ne(t){return t==="/"?t:t.replace(/^\/{1,}/,"")}function J(t){return t==="/"?t:t.replace(/\/{1,}$/,"")}function Ct(t){return J(ne(t))}function It(t,o){return t?.endsWith("/")&&t!=="/"&&t!==`${o}/`?t.slice(0,-1):t}function Mo(t,o,e){return It(t,e)===It(o,e)}function bo(t){const{type:o,value:e}=t;if(o===U)return e;const{prefixSegment:s,suffixSegment:n}=t;if(o===ot){const r=e.substring(1);if(s&&n)return`${s}{$${r}}${n}`;if(s)return`${s}{$${r}}`;if(n)return`{$${r}}${n}`}if(o===ct){const r=e.substring(1);return s&&n?`${s}{-$${r}}${n}`:s?`${s}{-$${r}}`:n?`{-$${r}}${n}`:`{-$${r}}`}if(o===at){if(s&&n)return`${s}{$}${n}`;if(s)return`${s}{$}`;if(n)return`{$}${n}`}return e}function Eo({base:t,to:o,trailingSlash:e="never",parseCache:s}){let n=ut(t,s).slice();const r=ut(o,s);n.length>1&&Xt(n)?.value==="/"&&n.pop();for(let a=0,l=r.length;a1&&(Xt(n).value==="/"?e==="never"&&n.pop():e==="always"&&n.push({type:U,value:"/"}));const i=n.map(bo);return z(i)}const ut=(t,o)=>{if(!t)return[];const e=o?.get(t);if(e)return e;const s=Ao(t);return o?.set(t,s),s},To=/^\$.{1,}$/,Io=/^(.*?)\{(\$[a-zA-Z_$][a-zA-Z0-9_$]*)\}(.*)$/,ko=/^(.*?)\{-(\$[a-zA-Z_$][a-zA-Z0-9_$]*)\}(.*)$/,Oo=/^\$$/,Fo=/^(.*?)\{\$\}(.*)$/;function Ao(t){t=se(t);const o=[];if(t.slice(0,1)==="/"&&(t=t.substring(1),o.push({type:U,value:"/"})),!t)return o;const e=t.split("/").filter(Boolean);return o.push(...e.map(s=>{const n=s.match(Fo);if(n){const c=n[1],a=n[2];return{type:at,value:"$",prefixSegment:c||void 0,suffixSegment:a||void 0}}const r=s.match(ko);if(r){const c=r[1],a=r[2],l=r[3];return{type:ct,value:a,prefixSegment:c||void 0,suffixSegment:l||void 0}}const i=s.match(Io);if(i){const c=i[1],a=i[2],l=i[3];return{type:ot,value:""+a,prefixSegment:c||void 0,suffixSegment:l||void 0}}if(To.test(s)){const c=s.substring(1);return{type:ot,value:"$"+c,prefixSegment:void 0,suffixSegment:void 0}}return Oo.test(s)?{type:at,value:"$",prefixSegment:void 0,suffixSegment:void 0}:{type:U,value:s}})),t.slice(-1)==="/"&&(t=t.substring(1),o.push({type:U,value:"/"})),o}function Ut({path:t,params:o,decodeCharMap:e,parseCache:s}){const n=ut(t,s);function r(l){const u=o[l],h=typeof u=="string";return l==="*"||l==="_splat"?h?encodeURI(u):u:h?Bo(u,e):u}let i=!1;const c={},a=z(n.map(l=>{if(l.type===U)return l.value;if(l.type===at){c._splat=o._splat,c["*"]=o._splat;const u=l.prefixSegment||"",h=l.suffixSegment||"";if(!o._splat)return i=!0,u||h?`${u}${h}`:void 0;const f=r("_splat");return`${u}${f}${h}`}if(l.type===ot){const u=l.value.substring(1);!i&&!(u in o)&&(i=!0),c[u]=o[u];const h=l.prefixSegment||"",f=l.suffixSegment||"";return`${h}${r(u)??"undefined"}${f}`}if(l.type===ct){const u=l.value.substring(1),h=l.prefixSegment||"",f=l.suffixSegment||"";return!(u in o)||o[u]==null?h||f?`${h}${f}`:void 0:(c[u]=o[u],`${h}${r(u)??""}${f}`)}return l.value}));return{usedParams:c,interpolatedPath:a,isMissingParams:i}}function Bo(t,o){let e=encodeURIComponent(t);if(o)for(const[s,n]of o)e=e.replaceAll(s,n);return e}function Zt(t,o,e){const s=Do(t,o,e);if(!(o.to&&!s))return s??{}}function Do(t,{to:o,fuzzy:e,caseSensitive:s},n){const r=o,i=ut(t.startsWith("/")?t:`/${t}`,n),c=ut(r.startsWith("/")?r:`/${r}`,n),a={};return $o(i,c,a,e,s)?a:void 0}function $o(t,o,e,s,n){let r=0,i=0;for(;rm.value)));h&&p.startsWith(h)&&(p=p.slice(h.length)),f&&p.endsWith(f)&&(p=p.slice(0,p.length-f.length)),u=p}else u=decodeURI(z(l.map(h=>h.value)));return e["*"]=u,e._splat=u,!0}if(a.type===U){if(a.value==="/"&&!c?.value){i++;continue}if(c){if(n){if(a.value!==c.value)return!1}else if(a.value.toLowerCase()!==c.value.toLowerCase())return!1;r++,i++;continue}else return!1}if(a.type===ot){if(!c||c.value==="/")return!1;let l="",u=!1;if(a.prefixSegment||a.suffixSegment){const h=a.prefixSegment||"",f=a.suffixSegment||"",d=c.value;if(h&&!d.startsWith(h)||f&&!d.endsWith(f))return!1;let p=d;h&&p.startsWith(h)&&(p=p.slice(h.length)),f&&p.endsWith(f)&&(p=p.slice(0,p.length-f.length)),l=decodeURIComponent(p),u=!0}else l=decodeURIComponent(c.value),u=!0;u&&(e[a.value.substring(1)]=l,r++),i++;continue}if(a.type===ct){if(!c){i++;continue}if(c.value==="/"){i++;continue}let l="",u=!1;if(a.prefixSegment||a.suffixSegment){const h=a.prefixSegment||"",f=a.suffixSegment||"",d=c.value;if((!h||d.startsWith(h))&&(!f||d.endsWith(f))){let p=d;h&&p.startsWith(h)&&(p=p.slice(h.length)),f&&p.endsWith(f)&&(p=p.slice(0,p.length-f.length)),l=decodeURIComponent(p),u=!0}}else{let h=!0;for(let f=i+1;f=o.length)return e["**"]=z(t.slice(r).map(l=>l.value)),!!s&&o[o.length-1]?.value!=="/";if(i=t.length){for(let l=i;l{if(s.isRoot||!s.path)return;const r=ne(s.fullPath);let i=ut(r),c=0;for(;i.length>c+1&&i[c]?.value==="/";)c++;c>0&&(i=i.slice(c));let a=0,l=!1;const u=i.map((h,f)=>{if(h.value==="/")return jo;if(h.type===U)return No;let d;h.type===ot?d=Uo:h.type===ct?(d=Vo,a++):d=Wo;for(let p=f+1;p{const r=Math.min(s.scores.length,n.scores.length);for(let i=0;in.parsed[i].value?1:-1;return s.index-n.index}).map((s,n)=>(s.child.rank=n,s.child))}function Jo({routeTree:t,initRoute:o}){const e={},s={},n=i=>{i.forEach((c,a)=>{o?.(c,a);const l=e[c.id];if(K(!l,`Duplicate routes found with id: ${String(c.id)}`),e[c.id]=c,!c.isRoot&&c.path){const h=J(c.fullPath);(!s[h]||c.fullPath.endsWith("/"))&&(s[h]=c)}const u=c.children;u?.length&&n(u)})};n([t]);const r=qo(Object.values(e));return{routesById:e,routesByPath:s,flatRoutes:r}}function j(t){return!!t?.isNotFound}function Yo(){try{if(typeof window<"u"&&typeof window.sessionStorage=="object")return window.sessionStorage}catch{}}const kt="tsr-scroll-restoration-v1_3",Xo=(t,o)=>{let e;return(...s)=>{e||(e=setTimeout(()=>{t(...s),e=null},o))}};function Zo(){const t=Yo();if(!t)return null;const o=t.getItem(kt);let e=o?JSON.parse(o):{};return{state:e,set:s=>(e=Q(s,e)||e,t.setItem(kt,JSON.stringify(e)))}}const wt=Zo(),Qt=t=>t.state.__TSR_key||t.href;function Qo(t){const o=[];let e;for(;e=t.parentNode;)o.push(`${t.tagName}:nth-child(${Array.prototype.indexOf.call(e.children,t)+1})`),t=e;return`${o.reverse().join(" > ")}`.toLowerCase()}let Ot=!1;function We({storageKey:t,key:o,behavior:e,shouldScrollRestoration:s,scrollToTopSelectors:n,location:r}){let i;try{i=JSON.parse(sessionStorage.getItem(t)||"{}")}catch(l){console.error(l);return}const c=o||window.history.state?.__TSR_key,a=i[c];Ot=!0;t:{if(s&&a&&Object.keys(a).length>0){for(const h in a){const f=a[h];if(h==="window")window.scrollTo({top:f.scrollY,left:f.scrollX,behavior:e});else if(h){const d=document.querySelector(h);d&&(d.scrollLeft=f.scrollX,d.scrollTop=f.scrollY)}}break t}const l=(r??window.location).hash.split("#",2)[1];if(l){const h=window.history.state?.__hashScrollIntoViewOptions??!0;if(h){const f=document.getElementById(l);f&&f.scrollIntoView(h)}break t}const u={top:0,left:0,behavior:e};if(window.scrollTo(u),n)for(const h of n){if(h==="window")continue;const f=typeof h=="function"?h():document.querySelector(h);f&&f.scrollTo(u)}}Ot=!1}function ts(t,o){if(!wt&&!t.isServer||((t.options.scrollRestoration??!1)&&(t.isScrollRestoring=!0),t.isServer||t.isScrollRestorationSetup||!wt))return;t.isScrollRestorationSetup=!0,Ot=!1;const s=t.options.getScrollRestorationKey||Qt;window.history.scrollRestoration="manual";const n=r=>{if(Ot||!t.isScrollRestoring)return;let i="";if(r.target===document||r.target===window)i="window";else{const a=r.target.getAttribute("data-scroll-restoration-id");a?i=`[data-scroll-restoration-id="${a}"]`:i=Qo(r.target)}const c=s(t.state.location);wt.set(a=>{const l=a[c]||={},u=l[i]||={};if(i==="window")u.scrollX=window.scrollX||0,u.scrollY=window.scrollY||0;else if(i){const h=document.querySelector(i);h&&(u.scrollX=h.scrollLeft||0,u.scrollY=h.scrollTop||0)}return a})};typeof document<"u"&&document.addEventListener("scroll",Xo(n,100),!0),t.subscribe("onRendered",r=>{const i=s(r.toLocation);if(!t.resetNextScroll){t.resetNextScroll=!0;return}typeof t.options.scrollRestoration=="function"&&!t.options.scrollRestoration({location:t.latestLocation})||(We({storageKey:kt,key:i,behavior:t.options.scrollRestorationBehavior,shouldScrollRestoration:t.isScrollRestoring,scrollToTopSelectors:t.options.scrollToTopSelectors,location:t.history.location}),t.isScrollRestoring&&wt.set(c=>(c[i]||={},c)))})}function es(t){if(typeof document<"u"&&document.querySelector){const o=t.state.location.state.__hashScrollIntoViewOptions??!0;if(o&&t.state.location.hash!==""){const e=document.getElementById(t.state.location.hash);e&&e.scrollIntoView(o)}}}function os(t,o=String){const e=new URLSearchParams;for(const s in t){const n=t[s];n!==void 0&&e.set(s,o(n))}return e.toString()}function Vt(t){return t?t==="false"?!1:t==="true"?!0:+t*0===0&&+t+""===t?+t:t:""}function ss(t){const o=new URLSearchParams(t),e={};for(const[s,n]of o.entries()){const r=e[s];r==null?e[s]=Vt(n):Array.isArray(r)?r.push(Vt(n)):e[s]=[r,Vt(n)]}return e}const ns=is(JSON.parse),rs=as(JSON.stringify,JSON.parse);function is(t){return o=>{o[0]==="?"&&(o=o.substring(1));const e=ss(o);for(const s in e){const n=e[s];if(typeof n=="string")try{e[s]=t(n)}catch{}}return e}}function as(t,o){const e=typeof o=="function";function s(n){if(typeof n=="object"&&n!==null)try{return t(n)}catch{}else if(e&&typeof n=="string")try{return o(n),t(n)}catch{}return n}return n=>{const r=os(n,s);return r?`?${r}`:""}}const A="__root__";function cs(t){if(t.statusCode=t.statusCode||t.code||307,!t.reloadDocument&&typeof t.href=="string")try{new URL(t.href),t.reloadDocument=!0}catch{}const o=new Headers(t.headers);t.href&&o.get("Location")===null&&o.set("Location",t.href);const e=new Response(null,{status:t.statusCode,headers:o});if(e.options=t,t.throw)throw e;return e}function N(t){return t instanceof Response&&!!t.options}function us(t){const o=new Map;let e,s;const n=r=>{r.next&&(r.prev?(r.prev.next=r.next,r.next.prev=r.prev,r.next=void 0,s&&(s.next=r,r.prev=s)):(r.next.prev=void 0,e=r.next,r.next=void 0,s&&(r.prev=s,s.next=r)),s=r)};return{get(r){const i=o.get(r);if(i)return n(i),i.value},set(r,i){if(o.size>=t&&e){const a=e;o.delete(a.key),a.next&&(e=a.next,a.next.prev=void 0),a===s&&(s=void 0)}const c=o.get(r);if(c)c.value=i,n(c);else{const a={key:r,value:i,prev:s};s&&(s.next=a),s=a,e||(e=a),o.set(r,a)}}}}const Mt=t=>{if(!t.rendered)return t.rendered=!0,t.onReady?.()},At=(t,o)=>!!(t.preload&&!t.router.state.matches.some(e=>e.id===o)),ze=(t,o)=>{const e=t.router.routesById[o.routeId??""]??t.router.routeTree;!e.options.notFoundComponent&&t.router.options?.defaultNotFoundComponent&&(e.options.notFoundComponent=t.router.options.defaultNotFoundComponent),K(e.options.notFoundComponent);const s=t.matches.find(n=>n.routeId===e.id);K(s,"Could not find match for route: "+e.id),t.updateMatch(s.id,n=>({...n,status:"notFound",error:o,isFetching:!1})),o.routerCode==="BEFORE_LOAD"&&e.parentRoute&&(o.routeId=e.parentRoute.id,ze(t,o))},H=(t,o,e)=>{if(!(!N(e)&&!j(e))){if(N(e)&&e.redirectHandled&&!e.options.reloadDocument)throw e;if(o){o._nonReactive.beforeLoadPromise?.resolve(),o._nonReactive.loaderPromise?.resolve(),o._nonReactive.beforeLoadPromise=void 0,o._nonReactive.loaderPromise=void 0;const s=N(e)?"redirected":"notFound";o._nonReactive.error=e,t.updateMatch(o.id,n=>({...n,status:s,isFetching:!1,error:e})),j(e)&&!e.routeId&&(e.routeId=o.routeId),o._nonReactive.loadPromise?.resolve()}throw N(e)?(t.rendered=!0,e.options._fromLocation=t.location,e.redirectHandled=!0,e=t.router.resolveRedirect(e),e):(ze(t,e),e)}},Ke=(t,o)=>{const e=t.router.getMatch(o);return!!(!t.router.isServer&&e._nonReactive.dehydrated||t.router.isServer&&e.ssr===!1)},ht=(t,o,e,s)=>{const{id:n,routeId:r}=t.matches[o],i=t.router.looseRoutesById[r];if(e instanceof Promise)throw e;e.routerCode=s,t.firstBadMatchIndex??=o,H(t,t.router.getMatch(n),e);try{i.options.onError?.(e)}catch(c){e=c,H(t,t.router.getMatch(n),e)}t.updateMatch(n,c=>(c._nonReactive.beforeLoadPromise?.resolve(),c._nonReactive.beforeLoadPromise=void 0,c._nonReactive.loadPromise?.resolve(),{...c,error:e,status:"error",isFetching:!1,updatedAt:Date.now(),abortController:new AbortController}))},ls=(t,o,e,s)=>{const n=t.router.getMatch(o),r=t.matches[e-1]?.id,i=r?t.router.getMatch(r):void 0;if(t.router.isShell()){n.ssr=s.id===A;return}if(i?.ssr===!1){n.ssr=!1;return}const c=d=>d===!0&&i?.ssr==="data-only"?"data-only":d,a=t.router.options.defaultSsr??!0;if(s.options.ssr===void 0){n.ssr=c(a);return}if(typeof s.options.ssr!="function"){n.ssr=c(s.options.ssr);return}const{search:l,params:u}=n,h={search:xt(l,n.searchError),params:xt(u,n.paramsError),location:t.location,matches:t.matches.map(d=>({index:d.index,pathname:d.pathname,fullPath:d.fullPath,staticData:d.staticData,id:d.id,routeId:d.routeId,search:xt(d.search,d.searchError),params:xt(d.params,d.paramsError),ssr:d.ssr}))},f=s.options.ssr(h);if(q(f))return f.then(d=>{n.ssr=c(d??a)});n.ssr=c(f??a)},He=(t,o,e,s)=>{if(s._nonReactive.pendingTimeout!==void 0)return;const n=e.options.pendingMs??t.router.options.defaultPendingMs;if(!!(t.onReady&&!t.router.isServer&&!At(t,o)&&(e.options.loader||e.options.beforeLoad||Je(e))&&typeof n=="number"&&n!==1/0&&(e.options.pendingComponent??t.router.options?.defaultPendingComponent))){const i=setTimeout(()=>{Mt(t)},n);s._nonReactive.pendingTimeout=i}},hs=(t,o,e)=>{const s=t.router.getMatch(o);if(!s._nonReactive.beforeLoadPromise&&!s._nonReactive.loaderPromise)return;He(t,o,e,s);const n=()=>{const r=t.router.getMatch(o);r.preload&&(r.status==="redirected"||r.status==="notFound")&&H(t,r,r.error)};return s._nonReactive.beforeLoadPromise?s._nonReactive.beforeLoadPromise.then(n):n()},fs=(t,o,e,s)=>{const n=t.router.getMatch(o),r=n._nonReactive.loadPromise;n._nonReactive.loadPromise=it(()=>{r?.resolve()});const{paramsError:i,searchError:c}=n;i&&ht(t,e,i,"PARSE_PARAMS"),c&&ht(t,e,c,"VALIDATE_SEARCH"),He(t,o,s,n);const a=new AbortController,l=t.matches[e-1]?.id,f={...(l?t.router.getMatch(l):void 0)?.context??t.router.options.context??void 0,...n.__routeContext};let d=!1;const p=()=>{d||(d=!0,t.updateMatch(o,S=>({...S,isFetching:"beforeLoad",fetchCount:S.fetchCount+1,abortController:a,context:f})))},m=()=>{n._nonReactive.beforeLoadPromise?.resolve(),n._nonReactive.beforeLoadPromise=void 0,t.updateMatch(o,S=>({...S,isFetching:!1}))};if(!s.options.beforeLoad){gt(()=>{p(),m()});return}n._nonReactive.beforeLoadPromise=it();const{search:y,params:_,cause:x}=n,P=At(t,o),L={search:y,abortController:a,params:_,preload:P,context:f,location:t.location,navigate:S=>t.router.navigate({...S,_fromLocation:t.location}),buildLocation:t.router.buildLocation,cause:P?"preload":x,matches:t.matches,...t.router.options.additionalContext},E=S=>{if(S===void 0){gt(()=>{p(),m()});return}(N(S)||j(S))&&(p(),ht(t,e,S,"BEFORE_LOAD")),gt(()=>{p(),t.updateMatch(o,v=>({...v,__beforeLoadContext:S,context:{...v.context,...S}})),m()})};let w;try{if(w=s.options.beforeLoad(L),q(w))return p(),w.catch(S=>{ht(t,e,S,"BEFORE_LOAD")}).then(E)}catch(S){p(),ht(t,e,S,"BEFORE_LOAD")}E(w)},ds=(t,o)=>{const{id:e,routeId:s}=t.matches[o],n=t.router.looseRoutesById[s],r=()=>{if(t.router.isServer){const a=ls(t,e,o,n);if(q(a))return a.then(c)}return c()},i=()=>fs(t,e,o,n),c=()=>{if(Ke(t,e))return;const a=hs(t,e,n);return q(a)?a.then(i):i()};return r()},yt=(t,o,e)=>{const s=t.router.getMatch(o);if(!s||!e.options.head&&!e.options.scripts&&!e.options.headers)return;const n={matches:t.matches,match:s,params:s.params,loaderData:s.loaderData};return Promise.all([e.options.head?.(n),e.options.scripts?.(n),e.options.headers?.(n)]).then(([r,i,c])=>{const a=r?.meta,l=r?.links,u=r?.scripts,h=r?.styles;return{meta:a,links:l,headScripts:u,headers:c,scripts:i,styles:h}})},Ge=(t,o,e,s)=>{const n=t.matchPromises[e-1],{params:r,loaderDeps:i,abortController:c,cause:a}=t.router.getMatch(o);let l=t.router.options.context??{};for(let h=0;h<=e;h++){const f=t.matches[h];if(!f)continue;const d=t.router.getMatch(f.id);d&&(l={...l,...d.__routeContext??{},...d.__beforeLoadContext??{}})}const u=At(t,o);return{params:r,deps:i,preload:!!u,parentMatchPromise:n,abortController:c,context:l,location:t.location,navigate:h=>t.router.navigate({...h,_fromLocation:t.location}),cause:u?"preload":a,route:s,...t.router.options.additionalContext}},be=async(t,o,e,s)=>{try{const n=t.router.getMatch(o);try{(!t.router.isServer||n.ssr===!0)&&qe(s);const r=s.options.loader?.(Ge(t,o,e,s)),i=s.options.loader&&q(r);if(!!(i||s._lazyPromise||s._componentsPromise||s.options.head||s.options.scripts||s.options.headers||n._nonReactive.minPendingPromise)&&t.updateMatch(o,h=>({...h,isFetching:"loader"})),s.options.loader){const h=i?await r:r;H(t,t.router.getMatch(o),h),h!==void 0&&t.updateMatch(o,f=>({...f,loaderData:h}))}s._lazyPromise&&await s._lazyPromise;const a=yt(t,o,s),l=a?await a:void 0,u=n._nonReactive.minPendingPromise;u&&await u,s._componentsPromise&&await s._componentsPromise,t.updateMatch(o,h=>({...h,error:void 0,status:"success",isFetching:!1,updatedAt:Date.now(),...l}))}catch(r){let i=r;const c=n._nonReactive.minPendingPromise;c&&await c,j(r)&&await s.options.notFoundComponent?.preload?.(),H(t,t.router.getMatch(o),r);try{s.options.onError?.(r)}catch(u){i=u,H(t,t.router.getMatch(o),u)}const a=yt(t,o,s),l=a?await a:void 0;t.updateMatch(o,u=>({...u,error:i,status:"error",isFetching:!1,...l}))}}catch(n){const r=t.router.getMatch(o);if(r){const i=yt(t,o,s);if(i){const c=await i;t.updateMatch(o,a=>({...a,...c}))}r._nonReactive.loaderPromise=void 0}H(t,r,n)}},ps=async(t,o)=>{const{id:e,routeId:s}=t.matches[o];let n=!1,r=!1;const i=t.router.looseRoutesById[s];if(Ke(t,e)){if(t.router.isServer){const l=yt(t,e,i);if(l){const u=await l;t.updateMatch(e,h=>({...h,...u}))}return t.router.getMatch(e)}}else{const l=t.router.getMatch(e);if(l._nonReactive.loaderPromise){if(l.status==="success"&&!t.sync&&!l.preload)return l;await l._nonReactive.loaderPromise;const u=t.router.getMatch(e),h=u._nonReactive.error||u.error;h&&H(t,u,h)}else{const u=Date.now()-l.updatedAt,h=At(t,e),f=h?i.options.preloadStaleTime??t.router.options.defaultPreloadStaleTime??3e4:i.options.staleTime??t.router.options.defaultStaleTime??0,d=i.options.shouldReload,p=typeof d=="function"?d(Ge(t,e,o,i)):d,m=!!h&&!t.router.state.matches.some(P=>P.id===e),y=t.router.getMatch(e);y._nonReactive.loaderPromise=it(),m!==y.preload&&t.updateMatch(e,P=>({...P,preload:m}));const{status:_,invalid:x}=y;if(n=_==="success"&&(x||(p??u>f)),!(h&&i.options.preload===!1))if(n&&!t.sync)r=!0,(async()=>{try{await be(t,e,o,i);const P=t.router.getMatch(e);P._nonReactive.loaderPromise?.resolve(),P._nonReactive.loadPromise?.resolve(),P._nonReactive.loaderPromise=void 0}catch(P){N(P)&&await t.router.navigate(P.options)}})();else if(_!=="success"||n&&t.sync)await be(t,e,o,i);else{const P=yt(t,e,i);if(P){const L=await P;t.updateMatch(e,E=>({...E,...L}))}}}}const c=t.router.getMatch(e);r||(c._nonReactive.loaderPromise?.resolve(),c._nonReactive.loadPromise?.resolve()),clearTimeout(c._nonReactive.pendingTimeout),c._nonReactive.pendingTimeout=void 0,r||(c._nonReactive.loaderPromise=void 0),c._nonReactive.dehydrated=void 0;const a=r?c.isFetching:!1;return a!==c.isFetching||c.invalid!==!1?(t.updateMatch(e,l=>({...l,isFetching:a,invalid:!1})),t.router.getMatch(e)):c};async function Ee(t){const o=Object.assign(t,{matchPromises:[]});!o.router.isServer&&o.router.state.matches.some(e=>e._forcePending)&&Mt(o);try{for(let n=0;n{const{id:e,...s}=o.options;Object.assign(t.options,s),t._lazyLoaded=!0,t._lazyPromise=void 0}):t._lazyLoaded=!0),!t._componentsLoaded&&t._componentsPromise===void 0){const o=()=>{const e=[];for(const s of Ye){const n=t.options[s]?.preload;n&&e.push(n())}if(e.length)return Promise.all(e).then(()=>{t._componentsLoaded=!0,t._componentsPromise=void 0});t._componentsLoaded=!0,t._componentsPromise=void 0};t._componentsPromise=t._lazyPromise?t._lazyPromise.then(o):o()}return t._componentsPromise}function xt(t,o){return o?{status:"error",error:o}:{status:"success",value:t}}function Je(t){for(const o of Ye)if(t.options[o]?.preload)return!0;return!1}const Ye=["component","errorComponent","pendingComponent","notFoundComponent"];function ms(t){return{input:({url:o})=>{for(const e of t)o=Xe(e,o);return o},output:({url:o})=>{for(let e=t.length-1;e>=0;e--)o=Ze(t[e],o);return o}}}function gs(t){const o=Ct(t.basepath),e=`/${o}`,s=`${e}/`,n=t.caseSensitive?e:e.toLowerCase(),r=t.caseSensitive?s:s.toLowerCase();return{input:({url:i})=>{const c=t.caseSensitive?i.pathname:i.pathname.toLowerCase();return c===n?i.pathname="/":c.startsWith(r)&&(i.pathname=i.pathname.slice(e.length)),i},output:({url:i})=>(i.pathname=z(["/",o,i.pathname]),i)}}function Xe(t,o){const e=t?.input?.({url:o});if(e){if(typeof e=="string")return new URL(e);if(e instanceof URL)return e}return o}function Ze(t,o){const e=t?.output?.({url:o});if(e){if(typeof e=="string")return new URL(e);if(e instanceof URL)return e}return o}function et(t){const o=t.resolvedLocation,e=t.location,s=o?.pathname!==e.pathname,n=o?.href!==e.href,r=o?.hash!==e.hash;return{fromLocation:o,toLocation:e,pathChanged:s,hrefChanged:n,hashChanged:r}}class ys{constructor(o){this.tempLocationKey=`${Math.round(Math.random()*1e7)}`,this.resetNextScroll=!0,this.shouldViewTransition=void 0,this.isViewTransitionTypesSupported=void 0,this.subscribers=new Set,this.isScrollRestoring=!1,this.isScrollRestorationSetup=!1,this.startTransition=e=>e(),this.update=e=>{e.notFoundRoute&&console.warn("The notFoundRoute API is deprecated and will be removed in the next major version. See https://tanstack.com/router/v1/docs/framework/react/guide/not-found-errors#migrating-from-notfoundroute for more info.");const s=this.options,n=this.basepath??s?.basepath??"/",r=this.basepath===void 0,i=s?.rewrite;this.options={...s,...e},this.isServer=this.options.isServer??typeof document>"u",this.pathParamsDecodeCharMap=this.options.pathParamsAllowedCharacters?new Map(this.options.pathParamsAllowedCharacters.map(f=>[encodeURIComponent(f),f])):void 0,(!this.history||this.options.history&&this.options.history!==this.history)&&(this.options.history?this.history=this.options.history:this.isServer||(this.history=Po())),this.origin=this.options.origin,this.origin||(!this.isServer&&window?.origin&&window.origin!=="null"?this.origin=window.origin:this.origin="http://localhost"),this.history&&this.updateLatestLocation(),this.options.routeTree!==this.routeTree&&(this.routeTree=this.options.routeTree,this.buildRouteTree()),!this.__store&&this.latestLocation&&(this.__store=new _o(Ss(this.latestLocation),{onUpdate:()=>{this.__store.state={...this.state,cachedMatches:this.state.cachedMatches.filter(f=>!["redirected"].includes(f.status))}}}),ts(this));let c=!1;const a=this.options.basepath??"/",l=this.options.rewrite;if(r||n!==a||i!==l){this.basepath=a;const f=[];Ct(a)!==""&&f.push(gs({basepath:a})),l&&f.push(l),this.rewrite=f.length===0?void 0:f.length===1?f[0]:ms(f),this.history&&this.updateLatestLocation(),c=!0}c&&this.__store&&(this.__store.state={...this.state,location:this.latestLocation}),typeof window<"u"&&"CSS"in window&&typeof window.CSS?.supports=="function"&&(this.isViewTransitionTypesSupported=window.CSS.supports("selector(:active-view-transition-type(a)"))},this.updateLatestLocation=()=>{this.latestLocation=this.parseLocation(this.history.location,this.latestLocation)},this.buildRouteTree=()=>{const{routesById:e,routesByPath:s,flatRoutes:n}=Jo({routeTree:this.routeTree,initRoute:(i,c)=>{i.init({originalIndex:c})}});this.routesById=e,this.routesByPath=s,this.flatRoutes=n;const r=this.options.notFoundRoute;r&&(r.init({originalIndex:99999999999}),this.routesById[r.id]=r)},this.subscribe=(e,s)=>{const n={eventType:e,fn:s};return this.subscribers.add(n),()=>{this.subscribers.delete(n)}},this.emit=e=>{this.subscribers.forEach(s=>{s.eventType===e.type&&s.fn(e)})},this.parseLocation=(e,s)=>{const n=({href:a,state:l})=>{const u=new URL(a,this.origin),h=Xe(this.rewrite,u),f=this.options.parseSearch(h.search),d=this.options.stringifySearch(f);h.search=d;const p=h.href.replace(h.origin,""),{pathname:m,hash:y}=h;return{href:p,publicHref:a,url:h.href,pathname:xe(m),searchStr:d,search:B(s?.search,f),hash:y.split("#").reverse()[0]??"",state:B(s?.state,l)}},r=n(e),{__tempLocation:i,__tempKey:c}=r.state;if(i&&(!c||c===this.tempLocationKey)){const a=n(i);return a.state.key=r.state.key,a.state.__TSR_key=r.state.__TSR_key,delete a.state.__tempLocation,{...a,maskedLocation:r}}return r},this.resolvePathWithBase=(e,s)=>Eo({base:e,to:se(s),trailingSlash:this.options.trailingSlash,parseCache:this.parsePathnameCache}),this.matchRoutes=(e,s,n)=>typeof e=="string"?this.matchRoutesInternal({pathname:e,search:s},n):this.matchRoutesInternal(e,s),this.parsePathnameCache=us(1e3),this.getMatchedRoutes=(e,s)=>_s({pathname:e,routePathname:s,caseSensitive:this.options.caseSensitive,routesByPath:this.routesByPath,routesById:this.routesById,flatRoutes:this.flatRoutes,parseCache:this.parsePathnameCache}),this.cancelMatch=e=>{const s=this.getMatch(e);s&&(s.abortController.abort(),clearTimeout(s._nonReactive.pendingTimeout),s._nonReactive.pendingTimeout=void 0)},this.cancelMatches=()=>{const e=this.state.matches.filter(r=>r.status==="pending"),s=this.state.matches.filter(r=>r.isFetching==="loader");new Set([...this.state.pendingMatches??[],...e,...s]).forEach(r=>{this.cancelMatch(r.id)})},this.buildLocation=e=>{const s=(r={})=>{const i=r._fromLocation||this.pendingBuiltLocation||this.latestLocation,c=this.matchRoutes(i,{_buildLocation:!0}),a=Xt(c);r.from;const l=r.unsafeRelative==="path"?i.pathname:r.from??a.fullPath,u=this.resolvePathWithBase(l,"."),h=a.search,f={...a.params},d=r.to?this.resolvePathWithBase(u,`${r.to}`):this.resolvePathWithBase(u,"."),p=r.params===!1||r.params===null?{}:(r.params??!0)===!0?f:Object.assign(f,Q(r.params,f)),m=Ut({path:d,params:p,parseCache:this.parsePathnameCache}).interpolatedPath,y=this.matchRoutes(m,void 0,{_buildLocation:!0}).map(M=>this.looseRoutesById[M.routeId]);if(Object.keys(p).length>0)for(const M of y){const T=M.options.params?.stringify??M.options.stringifyParams;T&&Object.assign(p,T(p))}const _=e.leaveParams?d:xe(Ut({path:d,params:p,decodeCharMap:this.pathParamsDecodeCharMap,parseCache:this.parsePathnameCache}).interpolatedPath);let x=h;if(e._includeValidateSearch&&this.options.search?.strict){const M={};y.forEach(T=>{if(T.options.validateSearch)try{Object.assign(M,te(T.options.validateSearch,{...M,...x}))}catch{}}),x=M}x=Rs({search:x,dest:r,destRoutes:y,_includeValidateSearch:e._includeValidateSearch}),x=B(h,x);const P=this.options.stringifySearch(x),L=r.hash===!0?i.hash:r.hash?Q(r.hash,i.hash):void 0,E=L?`#${L}`:"";let w=r.state===!0?i.state:r.state?Q(r.state,i.state):{};w=B(i.state,w);const S=`${_}${P}${E}`,v=new URL(S,this.origin),C=Ze(this.rewrite,v);return{publicHref:C.pathname+C.search+C.hash,href:S,url:C.href,pathname:_,search:x,searchStr:P,state:w,hash:L??"",unmaskOnReload:r.unmaskOnReload}},n=(r={},i)=>{const c=s(r);let a=i?s(i):void 0;if(!a){let l={};const u=this.options.routeMasks?.find(h=>{const f=Zt(c.pathname,{to:h.from,caseSensitive:!1,fuzzy:!1},this.parsePathnameCache);return f?(l=f,!0):!1});if(u){const{from:h,...f}=u;i={from:e.from,...f,params:l},a=s(i)}}return a&&(c.maskedLocation=a),c};return e.mask?n(e,{from:e.from,...e.mask}):n(e)},this.commitLocation=({viewTransition:e,ignoreBlocker:s,...n})=>{const r=()=>{const a=["key","__TSR_key","__TSR_index","__hashScrollIntoViewOptions"];a.forEach(u=>{n.state[u]=this.latestLocation.state[u]});const l=tt(n.state,this.latestLocation.state);return a.forEach(u=>{delete n.state[u]}),l},i=J(this.latestLocation.href)===J(n.href),c=this.commitLocationPromise;if(this.commitLocationPromise=it(()=>{c?.resolve()}),i&&r())this.load();else{let{maskedLocation:a,hashScrollIntoView:l,...u}=n;a&&(u={...a,state:{...a.state,__tempKey:void 0,__tempLocation:{...u,search:u.searchStr,state:{...u.state,__tempKey:void 0,__tempLocation:void 0,__TSR_key:void 0,key:void 0}}}},(u.unmaskOnReload??this.options.unmaskOnReload??!1)&&(u.state.__tempKey=this.tempLocationKey)),u.state.__hashScrollIntoViewOptions=l??this.options.defaultHashScrollIntoView??!0,this.shouldViewTransition=e,this.history[n.replace?"replace":"push"](u.publicHref,u.state,{ignoreBlocker:s})}return this.resetNextScroll=n.resetScroll??!0,this.history.subscribers.size||this.load(),this.commitLocationPromise},this.buildAndCommitLocation=({replace:e,resetScroll:s,hashScrollIntoView:n,viewTransition:r,ignoreBlocker:i,href:c,...a}={})=>{if(c){const h=this.history.location.state.__TSR_index,f=Et(c,{__TSR_index:e?h:h+1});a.to=f.pathname,a.search=this.options.parseSearch(f.search),a.hash=f.hash.slice(1)}const l=this.buildLocation({...a,_includeValidateSearch:!0});this.pendingBuiltLocation=l;const u=this.commitLocation({...l,viewTransition:r,replace:e,resetScroll:s,hashScrollIntoView:n,ignoreBlocker:i});return Promise.resolve().then(()=>{this.pendingBuiltLocation===l&&(this.pendingBuiltLocation=void 0)}),u},this.navigate=({to:e,reloadDocument:s,href:n,...r})=>{if(!s&&n)try{new URL(`${n}`),s=!0}catch{}return s?(n||(n=this.buildLocation({to:e,...r}).url),r.replace?window.location.replace(n):window.location.href=n,Promise.resolve()):this.buildAndCommitLocation({...r,href:n,to:e,_isNavigate:!0})},this.beforeLoad=()=>{if(this.cancelMatches(),this.updateLatestLocation(),this.isServer){const s=this.buildLocation({to:this.latestLocation.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0}),n=r=>{try{return encodeURI(decodeURI(r))}catch{return r}};if(Ct(n(this.latestLocation.href))!==Ct(n(s.href))){let r=s.url;throw this.origin&&r.startsWith(this.origin)&&(r=r.replace(this.origin,"")||"/"),cs({href:r})}}const e=this.matchRoutes(this.latestLocation);this.__store.setState(s=>({...s,status:"pending",statusCode:200,isLoading:!0,location:this.latestLocation,pendingMatches:e,cachedMatches:s.cachedMatches.filter(n=>!e.some(r=>r.id===n.id))}))},this.load=async e=>{let s,n,r;for(r=new Promise(c=>{this.startTransition(async()=>{try{this.beforeLoad();const a=this.latestLocation,l=this.state.resolvedLocation;this.state.redirect||this.emit({type:"onBeforeNavigate",...et({resolvedLocation:l,location:a})}),this.emit({type:"onBeforeLoad",...et({resolvedLocation:l,location:a})}),await Ee({router:this,sync:e?.sync,matches:this.state.pendingMatches,location:a,updateMatch:this.updateMatch,onReady:async()=>{this.startTransition(()=>{this.startViewTransition(async()=>{let u=[],h=[],f=[];gt(()=>{this.__store.setState(d=>{const p=d.matches,m=d.pendingMatches||d.matches;return u=p.filter(y=>!m.some(_=>_.id===y.id)),h=m.filter(y=>!p.some(_=>_.id===y.id)),f=m.filter(y=>p.some(_=>_.id===y.id)),{...d,isLoading:!1,loadedAt:Date.now(),matches:m,pendingMatches:void 0,cachedMatches:[...d.cachedMatches,...u.filter(y=>y.status!=="error")]}}),this.clearExpiredCache()}),[[u,"onLeave"],[h,"onEnter"],[f,"onStay"]].forEach(([d,p])=>{d.forEach(m=>{this.looseRoutesById[m.routeId].options[p]?.(m)})})})})}})}catch(a){N(a)?(s=a,this.isServer||this.navigate({...s.options,replace:!0,ignoreBlocker:!0})):j(a)&&(n=a),this.__store.setState(l=>({...l,statusCode:s?s.status:n?404:l.matches.some(u=>u.status==="error")?500:200,redirect:s}))}this.latestLoadPromise===r&&(this.commitLocationPromise?.resolve(),this.latestLoadPromise=void 0,this.commitLocationPromise=void 0),c()})}),this.latestLoadPromise=r,await r;this.latestLoadPromise&&r!==this.latestLoadPromise;)await this.latestLoadPromise;let i;this.hasNotFoundMatch()?i=404:this.__store.state.matches.some(c=>c.status==="error")&&(i=500),i!==void 0&&this.__store.setState(c=>({...c,statusCode:i}))},this.startViewTransition=e=>{const s=this.shouldViewTransition??this.options.defaultViewTransition;if(delete this.shouldViewTransition,s&&typeof document<"u"&&"startViewTransition"in document&&typeof document.startViewTransition=="function"){let n;if(typeof s=="object"&&this.isViewTransitionTypesSupported){const r=this.latestLocation,i=this.state.resolvedLocation,c=typeof s.types=="function"?s.types(et({resolvedLocation:i,location:r})):s.types;if(c===!1){e();return}n={update:e,types:c}}else n=e;document.startViewTransition(n)}else e()},this.updateMatch=(e,s)=>{this.startTransition(()=>{const n=this.state.pendingMatches?.some(r=>r.id===e)?"pendingMatches":this.state.matches.some(r=>r.id===e)?"matches":this.state.cachedMatches.some(r=>r.id===e)?"cachedMatches":"";n&&this.__store.setState(r=>({...r,[n]:r[n]?.map(i=>i.id===e?s(i):i)}))})},this.getMatch=e=>{const s=n=>n.id===e;return this.state.cachedMatches.find(s)??this.state.pendingMatches?.find(s)??this.state.matches.find(s)},this.invalidate=e=>{const s=n=>e?.filter?.(n)??!0?{...n,invalid:!0,...e?.forcePending||n.status==="error"?{status:"pending",error:void 0}:void 0}:n;return this.__store.setState(n=>({...n,matches:n.matches.map(s),cachedMatches:n.cachedMatches.map(s),pendingMatches:n.pendingMatches?.map(s)})),this.shouldViewTransition=!1,this.load({sync:e?.sync})},this.resolveRedirect=e=>{if(!e.options.href){const s=this.buildLocation(e.options);let n=s.url;this.origin&&n.startsWith(this.origin)&&(n=n.replace(this.origin,"")||"/"),e.options.href=s.href,e.headers.set("Location",n)}return e.headers.get("Location")||e.headers.set("Location",e.options.href),e},this.clearCache=e=>{const s=e?.filter;s!==void 0?this.__store.setState(n=>({...n,cachedMatches:n.cachedMatches.filter(r=>!s(r))})):this.__store.setState(n=>({...n,cachedMatches:[]}))},this.clearExpiredCache=()=>{const e=s=>{const n=this.looseRoutesById[s.routeId];if(!n.options.loader)return!0;const r=(s.preload?n.options.preloadGcTime??this.options.defaultPreloadGcTime:n.options.gcTime??this.options.defaultGcTime)??300*1e3;return s.status==="error"?!0:Date.now()-s.updatedAt>=r};this.clearCache({filter:e})},this.loadRouteChunk=qe,this.preloadRoute=async e=>{const s=this.buildLocation(e);let n=this.matchRoutes(s,{throwOnError:!0,preload:!0,dest:e});const r=new Set([...this.state.matches,...this.state.pendingMatches??[]].map(c=>c.id)),i=new Set([...r,...this.state.cachedMatches.map(c=>c.id)]);gt(()=>{n.forEach(c=>{i.has(c.id)||this.__store.setState(a=>({...a,cachedMatches:[...a.cachedMatches,c]}))})});try{return n=await Ee({router:this,matches:n,location:s,preload:!0,updateMatch:(c,a)=>{r.has(c)?n=n.map(l=>l.id===c?a(l):l):this.updateMatch(c,a)}}),n}catch(c){if(N(c))return c.options.reloadDocument?void 0:await this.preloadRoute({...c.options,_fromLocation:s});j(c)||console.error(c);return}},this.matchRoute=(e,s)=>{const n={...e,to:e.to?this.resolvePathWithBase(e.from||"",e.to):void 0,params:e.params||{},leaveParams:!0},r=this.buildLocation(n);if(s?.pending&&this.state.status!=="pending")return!1;const c=(s?.pending===void 0?!this.state.isLoading:s.pending)?this.latestLocation:this.state.resolvedLocation||this.state.location,a=Zt(c.pathname,{...s,to:r.pathname},this.parsePathnameCache);return!a||e.params&&!tt(a,e.params,{partial:!0})?!1:a&&(s?.includeSearch??!0)?tt(c.search,r.search,{partial:!0})?a:!1:a},this.hasNotFoundMatch=()=>this.__store.state.matches.some(e=>e.status==="notFound"||e.globalNotFound),this.update({defaultPreloadDelay:50,defaultPendingMs:1e3,defaultPendingMinMs:500,context:void 0,...o,caseSensitive:o.caseSensitive??!1,notFoundMode:o.notFoundMode??"fuzzy",stringifySearch:o.stringifySearch??rs,parseSearch:o.parseSearch??ns}),typeof document<"u"&&(self.__TSR_ROUTER__=this)}isShell(){return!!this.options.isShell}isPrerendering(){return!!this.options.isPrerendering}get state(){return this.__store.state}get looseRoutesById(){return this.routesById}matchRoutesInternal(o,e){const{foundRoute:s,matchedRoutes:n,routeParams:r}=this.getMatchedRoutes(o.pathname,e?.dest?.to);let i=!1;(s?s.path!=="/"&&r["**"]:J(o.pathname))&&(this.options.notFoundRoute?n.push(this.options.notFoundRoute):i=!0);const c=(()=>{if(i){if(this.options.notFoundMode!=="root")for(let u=n.length-1;u>=0;u--){const h=n[u];if(h.children)return h.id}return A}})(),a=[],l=u=>u?.id?u.context??this.options.context??void 0:this.options.context??void 0;return n.forEach((u,h)=>{const f=a[h-1],[d,p,m]=(()=>{const I=f?.search??o.search,Y=f?._strictSearch??void 0;try{const D=te(u.options.validateSearch,{...I})??void 0;return[{...I,...D},{...Y,...D},void 0]}catch(D){let X=D;if(D instanceof Ft||(X=new Ft(D.message,{cause:D})),e?.throwOnError)throw X;return[I,{},X]}})(),y=u.options.loaderDeps?.({search:d})??"",_=y?JSON.stringify(y):"",{interpolatedPath:x,usedParams:P}=Ut({path:u.fullPath,params:r,decodeCharMap:this.pathParamsDecodeCharMap}),L=u.id+x+_,E=this.getMatch(L),w=this.state.matches.find(I=>I.routeId===u.id),S=E?._strictParams??P;let v;if(!E){const I=u.options.params?.parse??u.options.parseParams;if(I)try{Object.assign(S,I(S))}catch(Y){if(v=new vs(Y.message,{cause:Y}),e?.throwOnError)throw v}}Object.assign(r,S);const C=w?"stay":"enter";let M;if(E)M={...E,cause:C,params:w?B(w.params,r):r,_strictParams:S,search:B(w?w.search:E.search,d),_strictSearch:p};else{const I=u.options.loader||u.options.beforeLoad||u.lazyFn||Je(u)?"pending":"success";M={id:L,index:h,routeId:u.id,params:w?B(w.params,r):r,_strictParams:S,pathname:x,updatedAt:Date.now(),search:w?B(w.search,d):d,_strictSearch:p,searchError:void 0,status:I,isFetching:!1,error:void 0,paramsError:v,__routeContext:void 0,_nonReactive:{loadPromise:it()},__beforeLoadContext:void 0,context:{},abortController:new AbortController,fetchCount:0,cause:C,loaderDeps:w?B(w.loaderDeps,y):y,invalid:!1,preload:!1,links:void 0,scripts:void 0,headScripts:void 0,meta:void 0,staticData:u.options.staticData||{},fullPath:u.fullPath}}e?.preload||(M.globalNotFound=c===u.id),M.searchError=m;const T=l(f);M.context={...T,...M.__routeContext,...M.__beforeLoadContext},a.push(M)}),a.forEach((u,h)=>{const f=this.looseRoutesById[u.routeId];if(!this.getMatch(u.id)&&e?._buildLocation!==!0){const p=a[h-1],m=l(p);if(f.options.context){const y={deps:u.loaderDeps,params:u.params,context:m??{},location:o,navigate:_=>this.navigate({..._,_fromLocation:o}),buildLocation:this.buildLocation,cause:u.cause,abortController:u.abortController,preload:!!u.preload,matches:a};u.__routeContext=f.options.context(y)??void 0}u.context={...m,...u.__routeContext,...u.__beforeLoadContext}}}),a}}class Ft extends Error{}class vs extends Error{}function Ss(t){return{loadedAt:0,isLoading:!1,isTransitioning:!1,status:"idle",resolvedLocation:void 0,location:t,matches:[],pendingMatches:[],cachedMatches:[],statusCode:200}}function te(t,o){if(t==null)return{};if("~standard"in t){const e=t["~standard"].validate(o);if(e instanceof Promise)throw new Ft("Async validation not supported");if(e.issues)throw new Ft(JSON.stringify(e.issues,void 0,2),{cause:e});return e.value}return"parse"in t?t.parse(o):typeof t=="function"?t(o):{}}function _s({pathname:t,routePathname:o,caseSensitive:e,routesByPath:s,routesById:n,flatRoutes:r,parseCache:i}){let c={};const a=J(t),l=d=>Zt(a,{to:d.fullPath,caseSensitive:d.options?.caseSensitive??e,fuzzy:!0},i);let u=o!==void 0?s[o]:void 0;if(u)c=l(u);else{let d;for(const p of r){const m=l(p);if(m)if(p.path!=="/"&&m["**"])d||(d={foundRoute:p,routeParams:m});else{u=p,c=m;break}}!u&&d&&(u=d.foundRoute,c=d.routeParams)}let h=u||n[A];const f=[h];for(;h.parentRoute;)h=h.parentRoute,f.push(h);return f.reverse(),{matchedRoutes:f,routeParams:c,foundRoute:u}}function Rs({search:t,dest:o,destRoutes:e,_includeValidateSearch:s}){const n=e.reduce((c,a)=>{const l=[];if("search"in a.options)a.options.search?.middlewares&&l.push(...a.options.search.middlewares);else if(a.options.preSearchFilters||a.options.postSearchFilters){const u=({search:h,next:f})=>{let d=h;"preSearchFilters"in a.options&&a.options.preSearchFilters&&(d=a.options.preSearchFilters.reduce((m,y)=>y(m),h));const p=f(d);return"postSearchFilters"in a.options&&a.options.postSearchFilters?a.options.postSearchFilters.reduce((m,y)=>y(m),p):p};l.push(u)}if(s&&a.options.validateSearch){const u=({search:h,next:f})=>{const d=f(h);try{return{...d,...te(a.options.validateSearch,d)??void 0}}catch{return d}};l.push(u)}return c.concat(l)},[])??[],r=({search:c})=>o.search?o.search===!0?c:Q(o.search,c):{};n.push(r);const i=(c,a)=>{if(c>=n.length)return a;const l=n[c];return l({search:a,next:h=>i(c+1,h)})};return i(0,t)}const Ps="Error preloading route! ☝️";class Qe{constructor(o){if(this.init=e=>{this.originalIndex=e.originalIndex;const s=this.options,n=!s?.path&&!s?.id;this.parentRoute=this.options.getParentRoute?.(),n?this._path=A:this.parentRoute||K(!1);let r=n?A:s?.path;r&&r!=="/"&&(r=ne(r));const i=s?.id||r;let c=n?A:z([this.parentRoute.id===A?"":this.parentRoute.id,i]);r===A&&(r="/"),c!==A&&(c=z(["/",c]));const a=c===A?"/":z([this.parentRoute.fullPath,r]);this._path=r,this._id=c,this._fullPath=a,this._to=a},this.addChildren=e=>this._addFileChildren(e),this._addFileChildren=e=>(Array.isArray(e)&&(this.children=e),typeof e=="object"&&e!==null&&(this.children=Object.values(e)),this),this._addFileTypes=()=>this,this.updateLoader=e=>(Object.assign(this.options,e),this),this.update=e=>(Object.assign(this.options,e),this),this.lazy=e=>(this.lazyFn=e,this),this.options=o||{},this.isRoot=!o?.getParentRoute,o?.id&&o?.path)throw new Error("Route cannot have both an 'id' and a 'path' option.")}get to(){return this._to}get id(){return this._id}get path(){return this._path}get fullPath(){return this._fullPath}}class ws extends Qe{constructor(o){super(o)}}function re(t){const o=t.errorComponent??Bt;return g.jsx(xs,{getResetKey:t.getResetKey,onCatch:t.onCatch,children:({error:e,reset:s})=>e?R.createElement(o,{error:e,reset:s}):t.children})}class xs extends R.Component{constructor(){super(...arguments),this.state={error:null}}static getDerivedStateFromProps(o){return{resetKey:o.getResetKey()}}static getDerivedStateFromError(o){return{error:o}}reset(){this.setState({error:null})}componentDidUpdate(o,e){e.error&&e.resetKey!==this.state.resetKey&&this.reset()}componentDidCatch(o,e){this.props.onCatch&&this.props.onCatch(o,e)}render(){return this.props.children({error:this.state.resetKey!==this.props.getResetKey()?null:this.state.error,reset:()=>{this.reset()}})}}function Bt({error:t}){const[o,e]=R.useState(!1);return g.jsxs("div",{style:{padding:".5rem",maxWidth:"100%"},children:[g.jsxs("div",{style:{display:"flex",alignItems:"center",gap:".5rem"},children:[g.jsx("strong",{style:{fontSize:"1rem"},children:"Something went wrong!"}),g.jsx("button",{style:{appearance:"none",fontSize:".6em",border:"1px solid currentColor",padding:".1rem .2rem",fontWeight:"bold",borderRadius:".25rem"},onClick:()=>e(s=>!s),children:o?"Hide Error":"Show Error"})]}),g.jsx("div",{style:{height:".25rem"}}),o?g.jsx("div",{children:g.jsx("pre",{style:{fontSize:".7em",border:"1px solid red",borderRadius:".25rem",padding:".3rem",color:"red",overflow:"auto"},children:t.message?g.jsx("code",{children:t.message}):null})}):null]})}function Ls({children:t,fallback:o=null}){return Cs()?g.jsx(rt.Fragment,{children:t}):g.jsx(rt.Fragment,{children:o})}function Cs(){return rt.useSyncExternalStore(Ms,()=>!0,()=>!1)}function Ms(){return()=>{}}var Wt={exports:{}},zt={},Kt={exports:{}},Ht={};var Te;function bs(){if(Te)return Ht;Te=1;var t=ee();function o(h,f){return h===f&&(h!==0||1/h===1/f)||h!==h&&f!==f}var e=typeof Object.is=="function"?Object.is:o,s=t.useState,n=t.useEffect,r=t.useLayoutEffect,i=t.useDebugValue;function c(h,f){var d=f(),p=s({inst:{value:d,getSnapshot:f}}),m=p[0].inst,y=p[1];return r(function(){m.value=d,m.getSnapshot=f,a(m)&&y({inst:m})},[h,d,f]),n(function(){return a(m)&&y({inst:m}),h(function(){a(m)&&y({inst:m})})},[h]),i(d),d}function a(h){var f=h.getSnapshot;h=h.value;try{var d=f();return!e(h,d)}catch{return!0}}function l(h,f){return f()}var u=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?l:c;return Ht.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:u,Ht}var Ie;function Es(){return Ie||(Ie=1,Kt.exports=bs()),Kt.exports}var ke;function Ts(){if(ke)return zt;ke=1;var t=ee(),o=Es();function e(l,u){return l===u&&(l!==0||1/l===1/u)||l!==l&&u!==u}var s=typeof Object.is=="function"?Object.is:e,n=o.useSyncExternalStore,r=t.useRef,i=t.useEffect,c=t.useMemo,a=t.useDebugValue;return zt.useSyncExternalStoreWithSelector=function(l,u,h,f,d){var p=r(null);if(p.current===null){var m={hasValue:!1,value:null};p.current=m}else m=p.current;p=c(function(){function _(w){if(!x){if(x=!0,P=w,w=f(w),d!==void 0&&m.hasValue){var S=m.value;if(d(S,w))return L=S}return L=w}if(S=L,s(P,w))return S;var v=f(w);return d!==void 0&&d(S,v)?(P=w,S):(P=w,L=v)}var x=!1,P,L,E=h===void 0?null:h;return[function(){return _(u())},E===null?void 0:function(){return _(E())}]},[u,h,f,d]);var y=n(l,p[0],p[1]);return i(function(){m.hasValue=!0,m.value=y},[y]),a(y),y},zt}var Oe;function Is(){return Oe||(Oe=1,Wt.exports=Ts()),Wt.exports}var ks=Is();function Os(t,o=s=>s,e={}){const s=e.equal??Fs;return ks.useSyncExternalStoreWithSelector(t.subscribe,()=>t.state,()=>t.state,o,s)}function Fs(t,o){if(Object.is(t,o))return!0;if(typeof t!="object"||t===null||typeof o!="object"||o===null)return!1;if(t instanceof Map&&o instanceof Map){if(t.size!==o.size)return!1;for(const[s,n]of t)if(!o.has(s)||!Object.is(n,o.get(s)))return!1;return!0}if(t instanceof Set&&o instanceof Set){if(t.size!==o.size)return!1;for(const s of t)if(!o.has(s))return!1;return!0}if(t instanceof Date&&o instanceof Date)return t.getTime()===o.getTime();const e=Fe(t);if(e.length!==Fe(o).length)return!1;for(let s=0;s"u"?Gt:window.__TSR_ROUTER_CONTEXT__?window.__TSR_ROUTER_CONTEXT__:(window.__TSR_ROUTER_CONTEXT__=Gt,Gt)}function F(t){const o=R.useContext(to());return t?.warn,o}function O(t){const o=F({warn:t?.router===void 0}),e=t?.router||o,s=R.useRef(void 0);return Os(e.__store,n=>{if(t?.select){if(t.structuralSharing??e.options.defaultStructuralSharing){const r=B(s.current,t.select(n));return s.current=r,r}return t.select(n)}return n})}const Dt=R.createContext(void 0),As=R.createContext(void 0);function V(t){const o=R.useContext(t.from?As:Dt);return O({select:s=>{const n=s.matches.find(r=>t.from?t.from===r.routeId:r.id===o);if(K(!((t.shouldThrow??!0)&&!n),`Could not find ${t.from?`an active match from "${t.from}"`:"a nearest match!"}`),n!==void 0)return t.select?t.select(n):n},structuralSharing:t.structuralSharing})}function ie(t){return V({from:t.from,strict:t.strict,structuralSharing:t.structuralSharing,select:o=>t.select?t.select(o.loaderData):o.loaderData})}function ae(t){const{select:o,...e}=t;return V({...e,select:s=>o?o(s.loaderDeps):s.loaderDeps})}function ce(t){return V({from:t.from,shouldThrow:t.shouldThrow,structuralSharing:t.structuralSharing,strict:t.strict,select:o=>{const e=t.strict===!1?o.params:o._strictParams;return t.select?t.select(e):e}})}function ue(t){return V({from:t.from,strict:t.strict,shouldThrow:t.shouldThrow,structuralSharing:t.structuralSharing,select:o=>t.select?t.select(o.search):o.search})}function le(t){const o=F();return R.useCallback(e=>o.navigate({...e,from:e.from??t?.from}),[t?.from,o])}var eo=po();const fn=Ne(eo),Lt=typeof window<"u"?R.useLayoutEffect:R.useEffect;function qt(t){const o=R.useRef({value:t,prev:null}),e=o.current.value;return t!==e&&(o.current={value:t,prev:e}),o.current.prev}function Bs(t,o,e={},s={}){R.useEffect(()=>{if(!t.current||s.disabled||typeof IntersectionObserver!="function")return;const n=new IntersectionObserver(([r])=>{o(r)},e);return n.observe(t.current),()=>{n.disconnect()}},[o,e,s.disabled,t])}function Ds(t){const o=R.useRef(null);return R.useImperativeHandle(t,()=>o.current,[]),o}function $s(t,o){const e=F(),[s,n]=R.useState(!1),r=R.useRef(!1),i=Ds(o),{activeProps:c,inactiveProps:a,activeOptions:l,to:u,preload:h,preloadDelay:f,hashScrollIntoView:d,replace:p,startTransition:m,resetScroll:y,viewTransition:_,children:x,target:P,disabled:L,style:E,className:w,onClick:S,onFocus:v,onMouseEnter:C,onMouseLeave:M,onTouchStart:T,ignoreBlocker:I,params:Y,search:D,hash:X,state:he,mask:ro,reloadDocument:rn,unsafeRelative:an,from:cn,_fromLocation:un,...fe}=t,io=O({select:b=>b.location.search,structuralSharing:!0}),de=t.from,lt=R.useMemo(()=>({...t,from:de}),[e,io,de,t._fromLocation,t.hash,t.to,t.search,t.params,t.state,t.mask,t.unsafeRelative]),W=R.useMemo(()=>e.buildLocation({...lt}),[e,lt]),vt=R.useMemo(()=>{if(L)return;let b=W.maskedLocation?W.maskedLocation.url:W.url,k=!1;return e.origin&&(b.startsWith(e.origin)?b=e.history.createHref(b.replace(e.origin,""))||"/":k=!0),{href:b,external:k}},[L,W.maskedLocation,W.url,e.origin,e.history]),St=R.useMemo(()=>{if(vt?.external)return vt.href;try{return new URL(u),u}catch{}},[u,vt]),st=t.reloadDocument||St?!1:h??e.options.defaultPreload,$t=f??e.options.defaultPreloadDelay??0,jt=O({select:b=>{if(St)return!1;if(l?.exact){if(!Mo(b.location.pathname,W.pathname,e.basepath))return!1}else{const k=It(b.location.pathname,e.basepath),$=It(W.pathname,e.basepath);if(!(k.startsWith($)&&(k.length===$.length||k[$.length]==="/")))return!1}return(l?.includeSearch??!0)&&!tt(b.location.search,W.search,{partial:!l?.exact,ignoreUndefined:!l?.explicitUndefined})?!1:l?.includeHash?b.location.hash===W.hash:!0}}),Z=R.useCallback(()=>{e.preloadRoute({...lt}).catch(b=>{console.warn(b),console.warn(Ps)})},[e,lt]),ao=R.useCallback(b=>{b?.isIntersecting&&Z()},[Z]);Bs(i,ao,Ws,{disabled:!!L||st!=="viewport"}),R.useEffect(()=>{r.current||!L&&st==="render"&&(Z(),r.current=!0)},[L,Z,st]);const co=b=>{const k=b.currentTarget.getAttribute("target"),$=P!==void 0?P:k;if(!L&&!zs(b)&&!b.defaultPrevented&&(!$||$==="_self")&&b.button===0){b.preventDefault(),eo.flushSync(()=>{n(!0)});const ye=e.subscribe("onResolved",()=>{ye(),n(!1)});e.navigate({...lt,replace:p,resetScroll:y,hashScrollIntoView:d,startTransition:m,viewTransition:_,ignoreBlocker:I})}};if(St)return{...fe,ref:i,href:St,...x&&{children:x},...P&&{target:P},...L&&{disabled:L},...E&&{style:E},...w&&{className:w},...S&&{onClick:S},...v&&{onFocus:v},...C&&{onMouseEnter:C},...M&&{onMouseLeave:M},...T&&{onTouchStart:T}};const pe=b=>{L||st&&Z()},uo=pe,lo=b=>{if(!(L||!st))if(!$t)Z();else{const k=b.target;if(ft.has(k))return;const $=setTimeout(()=>{ft.delete(k),Z()},$t);ft.set(k,$)}},ho=b=>{if(L||!st||!$t)return;const k=b.target,$=ft.get(k);$&&(clearTimeout($),ft.delete(k))},_t=jt?Q(c,{})??js:Jt,Rt=jt?Jt:Q(a,{})??Jt,me=[w,_t.className,Rt.className].filter(Boolean).join(" "),ge=(E||_t.style||Rt.style)&&{...E,..._t.style,...Rt.style};return{...fe,..._t,...Rt,href:vt?.href,ref:i,onClick:dt([S,co]),onFocus:dt([v,pe]),onMouseEnter:dt([C,lo]),onMouseLeave:dt([M,ho]),onTouchStart:dt([T,uo]),disabled:!!L,target:P,...ge&&{style:ge},...me&&{className:me},...L&&Ns,...jt&&Us,...s&&Vs}}const Jt={},js={className:"active"},Ns={role:"link","aria-disabled":!0},Us={"data-status":"active","aria-current":"page"},Vs={"data-transitioning":"transitioning"},ft=new WeakMap,Ws={rootMargin:"100px"},dt=t=>o=>{for(const e of t)if(e){if(o.defaultPrevented)return;e(o)}},oo=R.forwardRef((t,o)=>{const{_asChild:e,...s}=t,{type:n,ref:r,...i}=$s(s,o),c=typeof s.children=="function"?s.children({isActive:i["data-status"]==="active"}):s.children;return e===void 0&&delete i.disabled,R.createElement(e||"a",{...i,ref:r},c)});function zs(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}class Ks extends Qe{constructor(o){super(o),this.useMatch=e=>V({select:e?.select,from:this.id,structuralSharing:e?.structuralSharing}),this.useRouteContext=e=>V({...e,from:this.id,select:s=>e?.select?e.select(s.context):s.context}),this.useSearch=e=>ue({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useParams=e=>ce({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useLoaderDeps=e=>ae({...e,from:this.id}),this.useLoaderData=e=>ie({...e,from:this.id}),this.useNavigate=()=>le({from:this.fullPath}),this.Link=rt.forwardRef((e,s)=>g.jsx(oo,{ref:s,from:this.fullPath,...e})),this.$$typeof=Symbol.for("react.memo")}}function Hs(t){return new Ks(t)}class Gs extends ws{constructor(o){super(o),this.useMatch=e=>V({select:e?.select,from:this.id,structuralSharing:e?.structuralSharing}),this.useRouteContext=e=>V({...e,from:this.id,select:s=>e?.select?e.select(s.context):s.context}),this.useSearch=e=>ue({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useParams=e=>ce({select:e?.select,structuralSharing:e?.structuralSharing,from:this.id}),this.useLoaderDeps=e=>ae({...e,from:this.id}),this.useLoaderData=e=>ie({...e,from:this.id}),this.useNavigate=()=>le({from:this.fullPath}),this.Link=rt.forwardRef((e,s)=>g.jsx(oo,{ref:s,from:this.fullPath,...e})),this.$$typeof=Symbol.for("react.memo")}}function dn(t){return new Gs(t)}function Ae(t){return typeof t=="object"?new Be(t,{silent:!0}).createRoute(t):new Be(t,{silent:!0}).createRoute}class Be{constructor(o,e){this.path=o,this.createRoute=s=>{this.silent;const n=Hs(s);return n.isRoot=!1,n},this.silent=e?.silent}}class De{constructor(o){this.useMatch=e=>V({select:e?.select,from:this.options.id,structuralSharing:e?.structuralSharing}),this.useRouteContext=e=>V({from:this.options.id,select:s=>e?.select?e.select(s.context):s.context}),this.useSearch=e=>ue({select:e?.select,structuralSharing:e?.structuralSharing,from:this.options.id}),this.useParams=e=>ce({select:e?.select,structuralSharing:e?.structuralSharing,from:this.options.id}),this.useLoaderDeps=e=>ae({...e,from:this.options.id}),this.useLoaderData=e=>ie({...e,from:this.options.id}),this.useNavigate=()=>{const e=F();return le({from:e.routesById[this.options.id].fullPath})},this.options=o,this.$$typeof=Symbol.for("react.memo")}}function $e(t){return typeof t=="object"?new De(t):o=>new De({id:t,...o})}function qs(){const t=F(),o=R.useRef({router:t,mounted:!1}),[e,s]=R.useState(!1),{hasPendingMatches:n,isLoading:r}=O({select:h=>({isLoading:h.isLoading,hasPendingMatches:h.matches.some(f=>f.status==="pending")}),structuralSharing:!0}),i=qt(r),c=r||e||n,a=qt(c),l=r||n,u=qt(l);return t.startTransition=h=>{s(!0),R.startTransition(()=>{h(),s(!1)})},R.useEffect(()=>{const h=t.history.subscribe(t.load),f=t.buildLocation({to:t.latestLocation.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0});return J(t.latestLocation.href)!==J(f.href)&&t.commitLocation({...f,replace:!0}),()=>{h()}},[t,t.history]),Lt(()=>{if(typeof window<"u"&&t.ssr||o.current.router===t&&o.current.mounted)return;o.current={router:t,mounted:!0},(async()=>{try{await t.load()}catch(f){console.error(f)}})()},[t]),Lt(()=>{i&&!r&&t.emit({type:"onLoad",...et(t.state)})},[i,t,r]),Lt(()=>{u&&!l&&t.emit({type:"onBeforeRouteMount",...et(t.state)})},[l,u,t]),Lt(()=>{a&&!c&&(t.emit({type:"onResolved",...et(t.state)}),t.__store.setState(h=>({...h,status:"idle",resolvedLocation:h.location})),es(t))},[c,a,t]),null}function Js(t){const o=O({select:e=>`not-found-${e.location.pathname}-${e.status}`});return g.jsx(re,{getResetKey:()=>o,onCatch:(e,s)=>{if(j(e))t.onCatch?.(e,s);else throw e},errorComponent:({error:e})=>{if(j(e))return t.fallback?.(e);throw e},children:t.children})}function Ys(){return g.jsx("p",{children:"Not Found"})}function nt(t){return g.jsx(g.Fragment,{children:t.children})}function so(t,o,e){return o.options.notFoundComponent?g.jsx(o.options.notFoundComponent,{data:e}):t.options.defaultNotFoundComponent?g.jsx(t.options.defaultNotFoundComponent,{data:e}):g.jsx(Ys,{})}function Xs({children:t}){const o=F();return o.isServer?g.jsx("script",{nonce:o.options.ssr?.nonce,className:"$tsr",dangerouslySetInnerHTML:{__html:[t].filter(Boolean).join(` -`)+";$_TSR.c()"}}):null}function Zs(){const t=F();if(!t.isScrollRestoring||!t.isServer||typeof t.options.scrollRestoration=="function"&&!t.options.scrollRestoration({location:t.latestLocation}))return null;const e=(t.options.getScrollRestorationKey||Qt)(t.latestLocation),s=e!==Qt(t.latestLocation)?e:void 0,n={storageKey:kt,shouldScrollRestoration:!0};return s&&(n.key=s),g.jsx(Xs,{children:`(${We.toString()})(${JSON.stringify(n)})`})}const no=R.memo(function({matchId:o}){const e=F(),s=O({select:_=>{const x=_.matches.find(P=>P.id===o);return K(x),{routeId:x.routeId,ssr:x.ssr,_displayPending:x._displayPending}},structuralSharing:!0}),n=e.routesById[s.routeId],r=n.options.pendingComponent??e.options.defaultPendingComponent,i=r?g.jsx(r,{}):null,c=n.options.errorComponent??e.options.defaultErrorComponent,a=n.options.onCatch??e.options.defaultOnCatch,l=n.isRoot?n.options.notFoundComponent??e.options.notFoundRoute?.options.component:n.options.notFoundComponent,u=s.ssr===!1||s.ssr==="data-only",h=(!n.isRoot||n.options.wrapInSuspense||u)&&(n.options.wrapInSuspense??r??(n.options.errorComponent?.preload||u))?R.Suspense:nt,f=c?re:nt,d=l?Js:nt,p=O({select:_=>_.loadedAt}),m=O({select:_=>{const x=_.matches.findIndex(P=>P.id===o);return _.matches[x-1]?.routeId}}),y=n.isRoot?n.options.shellComponent??nt:nt;return g.jsxs(y,{children:[g.jsx(Dt.Provider,{value:o,children:g.jsx(h,{fallback:i,children:g.jsx(f,{getResetKey:()=>p,errorComponent:c||Bt,onCatch:(_,x)=>{if(j(_))throw _;a?.(_,x)},children:g.jsx(d,{fallback:_=>{if(!l||_.routeId&&_.routeId!==s.routeId||!_.routeId&&!n.isRoot)throw _;return R.createElement(l,_)},children:u||s._displayPending?g.jsx(Ls,{fallback:i,children:g.jsx(je,{matchId:o})}):g.jsx(je,{matchId:o})})})})}),m===A&&e.options.scrollRestoration?g.jsxs(g.Fragment,{children:[g.jsx(Qs,{}),g.jsx(Zs,{})]}):null]})});function Qs(){const t=F(),o=R.useRef(void 0);return g.jsx("script",{suppressHydrationWarning:!0,ref:e=>{e&&(o.current===void 0||o.current.href!==t.latestLocation.href)&&(t.emit({type:"onRendered",...et(t.state)}),o.current=t.latestLocation)}},t.latestLocation.state.__TSR_key)}const je=R.memo(function({matchId:o}){const e=F(),{match:s,key:n,routeId:r}=O({select:a=>{const l=a.matches.find(p=>p.id===o),u=l.routeId,f=(e.routesById[u].options.remountDeps??e.options.defaultRemountDeps)?.({routeId:u,loaderDeps:l.loaderDeps,params:l._strictParams,search:l._strictSearch});return{key:f?JSON.stringify(f):void 0,routeId:u,match:{id:l.id,status:l.status,error:l.error,_forcePending:l._forcePending,_displayPending:l._displayPending}}},structuralSharing:!0}),i=e.routesById[r],c=R.useMemo(()=>{const a=i.options.component??e.options.defaultComponent;return a?g.jsx(a,{},n):g.jsx(tn,{})},[n,i.options.component,e.options.defaultComponent]);if(s._displayPending)throw e.getMatch(s.id)?._nonReactive.displayPendingPromise;if(s._forcePending)throw e.getMatch(s.id)?._nonReactive.minPendingPromise;if(s.status==="pending"){const a=i.options.pendingMinMs??e.options.defaultPendingMinMs;if(a){const l=e.getMatch(s.id);if(l&&!l._nonReactive.minPendingPromise&&!e.isServer){const u=it();l._nonReactive.minPendingPromise=u,setTimeout(()=>{u.resolve(),l._nonReactive.minPendingPromise=void 0},a)}}throw e.getMatch(s.id)?._nonReactive.loadPromise}if(s.status==="notFound")return K(j(s.error)),so(e,i,s.error);if(s.status==="redirected")throw K(N(s.error)),e.getMatch(s.id)?._nonReactive.loadPromise;if(s.status==="error"){if(e.isServer){const a=(i.options.errorComponent??e.options.defaultErrorComponent)||Bt;return g.jsx(a,{error:s.error,reset:void 0,info:{componentStack:""}})}throw s.error}return c}),tn=R.memo(function(){const o=F(),e=R.useContext(Dt),s=O({select:l=>l.matches.find(u=>u.id===e)?.routeId}),n=o.routesById[s],r=O({select:l=>{const h=l.matches.find(f=>f.id===e);return K(h),h.globalNotFound}}),i=O({select:l=>{const u=l.matches,h=u.findIndex(f=>f.id===e);return u[h+1]?.id}}),c=o.options.defaultPendingComponent?g.jsx(o.options.defaultPendingComponent,{}):null;if(r)return so(o,n,void 0);if(!i)return null;const a=g.jsx(no,{matchId:i});return s===A?g.jsx(R.Suspense,{fallback:c,children:a}):a});function en(){const t=F(),e=t.routesById[A].options.pendingComponent??t.options.defaultPendingComponent,s=e?g.jsx(e,{}):null,n=t.isServer||typeof document<"u"&&t.ssr?nt:R.Suspense,r=g.jsxs(n,{fallback:s,children:[!t.isServer&&g.jsx(qs,{}),g.jsx(on,{})]});return t.options.InnerWrap?g.jsx(t.options.InnerWrap,{children:r}):r}function on(){const t=F(),o=O({select:n=>n.matches[0]?.id}),e=O({select:n=>n.loadedAt}),s=o?g.jsx(no,{matchId:o}):null;return g.jsx(Dt.Provider,{value:o,children:t.options.disableGlobalCatchBoundary?s:g.jsx(re,{getResetKey:()=>e,errorComponent:Bt,onCatch:n=>{n.message||n.toString()},children:s})})}function pn(){const t=F();return O({select:o=>[o.location.href,o.resolvedLocation?.href,o.status],structuralSharing:!0}),R.useCallback(o=>{const{pending:e,caseSensitive:s,fuzzy:n,includeSearch:r,...i}=o;return t.matchRoute(i,{pending:e,caseSensitive:s,fuzzy:n,includeSearch:r})},[t])}const mn=t=>new sn(t);class sn extends ys{constructor(o){super(o)}}typeof globalThis<"u"?(globalThis.createFileRoute=Ae,globalThis.createLazyFileRoute=$e):typeof window<"u"&&(window.createFileRoute=Ae,window.createLazyFileRoute=$e);function nn({router:t,children:o,...e}){Object.keys(e).length>0&&t.update({...t.options,...e,context:{...t.options.context,...e.context}});const s=to(),n=g.jsx(s.Provider,{value:t,children:o});return t.options.Wrap?g.jsx(t.options.Wrap,{children:n}):n}function gn({router:t,...o}){return g.jsx(nn,{router:t,...o,children:g.jsx(en,{})})}export{oo as L,tn as O,rt as R,hn as a,eo as b,fn as c,pn as d,dn as e,Hs as f,mn as g,cs as h,K as i,g as j,gn as k,R as r,le as u}; diff --git a/webui/dist/assets/ui-vendor-nTGLnMlb.js b/webui/dist/assets/ui-vendor-nTGLnMlb.js deleted file mode 100644 index 0fcce437..00000000 --- a/webui/dist/assets/ui-vendor-nTGLnMlb.js +++ /dev/null @@ -1,45 +0,0 @@ -import{r as a,j as x,R as we,a as Vt,b as at,c as yr}from"./router-BWgTyY51.js";function k(e,t,{checkForDefaultPrevented:n=!0}={}){return function(r){if(e?.(r),n===!1||!r.defaultPrevented)return t?.(r)}}function wr(e,t){const n=a.createContext(t),o=i=>{const{children:c,...s}=i,l=a.useMemo(()=>s,Object.values(s));return x.jsx(n.Provider,{value:l,children:c})};o.displayName=e+"Provider";function r(i){const c=a.useContext(n);if(c)return c;if(t!==void 0)return t;throw new Error(`\`${i}\` must be used within \`${e}\``)}return[o,r]}function Ve(e,t=[]){let n=[];function o(i,c){const s=a.createContext(c),l=n.length;n=[...n,c];const u=p=>{const{scope:h,children:m,...w}=p,f=h?.[e]?.[l]||s,g=a.useMemo(()=>w,Object.values(w));return x.jsx(f.Provider,{value:g,children:m})};u.displayName=i+"Provider";function d(p,h){const m=h?.[e]?.[l]||s,w=a.useContext(m);if(w)return w;if(c!==void 0)return c;throw new Error(`\`${p}\` must be used within \`${i}\``)}return[u,d]}const r=()=>{const i=n.map(c=>a.createContext(c));return function(s){const l=s?.[e]||i;return a.useMemo(()=>({[`__scope${e}`]:{...s,[e]:l}}),[s,l])}};return r.scopeName=e,[o,xr(r,...t)]}function xr(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const o=e.map(r=>({useScope:r(),scopeName:r.scopeName}));return function(i){const c=o.reduce((s,{useScope:l,scopeName:u})=>{const p=l(i)[`__scope${u}`];return{...s,...p}},{});return a.useMemo(()=>({[`__scope${t.scopeName}`]:c}),[c])}};return n.scopeName=t.scopeName,n}function sn(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function _e(...e){return t=>{let n=!1;const o=e.map(r=>{const i=sn(r,t);return!n&&typeof i=="function"&&(n=!0),i});if(n)return()=>{for(let r=0;r{const{children:i,...c}=o,s=a.Children.toArray(i),l=s.find(Cr);if(l){const u=l.props.children,d=s.map(p=>p===l?a.Children.count(u)>1?a.Children.only(null):a.isValidElement(u)?u.props.children:null:p);return x.jsx(t,{...c,ref:r,children:a.isValidElement(u)?a.cloneElement(u,void 0,d):null})}return x.jsx(t,{...c,ref:r,children:i})});return n.displayName=`${e}.Slot`,n}function Sr(e){const t=a.forwardRef((n,o)=>{const{children:r,...i}=n;if(a.isValidElement(r)){const c=Rr(r),s=Er(i,r.props);return r.type!==a.Fragment&&(s.ref=o?_e(o,c):c),a.cloneElement(r,s)}return a.Children.count(r)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var br=Symbol("radix.slottable");function Cr(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===br}function Er(e,t){const n={...t};for(const o in t){const r=e[o],i=t[o];/^on[A-Z]/.test(o)?r&&i?n[o]=(...s)=>{const l=i(...s);return r(...s),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...i}:o==="className"&&(n[o]=[r,i].filter(Boolean).join(" "))}return{...e,...n}}function Rr(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function Pr(e){const t=e+"CollectionProvider",[n,o]=Ve(t),[r,i]=n(t,{collectionRef:{current:null},itemMap:new Map}),c=f=>{const{scope:g,children:y}=f,v=we.useRef(null),S=we.useRef(new Map).current;return x.jsx(r,{scope:g,itemMap:S,collectionRef:v,children:y})};c.displayName=t;const s=e+"CollectionSlot",l=cn(s),u=we.forwardRef((f,g)=>{const{scope:y,children:v}=f,S=i(s,y),b=H(g,S.collectionRef);return x.jsx(l,{ref:b,children:v})});u.displayName=s;const d=e+"CollectionItemSlot",p="data-radix-collection-item",h=cn(d),m=we.forwardRef((f,g)=>{const{scope:y,children:v,...S}=f,b=we.useRef(null),C=H(g,b),R=i(d,y);return we.useEffect(()=>(R.itemMap.set(b,{ref:b,...S}),()=>void R.itemMap.delete(b))),x.jsx(h,{[p]:"",ref:C,children:v})});m.displayName=d;function w(f){const g=i(e+"CollectionConsumer",f);return we.useCallback(()=>{const v=g.collectionRef.current;if(!v)return[];const S=Array.from(v.querySelectorAll(`[${p}]`));return Array.from(g.itemMap.values()).sort((R,E)=>S.indexOf(R.ref.current)-S.indexOf(E.ref.current))},[g.collectionRef,g.itemMap])}return[{Provider:c,Slot:u,ItemSlot:m},w,o]}var K=globalThis?.document?a.useLayoutEffect:()=>{},Ar=Vt[" useId ".trim().toString()]||(()=>{}),Or=0;function Te(e){const[t,n]=a.useState(Ar());return K(()=>{n(o=>o??String(Or++))},[e]),t?`radix-${t}`:""}function Tr(e){const t=Nr(e),n=a.forwardRef((o,r)=>{const{children:i,...c}=o,s=a.Children.toArray(i),l=s.find(Dr);if(l){const u=l.props.children,d=s.map(p=>p===l?a.Children.count(u)>1?a.Children.only(null):a.isValidElement(u)?u.props.children:null:p);return x.jsx(t,{...c,ref:r,children:a.isValidElement(u)?a.cloneElement(u,void 0,d):null})}return x.jsx(t,{...c,ref:r,children:i})});return n.displayName=`${e}.Slot`,n}function Nr(e){const t=a.forwardRef((n,o)=>{const{children:r,...i}=n;if(a.isValidElement(r)){const c=Mr(r),s=_r(i,r.props);return r.type!==a.Fragment&&(s.ref=o?_e(o,c):c),a.cloneElement(r,s)}return a.Children.count(r)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var Ir=Symbol("radix.slottable");function Dr(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Ir}function _r(e,t){const n={...t};for(const o in t){const r=e[o],i=t[o];/^on[A-Z]/.test(o)?r&&i?n[o]=(...s)=>{const l=i(...s);return r(...s),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...i}:o==="className"&&(n[o]=[r,i].filter(Boolean).join(" "))}return{...e,...n}}function Mr(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Lr=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],M=Lr.reduce((e,t)=>{const n=Tr(`Primitive.${t}`),o=a.forwardRef((r,i)=>{const{asChild:c,...s}=r,l=c?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),x.jsx(l,{...s,ref:i})});return o.displayName=`Primitive.${t}`,{...e,[t]:o}},{});function kr(e,t){e&&at.flushSync(()=>e.dispatchEvent(t))}function xe(e){const t=a.useRef(e);return a.useEffect(()=>{t.current=e}),a.useMemo(()=>(...n)=>t.current?.(...n),[])}var jr=Vt[" useInsertionEffect ".trim().toString()]||K;function et({prop:e,defaultProp:t,onChange:n=()=>{},caller:o}){const[r,i,c]=Fr({defaultProp:t,onChange:n}),s=e!==void 0,l=s?e:r;{const d=a.useRef(e!==void 0);a.useEffect(()=>{const p=d.current;p!==s&&console.warn(`${o} is changing from ${p?"controlled":"uncontrolled"} to ${s?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),d.current=s},[s,o])}const u=a.useCallback(d=>{if(s){const p=Wr(d)?d(e):d;p!==e&&c.current?.(p)}else i(d)},[s,e,i,c]);return[l,u]}function Fr({defaultProp:e,onChange:t}){const[n,o]=a.useState(e),r=a.useRef(n),i=a.useRef(t);return jr(()=>{i.current=t},[t]),a.useEffect(()=>{r.current!==n&&(i.current?.(n),r.current=n)},[n,r]),[n,o,i]}function Wr(e){return typeof e=="function"}var $r=a.createContext(void 0);function Br(e){const t=a.useContext($r);return e||t||"ltr"}function Vr(e,t){return a.useReducer((n,o)=>t[n][o]??n,e)}var He=e=>{const{present:t,children:n}=e,o=Hr(t),r=typeof n=="function"?n({present:o.isPresent}):a.Children.only(n),i=H(o.ref,Ur(r));return typeof n=="function"||o.isPresent?a.cloneElement(r,{ref:i}):null};He.displayName="Presence";function Hr(e){const[t,n]=a.useState(),o=a.useRef(null),r=a.useRef(e),i=a.useRef("none"),c=e?"mounted":"unmounted",[s,l]=Vr(c,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return a.useEffect(()=>{const u=ze(o.current);i.current=s==="mounted"?u:"none"},[s]),K(()=>{const u=o.current,d=r.current;if(d!==e){const h=i.current,m=ze(u);e?l("MOUNT"):m==="none"||u?.display==="none"?l("UNMOUNT"):l(d&&h!==m?"ANIMATION_OUT":"UNMOUNT"),r.current=e}},[e,l]),K(()=>{if(t){let u;const d=t.ownerDocument.defaultView??window,p=m=>{const f=ze(o.current).includes(CSS.escape(m.animationName));if(m.target===t&&f&&(l("ANIMATION_END"),!r.current)){const g=t.style.animationFillMode;t.style.animationFillMode="forwards",u=d.setTimeout(()=>{t.style.animationFillMode==="forwards"&&(t.style.animationFillMode=g)})}},h=m=>{m.target===t&&(i.current=ze(o.current))};return t.addEventListener("animationstart",h),t.addEventListener("animationcancel",p),t.addEventListener("animationend",p),()=>{d.clearTimeout(u),t.removeEventListener("animationstart",h),t.removeEventListener("animationcancel",p),t.removeEventListener("animationend",p)}}else l("ANIMATION_END")},[t,l]),{isPresent:["mounted","unmountSuspended"].includes(s),ref:a.useCallback(u=>{o.current=u?getComputedStyle(u):null,n(u)},[])}}function ze(e){return e?.animationName||"none"}function Ur(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function an(e,[t,n]){return Math.min(n,Math.max(t,e))}var zr=Symbol.for("react.lazy"),tt=Vt[" use ".trim().toString()];function Kr(e){return typeof e=="object"&&e!==null&&"then"in e}function Dn(e){return e!=null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===zr&&"_payload"in e&&Kr(e._payload)}function _n(e){const t=Yr(e),n=a.forwardRef((o,r)=>{let{children:i,...c}=o;Dn(i)&&typeof tt=="function"&&(i=tt(i._payload));const s=a.Children.toArray(i),l=s.find(Gr);if(l){const u=l.props.children,d=s.map(p=>p===l?a.Children.count(u)>1?a.Children.only(null):a.isValidElement(u)?u.props.children:null:p);return x.jsx(t,{...c,ref:r,children:a.isValidElement(u)?a.cloneElement(u,void 0,d):null})}return x.jsx(t,{...c,ref:r,children:i})});return n.displayName=`${e}.Slot`,n}var wa=_n("Slot");function Yr(e){const t=a.forwardRef((n,o)=>{let{children:r,...i}=n;if(Dn(r)&&typeof tt=="function"&&(r=tt(r._payload)),a.isValidElement(r)){const c=Zr(r),s=qr(i,r.props);return r.type!==a.Fragment&&(s.ref=o?_e(o,c):c),a.cloneElement(r,s)}return a.Children.count(r)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var Xr=Symbol("radix.slottable");function Gr(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Xr}function qr(e,t){const n={...t};for(const o in t){const r=e[o],i=t[o];/^on[A-Z]/.test(o)?r&&i?n[o]=(...s)=>{const l=i(...s);return r(...s),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...i}:o==="className"&&(n[o]=[r,i].filter(Boolean).join(" "))}return{...e,...n}}function Zr(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function Mn(e){const t=a.useRef({value:e,previous:e});return a.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}function Ln(e){const[t,n]=a.useState(void 0);return K(()=>{if(e){n({width:e.offsetWidth,height:e.offsetHeight});const o=new ResizeObserver(r=>{if(!Array.isArray(r)||!r.length)return;const i=r[0];let c,s;if("borderBoxSize"in i){const l=i.borderBoxSize,u=Array.isArray(l)?l[0]:l;c=u.inlineSize,s=u.blockSize}else c=e.offsetWidth,s=e.offsetHeight;n({width:c,height:s})});return o.observe(e,{box:"border-box"}),()=>o.unobserve(e)}else n(void 0)},[e]),t}var Qr=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Jr=Qr.reduce((e,t)=>{const n=_n(`Primitive.${t}`),o=a.forwardRef((r,i)=>{const{asChild:c,...s}=r,l=c?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),x.jsx(l,{...s,ref:i})});return o.displayName=`Primitive.${t}`,{...e,[t]:o}},{}),ei="Label",kn=a.forwardRef((e,t)=>x.jsx(Jr.label,{...e,ref:t,onMouseDown:n=>{n.target.closest("button, input, select, textarea")||(e.onMouseDown?.(n),!n.defaultPrevented&&n.detail>1&&n.preventDefault())}}));kn.displayName=ei;var xa=kn;function ti(e,t=globalThis?.document){const n=xe(e);a.useEffect(()=>{const o=r=>{r.key==="Escape"&&n(r)};return t.addEventListener("keydown",o,{capture:!0}),()=>t.removeEventListener("keydown",o,{capture:!0})},[n,t])}var ni="DismissableLayer",Dt="dismissableLayer.update",oi="dismissableLayer.pointerDownOutside",ri="dismissableLayer.focusOutside",ln,jn=a.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),lt=a.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:o,onPointerDownOutside:r,onFocusOutside:i,onInteractOutside:c,onDismiss:s,...l}=e,u=a.useContext(jn),[d,p]=a.useState(null),h=d?.ownerDocument??globalThis?.document,[,m]=a.useState({}),w=H(t,E=>p(E)),f=Array.from(u.layers),[g]=[...u.layersWithOutsidePointerEventsDisabled].slice(-1),y=f.indexOf(g),v=d?f.indexOf(d):-1,S=u.layersWithOutsidePointerEventsDisabled.size>0,b=v>=y,C=si(E=>{const O=E.target,_=[...u.branches].some(I=>I.contains(O));!b||_||(r?.(E),c?.(E),E.defaultPrevented||s?.())},h),R=ci(E=>{const O=E.target;[...u.branches].some(I=>I.contains(O))||(i?.(E),c?.(E),E.defaultPrevented||s?.())},h);return ti(E=>{v===u.layers.size-1&&(o?.(E),!E.defaultPrevented&&s&&(E.preventDefault(),s()))},h),a.useEffect(()=>{if(d)return n&&(u.layersWithOutsidePointerEventsDisabled.size===0&&(ln=h.body.style.pointerEvents,h.body.style.pointerEvents="none"),u.layersWithOutsidePointerEventsDisabled.add(d)),u.layers.add(d),un(),()=>{n&&u.layersWithOutsidePointerEventsDisabled.size===1&&(h.body.style.pointerEvents=ln)}},[d,h,n,u]),a.useEffect(()=>()=>{d&&(u.layers.delete(d),u.layersWithOutsidePointerEventsDisabled.delete(d),un())},[d,u]),a.useEffect(()=>{const E=()=>m({});return document.addEventListener(Dt,E),()=>document.removeEventListener(Dt,E)},[]),x.jsx(M.div,{...l,ref:w,style:{pointerEvents:S?b?"auto":"none":void 0,...e.style},onFocusCapture:k(e.onFocusCapture,R.onFocusCapture),onBlurCapture:k(e.onBlurCapture,R.onBlurCapture),onPointerDownCapture:k(e.onPointerDownCapture,C.onPointerDownCapture)})});lt.displayName=ni;var ii="DismissableLayerBranch",Fn=a.forwardRef((e,t)=>{const n=a.useContext(jn),o=a.useRef(null),r=H(t,o);return a.useEffect(()=>{const i=o.current;if(i)return n.branches.add(i),()=>{n.branches.delete(i)}},[n.branches]),x.jsx(M.div,{...e,ref:r})});Fn.displayName=ii;function si(e,t=globalThis?.document){const n=xe(e),o=a.useRef(!1),r=a.useRef(()=>{});return a.useEffect(()=>{const i=s=>{if(s.target&&!o.current){let l=function(){Wn(oi,n,u,{discrete:!0})};const u={originalEvent:s};s.pointerType==="touch"?(t.removeEventListener("click",r.current),r.current=l,t.addEventListener("click",r.current,{once:!0})):l()}else t.removeEventListener("click",r.current);o.current=!1},c=window.setTimeout(()=>{t.addEventListener("pointerdown",i)},0);return()=>{window.clearTimeout(c),t.removeEventListener("pointerdown",i),t.removeEventListener("click",r.current)}},[t,n]),{onPointerDownCapture:()=>o.current=!0}}function ci(e,t=globalThis?.document){const n=xe(e),o=a.useRef(!1);return a.useEffect(()=>{const r=i=>{i.target&&!o.current&&Wn(ri,n,{originalEvent:i},{discrete:!1})};return t.addEventListener("focusin",r),()=>t.removeEventListener("focusin",r)},[t,n]),{onFocusCapture:()=>o.current=!0,onBlurCapture:()=>o.current=!1}}function un(){const e=new CustomEvent(Dt);document.dispatchEvent(e)}function Wn(e,t,n,{discrete:o}){const r=n.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&r.addEventListener(e,t,{once:!0}),o?kr(r,i):r.dispatchEvent(i)}var Sa=lt,ba=Fn,Ct="focusScope.autoFocusOnMount",Et="focusScope.autoFocusOnUnmount",fn={bubbles:!1,cancelable:!0},ai="FocusScope",Ht=a.forwardRef((e,t)=>{const{loop:n=!1,trapped:o=!1,onMountAutoFocus:r,onUnmountAutoFocus:i,...c}=e,[s,l]=a.useState(null),u=xe(r),d=xe(i),p=a.useRef(null),h=H(t,f=>l(f)),m=a.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;a.useEffect(()=>{if(o){let f=function(S){if(m.paused||!s)return;const b=S.target;s.contains(b)?p.current=b:ue(p.current,{select:!0})},g=function(S){if(m.paused||!s)return;const b=S.relatedTarget;b!==null&&(s.contains(b)||ue(p.current,{select:!0}))},y=function(S){if(document.activeElement===document.body)for(const C of S)C.removedNodes.length>0&&ue(s)};document.addEventListener("focusin",f),document.addEventListener("focusout",g);const v=new MutationObserver(y);return s&&v.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",f),document.removeEventListener("focusout",g),v.disconnect()}}},[o,s,m.paused]),a.useEffect(()=>{if(s){pn.add(m);const f=document.activeElement;if(!s.contains(f)){const y=new CustomEvent(Ct,fn);s.addEventListener(Ct,u),s.dispatchEvent(y),y.defaultPrevented||(li(mi($n(s)),{select:!0}),document.activeElement===f&&ue(s))}return()=>{s.removeEventListener(Ct,u),setTimeout(()=>{const y=new CustomEvent(Et,fn);s.addEventListener(Et,d),s.dispatchEvent(y),y.defaultPrevented||ue(f??document.body,{select:!0}),s.removeEventListener(Et,d),pn.remove(m)},0)}}},[s,u,d,m]);const w=a.useCallback(f=>{if(!n&&!o||m.paused)return;const g=f.key==="Tab"&&!f.altKey&&!f.ctrlKey&&!f.metaKey,y=document.activeElement;if(g&&y){const v=f.currentTarget,[S,b]=ui(v);S&&b?!f.shiftKey&&y===b?(f.preventDefault(),n&&ue(S,{select:!0})):f.shiftKey&&y===S&&(f.preventDefault(),n&&ue(b,{select:!0})):y===v&&f.preventDefault()}},[n,o,m.paused]);return x.jsx(M.div,{tabIndex:-1,...c,ref:h,onKeyDown:w})});Ht.displayName=ai;function li(e,{select:t=!1}={}){const n=document.activeElement;for(const o of e)if(ue(o,{select:t}),document.activeElement!==n)return}function ui(e){const t=$n(e),n=dn(t,e),o=dn(t.reverse(),e);return[n,o]}function $n(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:o=>{const r=o.tagName==="INPUT"&&o.type==="hidden";return o.disabled||o.hidden||r?NodeFilter.FILTER_SKIP:o.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function dn(e,t){for(const n of e)if(!fi(n,{upTo:t}))return n}function fi(e,{upTo:t}){if(getComputedStyle(e).visibility==="hidden")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display==="none")return!0;e=e.parentElement}return!1}function di(e){return e instanceof HTMLInputElement&&"select"in e}function ue(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&di(e)&&t&&e.select()}}var pn=pi();function pi(){let e=[];return{add(t){const n=e[0];t!==n&&n?.pause(),e=mn(e,t),e.unshift(t)},remove(t){e=mn(e,t),e[0]?.resume()}}}function mn(e,t){const n=[...e],o=n.indexOf(t);return o!==-1&&n.splice(o,1),n}function mi(e){return e.filter(t=>t.tagName!=="A")}var hi="Portal",Ut=a.forwardRef((e,t)=>{const{container:n,...o}=e,[r,i]=a.useState(!1);K(()=>i(!0),[]);const c=n||r&&globalThis?.document?.body;return c?yr.createPortal(x.jsx(M.div,{...o,ref:t}),c):null});Ut.displayName=hi;var Rt=0;function Bn(){a.useEffect(()=>{const e=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",e[0]??hn()),document.body.insertAdjacentElement("beforeend",e[1]??hn()),Rt++,()=>{Rt===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(t=>t.remove()),Rt--}},[])}function hn(){const e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}var ne=function(){return ne=Object.assign||function(t){for(var n,o=1,r=arguments.length;o"u")return Di;var t=_i(e),n=document.documentElement.clientWidth,o=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,o-n+t[2]-t[0])}},Li=zn(),Ne="data-scroll-locked",ki=function(e,t,n,o){var r=e.left,i=e.top,c=e.right,s=e.gap;return n===void 0&&(n="margin"),` - .`.concat(vi,` { - overflow: hidden `).concat(o,`; - padding-right: `).concat(s,"px ").concat(o,`; - } - body[`).concat(Ne,`] { - overflow: hidden `).concat(o,`; - overscroll-behavior: contain; - `).concat([t&&"position: relative ".concat(o,";"),n==="margin"&&` - padding-left: `.concat(r,`px; - padding-top: `).concat(i,`px; - padding-right: `).concat(c,`px; - margin-left:0; - margin-top:0; - margin-right: `).concat(s,"px ").concat(o,`; - `),n==="padding"&&"padding-right: ".concat(s,"px ").concat(o,";")].filter(Boolean).join(""),` - } - - .`).concat(Ze,` { - right: `).concat(s,"px ").concat(o,`; - } - - .`).concat(Qe,` { - margin-right: `).concat(s,"px ").concat(o,`; - } - - .`).concat(Ze," .").concat(Ze,` { - right: 0 `).concat(o,`; - } - - .`).concat(Qe," .").concat(Qe,` { - margin-right: 0 `).concat(o,`; - } - - body[`).concat(Ne,`] { - `).concat(yi,": ").concat(s,`px; - } -`)},vn=function(){var e=parseInt(document.body.getAttribute(Ne)||"0",10);return isFinite(e)?e:0},ji=function(){a.useEffect(function(){return document.body.setAttribute(Ne,(vn()+1).toString()),function(){var e=vn()-1;e<=0?document.body.removeAttribute(Ne):document.body.setAttribute(Ne,e.toString())}},[])},Fi=function(e){var t=e.noRelative,n=e.noImportant,o=e.gapMode,r=o===void 0?"margin":o;ji();var i=a.useMemo(function(){return Mi(r)},[r]);return a.createElement(Li,{styles:ki(i,!t,r,n?"":"!important")})},_t=!1;if(typeof window<"u")try{var Ke=Object.defineProperty({},"passive",{get:function(){return _t=!0,!0}});window.addEventListener("test",Ke,Ke),window.removeEventListener("test",Ke,Ke)}catch{_t=!1}var Pe=_t?{passive:!1}:!1,Wi=function(e){return e.tagName==="TEXTAREA"},Kn=function(e,t){if(!(e instanceof Element))return!1;var n=window.getComputedStyle(e);return n[t]!=="hidden"&&!(n.overflowY===n.overflowX&&!Wi(e)&&n[t]==="visible")},$i=function(e){return Kn(e,"overflowY")},Bi=function(e){return Kn(e,"overflowX")},yn=function(e,t){var n=t.ownerDocument,o=t;do{typeof ShadowRoot<"u"&&o instanceof ShadowRoot&&(o=o.host);var r=Yn(e,o);if(r){var i=Xn(e,o),c=i[1],s=i[2];if(c>s)return!0}o=o.parentNode}while(o&&o!==n.body);return!1},Vi=function(e){var t=e.scrollTop,n=e.scrollHeight,o=e.clientHeight;return[t,n,o]},Hi=function(e){var t=e.scrollLeft,n=e.scrollWidth,o=e.clientWidth;return[t,n,o]},Yn=function(e,t){return e==="v"?$i(t):Bi(t)},Xn=function(e,t){return e==="v"?Vi(t):Hi(t)},Ui=function(e,t){return e==="h"&&t==="rtl"?-1:1},zi=function(e,t,n,o,r){var i=Ui(e,window.getComputedStyle(t).direction),c=i*o,s=n.target,l=t.contains(s),u=!1,d=c>0,p=0,h=0;do{if(!s)break;var m=Xn(e,s),w=m[0],f=m[1],g=m[2],y=f-g-i*w;(w||y)&&Yn(e,s)&&(p+=y,h+=w);var v=s.parentNode;s=v&&v.nodeType===Node.DOCUMENT_FRAGMENT_NODE?v.host:v}while(!l&&s!==document.body||l&&(t.contains(s)||t===s));return(d&&Math.abs(p)<1||!d&&Math.abs(h)<1)&&(u=!0),u},Ye=function(e){return"changedTouches"in e?[e.changedTouches[0].clientX,e.changedTouches[0].clientY]:[0,0]},wn=function(e){return[e.deltaX,e.deltaY]},xn=function(e){return e&&"current"in e?e.current:e},Ki=function(e,t){return e[0]===t[0]&&e[1]===t[1]},Yi=function(e){return` - .block-interactivity-`.concat(e,` {pointer-events: none;} - .allow-interactivity-`).concat(e,` {pointer-events: all;} -`)},Xi=0,Ae=[];function Gi(e){var t=a.useRef([]),n=a.useRef([0,0]),o=a.useRef(),r=a.useState(Xi++)[0],i=a.useState(zn)[0],c=a.useRef(e);a.useEffect(function(){c.current=e},[e]),a.useEffect(function(){if(e.inert){document.body.classList.add("block-interactivity-".concat(r));var f=gi([e.lockRef.current],(e.shards||[]).map(xn),!0).filter(Boolean);return f.forEach(function(g){return g.classList.add("allow-interactivity-".concat(r))}),function(){document.body.classList.remove("block-interactivity-".concat(r)),f.forEach(function(g){return g.classList.remove("allow-interactivity-".concat(r))})}}},[e.inert,e.lockRef.current,e.shards]);var s=a.useCallback(function(f,g){if("touches"in f&&f.touches.length===2||f.type==="wheel"&&f.ctrlKey)return!c.current.allowPinchZoom;var y=Ye(f),v=n.current,S="deltaX"in f?f.deltaX:v[0]-y[0],b="deltaY"in f?f.deltaY:v[1]-y[1],C,R=f.target,E=Math.abs(S)>Math.abs(b)?"h":"v";if("touches"in f&&E==="h"&&R.type==="range")return!1;var O=yn(E,R);if(!O)return!0;if(O?C=E:(C=E==="v"?"h":"v",O=yn(E,R)),!O)return!1;if(!o.current&&"changedTouches"in f&&(S||b)&&(o.current=C),!C)return!0;var _=o.current||C;return zi(_,g,f,_==="h"?S:b)},[]),l=a.useCallback(function(f){var g=f;if(!(!Ae.length||Ae[Ae.length-1]!==i)){var y="deltaY"in g?wn(g):Ye(g),v=t.current.filter(function(C){return C.name===g.type&&(C.target===g.target||g.target===C.shadowParent)&&Ki(C.delta,y)})[0];if(v&&v.should){g.cancelable&&g.preventDefault();return}if(!v){var S=(c.current.shards||[]).map(xn).filter(Boolean).filter(function(C){return C.contains(g.target)}),b=S.length>0?s(g,S[0]):!c.current.noIsolation;b&&g.cancelable&&g.preventDefault()}}},[]),u=a.useCallback(function(f,g,y,v){var S={name:f,delta:g,target:y,should:v,shadowParent:qi(y)};t.current.push(S),setTimeout(function(){t.current=t.current.filter(function(b){return b!==S})},1)},[]),d=a.useCallback(function(f){n.current=Ye(f),o.current=void 0},[]),p=a.useCallback(function(f){u(f.type,wn(f),f.target,s(f,e.lockRef.current))},[]),h=a.useCallback(function(f){u(f.type,Ye(f),f.target,s(f,e.lockRef.current))},[]);a.useEffect(function(){return Ae.push(i),e.setCallbacks({onScrollCapture:p,onWheelCapture:p,onTouchMoveCapture:h}),document.addEventListener("wheel",l,Pe),document.addEventListener("touchmove",l,Pe),document.addEventListener("touchstart",d,Pe),function(){Ae=Ae.filter(function(f){return f!==i}),document.removeEventListener("wheel",l,Pe),document.removeEventListener("touchmove",l,Pe),document.removeEventListener("touchstart",d,Pe)}},[]);var m=e.removeScrollBar,w=e.inert;return a.createElement(a.Fragment,null,w?a.createElement(i,{styles:Yi(r)}):null,m?a.createElement(Fi,{noRelative:e.noRelative,gapMode:e.gapMode}):null)}function qi(e){for(var t=null;e!==null;)e instanceof ShadowRoot&&(t=e.host,e=e.host),e=e.parentNode;return t}const Zi=Ri(Un,Gi);var zt=a.forwardRef(function(e,t){return a.createElement(ut,ne({},e,{ref:t,sideCar:Zi}))});zt.classNames=ut.classNames;var Qi=function(e){if(typeof document>"u")return null;var t=Array.isArray(e)?e[0]:e;return t.ownerDocument.body},Oe=new WeakMap,Xe=new WeakMap,Ge={},Tt=0,Gn=function(e){return e&&(e.host||Gn(e.parentNode))},Ji=function(e,t){return t.map(function(n){if(e.contains(n))return n;var o=Gn(n);return o&&e.contains(o)?o:(console.error("aria-hidden",n,"in not contained inside",e,". Doing nothing"),null)}).filter(function(n){return!!n})},es=function(e,t,n,o){var r=Ji(t,Array.isArray(e)?e:[e]);Ge[n]||(Ge[n]=new WeakMap);var i=Ge[n],c=[],s=new Set,l=new Set(r),u=function(p){!p||s.has(p)||(s.add(p),u(p.parentNode))};r.forEach(u);var d=function(p){!p||l.has(p)||Array.prototype.forEach.call(p.children,function(h){if(s.has(h))d(h);else try{var m=h.getAttribute(o),w=m!==null&&m!=="false",f=(Oe.get(h)||0)+1,g=(i.get(h)||0)+1;Oe.set(h,f),i.set(h,g),c.push(h),f===1&&w&&Xe.set(h,!0),g===1&&h.setAttribute(n,"true"),w||h.setAttribute(o,"true")}catch(y){console.error("aria-hidden: cannot operate on ",h,y)}})};return d(t),s.clear(),Tt++,function(){c.forEach(function(p){var h=Oe.get(p)-1,m=i.get(p)-1;Oe.set(p,h),i.set(p,m),h||(Xe.has(p)||p.removeAttribute(o),Xe.delete(p)),m||p.removeAttribute(n)}),Tt--,Tt||(Oe=new WeakMap,Oe=new WeakMap,Xe=new WeakMap,Ge={})}},qn=function(e,t,n){n===void 0&&(n="data-aria-hidden");var o=Array.from(Array.isArray(e)?e:[e]),r=Qi(e);return r?(o.push.apply(o,Array.from(r.querySelectorAll("[aria-live], script"))),es(o,r,n,"aria-hidden")):function(){return null}};function ts(e){const t=ns(e),n=a.forwardRef((o,r)=>{const{children:i,...c}=o,s=a.Children.toArray(i),l=s.find(rs);if(l){const u=l.props.children,d=s.map(p=>p===l?a.Children.count(u)>1?a.Children.only(null):a.isValidElement(u)?u.props.children:null:p);return x.jsx(t,{...c,ref:r,children:a.isValidElement(u)?a.cloneElement(u,void 0,d):null})}return x.jsx(t,{...c,ref:r,children:i})});return n.displayName=`${e}.Slot`,n}function ns(e){const t=a.forwardRef((n,o)=>{const{children:r,...i}=n;if(a.isValidElement(r)){const c=ss(r),s=is(i,r.props);return r.type!==a.Fragment&&(s.ref=o?_e(o,c):c),a.cloneElement(r,s)}return a.Children.count(r)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var os=Symbol("radix.slottable");function rs(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===os}function is(e,t){const n={...t};for(const o in t){const r=e[o],i=t[o];/^on[A-Z]/.test(o)?r&&i?n[o]=(...s)=>{const l=i(...s);return r(...s),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...i}:o==="className"&&(n[o]=[r,i].filter(Boolean).join(" "))}return{...e,...n}}function ss(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var ft="Dialog",[Zn,Ca]=Ve(ft),[cs,te]=Zn(ft),Qn=e=>{const{__scopeDialog:t,children:n,open:o,defaultOpen:r,onOpenChange:i,modal:c=!0}=e,s=a.useRef(null),l=a.useRef(null),[u,d]=et({prop:o,defaultProp:r??!1,onChange:i,caller:ft});return x.jsx(cs,{scope:t,triggerRef:s,contentRef:l,contentId:Te(),titleId:Te(),descriptionId:Te(),open:u,onOpenChange:d,onOpenToggle:a.useCallback(()=>d(p=>!p),[d]),modal:c,children:n})};Qn.displayName=ft;var Jn="DialogTrigger",eo=a.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=te(Jn,n),i=H(t,r.triggerRef);return x.jsx(M.button,{type:"button","aria-haspopup":"dialog","aria-expanded":r.open,"aria-controls":r.contentId,"data-state":Xt(r.open),...o,ref:i,onClick:k(e.onClick,r.onOpenToggle)})});eo.displayName=Jn;var Kt="DialogPortal",[as,to]=Zn(Kt,{forceMount:void 0}),no=e=>{const{__scopeDialog:t,forceMount:n,children:o,container:r}=e,i=te(Kt,t);return x.jsx(as,{scope:t,forceMount:n,children:a.Children.map(o,c=>x.jsx(He,{present:n||i.open,children:x.jsx(Ut,{asChild:!0,container:r,children:c})}))})};no.displayName=Kt;var nt="DialogOverlay",oo=a.forwardRef((e,t)=>{const n=to(nt,e.__scopeDialog),{forceMount:o=n.forceMount,...r}=e,i=te(nt,e.__scopeDialog);return i.modal?x.jsx(He,{present:o||i.open,children:x.jsx(us,{...r,ref:t})}):null});oo.displayName=nt;var ls=ts("DialogOverlay.RemoveScroll"),us=a.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=te(nt,n);return x.jsx(zt,{as:ls,allowPinchZoom:!0,shards:[r.contentRef],children:x.jsx(M.div,{"data-state":Xt(r.open),...o,ref:t,style:{pointerEvents:"auto",...o.style}})})}),Se="DialogContent",ro=a.forwardRef((e,t)=>{const n=to(Se,e.__scopeDialog),{forceMount:o=n.forceMount,...r}=e,i=te(Se,e.__scopeDialog);return x.jsx(He,{present:o||i.open,children:i.modal?x.jsx(fs,{...r,ref:t}):x.jsx(ds,{...r,ref:t})})});ro.displayName=Se;var fs=a.forwardRef((e,t)=>{const n=te(Se,e.__scopeDialog),o=a.useRef(null),r=H(t,n.contentRef,o);return a.useEffect(()=>{const i=o.current;if(i)return qn(i)},[]),x.jsx(io,{...e,ref:r,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:k(e.onCloseAutoFocus,i=>{i.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:k(e.onPointerDownOutside,i=>{const c=i.detail.originalEvent,s=c.button===0&&c.ctrlKey===!0;(c.button===2||s)&&i.preventDefault()}),onFocusOutside:k(e.onFocusOutside,i=>i.preventDefault())})}),ds=a.forwardRef((e,t)=>{const n=te(Se,e.__scopeDialog),o=a.useRef(!1),r=a.useRef(!1);return x.jsx(io,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:i=>{e.onCloseAutoFocus?.(i),i.defaultPrevented||(o.current||n.triggerRef.current?.focus(),i.preventDefault()),o.current=!1,r.current=!1},onInteractOutside:i=>{e.onInteractOutside?.(i),i.defaultPrevented||(o.current=!0,i.detail.originalEvent.type==="pointerdown"&&(r.current=!0));const c=i.target;n.triggerRef.current?.contains(c)&&i.preventDefault(),i.detail.originalEvent.type==="focusin"&&r.current&&i.preventDefault()}})}),io=a.forwardRef((e,t)=>{const{__scopeDialog:n,trapFocus:o,onOpenAutoFocus:r,onCloseAutoFocus:i,...c}=e,s=te(Se,n),l=a.useRef(null),u=H(t,l);return Bn(),x.jsxs(x.Fragment,{children:[x.jsx(Ht,{asChild:!0,loop:!0,trapped:o,onMountAutoFocus:r,onUnmountAutoFocus:i,children:x.jsx(lt,{role:"dialog",id:s.contentId,"aria-describedby":s.descriptionId,"aria-labelledby":s.titleId,"data-state":Xt(s.open),...c,ref:u,onDismiss:()=>s.onOpenChange(!1)})}),x.jsxs(x.Fragment,{children:[x.jsx(ps,{titleId:s.titleId}),x.jsx(hs,{contentRef:l,descriptionId:s.descriptionId})]})]})}),Yt="DialogTitle",so=a.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=te(Yt,n);return x.jsx(M.h2,{id:r.titleId,...o,ref:t})});so.displayName=Yt;var co="DialogDescription",ao=a.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=te(co,n);return x.jsx(M.p,{id:r.descriptionId,...o,ref:t})});ao.displayName=co;var lo="DialogClose",uo=a.forwardRef((e,t)=>{const{__scopeDialog:n,...o}=e,r=te(lo,n);return x.jsx(M.button,{type:"button",...o,ref:t,onClick:k(e.onClick,()=>r.onOpenChange(!1))})});uo.displayName=lo;function Xt(e){return e?"open":"closed"}var fo="DialogTitleWarning",[Ea,po]=wr(fo,{contentName:Se,titleName:Yt,docsSlug:"dialog"}),ps=({titleId:e})=>{const t=po(fo),n=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users. - -If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component. - -For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return a.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},ms="DialogDescriptionWarning",hs=({contentRef:e,descriptionId:t})=>{const o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${po(ms).contentName}}.`;return a.useEffect(()=>{const r=e.current?.getAttribute("aria-describedby");t&&r&&(document.getElementById(t)||console.warn(o))},[o,e,t]),null},Ra=Qn,Pa=eo,Aa=no,Oa=oo,Ta=ro,Na=so,Ia=ao,Da=uo;const gs=["top","right","bottom","left"],de=Math.min,G=Math.max,ot=Math.round,qe=Math.floor,re=e=>({x:e,y:e}),vs={left:"right",right:"left",bottom:"top",top:"bottom"},ys={start:"end",end:"start"};function Mt(e,t,n){return G(e,de(t,n))}function ce(e,t){return typeof e=="function"?e(t):e}function ae(e){return e.split("-")[0]}function Me(e){return e.split("-")[1]}function Gt(e){return e==="x"?"y":"x"}function qt(e){return e==="y"?"height":"width"}const ws=new Set(["top","bottom"]);function oe(e){return ws.has(ae(e))?"y":"x"}function Zt(e){return Gt(oe(e))}function xs(e,t,n){n===void 0&&(n=!1);const o=Me(e),r=Zt(e),i=qt(r);let c=r==="x"?o===(n?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(c=rt(c)),[c,rt(c)]}function Ss(e){const t=rt(e);return[Lt(e),t,Lt(t)]}function Lt(e){return e.replace(/start|end/g,t=>ys[t])}const Sn=["left","right"],bn=["right","left"],bs=["top","bottom"],Cs=["bottom","top"];function Es(e,t,n){switch(e){case"top":case"bottom":return n?t?bn:Sn:t?Sn:bn;case"left":case"right":return t?bs:Cs;default:return[]}}function Rs(e,t,n,o){const r=Me(e);let i=Es(ae(e),n==="start",o);return r&&(i=i.map(c=>c+"-"+r),t&&(i=i.concat(i.map(Lt)))),i}function rt(e){return e.replace(/left|right|bottom|top/g,t=>vs[t])}function Ps(e){return{top:0,right:0,bottom:0,left:0,...e}}function mo(e){return typeof e!="number"?Ps(e):{top:e,right:e,bottom:e,left:e}}function it(e){const{x:t,y:n,width:o,height:r}=e;return{width:o,height:r,top:n,left:t,right:t+o,bottom:n+r,x:t,y:n}}function Cn(e,t,n){let{reference:o,floating:r}=e;const i=oe(t),c=Zt(t),s=qt(c),l=ae(t),u=i==="y",d=o.x+o.width/2-r.width/2,p=o.y+o.height/2-r.height/2,h=o[s]/2-r[s]/2;let m;switch(l){case"top":m={x:d,y:o.y-r.height};break;case"bottom":m={x:d,y:o.y+o.height};break;case"right":m={x:o.x+o.width,y:p};break;case"left":m={x:o.x-r.width,y:p};break;default:m={x:o.x,y:o.y}}switch(Me(t)){case"start":m[c]-=h*(n&&u?-1:1);break;case"end":m[c]+=h*(n&&u?-1:1);break}return m}const As=async(e,t,n)=>{const{placement:o="bottom",strategy:r="absolute",middleware:i=[],platform:c}=n,s=i.filter(Boolean),l=await(c.isRTL==null?void 0:c.isRTL(t));let u=await c.getElementRects({reference:e,floating:t,strategy:r}),{x:d,y:p}=Cn(u,o,l),h=o,m={},w=0;for(let f=0;f({name:"arrow",options:e,async fn(t){const{x:n,y:o,placement:r,rects:i,platform:c,elements:s,middlewareData:l}=t,{element:u,padding:d=0}=ce(e,t)||{};if(u==null)return{};const p=mo(d),h={x:n,y:o},m=Zt(r),w=qt(m),f=await c.getDimensions(u),g=m==="y",y=g?"top":"left",v=g?"bottom":"right",S=g?"clientHeight":"clientWidth",b=i.reference[w]+i.reference[m]-h[m]-i.floating[w],C=h[m]-i.reference[m],R=await(c.getOffsetParent==null?void 0:c.getOffsetParent(u));let E=R?R[S]:0;(!E||!await(c.isElement==null?void 0:c.isElement(R)))&&(E=s.floating[S]||i.floating[w]);const O=b/2-C/2,_=E/2-f[w]/2-1,I=de(p[y],_),j=de(p[v],_),F=I,L=E-f[w]-j,N=E/2-f[w]/2+O,V=Mt(F,N,L),T=!l.arrow&&Me(r)!=null&&N!==V&&i.reference[w]/2-(NN<=0)){var j,F;const N=(((j=i.flip)==null?void 0:j.index)||0)+1,V=E[N];if(V&&(!(p==="alignment"?v!==oe(V):!1)||I.every(A=>oe(A.placement)===v?A.overflows[0]>0:!0)))return{data:{index:N,overflows:I},reset:{placement:V}};let T=(F=I.filter(D=>D.overflows[0]<=0).sort((D,A)=>D.overflows[1]-A.overflows[1])[0])==null?void 0:F.placement;if(!T)switch(m){case"bestFit":{var L;const D=(L=I.filter(A=>{if(R){const W=oe(A.placement);return W===v||W==="y"}return!0}).map(A=>[A.placement,A.overflows.filter(W=>W>0).reduce((W,X)=>W+X,0)]).sort((A,W)=>A[1]-W[1])[0])==null?void 0:L[0];D&&(T=D);break}case"initialPlacement":T=s;break}if(r!==T)return{reset:{placement:T}}}return{}}}};function En(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function Rn(e){return gs.some(t=>e[t]>=0)}const Ns=function(e){return e===void 0&&(e={}),{name:"hide",options:e,async fn(t){const{rects:n}=t,{strategy:o="referenceHidden",...r}=ce(e,t);switch(o){case"referenceHidden":{const i=await $e(t,{...r,elementContext:"reference"}),c=En(i,n.reference);return{data:{referenceHiddenOffsets:c,referenceHidden:Rn(c)}}}case"escaped":{const i=await $e(t,{...r,altBoundary:!0}),c=En(i,n.floating);return{data:{escapedOffsets:c,escaped:Rn(c)}}}default:return{}}}}},ho=new Set(["left","top"]);async function Is(e,t){const{placement:n,platform:o,elements:r}=e,i=await(o.isRTL==null?void 0:o.isRTL(r.floating)),c=ae(n),s=Me(n),l=oe(n)==="y",u=ho.has(c)?-1:1,d=i&&l?-1:1,p=ce(t,e);let{mainAxis:h,crossAxis:m,alignmentAxis:w}=typeof p=="number"?{mainAxis:p,crossAxis:0,alignmentAxis:null}:{mainAxis:p.mainAxis||0,crossAxis:p.crossAxis||0,alignmentAxis:p.alignmentAxis};return s&&typeof w=="number"&&(m=s==="end"?w*-1:w),l?{x:m*d,y:h*u}:{x:h*u,y:m*d}}const Ds=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var n,o;const{x:r,y:i,placement:c,middlewareData:s}=t,l=await Is(t,e);return c===((n=s.offset)==null?void 0:n.placement)&&(o=s.arrow)!=null&&o.alignmentOffset?{}:{x:r+l.x,y:i+l.y,data:{...l,placement:c}}}}},_s=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){const{x:n,y:o,placement:r}=t,{mainAxis:i=!0,crossAxis:c=!1,limiter:s={fn:g=>{let{x:y,y:v}=g;return{x:y,y:v}}},...l}=ce(e,t),u={x:n,y:o},d=await $e(t,l),p=oe(ae(r)),h=Gt(p);let m=u[h],w=u[p];if(i){const g=h==="y"?"top":"left",y=h==="y"?"bottom":"right",v=m+d[g],S=m-d[y];m=Mt(v,m,S)}if(c){const g=p==="y"?"top":"left",y=p==="y"?"bottom":"right",v=w+d[g],S=w-d[y];w=Mt(v,w,S)}const f=s.fn({...t,[h]:m,[p]:w});return{...f,data:{x:f.x-n,y:f.y-o,enabled:{[h]:i,[p]:c}}}}}},Ms=function(e){return e===void 0&&(e={}),{options:e,fn(t){const{x:n,y:o,placement:r,rects:i,middlewareData:c}=t,{offset:s=0,mainAxis:l=!0,crossAxis:u=!0}=ce(e,t),d={x:n,y:o},p=oe(r),h=Gt(p);let m=d[h],w=d[p];const f=ce(s,t),g=typeof f=="number"?{mainAxis:f,crossAxis:0}:{mainAxis:0,crossAxis:0,...f};if(l){const S=h==="y"?"height":"width",b=i.reference[h]-i.floating[S]+g.mainAxis,C=i.reference[h]+i.reference[S]-g.mainAxis;mC&&(m=C)}if(u){var y,v;const S=h==="y"?"width":"height",b=ho.has(ae(r)),C=i.reference[p]-i.floating[S]+(b&&((y=c.offset)==null?void 0:y[p])||0)+(b?0:g.crossAxis),R=i.reference[p]+i.reference[S]+(b?0:((v=c.offset)==null?void 0:v[p])||0)-(b?g.crossAxis:0);wR&&(w=R)}return{[h]:m,[p]:w}}}},Ls=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){var n,o;const{placement:r,rects:i,platform:c,elements:s}=t,{apply:l=()=>{},...u}=ce(e,t),d=await $e(t,u),p=ae(r),h=Me(r),m=oe(r)==="y",{width:w,height:f}=i.floating;let g,y;p==="top"||p==="bottom"?(g=p,y=h===(await(c.isRTL==null?void 0:c.isRTL(s.floating))?"start":"end")?"left":"right"):(y=p,g=h==="end"?"top":"bottom");const v=f-d.top-d.bottom,S=w-d.left-d.right,b=de(f-d[g],v),C=de(w-d[y],S),R=!t.middlewareData.shift;let E=b,O=C;if((n=t.middlewareData.shift)!=null&&n.enabled.x&&(O=S),(o=t.middlewareData.shift)!=null&&o.enabled.y&&(E=v),R&&!h){const I=G(d.left,0),j=G(d.right,0),F=G(d.top,0),L=G(d.bottom,0);m?O=w-2*(I!==0||j!==0?I+j:G(d.left,d.right)):E=f-2*(F!==0||L!==0?F+L:G(d.top,d.bottom))}await l({...t,availableWidth:O,availableHeight:E});const _=await c.getDimensions(s.floating);return w!==_.width||f!==_.height?{reset:{rects:!0}}:{}}}};function dt(){return typeof window<"u"}function Le(e){return go(e)?(e.nodeName||"").toLowerCase():"#document"}function q(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function se(e){var t;return(t=(go(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function go(e){return dt()?e instanceof Node||e instanceof q(e).Node:!1}function J(e){return dt()?e instanceof Element||e instanceof q(e).Element:!1}function ie(e){return dt()?e instanceof HTMLElement||e instanceof q(e).HTMLElement:!1}function Pn(e){return!dt()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof q(e).ShadowRoot}const ks=new Set(["inline","contents"]);function Ue(e){const{overflow:t,overflowX:n,overflowY:o,display:r}=ee(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+n)&&!ks.has(r)}const js=new Set(["table","td","th"]);function Fs(e){return js.has(Le(e))}const Ws=[":popover-open",":modal"];function pt(e){return Ws.some(t=>{try{return e.matches(t)}catch{return!1}})}const $s=["transform","translate","scale","rotate","perspective"],Bs=["transform","translate","scale","rotate","perspective","filter"],Vs=["paint","layout","strict","content"];function Qt(e){const t=Jt(),n=J(e)?ee(e):e;return $s.some(o=>n[o]?n[o]!=="none":!1)||(n.containerType?n.containerType!=="normal":!1)||!t&&(n.backdropFilter?n.backdropFilter!=="none":!1)||!t&&(n.filter?n.filter!=="none":!1)||Bs.some(o=>(n.willChange||"").includes(o))||Vs.some(o=>(n.contain||"").includes(o))}function Hs(e){let t=pe(e);for(;ie(t)&&!De(t);){if(Qt(t))return t;if(pt(t))return null;t=pe(t)}return null}function Jt(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}const Us=new Set(["html","body","#document"]);function De(e){return Us.has(Le(e))}function ee(e){return q(e).getComputedStyle(e)}function mt(e){return J(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function pe(e){if(Le(e)==="html")return e;const t=e.assignedSlot||e.parentNode||Pn(e)&&e.host||se(e);return Pn(t)?t.host:t}function vo(e){const t=pe(e);return De(t)?e.ownerDocument?e.ownerDocument.body:e.body:ie(t)&&Ue(t)?t:vo(t)}function Be(e,t,n){var o;t===void 0&&(t=[]),n===void 0&&(n=!0);const r=vo(e),i=r===((o=e.ownerDocument)==null?void 0:o.body),c=q(r);if(i){const s=kt(c);return t.concat(c,c.visualViewport||[],Ue(r)?r:[],s&&n?Be(s):[])}return t.concat(r,Be(r,[],n))}function kt(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function yo(e){const t=ee(e);let n=parseFloat(t.width)||0,o=parseFloat(t.height)||0;const r=ie(e),i=r?e.offsetWidth:n,c=r?e.offsetHeight:o,s=ot(n)!==i||ot(o)!==c;return s&&(n=i,o=c),{width:n,height:o,$:s}}function en(e){return J(e)?e:e.contextElement}function Ie(e){const t=en(e);if(!ie(t))return re(1);const n=t.getBoundingClientRect(),{width:o,height:r,$:i}=yo(t);let c=(i?ot(n.width):n.width)/o,s=(i?ot(n.height):n.height)/r;return(!c||!Number.isFinite(c))&&(c=1),(!s||!Number.isFinite(s))&&(s=1),{x:c,y:s}}const zs=re(0);function wo(e){const t=q(e);return!Jt()||!t.visualViewport?zs:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function Ks(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==q(e)?!1:t}function be(e,t,n,o){t===void 0&&(t=!1),n===void 0&&(n=!1);const r=e.getBoundingClientRect(),i=en(e);let c=re(1);t&&(o?J(o)&&(c=Ie(o)):c=Ie(e));const s=Ks(i,n,o)?wo(i):re(0);let l=(r.left+s.x)/c.x,u=(r.top+s.y)/c.y,d=r.width/c.x,p=r.height/c.y;if(i){const h=q(i),m=o&&J(o)?q(o):o;let w=h,f=kt(w);for(;f&&o&&m!==w;){const g=Ie(f),y=f.getBoundingClientRect(),v=ee(f),S=y.left+(f.clientLeft+parseFloat(v.paddingLeft))*g.x,b=y.top+(f.clientTop+parseFloat(v.paddingTop))*g.y;l*=g.x,u*=g.y,d*=g.x,p*=g.y,l+=S,u+=b,w=q(f),f=kt(w)}}return it({width:d,height:p,x:l,y:u})}function ht(e,t){const n=mt(e).scrollLeft;return t?t.left+n:be(se(e)).left+n}function xo(e,t){const n=e.getBoundingClientRect(),o=n.left+t.scrollLeft-ht(e,n),r=n.top+t.scrollTop;return{x:o,y:r}}function Ys(e){let{elements:t,rect:n,offsetParent:o,strategy:r}=e;const i=r==="fixed",c=se(o),s=t?pt(t.floating):!1;if(o===c||s&&i)return n;let l={scrollLeft:0,scrollTop:0},u=re(1);const d=re(0),p=ie(o);if((p||!p&&!i)&&((Le(o)!=="body"||Ue(c))&&(l=mt(o)),ie(o))){const m=be(o);u=Ie(o),d.x=m.x+o.clientLeft,d.y=m.y+o.clientTop}const h=c&&!p&&!i?xo(c,l):re(0);return{width:n.width*u.x,height:n.height*u.y,x:n.x*u.x-l.scrollLeft*u.x+d.x+h.x,y:n.y*u.y-l.scrollTop*u.y+d.y+h.y}}function Xs(e){return Array.from(e.getClientRects())}function Gs(e){const t=se(e),n=mt(e),o=e.ownerDocument.body,r=G(t.scrollWidth,t.clientWidth,o.scrollWidth,o.clientWidth),i=G(t.scrollHeight,t.clientHeight,o.scrollHeight,o.clientHeight);let c=-n.scrollLeft+ht(e);const s=-n.scrollTop;return ee(o).direction==="rtl"&&(c+=G(t.clientWidth,o.clientWidth)-r),{width:r,height:i,x:c,y:s}}const An=25;function qs(e,t){const n=q(e),o=se(e),r=n.visualViewport;let i=o.clientWidth,c=o.clientHeight,s=0,l=0;if(r){i=r.width,c=r.height;const d=Jt();(!d||d&&t==="fixed")&&(s=r.offsetLeft,l=r.offsetTop)}const u=ht(o);if(u<=0){const d=o.ownerDocument,p=d.body,h=getComputedStyle(p),m=d.compatMode==="CSS1Compat"&&parseFloat(h.marginLeft)+parseFloat(h.marginRight)||0,w=Math.abs(o.clientWidth-p.clientWidth-m);w<=An&&(i-=w)}else u<=An&&(i+=u);return{width:i,height:c,x:s,y:l}}const Zs=new Set(["absolute","fixed"]);function Qs(e,t){const n=be(e,!0,t==="fixed"),o=n.top+e.clientTop,r=n.left+e.clientLeft,i=ie(e)?Ie(e):re(1),c=e.clientWidth*i.x,s=e.clientHeight*i.y,l=r*i.x,u=o*i.y;return{width:c,height:s,x:l,y:u}}function On(e,t,n){let o;if(t==="viewport")o=qs(e,n);else if(t==="document")o=Gs(se(e));else if(J(t))o=Qs(t,n);else{const r=wo(e);o={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return it(o)}function So(e,t){const n=pe(e);return n===t||!J(n)||De(n)?!1:ee(n).position==="fixed"||So(n,t)}function Js(e,t){const n=t.get(e);if(n)return n;let o=Be(e,[],!1).filter(s=>J(s)&&Le(s)!=="body"),r=null;const i=ee(e).position==="fixed";let c=i?pe(e):e;for(;J(c)&&!De(c);){const s=ee(c),l=Qt(c);!l&&s.position==="fixed"&&(r=null),(i?!l&&!r:!l&&s.position==="static"&&!!r&&Zs.has(r.position)||Ue(c)&&!l&&So(e,c))?o=o.filter(d=>d!==c):r=s,c=pe(c)}return t.set(e,o),o}function ec(e){let{element:t,boundary:n,rootBoundary:o,strategy:r}=e;const c=[...n==="clippingAncestors"?pt(t)?[]:Js(t,this._c):[].concat(n),o],s=c[0],l=c.reduce((u,d)=>{const p=On(t,d,r);return u.top=G(p.top,u.top),u.right=de(p.right,u.right),u.bottom=de(p.bottom,u.bottom),u.left=G(p.left,u.left),u},On(t,s,r));return{width:l.right-l.left,height:l.bottom-l.top,x:l.left,y:l.top}}function tc(e){const{width:t,height:n}=yo(e);return{width:t,height:n}}function nc(e,t,n){const o=ie(t),r=se(t),i=n==="fixed",c=be(e,!0,i,t);let s={scrollLeft:0,scrollTop:0};const l=re(0);function u(){l.x=ht(r)}if(o||!o&&!i)if((Le(t)!=="body"||Ue(r))&&(s=mt(t)),o){const m=be(t,!0,i,t);l.x=m.x+t.clientLeft,l.y=m.y+t.clientTop}else r&&u();i&&!o&&r&&u();const d=r&&!o&&!i?xo(r,s):re(0),p=c.left+s.scrollLeft-l.x-d.x,h=c.top+s.scrollTop-l.y-d.y;return{x:p,y:h,width:c.width,height:c.height}}function Nt(e){return ee(e).position==="static"}function Tn(e,t){if(!ie(e)||ee(e).position==="fixed")return null;if(t)return t(e);let n=e.offsetParent;return se(e)===n&&(n=n.ownerDocument.body),n}function bo(e,t){const n=q(e);if(pt(e))return n;if(!ie(e)){let r=pe(e);for(;r&&!De(r);){if(J(r)&&!Nt(r))return r;r=pe(r)}return n}let o=Tn(e,t);for(;o&&Fs(o)&&Nt(o);)o=Tn(o,t);return o&&De(o)&&Nt(o)&&!Qt(o)?n:o||Hs(e)||n}const oc=async function(e){const t=this.getOffsetParent||bo,n=this.getDimensions,o=await n(e.floating);return{reference:nc(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}};function rc(e){return ee(e).direction==="rtl"}const ic={convertOffsetParentRelativeRectToViewportRelativeRect:Ys,getDocumentElement:se,getClippingRect:ec,getOffsetParent:bo,getElementRects:oc,getClientRects:Xs,getDimensions:tc,getScale:Ie,isElement:J,isRTL:rc};function Co(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function sc(e,t){let n=null,o;const r=se(e);function i(){var s;clearTimeout(o),(s=n)==null||s.disconnect(),n=null}function c(s,l){s===void 0&&(s=!1),l===void 0&&(l=1),i();const u=e.getBoundingClientRect(),{left:d,top:p,width:h,height:m}=u;if(s||t(),!h||!m)return;const w=qe(p),f=qe(r.clientWidth-(d+h)),g=qe(r.clientHeight-(p+m)),y=qe(d),S={rootMargin:-w+"px "+-f+"px "+-g+"px "+-y+"px",threshold:G(0,de(1,l))||1};let b=!0;function C(R){const E=R[0].intersectionRatio;if(E!==l){if(!b)return c();E?c(!1,E):o=setTimeout(()=>{c(!1,1e-7)},1e3)}E===1&&!Co(u,e.getBoundingClientRect())&&c(),b=!1}try{n=new IntersectionObserver(C,{...S,root:r.ownerDocument})}catch{n=new IntersectionObserver(C,S)}n.observe(e)}return c(!0),i}function cc(e,t,n,o){o===void 0&&(o={});const{ancestorScroll:r=!0,ancestorResize:i=!0,elementResize:c=typeof ResizeObserver=="function",layoutShift:s=typeof IntersectionObserver=="function",animationFrame:l=!1}=o,u=en(e),d=r||i?[...u?Be(u):[],...Be(t)]:[];d.forEach(y=>{r&&y.addEventListener("scroll",n,{passive:!0}),i&&y.addEventListener("resize",n)});const p=u&&s?sc(u,n):null;let h=-1,m=null;c&&(m=new ResizeObserver(y=>{let[v]=y;v&&v.target===u&&m&&(m.unobserve(t),cancelAnimationFrame(h),h=requestAnimationFrame(()=>{var S;(S=m)==null||S.observe(t)})),n()}),u&&!l&&m.observe(u),m.observe(t));let w,f=l?be(e):null;l&&g();function g(){const y=be(e);f&&!Co(f,y)&&n(),f=y,w=requestAnimationFrame(g)}return n(),()=>{var y;d.forEach(v=>{r&&v.removeEventListener("scroll",n),i&&v.removeEventListener("resize",n)}),p?.(),(y=m)==null||y.disconnect(),m=null,l&&cancelAnimationFrame(w)}}const ac=Ds,lc=_s,uc=Ts,fc=Ls,dc=Ns,Nn=Os,pc=Ms,mc=(e,t,n)=>{const o=new Map,r={platform:ic,...n},i={...r.platform,_c:o};return As(e,t,{...r,platform:i})};var hc=typeof document<"u",gc=function(){},Je=hc?a.useLayoutEffect:gc;function st(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let n,o,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(o=n;o--!==0;)if(!st(e[o],t[o]))return!1;return!0}if(r=Object.keys(e),n=r.length,n!==Object.keys(t).length)return!1;for(o=n;o--!==0;)if(!{}.hasOwnProperty.call(t,r[o]))return!1;for(o=n;o--!==0;){const i=r[o];if(!(i==="_owner"&&e.$$typeof)&&!st(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function Eo(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function In(e,t){const n=Eo(e);return Math.round(t*n)/n}function It(e){const t=a.useRef(e);return Je(()=>{t.current=e}),t}function vc(e){e===void 0&&(e={});const{placement:t="bottom",strategy:n="absolute",middleware:o=[],platform:r,elements:{reference:i,floating:c}={},transform:s=!0,whileElementsMounted:l,open:u}=e,[d,p]=a.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[h,m]=a.useState(o);st(h,o)||m(o);const[w,f]=a.useState(null),[g,y]=a.useState(null),v=a.useCallback(A=>{A!==R.current&&(R.current=A,f(A))},[]),S=a.useCallback(A=>{A!==E.current&&(E.current=A,y(A))},[]),b=i||w,C=c||g,R=a.useRef(null),E=a.useRef(null),O=a.useRef(d),_=l!=null,I=It(l),j=It(r),F=It(u),L=a.useCallback(()=>{if(!R.current||!E.current)return;const A={placement:t,strategy:n,middleware:h};j.current&&(A.platform=j.current),mc(R.current,E.current,A).then(W=>{const X={...W,isPositioned:F.current!==!1};N.current&&!st(O.current,X)&&(O.current=X,at.flushSync(()=>{p(X)}))})},[h,t,n,j,F]);Je(()=>{u===!1&&O.current.isPositioned&&(O.current.isPositioned=!1,p(A=>({...A,isPositioned:!1})))},[u]);const N=a.useRef(!1);Je(()=>(N.current=!0,()=>{N.current=!1}),[]),Je(()=>{if(b&&(R.current=b),C&&(E.current=C),b&&C){if(I.current)return I.current(b,C,L);L()}},[b,C,L,I,_]);const V=a.useMemo(()=>({reference:R,floating:E,setReference:v,setFloating:S}),[v,S]),T=a.useMemo(()=>({reference:b,floating:C}),[b,C]),D=a.useMemo(()=>{const A={position:n,left:0,top:0};if(!T.floating)return A;const W=In(T.floating,d.x),X=In(T.floating,d.y);return s?{...A,transform:"translate("+W+"px, "+X+"px)",...Eo(T.floating)>=1.5&&{willChange:"transform"}}:{position:n,left:W,top:X}},[n,s,T.floating,d.x,d.y]);return a.useMemo(()=>({...d,update:L,refs:V,elements:T,floatingStyles:D}),[d,L,V,T,D])}const yc=e=>{function t(n){return{}.hasOwnProperty.call(n,"current")}return{name:"arrow",options:e,fn(n){const{element:o,padding:r}=typeof e=="function"?e(n):e;return o&&t(o)?o.current!=null?Nn({element:o.current,padding:r}).fn(n):{}:o?Nn({element:o,padding:r}).fn(n):{}}}},wc=(e,t)=>({...ac(e),options:[e,t]}),xc=(e,t)=>({...lc(e),options:[e,t]}),Sc=(e,t)=>({...pc(e),options:[e,t]}),bc=(e,t)=>({...uc(e),options:[e,t]}),Cc=(e,t)=>({...fc(e),options:[e,t]}),Ec=(e,t)=>({...dc(e),options:[e,t]}),Rc=(e,t)=>({...yc(e),options:[e,t]});var Pc="Arrow",Ro=a.forwardRef((e,t)=>{const{children:n,width:o=10,height:r=5,...i}=e;return x.jsx(M.svg,{...i,ref:t,width:o,height:r,viewBox:"0 0 30 10",preserveAspectRatio:"none",children:e.asChild?n:x.jsx("polygon",{points:"0,0 30,0 15,10"})})});Ro.displayName=Pc;var Ac=Ro,tn="Popper",[Po,Ao]=Ve(tn),[Oc,Oo]=Po(tn),To=e=>{const{__scopePopper:t,children:n}=e,[o,r]=a.useState(null);return x.jsx(Oc,{scope:t,anchor:o,onAnchorChange:r,children:n})};To.displayName=tn;var No="PopperAnchor",Io=a.forwardRef((e,t)=>{const{__scopePopper:n,virtualRef:o,...r}=e,i=Oo(No,n),c=a.useRef(null),s=H(t,c),l=a.useRef(null);return a.useEffect(()=>{const u=l.current;l.current=o?.current||c.current,u!==l.current&&i.onAnchorChange(l.current)}),o?null:x.jsx(M.div,{...r,ref:s})});Io.displayName=No;var nn="PopperContent",[Tc,Nc]=Po(nn),Do=a.forwardRef((e,t)=>{const{__scopePopper:n,side:o="bottom",sideOffset:r=0,align:i="center",alignOffset:c=0,arrowPadding:s=0,avoidCollisions:l=!0,collisionBoundary:u=[],collisionPadding:d=0,sticky:p="partial",hideWhenDetached:h=!1,updatePositionStrategy:m="optimized",onPlaced:w,...f}=e,g=Oo(nn,n),[y,v]=a.useState(null),S=H(t,P=>v(P)),[b,C]=a.useState(null),R=Ln(b),E=R?.width??0,O=R?.height??0,_=o+(i!=="center"?"-"+i:""),I=typeof d=="number"?d:{top:0,right:0,bottom:0,left:0,...d},j=Array.isArray(u)?u:[u],F=j.length>0,L={padding:I,boundary:j.filter(Dc),altBoundary:F},{refs:N,floatingStyles:V,placement:T,isPositioned:D,middlewareData:A}=vc({strategy:"fixed",placement:_,whileElementsMounted:(...P)=>cc(...P,{animationFrame:m==="always"}),elements:{reference:g.anchor},middleware:[wc({mainAxis:r+O,alignmentAxis:c}),l&&xc({mainAxis:!0,crossAxis:!1,limiter:p==="partial"?Sc():void 0,...L}),l&&bc({...L}),Cc({...L,apply:({elements:P,rects:U,availableWidth:Y,availableHeight:$})=>{const{width:B,height:z}=U.reference,Z=P.floating.style;Z.setProperty("--radix-popper-available-width",`${Y}px`),Z.setProperty("--radix-popper-available-height",`${$}px`),Z.setProperty("--radix-popper-anchor-width",`${B}px`),Z.setProperty("--radix-popper-anchor-height",`${z}px`)}}),b&&Rc({element:b,padding:s}),_c({arrowWidth:E,arrowHeight:O}),h&&Ec({strategy:"referenceHidden",...L})]}),[W,X]=Lo(T),ge=xe(w);K(()=>{D&&ge?.()},[D,ge]);const je=A.arrow?.x,Fe=A.arrow?.y,le=A.arrow?.centerOffset!==0,[Re,ve]=a.useState();return K(()=>{y&&ve(window.getComputedStyle(y).zIndex)},[y]),x.jsx("div",{ref:N.setFloating,"data-radix-popper-content-wrapper":"",style:{...V,transform:D?V.transform:"translate(0, -200%)",minWidth:"max-content",zIndex:Re,"--radix-popper-transform-origin":[A.transformOrigin?.x,A.transformOrigin?.y].join(" "),...A.hide?.referenceHidden&&{visibility:"hidden",pointerEvents:"none"}},dir:e.dir,children:x.jsx(Tc,{scope:n,placedSide:W,onArrowChange:C,arrowX:je,arrowY:Fe,shouldHideArrow:le,children:x.jsx(M.div,{"data-side":W,"data-align":X,...f,ref:S,style:{...f.style,animation:D?void 0:"none"}})})})});Do.displayName=nn;var _o="PopperArrow",Ic={top:"bottom",right:"left",bottom:"top",left:"right"},Mo=a.forwardRef(function(t,n){const{__scopePopper:o,...r}=t,i=Nc(_o,o),c=Ic[i.placedSide];return x.jsx("span",{ref:i.onArrowChange,style:{position:"absolute",left:i.arrowX,top:i.arrowY,[c]:0,transformOrigin:{top:"",right:"0 0",bottom:"center 0",left:"100% 0"}[i.placedSide],transform:{top:"translateY(100%)",right:"translateY(50%) rotate(90deg) translateX(-50%)",bottom:"rotate(180deg)",left:"translateY(50%) rotate(-90deg) translateX(50%)"}[i.placedSide],visibility:i.shouldHideArrow?"hidden":void 0},children:x.jsx(Ac,{...r,ref:n,style:{...r.style,display:"block"}})})});Mo.displayName=_o;function Dc(e){return e!==null}var _c=e=>({name:"transformOrigin",options:e,fn(t){const{placement:n,rects:o,middlewareData:r}=t,c=r.arrow?.centerOffset!==0,s=c?0:e.arrowWidth,l=c?0:e.arrowHeight,[u,d]=Lo(n),p={start:"0%",center:"50%",end:"100%"}[d],h=(r.arrow?.x??0)+s/2,m=(r.arrow?.y??0)+l/2;let w="",f="";return u==="bottom"?(w=c?p:`${h}px`,f=`${-l}px`):u==="top"?(w=c?p:`${h}px`,f=`${o.floating.height+l}px`):u==="right"?(w=`${-l}px`,f=c?p:`${m}px`):u==="left"&&(w=`${o.floating.width+l}px`,f=c?p:`${m}px`),{data:{x:w,y:f}}}});function Lo(e){const[t,n="center"]=e.split("-");return[t,n]}var Mc=To,Lc=Io,kc=Do,jc=Mo;function Fc(e){const t=Wc(e),n=a.forwardRef((o,r)=>{const{children:i,...c}=o,s=a.Children.toArray(i),l=s.find(Bc);if(l){const u=l.props.children,d=s.map(p=>p===l?a.Children.count(u)>1?a.Children.only(null):a.isValidElement(u)?u.props.children:null:p);return x.jsx(t,{...c,ref:r,children:a.isValidElement(u)?a.cloneElement(u,void 0,d):null})}return x.jsx(t,{...c,ref:r,children:i})});return n.displayName=`${e}.Slot`,n}function Wc(e){const t=a.forwardRef((n,o)=>{const{children:r,...i}=n;if(a.isValidElement(r)){const c=Hc(r),s=Vc(i,r.props);return r.type!==a.Fragment&&(s.ref=o?_e(o,c):c),a.cloneElement(r,s)}return a.Children.count(r)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var $c=Symbol("radix.slottable");function Bc(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===$c}function Vc(e,t){const n={...t};for(const o in t){const r=e[o],i=t[o];/^on[A-Z]/.test(o)?r&&i?n[o]=(...s)=>{const l=i(...s);return r(...s),l}:r&&(n[o]=r):o==="style"?n[o]={...r,...i}:o==="className"&&(n[o]=[r,i].filter(Boolean).join(" "))}return{...e,...n}}function Hc(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var ko=Object.freeze({position:"absolute",border:0,width:1,height:1,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",wordWrap:"normal"}),Uc="VisuallyHidden",jo=a.forwardRef((e,t)=>x.jsx(M.span,{...e,ref:t,style:{...ko,...e.style}}));jo.displayName=Uc;var _a=jo,zc=[" ","Enter","ArrowUp","ArrowDown"],Kc=[" ","Enter"],Ce="Select",[gt,vt,Yc]=Pr(Ce),[ke]=Ve(Ce,[Yc,Ao]),yt=Ao(),[Xc,me]=ke(Ce),[Gc,qc]=ke(Ce),Fo=e=>{const{__scopeSelect:t,children:n,open:o,defaultOpen:r,onOpenChange:i,value:c,defaultValue:s,onValueChange:l,dir:u,name:d,autoComplete:p,disabled:h,required:m,form:w}=e,f=yt(t),[g,y]=a.useState(null),[v,S]=a.useState(null),[b,C]=a.useState(!1),R=Br(u),[E,O]=et({prop:o,defaultProp:r??!1,onChange:i,caller:Ce}),[_,I]=et({prop:c,defaultProp:s,onChange:l,caller:Ce}),j=a.useRef(null),F=g?w||!!g.closest("form"):!0,[L,N]=a.useState(new Set),V=Array.from(L).map(T=>T.props.value).join(";");return x.jsx(Mc,{...f,children:x.jsxs(Xc,{required:m,scope:t,trigger:g,onTriggerChange:y,valueNode:v,onValueNodeChange:S,valueNodeHasChildren:b,onValueNodeHasChildrenChange:C,contentId:Te(),value:_,onValueChange:I,open:E,onOpenChange:O,dir:R,triggerPointerDownPosRef:j,disabled:h,children:[x.jsx(gt.Provider,{scope:t,children:x.jsx(Gc,{scope:e.__scopeSelect,onNativeOptionAdd:a.useCallback(T=>{N(D=>new Set(D).add(T))},[]),onNativeOptionRemove:a.useCallback(T=>{N(D=>{const A=new Set(D);return A.delete(T),A})},[]),children:n})}),F?x.jsxs(ar,{"aria-hidden":!0,required:m,tabIndex:-1,name:d,autoComplete:p,value:_,onChange:T=>I(T.target.value),disabled:h,form:w,children:[_===void 0?x.jsx("option",{value:""}):null,Array.from(L)]},V):null]})})};Fo.displayName=Ce;var Wo="SelectTrigger",$o=a.forwardRef((e,t)=>{const{__scopeSelect:n,disabled:o=!1,...r}=e,i=yt(n),c=me(Wo,n),s=c.disabled||o,l=H(t,c.onTriggerChange),u=vt(n),d=a.useRef("touch"),[p,h,m]=ur(f=>{const g=u().filter(S=>!S.disabled),y=g.find(S=>S.value===c.value),v=fr(g,f,y);v!==void 0&&c.onValueChange(v.value)}),w=f=>{s||(c.onOpenChange(!0),m()),f&&(c.triggerPointerDownPosRef.current={x:Math.round(f.pageX),y:Math.round(f.pageY)})};return x.jsx(Lc,{asChild:!0,...i,children:x.jsx(M.button,{type:"button",role:"combobox","aria-controls":c.contentId,"aria-expanded":c.open,"aria-required":c.required,"aria-autocomplete":"none",dir:c.dir,"data-state":c.open?"open":"closed",disabled:s,"data-disabled":s?"":void 0,"data-placeholder":lr(c.value)?"":void 0,...r,ref:l,onClick:k(r.onClick,f=>{f.currentTarget.focus(),d.current!=="mouse"&&w(f)}),onPointerDown:k(r.onPointerDown,f=>{d.current=f.pointerType;const g=f.target;g.hasPointerCapture(f.pointerId)&&g.releasePointerCapture(f.pointerId),f.button===0&&f.ctrlKey===!1&&f.pointerType==="mouse"&&(w(f),f.preventDefault())}),onKeyDown:k(r.onKeyDown,f=>{const g=p.current!=="";!(f.ctrlKey||f.altKey||f.metaKey)&&f.key.length===1&&h(f.key),!(g&&f.key===" ")&&zc.includes(f.key)&&(w(),f.preventDefault())})})})});$o.displayName=Wo;var Bo="SelectValue",Vo=a.forwardRef((e,t)=>{const{__scopeSelect:n,className:o,style:r,children:i,placeholder:c="",...s}=e,l=me(Bo,n),{onValueNodeHasChildrenChange:u}=l,d=i!==void 0,p=H(t,l.onValueNodeChange);return K(()=>{u(d)},[u,d]),x.jsx(M.span,{...s,ref:p,style:{pointerEvents:"none"},children:lr(l.value)?x.jsx(x.Fragment,{children:c}):i})});Vo.displayName=Bo;var Zc="SelectIcon",Ho=a.forwardRef((e,t)=>{const{__scopeSelect:n,children:o,...r}=e;return x.jsx(M.span,{"aria-hidden":!0,...r,ref:t,children:o||"▼"})});Ho.displayName=Zc;var Qc="SelectPortal",Uo=e=>x.jsx(Ut,{asChild:!0,...e});Uo.displayName=Qc;var Ee="SelectContent",zo=a.forwardRef((e,t)=>{const n=me(Ee,e.__scopeSelect),[o,r]=a.useState();if(K(()=>{r(new DocumentFragment)},[]),!n.open){const i=o;return i?at.createPortal(x.jsx(Ko,{scope:e.__scopeSelect,children:x.jsx(gt.Slot,{scope:e.__scopeSelect,children:x.jsx("div",{children:e.children})})}),i):null}return x.jsx(Yo,{...e,ref:t})});zo.displayName=Ee;var Q=10,[Ko,he]=ke(Ee),Jc="SelectContentImpl",ea=Fc("SelectContent.RemoveScroll"),Yo=a.forwardRef((e,t)=>{const{__scopeSelect:n,position:o="item-aligned",onCloseAutoFocus:r,onEscapeKeyDown:i,onPointerDownOutside:c,side:s,sideOffset:l,align:u,alignOffset:d,arrowPadding:p,collisionBoundary:h,collisionPadding:m,sticky:w,hideWhenDetached:f,avoidCollisions:g,...y}=e,v=me(Ee,n),[S,b]=a.useState(null),[C,R]=a.useState(null),E=H(t,P=>b(P)),[O,_]=a.useState(null),[I,j]=a.useState(null),F=vt(n),[L,N]=a.useState(!1),V=a.useRef(!1);a.useEffect(()=>{if(S)return qn(S)},[S]),Bn();const T=a.useCallback(P=>{const[U,...Y]=F().map(z=>z.ref.current),[$]=Y.slice(-1),B=document.activeElement;for(const z of P)if(z===B||(z?.scrollIntoView({block:"nearest"}),z===U&&C&&(C.scrollTop=0),z===$&&C&&(C.scrollTop=C.scrollHeight),z?.focus(),document.activeElement!==B))return},[F,C]),D=a.useCallback(()=>T([O,S]),[T,O,S]);a.useEffect(()=>{L&&D()},[L,D]);const{onOpenChange:A,triggerPointerDownPosRef:W}=v;a.useEffect(()=>{if(S){let P={x:0,y:0};const U=$=>{P={x:Math.abs(Math.round($.pageX)-(W.current?.x??0)),y:Math.abs(Math.round($.pageY)-(W.current?.y??0))}},Y=$=>{P.x<=10&&P.y<=10?$.preventDefault():S.contains($.target)||A(!1),document.removeEventListener("pointermove",U),W.current=null};return W.current!==null&&(document.addEventListener("pointermove",U),document.addEventListener("pointerup",Y,{capture:!0,once:!0})),()=>{document.removeEventListener("pointermove",U),document.removeEventListener("pointerup",Y,{capture:!0})}}},[S,A,W]),a.useEffect(()=>{const P=()=>A(!1);return window.addEventListener("blur",P),window.addEventListener("resize",P),()=>{window.removeEventListener("blur",P),window.removeEventListener("resize",P)}},[A]);const[X,ge]=ur(P=>{const U=F().filter(B=>!B.disabled),Y=U.find(B=>B.ref.current===document.activeElement),$=fr(U,P,Y);$&&setTimeout(()=>$.ref.current.focus())}),je=a.useCallback((P,U,Y)=>{const $=!V.current&&!Y;(v.value!==void 0&&v.value===U||$)&&(_(P),$&&(V.current=!0))},[v.value]),Fe=a.useCallback(()=>S?.focus(),[S]),le=a.useCallback((P,U,Y)=>{const $=!V.current&&!Y;(v.value!==void 0&&v.value===U||$)&&j(P)},[v.value]),Re=o==="popper"?jt:Xo,ve=Re===jt?{side:s,sideOffset:l,align:u,alignOffset:d,arrowPadding:p,collisionBoundary:h,collisionPadding:m,sticky:w,hideWhenDetached:f,avoidCollisions:g}:{};return x.jsx(Ko,{scope:n,content:S,viewport:C,onViewportChange:R,itemRefCallback:je,selectedItem:O,onItemLeave:Fe,itemTextRefCallback:le,focusSelectedItem:D,selectedItemText:I,position:o,isPositioned:L,searchRef:X,children:x.jsx(zt,{as:ea,allowPinchZoom:!0,children:x.jsx(Ht,{asChild:!0,trapped:v.open,onMountAutoFocus:P=>{P.preventDefault()},onUnmountAutoFocus:k(r,P=>{v.trigger?.focus({preventScroll:!0}),P.preventDefault()}),children:x.jsx(lt,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:i,onPointerDownOutside:c,onFocusOutside:P=>P.preventDefault(),onDismiss:()=>v.onOpenChange(!1),children:x.jsx(Re,{role:"listbox",id:v.contentId,"data-state":v.open?"open":"closed",dir:v.dir,onContextMenu:P=>P.preventDefault(),...y,...ve,onPlaced:()=>N(!0),ref:E,style:{display:"flex",flexDirection:"column",outline:"none",...y.style},onKeyDown:k(y.onKeyDown,P=>{const U=P.ctrlKey||P.altKey||P.metaKey;if(P.key==="Tab"&&P.preventDefault(),!U&&P.key.length===1&&ge(P.key),["ArrowUp","ArrowDown","Home","End"].includes(P.key)){let $=F().filter(B=>!B.disabled).map(B=>B.ref.current);if(["ArrowUp","End"].includes(P.key)&&($=$.slice().reverse()),["ArrowUp","ArrowDown"].includes(P.key)){const B=P.target,z=$.indexOf(B);$=$.slice(z+1)}setTimeout(()=>T($)),P.preventDefault()}})})})})})})});Yo.displayName=Jc;var ta="SelectItemAlignedPosition",Xo=a.forwardRef((e,t)=>{const{__scopeSelect:n,onPlaced:o,...r}=e,i=me(Ee,n),c=he(Ee,n),[s,l]=a.useState(null),[u,d]=a.useState(null),p=H(t,E=>d(E)),h=vt(n),m=a.useRef(!1),w=a.useRef(!0),{viewport:f,selectedItem:g,selectedItemText:y,focusSelectedItem:v}=c,S=a.useCallback(()=>{if(i.trigger&&i.valueNode&&s&&u&&f&&g&&y){const E=i.trigger.getBoundingClientRect(),O=u.getBoundingClientRect(),_=i.valueNode.getBoundingClientRect(),I=y.getBoundingClientRect();if(i.dir!=="rtl"){const B=I.left-O.left,z=_.left-B,Z=E.left-z,ye=E.width+Z,xt=Math.max(ye,O.width),St=window.innerWidth-Q,bt=an(z,[Q,Math.max(Q,St-xt)]);s.style.minWidth=ye+"px",s.style.left=bt+"px"}else{const B=O.right-I.right,z=window.innerWidth-_.right-B,Z=window.innerWidth-E.right-z,ye=E.width+Z,xt=Math.max(ye,O.width),St=window.innerWidth-Q,bt=an(z,[Q,Math.max(Q,St-xt)]);s.style.minWidth=ye+"px",s.style.right=bt+"px"}const j=h(),F=window.innerHeight-Q*2,L=f.scrollHeight,N=window.getComputedStyle(u),V=parseInt(N.borderTopWidth,10),T=parseInt(N.paddingTop,10),D=parseInt(N.borderBottomWidth,10),A=parseInt(N.paddingBottom,10),W=V+T+L+A+D,X=Math.min(g.offsetHeight*5,W),ge=window.getComputedStyle(f),je=parseInt(ge.paddingTop,10),Fe=parseInt(ge.paddingBottom,10),le=E.top+E.height/2-Q,Re=F-le,ve=g.offsetHeight/2,P=g.offsetTop+ve,U=V+T+P,Y=W-U;if(U<=le){const B=j.length>0&&g===j[j.length-1].ref.current;s.style.bottom="0px";const z=u.clientHeight-f.offsetTop-f.offsetHeight,Z=Math.max(Re,ve+(B?Fe:0)+z+D),ye=U+Z;s.style.height=ye+"px"}else{const B=j.length>0&&g===j[0].ref.current;s.style.top="0px";const Z=Math.max(le,V+f.offsetTop+(B?je:0)+ve)+Y;s.style.height=Z+"px",f.scrollTop=U-le+f.offsetTop}s.style.margin=`${Q}px 0`,s.style.minHeight=X+"px",s.style.maxHeight=F+"px",o?.(),requestAnimationFrame(()=>m.current=!0)}},[h,i.trigger,i.valueNode,s,u,f,g,y,i.dir,o]);K(()=>S(),[S]);const[b,C]=a.useState();K(()=>{u&&C(window.getComputedStyle(u).zIndex)},[u]);const R=a.useCallback(E=>{E&&w.current===!0&&(S(),v?.(),w.current=!1)},[S,v]);return x.jsx(oa,{scope:n,contentWrapper:s,shouldExpandOnScrollRef:m,onScrollButtonChange:R,children:x.jsx("div",{ref:l,style:{display:"flex",flexDirection:"column",position:"fixed",zIndex:b},children:x.jsx(M.div,{...r,ref:p,style:{boxSizing:"border-box",maxHeight:"100%",...r.style}})})})});Xo.displayName=ta;var na="SelectPopperPosition",jt=a.forwardRef((e,t)=>{const{__scopeSelect:n,align:o="start",collisionPadding:r=Q,...i}=e,c=yt(n);return x.jsx(kc,{...c,...i,ref:t,align:o,collisionPadding:r,style:{boxSizing:"border-box",...i.style,"--radix-select-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-select-content-available-width":"var(--radix-popper-available-width)","--radix-select-content-available-height":"var(--radix-popper-available-height)","--radix-select-trigger-width":"var(--radix-popper-anchor-width)","--radix-select-trigger-height":"var(--radix-popper-anchor-height)"}})});jt.displayName=na;var[oa,on]=ke(Ee,{}),Ft="SelectViewport",Go=a.forwardRef((e,t)=>{const{__scopeSelect:n,nonce:o,...r}=e,i=he(Ft,n),c=on(Ft,n),s=H(t,i.onViewportChange),l=a.useRef(0);return x.jsxs(x.Fragment,{children:[x.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}"},nonce:o}),x.jsx(gt.Slot,{scope:n,children:x.jsx(M.div,{"data-radix-select-viewport":"",role:"presentation",...r,ref:s,style:{position:"relative",flex:1,overflow:"hidden auto",...r.style},onScroll:k(r.onScroll,u=>{const d=u.currentTarget,{contentWrapper:p,shouldExpandOnScrollRef:h}=c;if(h?.current&&p){const m=Math.abs(l.current-d.scrollTop);if(m>0){const w=window.innerHeight-Q*2,f=parseFloat(p.style.minHeight),g=parseFloat(p.style.height),y=Math.max(f,g);if(y0?b:0,p.style.justifyContent="flex-end")}}}l.current=d.scrollTop})})})]})});Go.displayName=Ft;var qo="SelectGroup",[ra,ia]=ke(qo),sa=a.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e,r=Te();return x.jsx(ra,{scope:n,id:r,children:x.jsx(M.div,{role:"group","aria-labelledby":r,...o,ref:t})})});sa.displayName=qo;var Zo="SelectLabel",Qo=a.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e,r=ia(Zo,n);return x.jsx(M.div,{id:r.id,...o,ref:t})});Qo.displayName=Zo;var ct="SelectItem",[ca,Jo]=ke(ct),er=a.forwardRef((e,t)=>{const{__scopeSelect:n,value:o,disabled:r=!1,textValue:i,...c}=e,s=me(ct,n),l=he(ct,n),u=s.value===o,[d,p]=a.useState(i??""),[h,m]=a.useState(!1),w=H(t,v=>l.itemRefCallback?.(v,o,r)),f=Te(),g=a.useRef("touch"),y=()=>{r||(s.onValueChange(o),s.onOpenChange(!1))};if(o==="")throw new Error("A must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder.");return x.jsx(ca,{scope:n,value:o,disabled:r,textId:f,isSelected:u,onItemTextChange:a.useCallback(v=>{p(S=>S||(v?.textContent??"").trim())},[]),children:x.jsx(gt.ItemSlot,{scope:n,value:o,disabled:r,textValue:d,children:x.jsx(M.div,{role:"option","aria-labelledby":f,"data-highlighted":h?"":void 0,"aria-selected":u&&h,"data-state":u?"checked":"unchecked","aria-disabled":r||void 0,"data-disabled":r?"":void 0,tabIndex:r?void 0:-1,...c,ref:w,onFocus:k(c.onFocus,()=>m(!0)),onBlur:k(c.onBlur,()=>m(!1)),onClick:k(c.onClick,()=>{g.current!=="mouse"&&y()}),onPointerUp:k(c.onPointerUp,()=>{g.current==="mouse"&&y()}),onPointerDown:k(c.onPointerDown,v=>{g.current=v.pointerType}),onPointerMove:k(c.onPointerMove,v=>{g.current=v.pointerType,r?l.onItemLeave?.():g.current==="mouse"&&v.currentTarget.focus({preventScroll:!0})}),onPointerLeave:k(c.onPointerLeave,v=>{v.currentTarget===document.activeElement&&l.onItemLeave?.()}),onKeyDown:k(c.onKeyDown,v=>{l.searchRef?.current!==""&&v.key===" "||(Kc.includes(v.key)&&y(),v.key===" "&&v.preventDefault())})})})})});er.displayName=ct;var We="SelectItemText",tr=a.forwardRef((e,t)=>{const{__scopeSelect:n,className:o,style:r,...i}=e,c=me(We,n),s=he(We,n),l=Jo(We,n),u=qc(We,n),[d,p]=a.useState(null),h=H(t,y=>p(y),l.onItemTextChange,y=>s.itemTextRefCallback?.(y,l.value,l.disabled)),m=d?.textContent,w=a.useMemo(()=>x.jsx("option",{value:l.value,disabled:l.disabled,children:m},l.value),[l.disabled,l.value,m]),{onNativeOptionAdd:f,onNativeOptionRemove:g}=u;return K(()=>(f(w),()=>g(w)),[f,g,w]),x.jsxs(x.Fragment,{children:[x.jsx(M.span,{id:l.textId,...i,ref:h}),l.isSelected&&c.valueNode&&!c.valueNodeHasChildren?at.createPortal(i.children,c.valueNode):null]})});tr.displayName=We;var nr="SelectItemIndicator",or=a.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e;return Jo(nr,n).isSelected?x.jsx(M.span,{"aria-hidden":!0,...o,ref:t}):null});or.displayName=nr;var Wt="SelectScrollUpButton",rr=a.forwardRef((e,t)=>{const n=he(Wt,e.__scopeSelect),o=on(Wt,e.__scopeSelect),[r,i]=a.useState(!1),c=H(t,o.onScrollButtonChange);return K(()=>{if(n.viewport&&n.isPositioned){let s=function(){const u=l.scrollTop>0;i(u)};const l=n.viewport;return s(),l.addEventListener("scroll",s),()=>l.removeEventListener("scroll",s)}},[n.viewport,n.isPositioned]),r?x.jsx(sr,{...e,ref:c,onAutoScroll:()=>{const{viewport:s,selectedItem:l}=n;s&&l&&(s.scrollTop=s.scrollTop-l.offsetHeight)}}):null});rr.displayName=Wt;var $t="SelectScrollDownButton",ir=a.forwardRef((e,t)=>{const n=he($t,e.__scopeSelect),o=on($t,e.__scopeSelect),[r,i]=a.useState(!1),c=H(t,o.onScrollButtonChange);return K(()=>{if(n.viewport&&n.isPositioned){let s=function(){const u=l.scrollHeight-l.clientHeight,d=Math.ceil(l.scrollTop)l.removeEventListener("scroll",s)}},[n.viewport,n.isPositioned]),r?x.jsx(sr,{...e,ref:c,onAutoScroll:()=>{const{viewport:s,selectedItem:l}=n;s&&l&&(s.scrollTop=s.scrollTop+l.offsetHeight)}}):null});ir.displayName=$t;var sr=a.forwardRef((e,t)=>{const{__scopeSelect:n,onAutoScroll:o,...r}=e,i=he("SelectScrollButton",n),c=a.useRef(null),s=vt(n),l=a.useCallback(()=>{c.current!==null&&(window.clearInterval(c.current),c.current=null)},[]);return a.useEffect(()=>()=>l(),[l]),K(()=>{s().find(d=>d.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:"nearest"})},[s]),x.jsx(M.div,{"aria-hidden":!0,...r,ref:t,style:{flexShrink:0,...r.style},onPointerDown:k(r.onPointerDown,()=>{c.current===null&&(c.current=window.setInterval(o,50))}),onPointerMove:k(r.onPointerMove,()=>{i.onItemLeave?.(),c.current===null&&(c.current=window.setInterval(o,50))}),onPointerLeave:k(r.onPointerLeave,()=>{l()})})}),aa="SelectSeparator",cr=a.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e;return x.jsx(M.div,{"aria-hidden":!0,...o,ref:t})});cr.displayName=aa;var Bt="SelectArrow",la=a.forwardRef((e,t)=>{const{__scopeSelect:n,...o}=e,r=yt(n),i=me(Bt,n),c=he(Bt,n);return i.open&&c.position==="popper"?x.jsx(jc,{...r,...o,ref:t}):null});la.displayName=Bt;var ua="SelectBubbleInput",ar=a.forwardRef(({__scopeSelect:e,value:t,...n},o)=>{const r=a.useRef(null),i=H(o,r),c=Mn(t);return a.useEffect(()=>{const s=r.current;if(!s)return;const l=window.HTMLSelectElement.prototype,d=Object.getOwnPropertyDescriptor(l,"value").set;if(c!==t&&d){const p=new Event("change",{bubbles:!0});d.call(s,t),s.dispatchEvent(p)}},[c,t]),x.jsx(M.select,{...n,style:{...ko,...n.style},ref:i,defaultValue:t})});ar.displayName=ua;function lr(e){return e===""||e===void 0}function ur(e){const t=xe(e),n=a.useRef(""),o=a.useRef(0),r=a.useCallback(c=>{const s=n.current+c;t(s),(function l(u){n.current=u,window.clearTimeout(o.current),u!==""&&(o.current=window.setTimeout(()=>l(""),1e3))})(s)},[t]),i=a.useCallback(()=>{n.current="",window.clearTimeout(o.current)},[]);return a.useEffect(()=>()=>window.clearTimeout(o.current),[]),[n,r,i]}function fr(e,t,n){const r=t.length>1&&Array.from(t).every(u=>u===t[0])?t[0]:t,i=n?e.indexOf(n):-1;let c=fa(e,Math.max(i,0));r.length===1&&(c=c.filter(u=>u!==n));const l=c.find(u=>u.textValue.toLowerCase().startsWith(r.toLowerCase()));return l!==n?l:void 0}function fa(e,t){return e.map((n,o)=>e[(t+o)%e.length])}var Ma=Fo,La=$o,ka=Vo,ja=Ho,Fa=Uo,Wa=zo,$a=Go,Ba=Qo,Va=er,Ha=tr,Ua=or,za=rr,Ka=ir,Ya=cr,wt="Checkbox",[da]=Ve(wt),[pa,rn]=da(wt);function ma(e){const{__scopeCheckbox:t,checked:n,children:o,defaultChecked:r,disabled:i,form:c,name:s,onCheckedChange:l,required:u,value:d="on",internal_do_not_use_render:p}=e,[h,m]=et({prop:n,defaultProp:r??!1,onChange:l,caller:wt}),[w,f]=a.useState(null),[g,y]=a.useState(null),v=a.useRef(!1),S=w?!!c||!!w.closest("form"):!0,b={checked:h,disabled:i,setChecked:m,control:w,setControl:f,name:s,form:c,value:d,hasConsumerStoppedPropagationRef:v,required:u,defaultChecked:fe(r)?!1:r,isFormControl:S,bubbleInput:g,setBubbleInput:y};return x.jsx(pa,{scope:t,...b,children:va(p)?p(b):o})}var dr="CheckboxTrigger",pr=a.forwardRef(({__scopeCheckbox:e,onKeyDown:t,onClick:n,...o},r)=>{const{control:i,value:c,disabled:s,checked:l,required:u,setControl:d,setChecked:p,hasConsumerStoppedPropagationRef:h,isFormControl:m,bubbleInput:w}=rn(dr,e),f=H(r,d),g=a.useRef(l);return a.useEffect(()=>{const y=i?.form;if(y){const v=()=>p(g.current);return y.addEventListener("reset",v),()=>y.removeEventListener("reset",v)}},[i,p]),x.jsx(M.button,{type:"button",role:"checkbox","aria-checked":fe(l)?"mixed":l,"aria-required":u,"data-state":vr(l),"data-disabled":s?"":void 0,disabled:s,value:c,...o,ref:f,onKeyDown:k(t,y=>{y.key==="Enter"&&y.preventDefault()}),onClick:k(n,y=>{p(v=>fe(v)?!0:!v),w&&m&&(h.current=y.isPropagationStopped(),h.current||y.stopPropagation())})})});pr.displayName=dr;var ha=a.forwardRef((e,t)=>{const{__scopeCheckbox:n,name:o,checked:r,defaultChecked:i,required:c,disabled:s,value:l,onCheckedChange:u,form:d,...p}=e;return x.jsx(ma,{__scopeCheckbox:n,checked:r,defaultChecked:i,disabled:s,required:c,onCheckedChange:u,name:o,form:d,value:l,internal_do_not_use_render:({isFormControl:h})=>x.jsxs(x.Fragment,{children:[x.jsx(pr,{...p,ref:t,__scopeCheckbox:n}),h&&x.jsx(gr,{__scopeCheckbox:n})]})})});ha.displayName=wt;var mr="CheckboxIndicator",ga=a.forwardRef((e,t)=>{const{__scopeCheckbox:n,forceMount:o,...r}=e,i=rn(mr,n);return x.jsx(He,{present:o||fe(i.checked)||i.checked===!0,children:x.jsx(M.span,{"data-state":vr(i.checked),"data-disabled":i.disabled?"":void 0,...r,ref:t,style:{pointerEvents:"none",...e.style}})})});ga.displayName=mr;var hr="CheckboxBubbleInput",gr=a.forwardRef(({__scopeCheckbox:e,...t},n)=>{const{control:o,hasConsumerStoppedPropagationRef:r,checked:i,defaultChecked:c,required:s,disabled:l,name:u,value:d,form:p,bubbleInput:h,setBubbleInput:m}=rn(hr,e),w=H(n,m),f=Mn(i),g=Ln(o);a.useEffect(()=>{const v=h;if(!v)return;const S=window.HTMLInputElement.prototype,C=Object.getOwnPropertyDescriptor(S,"checked").set,R=!r.current;if(f!==i&&C){const E=new Event("click",{bubbles:R});v.indeterminate=fe(i),C.call(v,fe(i)?!1:i),v.dispatchEvent(E)}},[h,f,i,r]);const y=a.useRef(fe(i)?!1:i);return x.jsx(M.input,{type:"checkbox","aria-hidden":!0,defaultChecked:c??y.current,required:s,disabled:l,name:u,value:d,form:p,...t,tabIndex:-1,ref:w,style:{...t.style,...g,position:"absolute",pointerEvents:"none",opacity:0,margin:0,transform:"translateX(-100%)"}})});gr.displayName=hr;function va(e){return typeof e=="function"}function fe(e){return e==="indeterminate"}function vr(e){return fe(e)?"indeterminate":e?"checked":"unchecked"}export{ha as $,Ha as A,Ya as B,Ta as C,Ia as D,Ma as E,ka as F,_e as G,Ut as H,ja as I,Ao as J,qn as K,Ba as L,zt as M,Bn as N,Oa as O,M as P,Ht as Q,xa as R,wa as S,Na as T,lt as U,$a as V,Ea as W,kc as X,Mc as Y,Lc as Z,jc as _,Pr as a,ga as a0,kr as a1,_a as a2,ba as a3,jo as a4,Sa as a5,k as b,Ve as c,H as d,Br as e,et as f,xe as g,He as h,K as i,an as j,_n as k,Mn as l,Ln as m,Aa as n,Da as o,Ra as p,Pa as q,Ca as r,La as s,za as t,Te as u,Ka as v,Fa as w,Wa as x,Va as y,Ua as z}; diff --git a/webui/dist/assets/uppy-x-2TBvZ1.js b/webui/dist/assets/uppy-x-2TBvZ1.js new file mode 100644 index 00000000..38cfc9fd --- /dev/null +++ b/webui/dist/assets/uppy-x-2TBvZ1.js @@ -0,0 +1,11 @@ +import{g as re}from"./react-vendor-BmxF9s7Q.js";import{r as Ti,a as gs,b as ys}from"./reactflow-DtsZHOR4.js";import"./router-9vIXuQkh.js";import"./charts-simvewUa.js";import"./radix-extra-CTMrA3du.js";const bs=/^data:([^/]+\/[^,;]+(?:[^,]*?))(;base64)?,([\s\S]*)$/;function vs(i,e,t){const s=bs.exec(i),n=e.mimeType??s?.[1]??"plain/text";let r;if(s?.[2]!=null){const a=atob(decodeURIComponent(s[3])),o=new Uint8Array(a.length);for(let d=0;d(e+=`-${_s(t)}`,"/"))+e}function Fs(i,e){let t=e||"uppy";return typeof i.name=="string"&&(t+=`-${Nt(i.name.toLowerCase())}`),i.type!==void 0&&(t+=`-${i.type}`),i.meta&&typeof i.meta.relativePath=="string"&&(t+=`-${Nt(i.meta.relativePath.toLowerCase())}`),i.data?.size!==void 0&&(t+=`-${i.data.size}`),i.data.lastModified!==void 0&&(t+=`-${i.data.lastModified}`),t}function Ss(i){return!i.isRemote||!i.remote?!1:new Set(["box","dropbox","drive","facebook","unsplash"]).has(i.remote.provider)}function Ts(i,e){if(Ss(i))return i.id;const t=ki(i);return Fs({...i,type:t},e)}const ue=Array.from;function Ps(i){const e=ue(i.files);return Promise.resolve(e)}function Ai(i,e,t,{onSuccess:s}){i.readEntries(n=>{const r=[...e,...n];n.length?queueMicrotask(()=>{Ai(i,r,t,{onSuccess:s})}):s(r)},n=>{t(n),s(e)})}function Oi(i,e){return i==null?i:{kind:i.isFile?"file":i.isDirectory?"directory":void 0,name:i.name,getFile(){return new Promise((t,s)=>i.file(t,s))},async*values(){const t=i.createReader();yield*await new Promise(n=>{Ai(t,[],e,{onSuccess:r=>n(r.map(a=>Oi(a,e)))})})},isSameEntry:void 0}}async function*Ui(i,e,t=void 0){const s=()=>`${e}/${i.name}`;if(i.kind==="file"){const n=await i.getFile();n!=null?(n.relativePath=e?s():null,yield n):t!=null&&(yield t)}else if(i.kind==="directory")for await(const n of i.values())yield*Ui(n,e?s():i.name);else t!=null&&(yield t)}async function*Cs(i,e){const t=await Promise.all(Array.from(i.items,async s=>{let n;return n??=Oi(typeof s.getAsEntry=="function"?s.getAsEntry():s.webkitGetAsEntry(),e),{fileSystemHandle:n,lastResortFile:s.getAsFile()}}));for(const{lastResortFile:s,fileSystemHandle:n}of t)if(n!=null)try{yield*Ui(n,"",s)}catch(r){s!=null?yield s:e(r)}else s!=null&&(yield s)}async function Es(i,e){const t=e?.logDropError??Function.prototype;try{const s=[];for await(const n of Cs(i,t))s.push(n);return s}catch{return Ps(i)}}function ks(i){for(;i&&!i.dir;)i=i.parentNode;return i?.dir}function Me(i){return i<10?`0${i}`:i.toString()}function Oe(){const i=new Date,e=Me(i.getHours()),t=Me(i.getMinutes()),s=Me(i.getSeconds());return`${e}:${t}:${s}`}function As(){if(typeof window>"u")return!1;const i=document.body;return!(i==null||window==null||!("draggable"in i)||!("ondragstart"in i)||!("ondrop"in i)||!("FormData"in window)||!("FileReader"in window))}function Dt(i){return i.startsWith("blob:")}function It(i){return i?/^[^/]+\/(jpe?g|gif|png|svg|svg\+xml|bmp|webp|avif)$/.test(i):!1}function Os(i){const e=Math.floor(i/3600)%24,t=Math.floor(i/60)%60,s=Math.floor(i%60);return{hours:e,minutes:t,seconds:s}}function Us(i){const e=Os(i),t=e.hours===0?"":`${e.hours}h`,s=e.minutes===0?"":`${e.hours===0?e.minutes:` ${e.minutes.toString(10).padStart(2,"0")}`}m`,n=e.hours!==0?"":`${e.minutes===0?e.seconds:` ${e.seconds.toString(10).padStart(2,"0")}`}s`;return`${t}${s}${n}`}function Ns(i,e,t){const s=[];return i.forEach(n=>typeof n!="string"?s.push(n):e[Symbol.split](n).forEach((r,a,o)=>{r!==""&&s.push(r),a{throw new Error(`missing string: ${i}`)};class Ni{locale;constructor(e,{onMissingKey:t=Ds}={}){this.locale={strings:{},pluralize(s){return s===1?0:1}},Array.isArray(e)?e.forEach(this.#t,this):this.#t(e),this.#e=t}#e;#t(e){if(!e?.strings)return;const t=this.locale;Object.assign(this.locale,{strings:{...t.strings,...e.strings},pluralize:e.pluralize||t.pluralize})}translate(e,t){return this.translateArray(e,t).join("")}translateArray(e,t){let s=this.locale.strings[e];if(s==null&&(this.#e(e),s=e),typeof s=="object"){if(t&&typeof t.smart_count<"u"){const r=this.locale.pluralize(t.smart_count);return xt(s[r],t)}throw new Error("Attempted to use a string with plural forms, but no value was given for %{smart_count}")}if(typeof s!="string")throw new Error("string was not a string");return xt(s,t)}}const Be="...";function Di(i,e){if(e===0)return"";if(i.length<=e)return i;if(e<=Be.length+1)return`${i.slice(0,e-1)}…`;const t=e-Be.length,s=Math.ceil(t/2),n=Math.floor(t/2);return i.slice(0,s)+Be+i.slice(-n)}var ye,T,Ii,Q,Mt,xi,Mi,Bi,ut,tt,it,ce={},Ri=[],Is=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,be=Array.isArray;function V(i,e){for(var t in e)i[t]=e[t];return i}function ht(i){i&&i.parentNode&&i.parentNode.removeChild(i)}function ct(i,e,t){var s,n,r,a={};for(r in e)r=="key"?s=e[r]:r=="ref"?n=e[r]:a[r]=e[r];if(arguments.length>2&&(a.children=arguments.length>3?ye.call(arguments,2):t),typeof i=="function"&&i.defaultProps!=null)for(r in i.defaultProps)a[r]===void 0&&(a[r]=i.defaultProps[r]);return he(i,a,s,n,null)}function he(i,e,t,s,n){var r={type:i,props:e,key:t,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:n??++Ii,__i:-1,__u:0};return n==null&&T.vnode!=null&&T.vnode(r),r}function xs(){return{current:null}}function G(i){return i.children}function W(i,e){this.props=i,this.context=e}function se(i,e){if(e==null)return i.__?se(i.__,i.__i+1):null;for(var t;eo&&Q.sort(Mi),i=Q.shift(),o=Q.length,i.__d&&(t=void 0,s=void 0,n=(s=(e=i).__v).__e,r=[],a=[],e.__P&&((t=V({},s)).__v=s.__v+1,T.vnode&&T.vnode(t),pt(e.__P,t,s,e.__n,e.__P.namespaceURI,32&s.__u?[n]:null,r,n??se(s),!!(32&s.__u),a),t.__v=s.__v,t.__.__k[t.__i]=t,Hi(r,t,a),s.__e=s.__=null,t.__e!=n&&Li(t)));Ne.__r=0}function zi(i,e,t,s,n,r,a,o,d,u,c){var h,p,f,m,y,v,b,g=s&&s.__k||Ri,w=e.length;for(d=Ms(t,e,g,d,w),h=0;h0?he(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):a).__=i,a.__b=i.__b+1,o=null,(u=a.__i=Bs(a,t,d,h))!=-1&&(h--,(o=t[u])&&(o.__u|=2)),o==null||o.__v==null?(u==-1&&(n>c?p--:nd?p--:p++,a.__u|=4))):i.__k[r]=null;if(h)for(r=0;r(c?1:0)){for(n=t-1,r=t+1;n>=0||r=0?n--:r++])!=null&&(2&u.__u)==0&&o==u.key&&d==u.type)return a}return-1}function Rt(i,e,t){e[0]=="-"?i.setProperty(e,t??""):i[e]=t==null?"":typeof t!="number"||Is.test(e)?t:t+"px"}function we(i,e,t,s,n){var r,a;e:if(e=="style")if(typeof t=="string")i.style.cssText=t;else{if(typeof s=="string"&&(i.style.cssText=s=""),s)for(e in s)t&&e in t||Rt(i.style,e,"");if(t)for(e in t)s&&t[e]==s[e]||Rt(i.style,e,t[e])}else if(e[0]=="o"&&e[1]=="n")r=e!=(e=e.replace(Bi,"$1")),a=e.toLowerCase(),e=a in i||e=="onFocusOut"||e=="onFocusIn"?a.slice(2):e.slice(2),i.l||(i.l={}),i.l[e+r]=t,t?s?t.u=s.u:(t.u=ut,i.addEventListener(e,r?it:tt,r)):i.removeEventListener(e,r?it:tt,r);else{if(n=="http://www.w3.org/2000/svg")e=e.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(e!="width"&&e!="height"&&e!="href"&&e!="list"&&e!="form"&&e!="tabIndex"&&e!="download"&&e!="rowSpan"&&e!="colSpan"&&e!="role"&&e!="popover"&&e in i)try{i[e]=t??"";break e}catch{}typeof t=="function"||(t==null||t===!1&&e[4]!="-"?i.removeAttribute(e):i.setAttribute(e,e=="popover"&&t==1?"":t))}}function Lt(i){return function(e){if(this.l){var t=this.l[e.type+i];if(e.t==null)e.t=ut++;else if(e.t0?i:be(i)?i.map(qi):V({},i)}function Rs(i,e,t,s,n,r,a,o,d){var u,c,h,p,f,m,y,v=t.props,b=e.props,g=e.type;if(g=="svg"?n="http://www.w3.org/2000/svg":g=="math"?n="http://www.w3.org/1998/Math/MathML":n||(n="http://www.w3.org/1999/xhtml"),r!=null){for(u=0;u2&&(o.children=arguments.length>3?ye.call(arguments,2):t),he(i.type,o,s||i.key,n||i.ref,null)}ye=Ri.slice,T={__e:function(i,e,t,s){for(var n,r,a;e=e.__;)if((n=e.__c)&&!n.__)try{if((r=n.constructor)&&r.getDerivedStateFromError!=null&&(n.setState(r.getDerivedStateFromError(i)),a=n.__d),n.componentDidCatch!=null&&(n.componentDidCatch(i,s||{}),a=n.__d),a)return n.__E=n}catch(o){i=o}throw i}},Ii=0,W.prototype.setState=function(i,e){var t;t=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=V({},this.state),typeof i=="function"&&(i=i(V({},t),this.props)),i&&V(t,i),i!=null&&this.__v&&(e&&this._sb.push(e),Bt(this))},W.prototype.forceUpdate=function(i){this.__v&&(this.__e=!0,i&&this.__h.push(i),Bt(this))},W.prototype.render=G,Q=[],xi=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Mi=function(i,e){return i.__v.__b-e.__v.__b},Ne.__r=0,Bi=/(PointerCapture)$|Capture$/i,ut=0,tt=Lt(!1),it=Lt(!0);var zs=0;function l(i,e,t,s,n,r){e||(e={});var a,o,d=e;if("ref"in d)for(o in d={},e)o=="ref"?a=e[o]:d[o]=e[o];var u={type:i,props:d,key:t,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--zs,__i:-1,__u:0,__source:n,__self:r};if(typeof i=="function"&&(a=i.defaultProps))for(o in a)d[o]===void 0&&(d[o]=a[o]);return T.vnode&&T.vnode(u),u}var pe,k,Re,$t,fe=0,Wi=[],O=T,Ht=O.__b,qt=O.__r,jt=O.diffed,Vt=O.__c,Wt=O.unmount,Gt=O.__;function mt(i,e){O.__h&&O.__h(k,i,fe||e),fe=0;var t=k.__H||(k.__H={__:[],__h:[]});return i>=t.__.length&&t.__.push({}),t.__[i]}function ne(i){return fe=1,$s(Ki,i)}function $s(i,e,t){var s=mt(pe++,2);if(s.t=i,!s.__c&&(s.__=[Ki(void 0,e),function(o){var d=s.__N?s.__N[0]:s.__[0],u=s.t(d,o);d!==u&&(s.__N=[u,s.__[1]],s.__c.setState({}))}],s.__c=k,!k.__f)){var n=function(o,d,u){if(!s.__c.__H)return!0;var c=s.__c.__H.__.filter(function(p){return!!p.__c});if(c.every(function(p){return!p.__N}))return!r||r.call(this,o,d,u);var h=s.__c.props!==o;return c.forEach(function(p){if(p.__N){var f=p.__[0];p.__=p.__N,p.__N=void 0,f!==p.__[0]&&(h=!0)}}),r&&r.call(this,o,d,u)||h};k.__f=!0;var r=k.shouldComponentUpdate,a=k.componentWillUpdate;k.componentWillUpdate=function(o,d,u){if(this.__e){var c=r;r=void 0,n(o,d,u),r=c}a&&a.call(this,o,d,u)},k.shouldComponentUpdate=n}return s.__N||s.__}function De(i,e){var t=mt(pe++,3);!O.__s&&Gi(t.__H,e)&&(t.__=i,t.u=e,k.__H.__h.push(t))}function ie(i){return fe=5,gt(function(){return{current:i}},[])}function gt(i,e){var t=mt(pe++,7);return Gi(t.__H,e)&&(t.__=i(),t.__H=e,t.__h=i),t.__}function Ie(i,e){return fe=8,gt(function(){return i},e)}function Hs(){for(var i;i=Wi.shift();)if(i.__P&&i.__H)try{i.__H.__h.forEach(Ue),i.__H.__h.forEach(nt),i.__H.__h=[]}catch(e){i.__H.__h=[],O.__e(e,i.__v)}}O.__b=function(i){k=null,Ht&&Ht(i)},O.__=function(i,e){i&&e.__k&&e.__k.__m&&(i.__m=e.__k.__m),Gt&&Gt(i,e)},O.__r=function(i){qt&&qt(i),pe=0;var e=(k=i.__c).__H;e&&(Re===k?(e.__h=[],k.__h=[],e.__.forEach(function(t){t.__N&&(t.__=t.__N),t.u=t.__N=void 0})):(e.__h.forEach(Ue),e.__h.forEach(nt),e.__h=[],pe=0)),Re=k},O.diffed=function(i){jt&&jt(i);var e=i.__c;e&&e.__H&&(e.__H.__h.length&&(Wi.push(e)!==1&&$t===O.requestAnimationFrame||(($t=O.requestAnimationFrame)||qs)(Hs)),e.__H.__.forEach(function(t){t.u&&(t.__H=t.u),t.u=void 0})),Re=k=null},O.__c=function(i,e){e.some(function(t){try{t.__h.forEach(Ue),t.__h=t.__h.filter(function(s){return!s.__||nt(s)})}catch(s){e.some(function(n){n.__h&&(n.__h=[])}),e=[],O.__e(s,t.__v)}}),Vt&&Vt(i,e)},O.unmount=function(i){Wt&&Wt(i);var e,t=i.__c;t&&t.__H&&(t.__H.__.forEach(function(s){try{Ue(s)}catch(n){e=n}}),t.__H=void 0,e&&O.__e(e,t.__v))};var Kt=typeof requestAnimationFrame=="function";function qs(i){var e,t=function(){clearTimeout(s),Kt&&cancelAnimationFrame(e),setTimeout(i)},s=setTimeout(t,35);Kt&&(e=requestAnimationFrame(t))}function Ue(i){var e=k,t=i.__c;typeof t=="function"&&(i.__c=void 0,t()),k=e}function nt(i){var e=k;i.__c=i.__(),k=e}function Gi(i,e){return!i||i.length!==e.length||e.some(function(t,s){return t!==i[s]})}function Ki(i,e){return typeof e=="function"?e(i):e}const js={position:"relative",width:"100%",minHeight:"100%"},Vs={position:"absolute",top:0,left:0,width:"100%",overflow:"visible"};function Ws({data:i,rowHeight:e,renderRow:t,overscanCount:s=10,padding:n=4,...r}){const a=ie(null),[o,d]=ne(0),[u,c]=ne(0);De(()=>{function g(){a.current!=null&&u!==a.current.offsetHeight&&c(a.current.offsetHeight)}return g(),window.addEventListener("resize",g),()=>{window.removeEventListener("resize",g)}},[u]);const h=Ie(()=>{a.current&&d(a.current.scrollTop)},[]);let p=Math.floor(o/e),f=Math.floor(u/e);s&&(p=Math.max(0,p-p%s),f+=s);const m=p+f+n,y=i.slice(p,m),v={...js,height:i.length*e},b={...Vs,top:p*e};return l("div",{onScroll:h,ref:a,...r,children:l("div",{role:"presentation",style:v,children:l("div",{role:"presentation",style:b,children:y.map(t)})})})}class Gs{uppy;opts;id;defaultLocale;i18n;i18nArray;type;VERSION;constructor(e,t){this.uppy=e,this.opts=t??{}}getPluginState(){const{plugins:e}=this.uppy.getState();return e?.[this.id]||{}}setPluginState(e){const{plugins:t}=this.uppy.getState();this.uppy.setState({plugins:{...t,[this.id]:{...t[this.id],...e}}})}setOptions(e){this.opts={...this.opts,...e},this.setPluginState(void 0),this.i18nInit()}i18nInit(){const e=new Ni([this.defaultLocale,this.uppy.locale,this.opts.locale]);this.i18n=e.translate.bind(e),this.i18nArray=e.translateArray.bind(e),this.setPluginState(void 0)}addTarget(e){throw new Error("Extend the addTarget method to add your plugin to another plugin's target")}install(){}uninstall(){}update(e){}afterUpdate(){}}const Ks={debug:()=>{},warn:()=>{},error:(...i)=>console.error(`[Uppy] [${Oe()}]`,...i)},Xs={debug:(...i)=>console.debug(`[Uppy] [${Oe()}]`,...i),warn:(...i)=>console.warn(`[Uppy] [${Oe()}]`,...i),error:(...i)=>console.error(`[Uppy] [${Oe()}]`,...i)};var Le,Xt;function Ys(){return Xt||(Xt=1,Le=function(e){if(typeof e!="number"||Number.isNaN(e))throw new TypeError(`Expected a number, got ${typeof e}`);const t=e<0;let s=Math.abs(e);if(t&&(s=-s),s===0)return"0 B";const n=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],r=Math.min(Math.floor(Math.log(s)/Math.log(1024)),n.length-1),a=Number(s/1024**r),o=n[r];return`${a>=10||a%1===0?Math.round(a):a.toFixed(1)} ${o}`}),Le}var Qs=Ys();const J=re(Qs);var ze,Yt;function Js(){if(Yt)return ze;Yt=1;function i(e,t){this.text=e=e||"",this.hasWild=~e.indexOf("*"),this.separator=t,this.parts=e.split(t)}return i.prototype.match=function(e){var t=!0,s=this.parts,n,r=s.length,a;if(typeof e=="string"||e instanceof String)if(!this.hasWild&&this.text!=e)t=!1;else{for(a=(e||"").split(this.separator),n=0;t&&n=2}return s?n(s.split(";")[0]):n},$e}var en=Zs();const tn=re(en),sn={maxFileSize:null,minFileSize:null,maxTotalFileSize:null,maxNumberOfFiles:null,minNumberOfFiles:null,allowedFileTypes:null,requiredMetaFields:[]};class R extends Error{isUserFacing;file;constructor(e,t){super(e),this.isUserFacing=t?.isUserFacing??!0,t?.file&&(this.file=t.file)}isRestriction=!0}class nn{getI18n;getOpts;constructor(e,t){this.getI18n=t,this.getOpts=()=>{const s=e();if(s.restrictions?.allowedFileTypes!=null&&!Array.isArray(s.restrictions.allowedFileTypes))throw new TypeError("`restrictions.allowedFileTypes` must be an array");return s}}validateAggregateRestrictions(e,t){const{maxTotalFileSize:s,maxNumberOfFiles:n}=this.getOpts().restrictions;if(n&&e.filter(a=>!a.isGhost).length+t.length>n)throw new R(`${this.getI18n()("youCanOnlyUploadX",{smart_count:n})}`);if(s){const r=[...e,...t].reduce((a,o)=>a+(o.size??0),0);if(r>s)throw new R(this.getI18n()("aggregateExceedsSize",{sizeAllowed:J(s),size:J(r)}))}}validateSingleFile(e){const{maxFileSize:t,minFileSize:s,allowedFileTypes:n}=this.getOpts().restrictions;if(n&&!n.some(a=>a.includes("/")?e.type?tn(e.type.replace(/;.*?$/,""),a):!1:a[0]==="."&&e.extension?e.extension.toLowerCase()===a.slice(1).toLowerCase():!1)){const a=n.join(", ");throw new R(this.getI18n()("youCanOnlyUploadFileTypes",{types:a}),{file:e})}if(t&&e.size!=null&&e.size>t)throw new R(this.getI18n()("exceedsSize",{size:J(t),file:e.name??this.getI18n()("unnamed")}),{file:e});if(s&&e.size!=null&&e.size{this.validateSingleFile(s)}),this.validateAggregateRestrictions(e,t)}validateMinNumberOfFiles(e){const{minNumberOfFiles:t}=this.getOpts().restrictions;if(t&&Object.keys(e).length(t=s,e||(e=Promise.resolve().then(()=>(e=null,i(...t)))),e)}class me extends Gs{#e;isTargetDOMEl;el;parent;title;getTargetPlugin(e){let t;if(typeof e?.addTarget=="function")t=e,t instanceof me||console.warn(new Error("The provided plugin is not an instance of UIPlugin. This is an indication of a bug with the way Uppy is bundled.",{cause:{targetPlugin:t,UIPlugin:me}}));else if(typeof e=="function"){const s=e;this.uppy.iteratePlugins(n=>{n instanceof s&&(t=n)})}return t}mount(e,t){const s=t.id,n=ws(e);if(n){this.isTargetDOMEl=!0;const o=document.createElement("div");return o.classList.add("uppy-Root"),this.#e=rn(d=>{this.uppy.getPlugin(this.id)&&(zt(this.render(d,o),o),this.afterUpdate())}),this.uppy.log(`Installing ${s} to a DOM element '${e}'`),this.opts.replaceTargetContent&&(n.innerHTML=""),zt(this.render(this.uppy.getState(),o),o),this.el=o,n.appendChild(o),o.dir=this.opts.direction||ks(o)||"ltr",this.onMount(),this.el}const r=this.getTargetPlugin(e);if(r)return this.uppy.log(`Installing ${s} to ${r.id}`),this.parent=r,this.el=r.addTarget(t),this.onMount(),this.el;this.uppy.log(`Not installing ${s}`);let a=`Invalid target option given to ${s}.`;throw typeof e=="function"?a+=" The given target is not a Plugin class. Please check that you're not specifying a React Component instead of a plugin. If you are using @uppy/* packages directly, make sure you have only 1 version of @uppy/core installed: run `npm ls @uppy/core` on the command line and verify that all the versions match and are deduped correctly.":a+="If you meant to target an HTML element, please make sure that the element exists. Check that the - - - - - - + + + + + + + + + + + + + + + -
+
diff --git a/webui/dist/maimai.ico b/webui/dist/maimai.ico index 578b11cd..3c1b131e 100644 Binary files a/webui/dist/maimai.ico and b/webui/dist/maimai.ico differ diff --git a/webui/dist/vite.svg b/webui/dist/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/webui/dist/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file
请求类型调用次数输入Token输出TokenToken总量累计花费平均耗时(秒)标准差(秒)
请求类型调用次数输入Token输出TokenToken总量累计花费平均耗时(秒)标准差(秒)每次回复平均调用次数每次回复平均Token数